How to delete an extra " in GEOjson (Javascript) - javascript

I tried to manipulate an object GEOjson to display it in my map OpenLayers. But my GEOjson is invalid.
First, in my API I request to my database to recover the geometry, then I parse it thanks to GEOjson.parse : GeoJSON.parse(data, {GeoJSON : 'geometry'});
the data looks like this :
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.699526704561417,49.5855766259652],[0.699132813373672,49.5855472259388],[0.698829663954256,49.5852457878428],[0.698308423811369,49.5855523688003],[0.699127661396565,49.5862481964213],[0.699752271011022,49.5859030239836],[0.699526704561417,49.5855766259652]]]]}",
"properties": {
"libgeo": "Bois-Himont",
"nature": "Parcelle bâtie"
}
},
{
"type": "Feature",
"geometry": "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.696220319484454,49.581274516207],[0.696272071456392,49.5820438187077],[0.697147417334422,49.5815673912038],[0.697102005023975,49.5814546891317],[0.697047441685103,49.5812624281067],[0.6969844037675,49.5812621313821],[0.696220319484454,49.581274516207]]]]}",
"properties": {
"libgeo": "Bois-Himont",
"nature": "Parcelle bâtie"
}
}, etc...
Then in my script.js (that files had the aim to display the map and the GEOjson) I parse the data thanks to JSON.parse, but the line geometry is invalid because there is an extra " and the type and the coordinates is surrounded by ".
How can I delete the extra " and delete the " for the type and the coordinates ?

The geometry is a string when it should be an object. After the first parse you will need loop through the features and parse each geometry string into an object.
var myGeoJSON = JSON.parse(myText);
myGeoJSON.features.forEach( function(feature) { feature.geometry = JSON.parse(feature.geometry) });

Related

How to convert geometry string like "POLYGON ((32.5 39.2, 32.6 39.4 .... ))" to GeoJSON in Javascript

I have strings like
POLYGON ((32.5 39.2, 32.6 39.4 .... ))
POINT (32.4 39.2)
using Leaflet, React is there a way to convert these string to GeoJSON like:
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [125.6, 10.1]
},
"properties": {
"name": "Dinagat Islands"
}
}
in JavaScript?
These strings are called WKT (https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry).
There are quite a few parsers out there:
https://www.npmjs.com/search?q=wkt
"wellknown" and "wicket" can output GeoJSON, probably there are other modules that support this too.
Note that WKT represents just "geometry" field in GeoJSON, content of "properties" field should come from somewhere else (say if this was CSV - from other CSV columns).

Converting a list of JSON polygon coordinates to Long/Lat arrays in GeoJSON format

I am fetching data from a REST API which results in a list of datasets. Some of these datasets contain coordinates that I want to project on a map. In order to project the coordinates, I need to convert the JSON output to GeoJSON. While the conversion goes well for most parts of the data. I struggle with a long array containing x and y coordinates. It is 4+ points combined into polygons (5th endpoint = begin point is missing).
How can I convert this one array with 4+ XY coordinates to the right format while also adding the last one that should match the first point?
I thought about slicing the array into new ones for each point but this would result in too much work for polygons with over 20 points.
Example of the JSON:
"footprint": {
"epsgId": 4326,
"data": [
[
5.785569964298996,
50.94215924789526,
5.934953425435474,
50.94154873163077,
5.9341556116101595,
50.87413533708443,
5.784989651500041,
50.87474468292546
]
],
},
This is how it should look like after conversion into GeoJSON. I wrote this down myself, but I need a JavaScript code to do this automatically while looping through the results.
{
"type": "Feature",
"properties": {
"name": "name"
"id" : "id"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[5.785569964298996, 50.94215924789526],
[5.934953425435474, 50.94154873163077],
[5.9341556116101595, 50.87413533708443],
[5.784989651500041, 50.87474468292546],
[5.785569964298996, 50.94215924789526]
]
]
}
}
i think this function will do the work for you.
d = {"footprint": {
"epsgId": 4326,
"data": [
[
5.785569964298996,
50.94215924789526,
5.934953425435474,
50.94154873163077,
5.9341556116101595,
50.87413533708443,
5.784989651500041,
50.87474468292546
]
],
}
}
console.log(d)
function convert(points)
{
geojson = {
"geometry": {
"type": "Polygon",
"coordinates": [
]
}
}
var coordinates = new Array();
for (var i = 0; i < points.length; i+=2) {
coordinates.push([points[i],points[i+1]])
}
//closing the polygon
coordinates.push([points[0],points[1]])
// points need to be in zero index of coordinates array
geojson.geometry.coordinates = new Array(coordinates);
return geojson;
}
console.log(convert(d["footprint"]["data"][0]))

