I'm building a map web app with the MEEN stack using Node.js, Express, Mongo, Mongoose and Mapbox api.
So far its been exciting. The data that I want to display is polygons from a shapefile that have attributes associated to them.
So far I've managed to load the data into Mongodb and configure a Mongoose model with a schema. In the node app I can access the data but not load it into the map api.
I get the error "Uncaught Error: Invalid GeoJSON object."
From inspecting the object in the devtools console I can see that the geometry record is blank. I assume this is due to a mis-configuration in the schema.
Below is one record from the Mongodb command line. I removed a couple elements for privacy purposes. It looks as expected:
{
"_id" : ObjectId("56c77259336aac299181a207"),
"type" : "Feature",
"properties" : {
"TNRTPCD" : "P",
"TNRSBTPCD" : "C",
"PRCNTOWNER" : 100,
"NTRTMSTMP" : "20140908161622",
"TNRSBTPDSC" : "CLAIM",
"TRMNTNTPDS" : null,
"TAG_NUMBER" : null,
"OBJECTID" : 40495,
"NTRSRD" : "MTA_ONLINE",
"NUM_OWNERS" : 1,
"PROTECTED" : "N",
"PDTSRD" : "MTA_ONLINE",
"TNRTPDSCRP" : "Placer",
"TNRNMBRD" : 1030842,
"RVSNNMBR" : 0,
"FCODE" : null,
"TRMNTNDT" : null,
"RNHCTRS" : 20.3496,
"TTLTPCD" : "PCX"
},
"geometry" : {
"type" : "Polygon",
"coordinates" : [
[
[
-121.88883540217063,
50.97489195799901,
0
],
[
-121.88883523174192,
50.97072525131302,
0
],
[
-121.8950854466247,
50.97072527980969,
0
],
[
-121.89508560169767,
50.97489198254216,
0
],
[
-121.88883540217063,
50.97489195799901,
0
]
]
]
}
}
Here is the code from my model file:
//Claim Model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Schema Defined Here
var claimSchema = new Schema({
gid: Number,
tnrtpcd: String,
ttltpdsc: String,
tnrsbtpcd: String,
prcntowner: Number,
ntrtmstmp: String,
tnrsbtpdsc: String,
owner_name: String,
trmntntpds: String,
tag_number: String,
objectid: Number,
gdtdt: String,
ntrsrd: String,
claim_name: String,
num_owners: Number,
clientnum: Number,
issue_date: String,
protected: String,
pdtsrd: String,
pdttmstmp: String,
tnrtpdscrp: String,
tnrnmbrd: Number,
rvsnnmbr: Number,
fcode: String,
trmntndt: String,
rnhctrs: Number,
ttltpcd: String,
geometry: { type: [String], index: '2dsphere'}
}, { collection : 'docs' });
mongoose.model('Claim', claimSchema);
The routing seems to work in the app.js since I am able to access the data. Here is the relevant part of the code in my view file:
script.
L.mapbox.accessToken = 'pk.[ommited]';
//- var geojson = mongoose.model('Claim').find({'properties.CLIENTNUM': 278107});
var geojson = $.getJSON('/claims/nick',function(result){
return result;
});
L.mapbox.map('map', 'mapbox.outdoors')
.featureLayer.setGeoJSON(geojson);
So the big question here is how do I properly define the schema for the geometry data? Assuming that's my problem.
Looks like more confusion of "type" as a field name and "type" as a declaration on a mongoose schema.
To flexibly allow a couple of GeoJSON types you basically want your "geometry" field to be:
"geometry": {
"type": { "type": String },
"coodinates": []
}
You can add enum
for "Point", "Polygon" etc if you want, but generally a loose "coordinates" as array []
matches the rules in those cases.
A bit of searching should reveal that people have created "types" for this before.