Search code examples
node.jsmongodbmongoosemapboxgeojson

GeoJSON working with Mongoose/Mongodb in Node.js


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.


Solution

  • 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.