10

I have the following problem with MongoDB. I got some geo data from my home country and i have to store them into mongodb to set up a simple Web Feature Service. This service will mostly do bounding box queries using the $within operator. The data is in GeoJSON format. Therefore i imported at first the Villages and Cities which are represented as points ([1,2]) in this format. No problem. Next step rivers and streets which are LineStrings and according to GeoJSON represented this way [[1,2],[3,4]]. But when importing the districts (which are in fact polygon and according to the GeoJSON specification 3 dim arrrays) i got the error geo values have to be numbers when creating the index.

db.collection.ensureIndex({"geometry.coordinates" : "2d"});

All data are valid GeoJSON, and are in plain 2d coordinates in EPSG:4326 projection.

Does anybody have an idea?

Dominik Nöger
  • 103
  • 1
  • 1
  • 5

6 Answers6

13

With MongoDB 2.4 use the "2dsphere" index for GeoJSON Points, LineStrings and Polygons.

For example, you can create this index:

db.mycoll.ensureIndex( { loc : "2dsphere" } )

And store this LineString:

{ loc : { type : "LineString" , coordinates : [ [ 1 , 2 ] , [ 3 , 4 ] ] } }

See http://docs.mongodb.org/manual/applications/2dsphere/.

Bob Grabar
  • 371
  • 2
  • 4
  • 2.6 will support MultiPoint, MultiLineString, MultiPolygon and GeometryCollection http://docs.mongodb.org/manual/release-notes/2.6/ – Gianfranco P. Oct 18 '13 at 15:30
3

It seems that mongo 2.3.2 development release now has GeoJSON support: Release Notes for MongoDB 2.4

Víctor Penela
  • 474
  • 1
  • 6
  • 16
2

I had to do this same thing myself to set up a GeoFence feature. What I did was store "polygon" data as a series of coordinate, and a center. For instance:

{ 
    "_id" : ObjectId( "4f189d132ae5e92272000000" ),
    "name" : "Alaska",
    "points" : [ 
        { "coords" : [ 
            -141.0205, 
            70.0187 ] 
        }, 

        ...

        { "coords" : [ 
            -141.0205, 
            70.0187 ] 
        } 
    ],
    "center" : { 
        "coords" : [ 
          -153.6370465116279, 
          61.42329302325581 ] 
    } 
}

In my application (in python) I am using the shapely library. What I first do is find a list of objects that have a center closest to my point. Then on the client side (python) I use shapely convert each large coordinate array to a polygon, and then test the regions to find which ones contain my point.

So you can store polygon data in MongoDB as just data, and use some other precomputed 2d index like a center.

jdi
  • 90,542
  • 19
  • 167
  • 203
2

Give this a try from the mongo shell:

// Polygon in GeoJson format
var poly = {};
poly.name = 'GeoJson polygon';
poly.geo = {};
poly.geo.type = 'Polygon';
poly.geo.coordinates = [
    [ [ -80.0, 30.0 ], [ -40.0, 30.0 ], [ -40.0, 60.0 ], [-80.0, 60.0 ], [ -80.0, 30.0 ] ]
];
db.foo.insert(poly);
db.foo.ensureIndex({geo: "2dsphere" });
qconner
  • 41
  • 2
  • I just started working with Polygons in MongoDB but I find the shape of the polygon structure weird... If a shape is a set of points, why the array of those points is inside another array? Shouldn't `poly.geo.coordinates = [[-80.0, 30.0], [-40.0, 30.0], ... ]` be enough? – Loupax Jun 20 '15 at 18:42
  • 1
    @Loupax Coordinates of a Polygon are an array of LinearRing coordinate arrays. The first element in the array represents the exterior ring. Any subsequent elements represent interior rings (or holes).(http://geojson.org/geojson-spec.html#id4) – Farhadi Aug 16 '15 at 04:10
1

MongoDB's geospatial features currently only support storing points, not shapes or lines. You are however able to query for points using circles, rectangles, or polygons.

mstearn
  • 4,156
  • 1
  • 19
  • 18
0

Based on the MongoDB documentation here, a polygon could be stored as a GeoJSON polygon like:

{
  type: "Polygon",
  coordinates: [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0  ] ] ]
}

It's a simple one with a simple ring but it's also possible to store a polygon with multiple rings.

Aboozar Rajabi
  • 1,683
  • 21
  • 26