Map data

Data structures used to store map data in the frontend and the database

Data stored in the moped_proj_features table

The features table stores rows that contain data about project features. Each row contains a location field which stores a GeoJSON feature. Each row is related to the moped_project table by a project_id field. A complete project feature records is shown below.

{
    feature_id: <a unique feature ID generated by the DB>,
    project_id: <ID of the project that this feature belongs to>,
    location: <A GeoJSON feature>,
    status_id: <1 (active) or 0 (inactive)>
}

Important values in the GeoJSON properties

Feature identifier

Each GeoJSON feature contains a key in its properties object called PROJECT_EXTENT_ID that contains its unique identifier. This pattern is flexible in the code, but it has been continued since this is the same field name that both the streets and points vector tile layers store their unique identifiers. Since these identifiers are derived from the ObjectID in the vector tile layers, their uniqueness is reliable since the vector tile layer functionality and data integrity depends on it. A UUID is generated for drawn points and stored as the value of the PROJECT_EXTENT_ID key the properties object of the GeoJSON of a drawn feature.

Source layer name

The name of the source layer from where a feature came is stored in the properties object its GeoJSON with a key called sourceLayer. The source layer name maps directly to the mapConfig object in the React code. Specifically, the layer configs are stored in mapConfig.layerConfigs. This relationship between the source layer name and the mapConfig.layerConfigs object is important to expose how a layer is styled, if is a vector tile layer or sourced from user draw inputs, the color of the layer features, and more.

Data extracted from a vector tile layer

To get data out of a feature of a vector tile layer like a street or point, react-map-gl exposes an array of GeoJSON features through mouse event objects. When interacting with a layer, the array of features will contain a single feature that can be exposed through e.features[0]. The feature will contain excess metadata for styles that will be already be handled in the code so the values of the following keys are stored in the frontend: geometry, id, properties, and type. An example of the feature extracted is below.

{
    "geometry": {
        "type": "LineString",
        "coordinates": [
            [
                -97.74078816175461,
                30.269537013352178
            ],
            [
                -97.73970287293196,
                30.269240063162812
            ]
        ]
    },
    "type": "Feature",
    "properties": {
        "PROJECT_EXTENT_ID": 147720,
        "FULL_STREET_NAME": "E 8TH ST",
    },
    "id": 47720,
}

Once this data is stored in the frontend, the properties object of the GeoJSON is supplemented with sourceLayer for later styling. After adding the needed data, the feature will look like the example below, and it is ready for the next step of creating a project feature record when the extent is saved.

{
    "geometry": {
        "type": "LineString",
        "coordinates": [
            [
                -97.74078816175461,
                30.269537013352178
            ],
            [
                -97.73970287293196,
                30.269240063162812
            ]
        ]
    },
    "type": "Feature",
    "properties": {
        "PROJECT_EXTENT_ID": 147720,
        "FULL_STREET_NAME": "E 8TH ST",
        "sourceLayer": "CTN"
    },
    "id": 47720,
}

Data from the draw UI

Data input through the draw UI is also a GeoJSON feature. The properties object contains three important key-value pairs. First, renderType is added by react-map-gl-draw and determines the type of geometry to render the feature as when shown through the draw UI. The sourceLayer is important to the React code which styles the drawn points based on this value.

{
  id: "b8a2d91e-70af-4d84-9c44-521d14e8542c",
  type: "Feature",
  geometry: {
    type: "Point",
    coordinates: [-97.74016188559338, 30.26986214136913],
  },
  properties: {
    renderType: "Point",
    sourceLayer: "drawnByUser",
    PROJECT_EXTENT_ID: "b8a2d91e-70af-4d84-9c44-521d14e8542c",
  },
}

Data ready to be inserted

After capturing a GeoJSON feature from a vector tile layer or through the draw UI, a record must be prepared for insertion. On insertion, the feature_id is generated by the database. On update, the feature_id is used to find the correct row by the database.

The status_id of 1 is passed from the React code to set the feature as active. When soft-deleting a feature record, the record status_id is updated to 0 to make the feature inactive. Since the React code only queries for records with status_id of 1, they are removed from future display in the UI. A sample of an active feature record is shown below.

{
    feature_id: <a unique feature ID generated by the DB>,
    project_id: "126",
    location: {
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -97.74078816175461,
                30.269537013352178
                ],
                [
                    -97.73970287293196,
                    30.269240063162812
                ]
            ]
        },
        "type": "Feature",
        "properties": {
            "PROJECT_EXTENT_ID": 147720,
            "FULL_STREET_NAME": "E 8TH ST",
            "sourceLayer": "CTN"
        },
        "id": 47720,
    },
    status_id: 1
}

Last updated