Published
Edited
Sep 27, 2019
Importers
Insert cell
md`# GeoFx`
Insert cell
md`### Lookups`
Insert cell
Insert cell
geom_lu = ({
"point": {wkt: "POINT", json: "Point"},
"multipoint": {wkt: "MULTIPOINT", json: "MultiPoint"},
"linestring": {wkt: "LINESTRING", json: "LineString"},
"polygon": {wkt: "POLYGON", json: "Polygon"},
"multipolygon": {wkt: "MULTIPOLYGON", json: "MultiPolygon"},
})
Insert cell
md`### Transform`
Insert cell
function transform(x, y, epgs_from, epgs_to = epgs_lu[4326]) {
let format="ogcwkt"
let proj_from = epgs_lu[epgs_from]
let proj_to = epgs_lu[epgs_to]
return proj4(proj_from, proj_to, [x, y])

}
Insert cell
function transformArray(coordinates, epgs_from, epgs_to = epgs_lu[4326]) {
for(let i = 0; i < coordinates.length; i++) {
let point = coordinates[i]
coordinates[i] = transform(point[0], point[1], epgs_from, epgs_to)
}
return coordinates
}
Insert cell
function transformNestedArray(coordinates, epgs_from, epgs_to = epgs_lu[4326]) {
for(let i = 0; i < coordinates.length; i++) {
coordinates[i] = transformArray(coordinates[i], epgs_from, epgs_to)
/*
let coordinates = coordinates[i]
for(let j = 0; j < nested.length; j++) {
let point = nested[j]
nested[j] = transform(point[0], point[1], epgs_from, epgs_to)
}
coordinates[i] = nested
*/
}
return coordinates
}
Insert cell
function transformDoubleNestedArray(coordinates, epgs_from, epgs_to = epgs_lu[4326]) {
for(let i = 0; i < coordinates.length; i++) {
coordinates[i] = transformNestedArray(coordinates[i], epgs_from, epgs_to)
}
return coordinates
}
Insert cell
function transformFeature(geometry, epgs_from, epgs_to = epgs_lu[4326]) {
let type = geometry.type.toLowerCase()
let coordinates = geometry.coordinates
switch(type) {
case "point":
geometry.coordinates = transform(coordinates[0], coordinates[1], epgs_from, epgs_to)
break
case "linestring":
case "multipoint":
geometry.coordinates = transformArray(coordinates, epgs_from, epgs_to)
break;
case "polygon":
case "multilinestring":
geometry.coordinates = transformNestedArray(coordinates, epgs_from, epgs_to)
break;
case "multipolygon":
geometry.coordinates = transformDoubleNestedArray(coordinates, epgs_from, epgs_to)
break;
}
return geometry
}
Insert cell
md`### WKT to GeoJson`
Insert cell
function wktToJson(wkt) {
let type = wkt.split("(")[0]
let coords = wkt.replace(type, "")
type = type.replace(" ", "").toLowerCase()

coords = coords.split("(").join("[")
coords = coords.split(")").join("]")
coords = coords.split(", ").join("],[")
coords = coords.split(" ").join(",")
switch(type) {
case "multipoint":
coords = coords.split(']],[[').join('],[')
console.log(coords)
break
}
switch(type) {
case "multipolygon":
case "linestring":
coords = `[${coords}]`
break
}
type = geom_lu[type].json
coords = JSON.parse(coords)
return {
type: type,
coordinates: coords
}
}
Insert cell
wktToJson('MULTIPOINT ((4240098.5 879949.06), (4240375.5 878260), (4239721.5 878235.69))')
Insert cell
md`### GeoJson to WKT`
Insert cell
function jsonToWkt(json) {
let type = geom_lu[json.type.toLowerCase()].wkt
let coords = json.coordinates
coords = JSON.stringify(coords)
coords = coords.split(" ").join("")
coords = coords.split("[").join("(")
coords = coords.split("]").join(")")
coords = coords.split(",").join(" ")
coords = coords.split(") (").join(",")
// dirty fix - look into a cleaner fix
coords = coords.replace("((((", "(((")
coords = coords.replace("))))", ")))")
let wkt = `${type} ${coords}`

return wkt
}
Insert cell
md`### Function Examples`
Insert cell
JSON.stringify(wktToJson("MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), ((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), (30 20, 20 15, 20 25, 30 20)))"))
Insert cell
pt = wktToJson(`POINT (-123 44)`)
Insert cell
ln = wktToJson(`LINESTRING (30 10, 10 30, 40 40)`)
Insert cell
mp = wktToJson(`MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),
((15 5, 40 10, 10 20, 5 10, 15 5)))`)
Insert cell
json = wktToJson(`MULTIPOLYGON (((4240798.8415422216 876707.41209763661, 4240938.0535376519 880733.89057715028, 4238928.0428281222 880796.74360999255, 4238508.9814029159 880807.24087823671, 4238440.4291313253 876762.80826649175, 4240798.8415422216 876707.41209763661)), ((4238788.55767483 875994.569164619, 4238790.99206148 875994.913981378, 4238793.33524065 875995.659061179, 4238795.52192354 875996.783078507, 4238797.49141452 875998.255193457, 4238799.18892348 876000.034067363, 4238800.56687818 876002.07015948, 4238801.58722083 876004.307367384, 4238802.22173616 876006.682698831, 4238802.45237954 876009.130865023, 4238802.27291735 876011.582968235, 4238803.14102881 876058.45803459, 4238805.57147844 876138.145811439, 4238807.51964393 876203.699710011, 4238810.11905706 876309.363901585, 4238797.28209662 876309.780896917, 4238647.83306617 876314.219879583, 4238645.93214485 876254.248994157, 4238642.12800561 876134.309847996, 4238641.49611494 876114.320974559, 4238638.30910257 876013.813942522, 4238638.21034914 876000.47173202, 4238689.77308618 875998.562280506, 4238788.55767483 875994.569164619)))`)
Insert cell
json2 = transformFeature(json, 2914, 4326)
Insert cell
transformFeature(point, 4326, 2914)
Insert cell
point = ({
"type": "Point",
"coordinates": [-123, 44]

})
Insert cell
transformFeature(multiPoint, 4326, 2914)
Insert cell
multiPoint = ({

"type": "MultiPoint",
"coordinates": [
[-123, 43], [-123, 44], [-123, 45], [-135, 45]
]
})



