Skip to content

Instantly share code, notes, and snippets.

@tordans
Created May 7, 2025 08:09
Show Gist options
  • Save tordans/efd25a31a22cd4c96f077231f133e98e to your computer and use it in GitHub Desktop.
Save tordans/efd25a31a22cd4c96f077231f133e98e to your computer and use it in GitHub Desktop.
Modernized version of https://github.com/gagan-bansal/geojson2poly that can be used in a typescript file. It returns the poly fine as a string based on a input GeoJson.
import { describe, expect, it } from 'bun:test'
import type { Feature, FeatureCollection, Polygon } from 'geojson'
import { geojsonToPoly } from './geojsonToPoly'
describe('geojsonToPoly', () => {
it('should convert a simple Polygon GeoJSON to a polyline string', () => {
const geojson: Feature<Polygon, {}> = {
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [
[
[0, 0],
[1, 0],
[1, 1],
[0, 1],
[0, 0],
],
],
},
}
const result = geojsonToPoly(geojson, 'test')
const expected = 'test-0\n1\n\t0\t0\n\t1\t0\n\t1\t1\n\t0\t1\n\t0\t0\nEND\nEND\n'
expect(result).toBe(expected)
})
it('should handle a FeatureCollection with multiple Polygons', () => {
const geojson: FeatureCollection<Polygon, {}> = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [
[
[0, 0],
[1, 0],
[1, 1],
[0, 1],
[0, 0],
],
],
},
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: [
[
[2, 2],
[3, 2],
[3, 3],
[2, 3],
[2, 2],
],
],
},
},
],
}
const result = geojsonToPoly(geojson, 'test')
const expected =
'test-0\n1\n\t0\t0\n\t1\t0\n\t1\t1\n\t0\t1\n\t0\t0\nEND\nEND\n' +
'test-1\n1\n\t2\t2\n\t3\t2\n\t3\t3\n\t2\t3\n\t2\t2\nEND\nEND\n'
expect(result).toBe(expected)
})
it('should throw an error for invalid GeoJSON', () => {
const invalidGeojson = null
// @ts-expect-error we are testing a non TS case here where the input is invalid and the types where ignored
expect(() => geojsonToPoly(invalidGeojson, 'test')).toThrow('Invalid GeoJSON object')
})
})
// This file is based on https://github.com/gagan-bansal/geojson2poly/blob/master/geojson2poly.js
// It is modernized and external packages are inlined.
import type { Feature, FeatureCollection, Geometry, Polygon } from 'geojson'
/**
* Extracts geometries of a specific type from a GeoJSON object.
*
* @param {FeatureCollection | Feature | Geometry} geojson - The GeoJSON object.
* @param {string} type - The type of geometry to extract (e.g., 'Polygon').
* @returns {Array<Geometry>} - An array of extracted geometries.
*/
function extract(geojson: FeatureCollection | Feature | Geometry, type: string): Geometry[] {
const geometries: Geometry[] = []
function extractFromFeature(feature: Feature): void {
if (feature.geometry && feature.geometry.type === type) {
geometries.push(feature.geometry)
} else if (feature.geometry && feature.geometry.type === 'GeometryCollection') {
feature.geometry.geometries.forEach((geometry: Geometry) => {
if (geometry.type === type) {
geometries.push(geometry)
}
})
}
}
if (geojson.type === 'FeatureCollection') {
geojson.features.forEach(extractFromFeature)
} else if (geojson.type === 'Feature') {
extractFromFeature(geojson)
} else if (geojson.type === type) {
geometries.push(geojson)
}
return geometries
}
/**
* Converts a GeoJSON object to a polyline string.
*
* @param {FeatureCollection | Feature | Geometry} geojson - The GeoJSON object.
* @param {string} name - The base name for the polyline entries.
* @returns {string} - The polyline string.
*/
export function geojsonToPoly(
geojson: FeatureCollection | Feature | Geometry,
name: string,
): string {
if (!geojson || typeof geojson !== 'object') {
throw new Error('Invalid GeoJSON object')
}
const polies = extract(geojson, 'Polygon') as Polygon[]
let result = ''
polies.forEach((poly, ind) => {
result += `${name}-${ind}\n1\n`
poly.coordinates[0].forEach((p: number[]) => {
result += `\t${p.join('\t')}\n`
})
result += 'END\nEND\n'
})
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment