Can't extract geo keys, longitude/latitude is out of bounds - mongodb

Working with MongoDB 2dsphere to store GEOJSON and on certain stores of lat/lng I keep getting the following error:
{
"code": 16755,
"index": 0,
"errmsg": "Can't extract geo keys: { _id: ObjectId('586ff135b79aa00b84181bfb'), name: \"Austin\", slug: \"Austin\", description: \"\", twitter: \"\", facebook: \"\", instagram: \"\", author: ObjectId('57b60fed8620b56af460d5c5'), tags: [], created: new Date(1483731253640), location: { address: \"Austin, TX, United States\", coordinates: [ 30.267153, -97.74306079999997 ], type: \"Point\" }, __v: 0 } longitude/latitude is out of bounds, lng: 30.2672 lat: -97.7431",
"op": {
"name": "Austin",
"slug": "Austin",
"description": "",
"twitter": "",
"facebook": "",
"instagram": "",
"author": "57b60fed8620b56af460d5c5",
"_id": "586ff135b79aa00b84181bfb",
"tags": [
],
"created": "2017-01-06T19:34:13.640Z",
"location": {
"address": "Austin, TX, United States",
"coordinates": [
30.267153,
-97.74306079999997
],
"type": "Point"
},
"__v": 0
}
}
I can't seem to figure out why it doesn't like some lat/lng coordinates.
Here is my schema for the location field:
location: {
type: { type: String, default: 'Point' },
coordinates: [Number],
address: String
},
and it's indexed as 2dsphere:
storeSchema.index({ location: '2dsphere' });
The only weird thing I can see is that the error message:
longitude/latitude is out of bounds, lng: 30.2672 lat: -97.7431",
the lat/lng are shortened from what I inputted - not sure if that has anything to do with it.

Oh wow - I'm not sure who decided this but Mongodb expects you to store as [lng, lat], not [lat,lng] like everything else in this world.
:|

Here is how I fixed the issue without having to swap the [lat,lng] sequence.
Somewhere in your code you are making a call to ensureIndex. Instead of calling (as I was previously doing) ...
collection.ensureIndex({ "location": "2dsphere" });
Use the following instead ...
collection.ensureIndex({ "location.coordinates":"2d"});
This completely got rid of the error at runtime and no massive refactor of data was needed.

Related

MongoDB: GeoJSON object type index, Can't extract geo keys

I have made many the below GeoJSON Point objects in MongoDB Compass as per the docs
{
"_id": {
"$oid": "5e86d275a3d7fd05e4f022a8"
},
"location": {
"type": "point",
"coordinates": ["-110.85458435", "39.68476146"]
},
"website": "carbonmedicalservice.com",
"address": "125 S Main St",
"state": "UT",
"zip": "84526",
"name": "Carbon Medical"
}
I want to be able te search the collection to return all records within an reactangle, I believe I need to add a Geospatial Indexe to the location but I get the error shown below...
This is how I entered the data:
In a GeoJSON type, coordinates should be float/double not string.
Also, the type should be Point, not point in your case. So, the GeoJSON in your case should be:
{
"type": "Point",
"coordinates": [-110.85458435, 39.68476146]
}
instead of
{
"type": "point",
"coordinates": ["-110.85458435", "39.68476146"]
}

How to remove specific feature in feature collection under geojson source in a places layer?

I got this:
map.addLayer({
"id": "places",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": features
}
},
"layout": {
"icon-image": "{icon}-15",
"text-field": "{title}",
"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
"text-offset": [0, 0.6],
"text-anchor": "top"
}
});
Where features is array of objects like this:
{
"id": SOME_ID,
"type": "Feature",
"properties": {
"title": SOME_TITLE,
"icon": "monument"
},
"geometry": {
"type": "Point",
"coordinates": SOME_COORDINATES
}
}
I want to delete this specific feature, NOT THE WHOLE places LAYER, how can it be done?
I have tried to create for each feature, a designated layer with predefined ID, but
when tried to remove it using map.removeLayer(SOME_ID) this told me that the
layer id does not exist.
How to delete specific geojson feature from feature collection in mapbox, without delete the wole
layer, just the json data?
If you want to hide the feature on the map, then you don't have to remove it from the source. You can filter this feature out using filter, so it wouldn't be rendered on the map.
Consider example:
map.addLayer({
id: 'points',
type: 'circle',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
id: 1,
properties: {},
geometry: {
type: 'Point',
coordinates: [127.61718749999999, 66.51326044311185]
}
},
{
type: 'Feature',
id: 2,
properties: {},
geometry: {
type: 'Point',
coordinates: [79.1015625, 72.50172235139388]
}
},
{
type: 'Feature',
id: 3,
properties: {},
geometry: {
type: 'Point',
coordinates: [61.17187499999999, 31.952162238024975]
}
}
]
}
},
filter: ['!=', '$id', 3]
});
This will render all features except feature with id=3.
You can also set this kind of filters using map.setFilter method.
map.setFilter('my-layer', ['==', 'name', 'USA']);
Edit:
If you really want to remove a specific feature from the source, you can filter this feature from the features array and update the source using setData:
map.getSource('places').setData({
"type": "FeatureCollection",
features
});

