flow on terrainsltoma/teaching/cs3225-gis/fall15/... · flow accumulation: smarter algorithms? •...

55
Laura Toma csci 3225 Algorithms for GIS Bowdoin College Flow on terrains

Upload: others

Post on 17-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Laura Toma csci 3225

Algorithms for GIS Bowdoin College

Flow on terrains

Page 2: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Overview

• Flow on grids (discrete) • flow direction • flow accumulation • algorithms for FD and FA • dealing with flat areas • watershed hierarchy

• Flow on TINs (geometric)

• Flooding

Page 3: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

• Where does the water go when it rains? • What will happen when it rains (a lot)? • What are the areas susceptible to flooding? • What areas will flood first? • What parts of the world will go under water when water rises by e.g. 10 ft? • River data is expensive to collect. Is it possible to model and automatically

compute rivers on a terrain? • What is the area that drains to a point? • Suppose I spilled (some pollutant) at this point on the terrain—-what area is

contaminated when it rains ? • Risks of landslides? • …

Page 4: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow on digital terrain models

river network, watersheds, flooding,

…..

Page 5: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Digital terrain models

grid TIN

Page 6: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Big data

• Massive amounts of terrain data available • e.g. NASA SRTM, acquired 80% of Earth at 30m

resolution. Total 5TB !! • USGS: most USA at 10m resolution • LIDAR data: 1m resolution

==> need efficient algorithms!

• Example: • Area if approx. 800 km x 800 km • Sampled at:

• 100 resolution: 64 million points (128MB)• 30m resolution: 640 (1.2GB) • 10m resolution: 6400 = 6.4 billion (12GB) • 1m resolution: 600.4 billion (1.2TB)

Page 7: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow on terrains

• Modeled by

• Flow direction (FD) • the direction water flows at a point

• Flow accumulation (FA) • total amount of water flowing through a point

• (Pfafstteter) river and watershed hierarchy

Page 8: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow on grid terrains

Page 9: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow direction (FD)

• FD(p) = the direction water flows at p • Generally,

• FD is direction of gradient at p, i.e. direction of greatest decrease • FD can be approximated based on a neighborhood of p

• FD on grids: • discretized to eight directions (8 neighbors), multiple of 45o • SFD: Single flow direction (steepest downslope) • MFD: Multiple flow directions (all downslope neighbors)

Page 10: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow direction

elevation grid FD grid

n = nb. of cells in the grid

• FD can be computed in O(n) time • Issue: flat areas… later

point (i,j) in FD grid stores FD(i,j) values usually coded as

1248

1632 64 128

Page 11: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow directionn = nb. of cells in the grid

Page 12: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation (FA)

• FA(p) = how much water goes through point p

• FA grid: • Compute, for each point/cell c, how much

water passes through that cell.

Page 13: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation (FA)

• FA(p) = how much water goes through point p

• FA grid: • Compute, for each point/cell c, how much

water passes through that cell.

elevation grid FD grid FA grid

Page 14: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FD and FA

• Some observations • FD graph: forest of trees • each tree represents a river tree • points with small FA= ridges • points with high FA = channels • FA: how many cells are upstream, or size of

subtree of that cell, if viewing the tree upside down

• FA models rivers!

Page 15: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation

FA grid draped over elevation gridFA 2D view

• high values: blue • medium values: light blue • low values: yellow

Page 16: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithms

• Idea 1: • Scan row-by-row: for each cell add +1 to flow of all cells along its

downstream path

• Idea 2: • Flow at cell c is the sum of the flows of the neighbors that flow into c • Use recursion • Do this for every cell

Page 17: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithms

• Idea 1: • Scan row-by-row: for each cell add +1 to flow of all cells along its

downstream path • Analysis??

• Idea 2: • Flow at cell c is the sum of the flows of the neighbors that flow into c • Use recursion • Do this for every cell • Analysis??

