Presentation is loading. Please wait.

Presentation is loading. Please wait.

2009.foss4g.org.

Similar presentations


Presentation on theme: "2009.foss4g.org."— Presentation transcript:

1 2009.foss4g.org

2 Spatial Database Tips & Tricks
Paul Ramsey

3 Housekeeping Copy workshop from DVD
Download from Install or not Ignore me or not Examples also at

4 Impatient People They try to install without reading instructions
When you see an error box during PostGIS install, click “Ignore” Remember to create “medford” (not “postgis”) database during PostGIS install

5 Impatient People

6 It’s not dead, it’s just resting…

7 Motivation Spatial databases are powerful Godlike, really
You do not need “GIS software” Your database is “GIS software” You do not need “spatial middleware” See above

8 Standard Database Has data types varchar integer real date

9 Spatial Database Has spatial data types point linestring polygon
multipoint multilinestring multipolygon

10 Standard Database Has one-dimensional indexes b-tree hash

11 Spatial Database Has spatial indexes r-tree quad-tree grid

12

13

14

15

16 Find intersecting shapes…

17 Start with all boxes,

18 find intersecting boxes,

19 then find intersecting shapes.

20 Standard Database Has functions Work against standard types lower()
round() substring() trim() dayofweek ()

21 Spatial Database Has spatial functions Work against spatial types
ST_Area(geometry) ST_Distance(geometry,geometry) ST_Intersects(geometry,geometry) ST_DWithin(geometry,geometry,radius) ST_Union(geometry,geometry)

22

23 Open Geospatial Consortium (OGC)
Simple Features for SQL (SFSQL)

24

25

26

27 Spatial Locator

28 No intersection operation No centroid point
L O C A T O R No buffer operation No union operation No intersection operation No centroid point No area or length calculation

29 S P A T I A L Linear referencing system (LRS) support Spatial analysis and mining functions and procedures (SDO_SAM package) Geocoding support (SDO_GCDR package) GeoRaster support Topology data model Network data model

30

31 SFSQL compliant New release, not as many features No coordinate reference system transforms Windows only Grid index

32 SELECT * FROM the_table
WHERE ST_Intersects( the_geom, ST_GeomFromText('POINT(0 0)',0) ); SELECT * FROM the_table WHERE the_geom.STIntersects( geometry::STGeomFromText('POINT(0 0)',0) );

33 PostgreSQL / PostGIS SFSQL compliant Open source (GPL) Proprietary / open source clients “geographic” coordinates require care

34

35

36

37

38 ST_Distance(‘POINT(0 0)’,’POINT(1 1)’)
What units? ST_Distance_Spheroid() ST_Distance_Sphere() Indexes are not sphere aware Spherical distance functions defined on points only

39

40

41

42

43 Installation

44 Installation

45 Installation

46 Installation

47 Data We are going to be installing data from PostgreSQL backup files, because it is fast and easy to get everything in the right place and indexed. But data you download from government will usually be in some other format.

48 Data Shape files .shp, .shx, .dbf, .prj shp2pgsql Other? FME ogr2ogr

49

50

51

52

53 Tomcat JNDI configured JSLT installed PostgreSQL JDBC
Connection to “medford” database JSLT installed <c:> <sql:> GeoServer installed Connections to “medford” tables Styles for “medford” tables

54 Tomcat

55 Workshop

56 #0 - Base Map with WMS

57 + =

58 + =

59

60

61 <body onload="init()">
<div id="map"></div> </body>