MongoDB date insert

This is my schema:
db.createCollection("user_clicks", {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "session_id", "country", "browser", "url", "date"],
properties: {
session_id: {
bsonType: "string",
description: "must be a string and is required" },
country: {
bsonType: "string",
description: "country name and is required"},
browser: {
bsonType: "string",
description: "browser name and is required"},
url : {
bsonType: "string",
description: "user click url and is required"},
date: {
bsonType: "date",
description: "localdatetime and is required"}}}})
This is the code I am using to generate data:
mgeneratejs `{
"session_id": "$oid",
"country": "$country",
"browser": {
"$choose": {
"from": [
"Firefox",
"Chrome",
"Safari",
"Explorer"
],
"weights": [
1,
2,
2,
1
]
}
},
"url": {
"$choose": {
"from": [
"google.com/images",
"facebook.com/profile1538713",
"soundcloud.com/playlist03",
"some-url.com/home",
"sinoptik.ua/kyiv"
],
"weights": [
1,
2,
2,
1,
3
]
}
},
"date": {
"$date": {
"min": "2016-08-01T23:59:59.999Z",
"max": "2016-10-01T23:59:59.999Z"
}
}
}` -n 5 | mongoimport --uri="mongodb://localhost:27017/events" --collection user_clicks --mode=insert
I'm trying to generate random date by using mgeneratejs and mongoimport. The problem is that i can't insert any date like : "3/13/2019" or "2019-03-26T23:44:26Z" (that's what i actually need). The error is:
**WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})**
I try to insert like new Date("2019-03-26T23:44:26Z") and it works! Please help how to automate every time inserting create new Date(date) or how to fix this !
I am confused at what your issue is... everything is working as it should.. You store dates in Mongo as Date objects (that have the type of Date)..
If you want to store dates in Mongo in a format like 3/13/2019 you can do something like this:
// javascript
let dateToInsert = new Date("3/13/2019");
Use the below before inserting the random date and it should work:
new Date(randomDate);

OSRM wrong waypoint index?