Insert cell
transformFeature(lineString, 4326, 2914)
Insert cell
lineString = ({
"type": "LineString",
"coordinates": [
[-123, 43], [-123, 44], [-123, 45], [-135, 45]
]

})
Insert cell
transformFeature(multiLineString, 4326, 2914)
Insert cell
multiLineString = ({

"type": "MultiLineString",
"coordinates": [
[[-123, 43], [-123, 44], [-123, 45], [-135, 45]],
[[-124, 43], [-124, 42], [-125, 44], [-135, 41]]
]

})
Insert cell
transformFeature(polygon, 4326, 2914)
Insert cell
polygon = ({

"type": "Polygon",
"coordinates": [
[
[-120.0, 44.0], [-121.0, 44.0], [-121.0, 45.0],
[-120.0, 45.0], [-120.0, 44.0]
]
]

})
Insert cell
transformFeature(multiPolygon, 4326, 2914)
Insert cell
multiPolygon = ({
"type": "MultiPolygon",
"coordinates": [
[
[[40, 40], [20, 45], [45, 30], [40, 40]]
],
[
[[20, 35], [10, 30], [10, 10], [30, 5], [45, 20], [20, 35]],
[[30, 20], [20, 15], [20, 25], [30, 20]]
]
]
})
Insert cell
eug_json.features[0].geometry
Insert cell
transformFeature(eug_json.features[0].geometry, 4326, 2914)
Insert cell
eug_json = fetch("https://gl.githack.com/epdcau/observable/raw/master/data/geojson/city_limits.geojson")
.then( data => data.json() )
.then( ( data ) => {
data.features = data.features.filter( f => f.properties.inccityabb == "EUG" );
return data;
})
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
md`### Libraries`
Insert cell
proj4 = require('proj4@2')
Insert cell
md`### To Purge`
Insert cell
async function epgs(epgs) {
let format="ogcwkt"
let epgs_url = `https://raw.githubusercontent.com/GeographicDesign/projections/master/epsg/${epgs}/${format}.txt`
return await fetch(epgs_url)
.then(d => d.text())
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more