Page 18: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 19: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 20: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 21: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 22: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 23: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 24: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 25: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 26: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 27: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 28: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 29: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

thanks!!! to H. Haverkort

Page 30: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithm (1)

worst-case running time

Theta(n2)

n = nb. of cells in the grid

thanks!!! to H. Haverkort

Page 31: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

//do it for all

for (i=0; i<nrows; i++)

for (j=0; j<ncols; j++)

flow[i][j] =compute_flow(i,j);

Computing FA: naive algorithm (2)

//return the flow of cell (i,j) void compute_flow(i,j) { assert(inside_grid(i,j)); int f = 0; //initial flow at (i,j) for (k=-1; k<= 1; k++) { for (l=-1; l<= 1; l++) { if flows_into(i+k, j+l, i,j) f += compute_flow(i+k, j+l); }//for k }//for l return f; }

//return 1 if cell (a,b) flows into cell (x,y) // that is, if (a,b)’s FD points towards (x,y) int flows_into(a,b, x,y) { if (!inside_grid(a,b)) return 0; … }

Page 32: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

• Questions: • What is the worst case running time? • Sketch a grid direction graph that triggers worst-case

Computing FA: naive algorithm (2)n = nb. of cells in the grid

Page 33: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing FA: naive algorithms

• Idea 1: • scan row-by-row: for each cell add +1 to flow of all cells along its

downstream path

• Idea 2: • flow at cell c is the sum of the flows of the neighbors that flow into c • use recursion • do this for every cell

worst-case running time

Theta(n2)

n = nb. of cells in the grid

Page 34: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation: smarter algorithms?

• Ideas?

Page 35: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation: smarter algorithms?

• Extend idea 2: Use recursion, but once a value flow(i,j) is computed, store it in a table. This avoids recomputation.

• i.e. dynamic programming

• To completely avoid recursion, compute flow(i,j) in topological order of FD graph • topological order can be computed in linear time • or: sort by height, but that’s O( n lg n)

How fast are these?

n = nb. of cells in the grid

Page 36: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation: smarter algorithms?

• Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in a table. This avoids recomputation.

• i.e. dynamic programming

• To completely avoid recursion, compute flow(i,j) in topological order of FD graph • topological order can be computed in linear time • or: sort by height, but that’s O( n lg n)

worst-case running time

Theta(n)

n = nb. of cells in the grid

Question: Which algorithm would you chose in practice?

Page 37: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FD: Dealing with flat areas

plateau sink

• Plateau: flat area has at least one spill point from which water flows downhill

• Sink: flat area that’s not a plateau

Page 38: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

• Want to label each flat area (maximally connected blob) with its own label.

• How?… and how long?

FD: Dealing with flat areas

Page 39: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FD on plateaus

• Water comes in on the plateau from higher grounds and leaves through the spill points ==> direct FD towards the spill points

• HOW? • One way is to do a BFS from all the spill points in parallel … when seeing

a new (white) cell, set its FD towards the cell that discovered it. • This way, water finds its shortest way to the spill point (recall BFS

computes shortest paths) • well… diagonal edges are longer. So not completely true.

Page 40: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FD on sinks

• Water comes in the sink from the surrounding area and cannot go out following downslope paths. The only way to route water out of the sink is to let water go uphill.

• Options

1. Do not route water out of the sinks, i.e. let FD be undefined on sinks. • Doing this essentially interrupts the flow of water at the sink. • FA looks chopped

Page 41: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flow accumulation: no FD on sinks

Page 42: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FD on sinks

• Water comes in the sink from the surrounding area and cannot go out following downslope paths. The only way to route water out of the sink is to let water go uphill.

• Options

1. Do not route water out of the sinks, i.e. let FD be undefined on sinks.

2. Allow the water to escape the sink by assigning FD upslope If we route water out of sinks the effect will be that every point in the terrain will have a path to the boundary of the terrain

