Ajaxを利用してPostGISの情報をGoogle Mapsに表示する。
まずはHTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta http-equiv="Content-Style-Type" content="text/css"> <title>地図サンプル</title> <script type="text/javascript" src="js/prototype.js"></script> <script type="text/javascript" charset="utf-8" src="http://maps.google.com/maps?file=api&v=2&key=AB・・・&hl=ja"></script> <script> <!-- var map; var objArray = new Array(); function initOnLoad() { map = new GMap2($("MAP")); map.addControl(new GLargeMapControl()); map.addControl(new GMapTypeControl()); map.enableContinuousZoom(); map.enableScrollWheelZoom(); map.disableDoubleClickZoom(); map.addMapType(G_PHYSICAL_MAP); map.addMapType(G_SATELLITE_3D_MAP); map.setCenter(new GLatLng(35.689487380721324, 139.6917736530304), 17); GEvent.addListener(map, "moveend", ajaxRequest); } function ajaxRequest() { var request = GXmlHttp.create(); var url = "http://localhost:8080/Sample/map"; var bounds = map.getBounds(); var ne = bounds.getNorthEast(); var sw = bounds.getSouthWest(); var params = "n=" + ne.lat() + "&s=" + sw.lat() + "&e=" + ne.lng() + "&w=" + sw.lng(); request.open("POST", url, true); request.onreadystatechange = function() { if( request.readyState == 4 ) { for( var i = 0; i < objArray.length; i++ ) { map.removeOverlay(objArray[i]); } objArray = new Array(); var xml = request.responseXML; var features = xml.documentElement.getElementsByTagName("point"); for( var i = 0; features && i < features.length; i++ ) { var feature = features[i]; var latlng = feature.getElementsByTagName("latlng")[0].firstChild.nodeValue; var obj = new GMarker(stringToGLatLngArray(latlng)[0]); map.addOverlay(obj); objArray.push(obj); } features = xml.documentElement.getElementsByTagName("linestring"); for( var i = 0; features && i < features.length; i++ ) { var feature = features[i]; var latlng = feature.getElementsByTagName("latlng")[0].firstChild.nodeValue; var obj = new GPolyline(stringToGLatLngArray(latlng), "#FF0000", 5); map.addOverlay(obj); objArray.push(obj); } features = xml.documentElement.getElementsByTagName("polygon"); for( var i = 0; features && i < features.length; i++ ) { var feature = features[i]; var latlng = feature.getElementsByTagName("latlng")[0].firstChild.nodeValue; var obj = new GPolygon(stringToGLatLngArray(latlng), "#00FF00", 5, 1, "#00FF00", 0.2); map.addOverlay(obj); objArray.push(obj); } } } request.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8"); request.send(params); } function stringToGLatLngArray(str) { var geometries = str.split(","); var geomArray = new Array(); for( var i = 0; i < geometries.length; i++ ) { var geometry = geometries[i].split(" "); geomArray.push(new GLatLng(geometry[1], geometry[0])); } return geomArray; } // --> </script> </head> <body onload="initOnLoad();"> <div id="MAP" style="width: 100%; height: 500px;"> </div> </body> </html>
DBはPostGISを利用可能な状態にして
sample=# CREATE TABLE GeometryTable ( id INTEGER NOT NULL ); sample=# SELECT AddGeometryColumn('geometrytable', 'geometry', 4326, 'GEOMETRY', 2); sample=# sample=# \d GeometryTable カラム | 型 | 修飾語 ---------------------------------- id | integer | not null geometry | geometry | CHECK 制約: "enforce_dims_geometry" CHECK (ndims(geometry) = 2) "enforce_srid_geometry" CHECK (srid(geometry) = 4326) sample=# sample=# INSERT INTO GeometryTable VALUES ( 1, GeomFromText('POINT(139.6917736530304 35.689487380721324)', 4326)); sample=# INSERT INTO GeometryTable VALUES ( 2, GeomFromText('LINESTRING(139.6921142935753 35.69046768390191,139.69293236732483 35.68719995978114)', 4326)); sample=# INSERT INTO GeometryTable VALUES ( 3, GeomFromText('POLYGON((139.690692722797 35.6902389475707,139.691510796547 35.6869494287404,139.694270789623 35.687415633699,139.69346344471 35.690718203893,139.69069272279735.6902389475707))', 4326));
生成されるXMLはこんな感じ
<?xml version="1.0" encoding="UTF-8" ?> <features> <point> <latlng>139.6917736530304 35.689487380721324</latlng> </point> <linestring> <latlng>139.6921142935753 35.69046768390191,139.69293236732483 35.68719995978114</latlng> </linestring> <polygon> <latlng>139.6906954050064 35.69023894757071,139.69150006771088 35.68694942874041,139.69426542520523 35.68741345517749,139.69345808029175 35.690720382324216,139.6906954050064 35.69023894757071</latlng> </polygon> </features>
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 北 String north = request.getParameter("n"); // 西 String west = request.getParameter("w"); // 東 String east = request.getParameter("e"); // 南 String south = request.getParameter("s"); StringBuffer geometry = new StringBuffer("POLYGON(("); geometry.append(west).append(" ").append(north).append(","); geometry.append(west).append(" ").append(south).append(","); geometry.append(east).append(" ").append(south).append(","); geometry.append(east).append(" ").append(north).append(","); geometry.append(west).append(" ").append(north); geometry.append("))"); String sql = "SELECT AsText(geometry) AS geometry FROM GeometryTable WHERE ST_Intersects(geometry, GeomFromText(?, 4326)) = True"; Connection con = null; Statement st = null; ResultSet rs = null; try { Class.forName("org.postgresql.Driver"); con = DriverManager.getConnection("jdbc:postgresql:sample", "postgres", "postgres"); st = con.createStatement(sql); st.setString(1, geometry.toString()); rs = st.executeQuery(); StringBuffer result = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); result.append("<features>"); while( rs.next() ) { String geometry = rs.getString("geometry"); if( geometry.startsWith("POINT") ) { result.append("<point><latlng>").append(geometry.substring(6, geometry.length() - 1)).append("</latlng></point>"); } else if( geometry.startsWith("LINESTRING") ) { result.append("<linestring><latlng>").append(geometry.substring(11, geometry.length() - 1)).append("</latlng></linestring>"); } else if( geometry.startsWith("POLYGON") ) { result.append("<polygon><latlng>").append(geometry.substring(9, geometry.length() - 2)).append("</latlng></polygon>"); } } result.append("</features>"); } catch( Exception e ) { return; } finally { if( rs != null ) { try { rs.close(); } catch( SQLException e ) { } } if( st != null ) { try { st.close(); } catch( SQLException e ) { } } if( con != null ) { try { con.close(); } catch( SQLException e ) { } } } response.setContentType("text/xml; charset=utf-8"); response.getWriter().println(result); }