Ein alternativer Geostack:
GeoCouch, OpenLayers und jQuery (MapQuery)

Was ist GeoCouch?

Was ist Apache CouchDB?

Dokumente

JSON

          {
              "_id": "Station-2942_001",
              "_rev": "3-77f17a55f6ab11f7f6668e63a75f2281",
          
              "name": "Station-2942",
              "date": "2011-04-06",
              "loc": [8.71, 49.412222],
              "country": "Germany",
              "temperature": 19,
              "rainfall": 30
          }
        

Schemafrei

          {
              "_id": "Station-2942_001",
              "_rev": "3-77f17a55f6ab11f7f6668e63a75f2281",
          
              "name": "Station-2942",
              "date": "2011-04-06",
              "loc": [8.71, 49.412222],
              "country": "Germany",
              "temperature": 19,
              "rainfall": 30,
              "atmospheric_pressure": 1012
          }
        

Und vieles mehr…

  • RESTful HTTP API
  • Multi-Master-Replikation
  • Echtzeit Feeds
  • Robustheit
  • Skaliert hoch und abwärts
  • Webserver

GeoCouch

  • Erweiterung für CouchDB
  • R-Baum Implementierung
  • Alle GeoJSON Geometrien (Punkte, Linien, Polygone…)
  • Rechecksabfragen
  • Polygonabfragen (leider noch nicht, aber sehr bald)
  • OpenSearch Geo

Beispiel

  • Ausgangspunkt: Shapefile
  • Import in CouchDB/GeoCouch mit shp2geocouch
    • Konvertierung zu GeoJSON (per ogr2ogr (GDAL))
    • Konvertierung zu UTF-8
    • Import in CouchDB via HTTP API
          {
             "_id":"0050bfa141ada373d64a8f2ca6099e36",
             "_rev":"1-ef2fe839264d5fd8f12a2bcd07e592be",
             "type":"Feature",
             "properties":{
                "GEODB_OID":1.0,
          
                "SHAPE_AREA":25564.248949,
                "SHAPE_LEN":767.237661
             },
             "geometry":{
                "type":"Polygon",
                "coordinates":[…]
             }
          }
       

Räumliche Index Funktion

          function(doc) {
           
           
           
          }
        

Räumliche Index Funktion

          function(doc) {
              if (doc.geometry) {
           
              }
          }
        

Räumliche Index Funktion

          function(doc) {
              if (doc.geometry) {
                  emit(               ,           );
              }
          }
        

Räumliche Index Funktion

          function(doc) {
              if (doc.geometry) {
                  emit(/* Schlüssel */, /* Wert */);
              }
          }
        

Räumliche Index Funktion

          function(doc) {
              if (doc.geometry) {
                  emit(doc.geometry, /* Wert */);
              }
          }
        

Räumliche Index Funktion

          function(doc) {
              if (doc.geometry) {
                  emit(doc.geometry, doc.properties);
              }
          }
        

Räumliche Anfrage

          http://localhost:5984/parks_pdx/_design/geo/_spatial/geom?
bbox=-180,-90,180,90

Räumliche Anfrage

          http://localhost:5984/parks_pdx/_design/geo/_spatial/geom?
bbox=-180,-90,180,90
{"update_seq":319,"rows":[
 
 
 
 
 
 
 
 
 
 
 
 
]}
        
{"update_seq":319,"rows":[
  {
    "id":"f6d120ecb21f269130106f2a1107a7ae",
    "bbox":[-122.547363,45.554482,-122.546373,45.555301],
    "geometry":{"type":"Polygon","coordinates":[…]},
    "value":{
      "GEODB_OID":257,
      "OBJECTID":257,
      "NAME":"Senns Dairy Park",

    }
  }
 
]}
        
{"update_seq":319,"rows":[
  {
    "id":"f6d120ecb21f269130106f2a1107a7ae",
    "bbox":[-122.547363,45.554482,-122.546373,45.555301],
    "geometry":{"type":"Polygon","coordinates":[…]},
    "value":{
      "GEODB_OID":257,
      "OBJECTID":257,
      "NAME":"Senns Dairy Park",

    }
  },
  
]}
        

Konvertierung zu GeoJSON

  • Serverseitige JavaScript Funktion
  • Wird auf jede „row“ angewendet
  • Für Endanwender nur eine andere URL
function(head, req) {
 
 
 
 
 
 
 
 
 
 
 
 
}
        
function(head, req) {
    var row;
 
 
    while (row = getRow()) {
 
 
 
 
 
 
    }
 
}
        
function(head, req) {
    var row, out;
 
 
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(out);
 
    }
 
}
        
function(head, req) {
    var row, out;
 
 
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(out);
 
    }
 
}
        
function(head, req) {
    var row, out;
 
 
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(out);
 
    }
 
}
        
function(head, req) {
    var row, out;
 
 
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(out);
 
    }
 
}
        
function(head, req) {
    var row, out;
 
    send('{"type": "FeatureCollection", "features":[');
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(out);
 
    }
    send("]}");
}
        
function(head, req) {
    var row, out, sep = '\n';
 
    send('{"type": "FeatureCollection", "features":[');
    while (row = getRow()) {
        out = '{"type": "Feature", "geometry": ' +
            JSON.stringify(row.geometry) +
            ', "properties": ' + JSON.stringify(row.value) +
            '}';
        send(sep + out);
        sep = ',\n';
    }
    send("]}");
};
        

Räumliche Anfrage

          http://localhost:5984/parks_pdx/_design/geo/
_spatial/_list/geojson/geom?bbox=-180,-90,180,90

Räumliche Anfrage

          http://localhost:5984/parks_pdx/_design/geo/
_spatial/_list/geojson/geom?bbox=-180,-90,180,90

Was ist MapQuery?

  • Früher bekannt als geojquery
  • OpenLayers + jQuery
  • Geschwister von GeoExt

Warum MapQuery?

  • Einfachere API
  • Weniger Boilerplate-Code
  • jQuery Events
  • Übliche Dinge einfach, komplexe Dinge möglich
  • Bemühungen zusammenführen

Vielen Dank für die Aufmerksamkeit!

Bilder

  • Nasa
    • http://spaceflight.nasa.gov/gallery/images/shuttle/sts-129/hires/sts129-s-070.jpg
    • http://images.cdn.fotopedia.com/flickr-2222548359-original.jpg
  • Greg Habermann (CC-BY 2.0)
    • http://www.flickr.com/photos/smomashup1/3298535567/sizes/m/in/photostream/