Rails jBuilder from GeoJSON to make another json

I'm trying to take a series of GeoJSON Line Strings and put them on a map. My jBuilder and Rails controller combination is not producing correctly formatted json for putting on a web map. Here's the relevant code.
overview_data.json.builder
json.type "FeatureCollection"
json.features #segments do |street|
if (street.extent_json) # only if item has a line drawn
json.type "Feature"
json.properties do
json.title "Was #{street.prevName} before #{street.dateEarliest} and now is #{street.currentName} #{street.dateLatest})"
end
json.geometry do
# json.type "LineString"
json.coordinates street.extent_json
end # json.geometry
end # if
end # json.features
overview_controller.rb
class OverviewController < ApplicationController
def index
end
def overview_data
#segments = Street.all
end
end
street.extent_json as it appears in a web form and in the database (Postgres via pgAdmin)
{"type":"LineString",
"coordinates":[[-118.25712423772116,34.01007010760971],
[-118.25649456380442,34.01016443793837],
[-118.25584971702219,34.01016443793837],
[-118.25427932544667,34.0102021700405],
[-118.25213995141625,34.010227324765935]]}
Output as seen in http://localhost:3000/overview/overview_data.json. At present there are about ten items that have extent_json. Below are the first few:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"title": "Was 10th St. before 1903 and now is part of E. 9th Place (21). 1908)"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.24982816353442,34.035546195508864],[-118.25104052200915,34.03663976724366]]}"
}
},
{
"type": "Feature",
"properties": {
"title": "Was 37th St before 1903 and now is part of E. 40th Place 1928)"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.25712423772116,34.01007010760971],[-118.25649456380442,34.01016443793837],[-118.25584971702219,34.01016443793837],[-118.25427932544667,34.0102021700405],[-118.25213995141625,34.010227324765935]]}"
}
},
{
"type": "Feature",
"properties": {
"title": "Was Brook before 1903 and now is part of S. Toluca St. (26). and second block south gone 1908)"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.25862396508458,34.06087254304104],[-118.25933206826451,34.05994816216629]]}"
}
},
{
"type": "Feature",
"properties": {
"title": "Was Auto Pl before 1928 and now is Commonwealth Pl and a portion abandoned 1930)"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.28558737412096,34.07543021182353],[-118.28369373455645,34.07646106299854]]}"
}
},
{
"type": "Feature",
"properties": {
"title": "Was 3rd St before 1921 and now is Miramar St. One block abandoned )"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.26117539280003,34.05901974362122],[-118.2593849946753,34.05823410691563],[-118.25815599257271,34.05768101430694],[-118.25759459655055,34.05717191451128],[-118.25663111959356,34.05654339202722]]}"
}
},
{
"type": "Feature",
"properties": {
"title": "Was Gregory Way before and now is Gregory Way 2017)"
},
"geometry": {
"coordinates": "{\"type\":\"LineString\",\"coordinates\":[[-118.37295765057208,34.06188579510917],[-118.37272698059681,34.06172580874592],[-118.37264114990832,34.06161026285129],[-118.3725660480559,34.06146805230318],[-118.37253386154772,34.061414723286084],[-118.37249631062151,34.06118363049104]]}"
}
},
The problem is the added "{\"type\":\"LineString\",\"coordinates\" and closing }". Otherwise I think it's OK.
In the jBuilder I originally had json.type "LineString" in the json.geometry do loop and it's even worse adding: "geometry":{"type":"LineString","coordinates":"{\"type\":\"LineString\",\"coordinates\".
As Зелёный pointed out json.coordinates JSON.parse(street.extent_json) replacing similar line was needed. As he also pointed out I must have had some malformed json inputs which I did. Once that was cleaned up everything is working.
He also pointed out "in jbuilder template all things must be in plain Ruby, but you pass a json string(which comes from database) as result Rails tried to convert json string to json again."
But output still has an error, here's the first item:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"title": "Was 10th St. before 1903 and now is part of E. 9th Place (21). 1908)"
},
"geometry": {
"coordinates": {
"type": "LineString",
"coordinates": [
[
-118.24982816353442,
34.035546195508864
],
[
-118.25104052200915,
34.03663976724366
]
]
}
}
},
An extra {
"coordinates": after geometry.
The problem is in extent_json method, it returns an object as json string. To resolve your issue, avoid the double call to_json.
To restate the problem: take a series of GeoJSONs from a database and use jBuilder to compile all the items that meet a certain criteria into a GeoJSON (for use in a Mapbox/Leaflet web map). https://stackoverflow.com/users/2057388/Зелёный provided the answer offline, but I want to document it to make sure I understand it and help anyone else with a similar problem. It helps to consider the jsons as hashes and that jbuilder is making another hash.
The input has two keys: type and coordinates.
The output has keys of type, properties, and geometry.
The properties value is a key title;
the geometry values are two keys type and coordinates. So overview_data.json.builder becomes:
extent = JSON.parse(street.extent_json) # the GeoJSON
json.type "Feature"
json.properties do
json.title h("Was #{street.prevName} before #{street.dateEarliest} and now is #{street.currentName} #{street.dateLatest}.")
end
json.geometry do
json.type "LineString"
json.coordinates extent["coordinates"]
end
Looks straightforward once it's laid out. Except for other key points. One was parsing extent_json to convert the string to a hash object. Then coordinates are extracted from that hash to put into the output json.

GeoJSON - Display all features in a table

I am trying to list all my features from a GeoJSON file in a table on a website and i am stuck figuring out how to achieve this.
As a first step i built a Leaflet map showing all locations loaded from the GeoJSON file which works pretty good.
What i would like to have in addition to the map is a rating system on a second page, which features all the locations from the GeoJSON in a table (I only need names for now, the rating system would be a different problem...).
Note that i am an absolute beginner and need a very detailed "tutorial" for this.
My GeoJSON looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ x,y ]
},
"properties": {
"FID":0,
"Shape *":"Point",
"Name":"XXX",
"Ditrict":"Dist1",
"Str_No":"Street 1",
"ZIP":"Some ZIP",
"Phone":"Some Number",
"Rating":4.5
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ x,y ]
}, and so on
I hope that there is a simple solution for this.
Thank you in advance!
If your GeoJSON object is var geoJSON, you can get all the names for each feature by doing the following:
var featureNames = [];
for (var i = 0; i < geoJSON.features.length; i++) {
var currentFeature = geoJSON.features[i];
var featureName = currentFeature.properties.Name;
var featureId = currentFeature.properties.FID;
console.log(featureName);
featureNames.push({ featureId: featureId, featureName : featureName });
}
So featureNames will have each feature object with it's name in an array.
To put them all in a table, I'm going to use jQuery DataTables. If I have a <div id="myTable">, then:
$('#myTable').DataTable( {
"columnDefs": [
{ "title": "Feature Names", "targets": 0 }
]
data: featureNames,
scrollY: 300,
paging: false
} );

