"MongoError: Can't extract geo keys from object" with Type : Point
Asked Answered
C

7

29

I try to prepare my database field for geocoding with this:

MyCollection._ensureIndex({'data.address.located':'2dsphere'});

But then this error comes:

MongoError: Can't extract geo keys from object, malformed geometry?:
{ type: "Point", coordinates: [ 32.4586858, -110.8571443 ] }

I can not see whats wrong with this field ? Any idea ?

When I take a look to this it shows up this:

The following example stores a GeoJSON Point:

{ loc: { type: "Point", coordinates: [ 40, 5 ] } }
Contradistinction answered 6/8, 2014 at 0:41 Comment(0)
S
74

The problem is that

[ 32.4586858, -110.8571443 ]

is not a valid coordinate. The order should be longitude followed by latitude whereas that coordinate appears to be the reverse (judging by the fact that the valid latitude range is -90 to 90 and -110.8571443 is outside of that).

I think you meant:

{ type: "Point", coordinates: [ -110.8571443, 32.4586858 ] }

or there was some other entry error.

Survance answered 6/8, 2014 at 1:12 Comment(6)
Damn ... you're right. This is so stupid ... I had the same problem a few days ago and fixed it ... and now the same error. Thanks ...Contradistinction
its happens on the best families! even on mine!Ferree
Mistakes happen. MongoDB could have a clearer message that explained that the failure reason was the longitude value was not valid.Abirritant
I "love" that everyone blames themselves for this when every other system I've seen puts lat first.Hamstring
@AndrewHedges that's the GeoJSON standard though. lon first!Callaghan
Generally Lat come first. Mongo should give proper error in simple words.Noelnoelani
B
9

As mentioned by @go-oleg the problem is that range of coordinate are next:

  • Longitude: (+-) 180°
  • Latitude: (+-) 90°

and index expects coordinates to be in that bounds.

But if you are trying to apply index on already imported data and found out that coordinates are swapped, you'll probably want to swap it back rather than reimporting whole collection. For this purpose you can use next mongoshell script.

Assuming that you already have well-formed GeoJSON of type Point.

db.coll.find().forEach(function (e) {
    // assuming that `geoJson` is our field containing `coordinates`
    e.geoJson.coordinates = [ // Swapping Lat/Lon
        e.geoJson.coordinates[1], // Longitude goes first
        e.geoJson.coordinates[0] // Latitude goes last
    ];
    db.coll.save(e);
    // Some `print(e.name)` can go here just to understand the progress
});
Bartie answered 9/5, 2015 at 12:44 Comment(3)
I take it MongoDB won't accept cartesian coordinates, only lat/long pairs?Aged
@Mike you will go ok with your coordinates as long as they are in lon/lat bounds. Otherwise index will force you to limit your coordinates which easily can be beyond those limits and you will end up in the same lon/lat pair anyway.Bartie
@PaulT.Rawkeen Not working for me. db.coll.save(e) is not updating the 'coll' collection. No error.Sutherlan
D
4

I had the same problem while my longitude, latitude order was correct. My mistake was that I had written coordiantes instead of coordinates the mongo gave me this:

pymongo.errors.WriteError: Can't extract geo keys: {data}  Point must be an array or object

so maybe you have the right ordering but you have problem in your key names.

Dromond answered 30/9, 2017 at 22:26 Comment(0)
F
1

Even the problem was solved, I need to highlight this bug also may appear if you omit the type of GeoJSON object.

In my case, it was corrected adding the type: 'Point' to model's value.

Foxglove answered 13/8, 2017 at 4:30 Comment(0)
I
0

I got the same error, but the issue was I had a LineString with two identical coordinates.

"geometry" : {
    "type" : "LineString",
    "coordinates" : [ 
        [ 
            143.345763, 
            -33.840952
        ], 
        [ 
            143.345763, 
            -33.840952
        ]
    ]
}

I had to make this into a Point for it to be valid

"geometry" : {
    "type" : "Point",
    "coordinates" : [ 
        143.345763, 
        -33.840952
    ]
}
Inamorato answered 26/7, 2018 at 23:49 Comment(0)
M
0

first step is to insert some data that should be in first object format otherwise this errors comes in picture

schema :
location:{
            type: { type: String },
            coordinates:[mongoose.Schema.Types.Mixed]
        },

then insert some data into db

db.userDetails.createIndex({location: "2dsphere"})

index only be created if location contains object

after that write query ,if u want to findout distance

db.userDetails.aggregate( [
 $geoNear: {
                  near: { type: "Point",  coordinates: [data.lat1,data.lon1]},
                  spherical: true,
                  "distanceMultiplier" : 0.001,
                  distanceField: "calcDistance",
                  $maxDistance: distance,

               }
] )

and one more thing data should be pass without quoated string

"lat":18.7323
"lon":73.1232 

like this

Mutazilite answered 12/10, 2018 at 10:45 Comment(0)
V
0

My problem was that the coordinates were strings instead of integers/floats.

So I changed

{ type: "Point", coordinates: [ "8.73167870769231", "49.3182756076923" ] } }

To

{ type: "Point", coordinates: [ 8.73167870769231, 49.3182756076923 ] } }

With:

const lat = Number(old_lat)
Violet answered 19/9, 2022 at 14:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.