62 var lon = ; var lat = ; var zoom = 18; var map; function initMap() { map = new OpenLayers.Map( 'map' , {controls:[new OpenLayers.Control.MouseDefaults(), new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.PanZoomBar()], numZoomLevels:20}); var gmap = new OpenLayers.Layer.Google( "Google Streets" // the default ); var gsat = new OpenLayers.Layer.Google( "Google Satellite", {type: G_SATELLITE_MAP} map.addLayers([gmap, gsat]); map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); }

63 // Initialize WMS layer from our local
// GeoServer var bwms = new OpenLayers.Layer.WMS( "Medford Buildings", " { "transparent":"true", "layers":"medford:buildings", "format":"image/png" }, { "reproject":"true" } ); // Add WMS layer to our map map.addLayer(bwms);

64 #1 – Click to Query

65 #1 – Click to Query

66 // Tie the map click event to our query function map. events
// Tie the map click event to our query function map.events.register("click", map, queryDatabase );

67 function queryDatabase(e) {
// Read the map coordinates from the click event var lonlat = map.getLonLatFromViewPortPx(e.xy); // Read the table we are going to query from page var table = document.getElementById("table").value; // Construct the query URL var url = "01-click-query.jsp"; url += "?lon=" + lonlat.lon; url += "&lat=" + lonlat.lat; url += "&table=" + table; // Load the URL into an iframe document.getElementById("query").src = url; }

68 01-click-query.jsp? lon= & lat= & table=medford.taxlots

69 01-click-query.jsp taglib uri=" prefix="sql" %> taglib uri=" prefix="c" %> page contentType="text/html" %> <sql:query var="rs" dataSource="jdbc/medford"> </sql:query>

70 select st_geometrytype(the_geom) as geometrytype, st_area(the_geom) as area, * from ${param.table} where st_contains( the_geom, st_transform( st_setsrid( st_makepoint(${param.lon},${param.lat}), 4326), 2270))

71 SQL

72 SRID?!? Location = Coordinate + SRID
Here = ( , 37.37) + EPSG:4326 ST_Transform() to change SRID Store data in an efficient SRID Transform inputs to your storage SRID Transform outputs to your display SRID

73 #2 – Click to Analyze

74 02-click-analyze.jsp? lon= & lat= & radius=200

75 select count(*) as "Number of Lots", round(avg(st_area(the_geom))::numeric/43560, 1) || ' acres' as "Average Lot Area", '$' || avg(impvalue)::integer as "Average Improvement Value", '$' || avg(landvalue)::integer as "Average Land Value", '$' || avg(impvalue + landvalue)::integer as "Average Total Value", avg(yearblt)::integer as "Average Year Built" from medford.taxlots where st_dwithin( taxlots.the_geom, st_transform( st_setsrid( st_makepoint(${param.lon},${param.lat}), 4326), 2270), ${param.radius} )

76 ST_DWithin()?!? Indexed distance query
ST_Distance(g1,g2) < r is not indexed ST_DWithin(g1,g2,r) is equivalent to g1 && ST_Expand(g2,r) AND ST_Distance(g1,g2) < r

77 #3 – Click and Join

78 zoning taxlots

79

80 Everything is related to everything else, but near things are more related than distant things Waldo Tobler

81 Spatial relationships are a universal key for joining
otherwise disparate data. zoning table customer table taxlot table census table road table stream table

82 select count(*) as num_lots, sum(st_area(taxlot.the_geom)) as total_lot_area, zone.zoning as zoning, sum(taxlot.landvalue) as total_land_value, sum(taxlot.landvalue) / as value_per_ft

83 from medford.taxlots taxlot join medford.zoning zone on ( st_contains( zone.the_geom, st_centroid(taxlot.the_geom) )

84

85

86 where st_dwithin( taxlot.the_geom, st_transform( st_setsrid( st_makepoint( ${param.lon}, ${param.lat}), 4326), 2270), ${param.radius} ) group by zone.zoning order by total_lot_area desc

87 #4 – Click and Union

88

89 ST_AsGeoJSON() select st_asgeojson(the_geom) from medford.streets
where st_npoints(the_geom) < 6 limit 1;

90 GeoJSON Geometry {"type":"MultiLineString", "coordinates":[[
[ , ], [ , ] ]]}

91 ST_As*() Standard PostGIS ST_AsText() – defined by OGC (SFSQL)
ST_AsBinary() – defined by OGC (SFSQL) ST_AsGML() – defined by OGC (GML) PostGIS ST_AsKML() – defined by Google (OGC) ST_AsSVG() – defined by W3C ST_AsGeoJSON() – defined by community

92 FeatureCollection Feature Geometry Properties Feature Geometry

93 <%@ taglib uri="http://java. sun
taglib uri=" prefix="sql" %> taglib uri=" prefix="c" %> page contentType="text/x-json" %> <sql:query var="rs" dataSource="jdbc/medford"> ${param.sql} </sql:query> {"type":"FeatureCollection", "features":[ <c:forEach var="row" items="${rs.rows}" varStatus="rowStatus"> {"type":"Feature", "geometry":<c:out value="${row.st_asgeojson}" escapeXml="false" />, "properties":{ <c:forEach var="column" items="${row}" varStatus="columnStatus"> <c:if test="${column.key != 'st_asgeojson'}"> "<c:out value="${column.key}" escapeXml="false" />": "<c:out value="${column.value}" escapeXml="false" />" <c:if test="${! columnStatus.last}">,</c:if> </c:if> </c:forEach> }} <c:if test="${! rowStatus.last}">,</c:if> ]}

94 select st_asgeojson( st_transform(the_geom,900913) ) from medford.taxlots where st_dwithin( the_geom, st_transform( st_setsrid( st_makepoint( , ), 900913), 2270), 100

95 // Make a fresh vector layer, pulling features our URL
json_layer = new OpenLayers.Layer.Vector("GeoJSON", { strategies: [new OpenLayers.Strategy.Fixed()], protocol: new OpenLayers.Protocol.HTTP({ url: json_url, format: new OpenLayers.Format.GeoJSON() }) }); // Add our vector layer to the map map.addLayer(json_layer);

96

97

98 #5 – Arbitrary SQL

99 DEMO

100 #6 – Walk a Network

101 medford.storm_drains node_fm node_to

102 medford.storm_drains id node_fm node_to 91058 D372W25CN0169
91061 D372W25CN0168 D372W25CN0167 id node_fm node_to 91062 D372W25CN0167 D372W25CN0166

103 DEMO

104 select d.node_fm, d.node_to, d.pipe_id
from medford.storm_drains d, medford.storm_drains e where st_dwithin(d.the_geom, e.the_geom, 5) and e.node_to = 'D371W28CN0134' and e.gid != d.gid and st_distance( st_endpoint(st_geometryn(e.the_geom, 1)), st_startpoint(st_geometryn(d.the_geom, 1)) ) < 5;

105 e.node_to = 'D371W28CN0134'

106 ST_DWithin()

107 ST_DWithin()

108 e.gid != d.gid

109 st_distance( st_endpoint(st_geometryn(e
st_distance( st_endpoint(st_geometryn(e.the_geom, 1)), st_startpoint(st_geometryn(d.the_geom, 1)) ) < 5;

110 st_distance( st_endpoint(st_geometryn(e
st_distance( st_endpoint(st_geometryn(e.the_geom, 1)), st_startpoint(st_geometryn(d.the_geom, 1)) ) < 5;

111 ST_GeometryN() Convert To MULTILINESTRING((0 0, 1 1, 2 2))

112 In conclusion…

113 Standards are good… SFSQL KML WMS GML WKT GeoJSON WFS WKB

114 Special middleware is unnecessary…

115

116 SQL

117

118 2009.foss4g.org


Download ppt "2009.foss4g.org."

Similar presentations


Ads by Google