I'm trying to use OSRM to get a list of locations ordered by the distance between them. For that I'm using the Trip service (https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md#trip-service).
Given the encoded polyline:
omq~Fji_vOg#sHQcnAjCtrAkCs|AvHpcBwCeeB
I receive the following:
"waypoints": [
{
"waypoint_index": 0,
"trips_index": 0,
"hint": "RzfEg1U3xIPaAAAAJgAAAAAAAAAAAAAANgAAAAoAAAAAAAAAAAAAAHM6AACFecb6__B-AoR5xvoQ8X4CAACPBd_PZ4A=",
"name": "",
"location": [
-87.656059,
41.873663
]
},
{
"waypoint_index": 2,
"trips_index": 0,
"hint": "OTfEg5M4xINDAwAAnwEAAAAAAAAAAAAA0AAAAGgAAAAAAAAAAAAAAHM6AACJf8b6xvF-Aoh_xvrY8X4CAADPEN_PZ4A=",
"name": "",
"location": [
-87.654519,
41.873862
]
},
{
"waypoint_index": 5,
"trips_index": 0,
"hint": "WuVchFzlXIQ6AwAAbwUAAAAAAAAAAAAAzgAAAFwBAAAAAAAAAAAAAHM6AAD3sMb6EPN-Avywxvoy8n4CAACfBd_PZ4A=",
"name": "",
"location": [
-87.641865,
41.874192
]
},
{
"waypoint_index": 1,
"trips_index": 0,
"hint": "PDfEg343xIOuAQAAggQAAAAAAAAAAAAAawAAACEBAAAAAAAAAAAAAHM6AACsfMb6su9-Aq58xvp2734CAADPEN_PZ4A=",
"name": "",
"location": [
-87.655252,
41.87333
]
},
{
"waypoint_index": 3,
"trips_index": 0,
"hint": "VuVchFjlXITqAQAA0QEAAAAAAAC1BAAAegAAAHUAAAAAAAAALQEAAHM6AACYtsb6L_J-AjK3xvoy8n4CAABvFt_PZ4A=",
"name": "",
"location": [
-87.640424,
41.873967
]
},
{
"waypoint_index": 6,
"trips_index": 0,
"hint": "6WJUhBgEhoTTBAAAdgQAAAAAAAAAAAAANAEAAB4BAAAAAAAAAAAAAHM6AAAJesb6H-x-Alh4xvoa7H4CAAB_Ft_PZ4A=",
"name": "",
"location": [
-87.655927,
41.872415
]
},
{
"waypoint_index": 4,
"trips_index": 0,
"hint": "TOVchFDlXIRTAgAAhQEAACoAAADuAAAAlAAAAGIAAAAKAAAAPAAAAHM6AAAtuMb6FvB-Aja4xvoS734CAQCPBd_PZ4A=",
"name": "",
"location": [
-87.640019,
41.87343
]
}
]
URL for testing: http://router.project-osrm.org/trip/v1/driving/polyline(omq~Fji_vOg#sHQcnAjCtrAkCs|AvHpcBwCeeB)?overview=false
This is how they were plotted (for better understanding):
If I understood the docs correctly, waypoint_index was supposed to provide the order of the locations by distance. If so, it doesn't seem to be working given the result. Check it here:
Wanted
Group 1
lat: 41.87368, lon: -87.65606
lat: 41.87388, lon: -87.65452
lat: 41.87327, lon: -87.65525
lat: 41.87241, lon: -87.65636
Group 2
lat: 41.87317, lon: -87.64001
lat: 41.87397, lon: -87.64186
lat: 41.87397, lon: -87.64027
Actual
Group 1
lat: 41.873663, lon: -87.656059
lat: 41.87333, lon: -87.655252
lat: 41.873862, lon: -87.654519
Group 2
lat: 41.873967, lon: -87.640424
lat: 41.87343, lon: -87.640019
lat: 41.874192, lon: -87.641865
Group 1
lat: 41.872415, lon: -87.655927
As you can see the order provided by waypoint_index under Actual does exclude the last item from its supposed group (1). I think this might be related to the roundtrip option, is this the case? If so, is there an option I can set on the trip service that will provide me with the result I need?
Or, is there another service that will receive a list of locations and return them ordered by the distance between them? Given that I can't provide the start/end.
I'd like to just send a list of locations and receive them ordered by proximity, not using roundtrip (if that's what's breaking the previous request).
Thanks!
ordered by the distance between them
What the trip service does is order them in a way that minimizes the total drive-time if you need to visit all waypoints, not cluster them by straight-line distance.
If you look at the route that was actually generated, the order makes sense: It is a circular trip that includes all provides locations (and at least looks optimal)

How to post data to a mapquest table

I'm trying to post data to a mapquest table and I've done everything according to their API
Here is my json:
{
"tableName": "mqap.jZ3uoAVablablabla_reported_points",
"append": true,
"returnResults": true,
"rows": [
[
{
"mqap_geography": "POINT (-123.3141509 48.4647675)",
"date": "2016-03-13T02:19:09.674Z",
"email": "anna#gmail.com",
"latitude": "48.47542496514236",
"longitude": "-123.37663650512695",
"message": "ss",
"user": "a"
}
]
]
}
Here is a screenshot of the table
And this is the response I get in Postman
{
"failures": [
{
"reason": "Either no latitude/longitude was provided, or the other information was insufficient for geocoding at or near line #0 of input.",
"row": ""
}
],
"append": true,
"returnResults": true,
"totalRows": 1,
"tableName": "mqap.jblablabla_reported_points",
"tableSize": {
"raw": 8192,
"readable": "8 KB"
},
"data": {
"rows": []
},
"failureCount": 1,
"rowCount": 0,
"info": {
"statusCode": 0,
"copyright": {
"text": "© 2015 MapQuest, Inc.",
"imageUrl": "http://api.mqcdn.com/res/mqlogo.gif",
"imageAltText": "© 2015 MapQuest, Inc."
},
"messages": []
}
}
What am I doing wrong?
The geography column should be in the table by default when the table is created: mqap_geography. This column is populated depending on information in other columns depending on their data type: Geography, [Latitude, Longitude], [Street, City, StateProvince, PostalCode, County, Country], and FullAddress. The Latitude, Longitude columns in the table above are type String so they won't populate the Geography column.
Two things I was missing:
The database NEEDS to have a geography object. So I added a latlong Geography object that I didn't end up using.
The format of the JSON should've been the following:
{
"tableName": "mqap.jZ3uoAVablablabla_reported_points",
"append": true,
"returnResults": true,
"rows": [
[
{"name":"user","value":user},
{"name":"email","value":email},
{"name":"date","value":date},
{"name":"message","value":message},
{"name":"latitude","value":latitude},
{"name":"longitude","value"longitude},
{"name":"latlong","value":"POINT(" + parseFloat(longitude) + " " + parseFloat(latitude) +")"}
]
]
}