Read Latitude and Longitude from a GeoJSON file, and then display each lat-long as a marker with Leaflet

I'm new to Javascript and hence I'm a little lost. I am able to read from a GeoJSON file; however, I do not understand how to iterate through the file to get the Lat-Long of the points, and then display those points as markers in Leaflet. I am hoping to also use the plugin Awesome Markers (based on font-awesome, for Leaflet)
This is a sample of my GeoJSON file:
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "Street Nam": "Aljunied Avenue 2", " Block": "118 Aljunied Avenue 2", " Postal Co": "380118", " Latitude": 1.320440, "Longitude": 103.887575 },
"geometry": { "type": "Point", "coordinates": [ 103.887575, 1.320440 ] } }
,
{ "type": "Feature", "properties": { "Street Nam": "Aljunied Crescent", " Block": "97A Aljunied Crescent", " Postal Co": "381097", " Latitude": 1.321107, "Longitude": 103.886127 },
"geometry": { "type": "Point", "coordinates": [ 103.886127, 1.321107 ] } }
]
}
Thank you for your attention and time =)
Process the geojson as described in the leaflet documentation. Specify a pointToLayer function which creates a marker with an awesome icon:
L.geoJson(geoJson, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng,
{icon: L.AwesomeMarkers.icon(
<< options based on feature.properties >>
)});
}
}).addTo(map);
After reading the file, you should have a javascript object that represents all the data in the file:
var geoData = JSON.parse(fileContents);
var features = geoData.features;
and so on. The parsed data will be converted to objects or arrays depending on whether they are key/value dictionaries or just lists. So from the above
var feature = geoData.features[0];
will get you a reference to the first feature object in the list. If you write
console.log(geoData);
and run with any recent browser you should be able to see an expandable description of the data to help make sense of it all.

Categories

Resources