• Ideally, want to assign FD such that every point in the terrain finds its lowest path outside

Formally: compute FD(p) such the path of p to a point on the boundary of the terrain has lowest possible height (where the height of a path is defined as the max height of vertices along the path).

• This can be done by simulating the process of flooding

Page 43: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding the sinks

• Flooding simulates steady state when an infinite amount of water/rain falls uniformly across the terrain, and the terrain is surrounded by a giant ocean (and no evaporation, infiltration, etc).

• At steady state all sinks are filled and at every point in the terrain, water has found a path towards the outside.

• A filled (flooded) terrain has no sinks. • at every point in the terrain, water has found a path towards the outside. • it’s the lowest path

1 23

Page 44: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding the sinks

Approach • Fill the terrain by flooding

• for each sink, record the lowest height at which it merges with the ocean. • raise each basin to this height

==> new elevation grid with no sinks • Compute FD on filled terrain

• view these directions as corresponding to the original terrain • this routes water out of the sink using lowest paths

1 23

Page 45: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding: • Identify the sinks in the terrain

• blobs of undefined FD that are no plateaus • For each sink, compute its basin (all points that flow into the sink).

This induces a partition of the terrain into sink-basins. • Find adjacencies between the sink-basins. Mark each edge (s,t)

between two sink-basins s and t with the elevation of the lowest edge along the s-t boundary. This represents the height at which the basins of s and t will merge.

• Merge sinks bottom-up until all sinks are DONE: • Initially, the outside is DONE. • Process edges in order of increasing elevation: for each

edge (s,t) of height h • union(s,t) • If none of s and t are DONE, raise them to height h • If one of them is DONE, then the other becomes DONE

and it is raised to h

1 23

Flooding the sinks

Page 46: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding the sinks

• Flooding creates more realistic, connected river networks. • If there is a lot of water, it eventually erodes a canyon …

• Partial flooding: • fill only “small” sinks. • fill sinks below given threshold.

Page 47: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

FA with floodingFA: no FD on sinks

Page 48: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Computing rivers and watersheds

Rivers: all points with FA above a given threshold

Watershed (s): all cells that have a flow path into s

River hierarchy: Find river backbone and its tributaries. Find their watersheds.

Page 49: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

River network

• Rivers: cells with FA > threshold

Page 50: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

• Rivers = cells with FA > threshold

River network

Page 51: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

The following animation due to

Herman Haverkort

U. Eindhoven

http://www.bowdoin.edu/~ltoma/teaching/cs350/fall14/Lectures/pfafstetter-short.pdf

Pfafstetter watershed hierarchy

Page 52: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding the land from the ocean

• We’ve seen how the concept of flooding is used to flood the sinks and compute steady-state FD and FA.

• Flooding is also used in a different context:

How will NYC look if water level raises by 10 ft?

At what level will NYC be completely under water?

Page 53: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Flooding the land from the ocean

Input: a grid terrain which has a coast, i.e. is connected to the ocean.

1. Model what happens when the water level in the ocean rises by x ft.

2. For each point p in the terrain, compute the height at which p is underwater.

Page 54: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Practical details

• grid ascii format • gdal library provides functions to read a grid from any format

Page 55: Flow on terrainsltoma/teaching/cs3225-GIS/fall15/... · Flow accumulation: smarter algorithms? • Extend idea2: Use recursion, but once a value flow(i,j) is computed, store it in

Raster ascii format

• header followed by data ncols 391nrows 472xllcorner 271845yllcorner 3875415cellsize 30NODATA_value -9999-9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 781 773 766 761 756 751 745 738 730 723 716 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 775 767 759 754 750 746 741 735 728 721 714 709 705 700 696 694 693 692 691 690 691 692 696 701 707 714 722 728 732 733 731 726 721 718 718 722 729 737 746 755 761 764 762 760 760 759 754 748 741 733 725 718 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 -9999 770. . . . . . .