Skip to content

Commit

Permalink
Merge pull request #33 from sanak/feature/change-wkt-reader-writer-type
Browse files Browse the repository at this point in the history
Change WKT Reader/Writer 'string' type to 'number' (#26)
  • Loading branch information
chrispahm committed Apr 7, 2024
2 parents 8af7374 + 20e51ee commit ea2977c
Show file tree
Hide file tree
Showing 82 changed files with 655 additions and 146 deletions.
4 changes: 3 additions & 1 deletion docs/functions/geojsonToGeosGeom.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ const geos = await initGeosJs()
const json = JSON.parse('{"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}')
const geomPtr = geojsonToGeosGeom(json, geos)
const writer = geos.GEOSWKTWriter_create()
const wkt = geos.GEOSWKTWriter_write(writer, geomPtr)
const wktPtr = geos.GEOSWKTWriter_write(writer, geomPtr)
const wkt = geos.Module.UTF8ToString(wktPtr)
geos.GEOSFree(wktPtr)
console.log(wkt)
// => POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))
```
Expand Down
6 changes: 5 additions & 1 deletion docs/functions/geos.GEOSArea.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ Calculate the area of a geometry.
```js
const reader = geos.GEOSWKTReader_create()
const wkt = 'POLYGON((0 0,0 10,10 10,10 0,0 0))'
const g = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const g = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
const area = geos.Module._malloc(8)
geos.GEOSArea(g, area)
const areaValue = geos.Module.getValue(area, 'double')
Expand Down
11 changes: 9 additions & 2 deletions docs/functions/geos.GEOSBoundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@ Computes the boundary of a geometry.
```js
const reader = geos.GEOSWKTReader_create()
const writer = geos.GEOSWKTWriter_create()
const geom = geos.GEOSWKTReader_read(reader, 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
const wkt = 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geom = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
const boundary = geos.GEOSBoundary(geom)
const wkt = geos.GEOSWKTWriter_write(writer, boundary)
const wktPtr = geos.GEOSWKTWriter_write(writer, boundary)
const wkt = geos.Module.UTF8ToString(wktPtr)
geos.GEOSFree(wktPtr)
console.log(wkt) // 'LINESTRING (0 0, 0 1, 1 1, 1 0, 0 0)'
```

Expand Down
4 changes: 2 additions & 2 deletions docs/functions/geos.GEOSWKTReader.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Reads a WKT string and returns a GEOSGeometry object.

| Param | Type | Description |
| --- | --- | --- |
| wkt | <code>string</code> | The WKT string to read. |
| wkt | <code>number</code> | The WKT string pointer to read. |


---
Expand All @@ -87,7 +87,7 @@ Reads a WKT string and returns a GEOSGeometry object.
| --- | --- | --- |
| handle | <code>number</code> | A pointer to the GEOS context handle. |
| reader | <code>number</code> | The pointer to the GEOSWKTReader object. |
| wkt | <code>string</code> | The WKT string to read. |
| wkt | <code>number</code> | The WKT string pointer to read. |


---
4 changes: 2 additions & 2 deletions docs/functions/geos.GEOSWKTWriter.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ padded with 0's out to the rounding precision.
Converts a GEOSGeometry object to a WKT string.

**Kind**: Exported member
**Returns**: <code>string</code> - The WKT representation of the geometry, or null on error.
**Returns**: <code>number</code> - The WKT representation pointer of the geometry, or null on error.

| Param | Type | Description |
| --- | --- | --- |
Expand All @@ -235,7 +235,7 @@ Converts a GEOSGeometry object to a WKT string.
Converts a GEOSGeometry object to a WKT string using a context handle.

**Kind**: Exported member
**Returns**: <code>string</code> - The WKT representation of the geometry, or null on error.
**Returns**: <code>number</code> - The WKT representation pointer of the geometry, or null on error.

| Param | Type | Description |
| --- | --- | --- |
Expand Down
6 changes: 5 additions & 1 deletion docs/functions/geosGeomToGeojson.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import { geojsonToGeosGeom } from 'geos-wasm/helpers'
const geos = await initGeosJs()
const reader = geos.GEOSWKTReader_create()
const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
const json = geosGeomToGeojson(geomPtr, geos)
console.log(JSON.stringify(json))
// => {"type":"Polygon","coordinates":[[[0,0],[1,0],[1,1],[0,1],[0,0]]]}
Expand Down
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ const geos = await initGeosJs()
const reader = geos.GEOSWKTReader_create()
const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
// read the WKT string into a GEOS geometry -> returns a pointer
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
geos.Module._free(wktPtr)
// create a pointer where the area will be written to
const areaPtr = geos.Module._malloc(8)
// calculate the area of the geometry
Expand Down
4 changes: 2 additions & 2 deletions src/allCFunctions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3226,7 +3226,7 @@ pointer * @param {number} s - The coordinate sequence pointer
* @see {@link https://libgeos.org/doxygen/geos__c_8h.html#a0a0f7c1b9f6a9f7c3c4d1b5a7b6f9e2e|GEOSWKTReader_read_r}
* @alias module:geos
*/
geos.GEOSWKTReader_read_r = Module.cwrap('GEOSWKTReader_read_r', 'number', ['number', 'number', 'string'])
geos.GEOSWKTReader_read_r = Module.cwrap('GEOSWKTReader_read_r', 'number', ['number', 'number', 'number'])

/**
* Creates a GEOSWKTWriter object.
Expand Down Expand Up @@ -3277,7 +3277,7 @@ pointer * @param {number} s - The coordinate sequence pointer
* @returns {string} The WKT representation of the geometry, or null on error.
* @alias module:geos
*/
geos.GEOSWKTWriter_write_r = Module.cwrap('GEOSWKTWriter_write_r', 'string', ['number', 'number', 'number'])
geos.GEOSWKTWriter_write_r = Module.cwrap('GEOSWKTWriter_write_r', 'number', ['number', 'number', 'number'])

/**
* Sets whether the output WKT string should be trimmed of unnecessary spaces.
Expand Down
6 changes: 5 additions & 1 deletion test/tests/GEOSArea.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ test('calculate area of a polygon', async (t) => {

const reader = geos.GEOSWKTReader_create()
const wkt = 'POLYGON((0 0,0 10,10 10,10 0,0 0))'
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
const areaPtr = geos.Module._malloc(8)
geos.GEOSArea(geomPtr, areaPtr)
const area = geos.Module.getValue(areaPtr, 'double')
Expand Down
11 changes: 9 additions & 2 deletions test/tests/GEOSBoundary.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@ test('GEOSBoundary', async (t) => {

// Create a polygon geometry from WKT
const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Get the boundary of the polygon
const boundaryPtr = geos.GEOSBoundary(geomPtr)

// Convert the boundary to WKT
const boundaryWkt = geos.GEOSWKTWriter_write(writer, boundaryPtr)
const boundaryWktPtr = geos.GEOSWKTWriter_write(writer, boundaryPtr)
const boundaryWkt = geos.Module.UTF8ToString(boundaryWktPtr)
geos.GEOSFree(boundaryWktPtr)

// Expect the boundary to be a linestring
t.equal(boundaryWkt, 'LINESTRING (0 0, 1 0, 1 1, 0 1, 0 0)', 'boundary is correct')

Expand Down
6 changes: 5 additions & 1 deletion test/tests/GEOSBuffer.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ test('GEOSBuffer', async (t) => {
const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'

// Read the WKT string and get a geometry pointer
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Buffer the geometry by 0.5 units and get a new geometry pointer
const bufferPtr = geos.GEOSBuffer(geomPtr, 0.5)
Expand Down
20 changes: 16 additions & 4 deletions test/tests/GEOSBufferWithStyle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import tape from 'tape'
import initGeosJs from '../../build/package/geos.esm.js'
const geos = await initGeosJs()

// Define a helper function to convert a GEOS geometry pointer to a WKT string
const geomToWkt = (writer, geomPtr) => {
const wktPtr = geos.GEOSWKTWriter_write(writer, geomPtr)
const wkt = geos.Module.UTF8ToString(wktPtr)
geos.GEOSFree(wktPtr)
return wkt
}

// Define a helper function to get the area of a GEOS geometry
const getArea = (geomPtr) => {
const ptr = geos.Module._malloc(8) // allocate 8 bytes for a double
Expand All @@ -30,17 +38,21 @@ tape('GEOSBufferWithStyle', (t) => {

// Create a polygon geometry from a WKT string
const wkt = 'POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))'
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Buffer the polygon with different styles and parameters
const buffer1 = geos.GEOSBufferWithStyle(geomPtr, 0.5, 8, GEOSBUF_CAP_ROUND, GEOSBUF_JOIN_ROUND, 5.0)
const buffer2 = geos.GEOSBufferWithStyle(geomPtr, -0.2, 4, GEOSBUF_CAP_FLAT, GEOSBUF_JOIN_MITRE, 2.0)
const buffer3 = geos.GEOSBufferWithStyle(geomPtr, -0.4, -1, GEOSBUF_CAP_SQUARE, GEOSBUF_JOIN_BEVEL, -1.0)

// Convert the buffered geometries to WKT strings
const wkt1 = geos.GEOSWKTWriter_write(writer, buffer1)
const wkt2 = geos.GEOSWKTWriter_write(writer, buffer2)
const wkt3 = geos.GEOSWKTWriter_write(writer, buffer3)
const wkt1 = geomToWkt(writer, buffer1)
const wkt2 = geomToWkt(writer, buffer2)
const wkt3 = geomToWkt(writer, buffer3)

// Get the areas of the buffered geometries
const area1 = getArea(buffer1)
Expand Down
20 changes: 16 additions & 4 deletions test/tests/GEOSBuildArea.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import test from 'tape'
import initGeosJs from '../../build/package/geos.esm.js'
const geos = await initGeosJs()

// Define a helper function to convert a WKT string to a GEOS geometry pointer
const wktToGeom = (reader, wkt) => {
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
return geomPtr
}

// Test GEOSBuildArea function
test('GEOSBuildArea', async (t) => {
// Create a reader and a writer for WKT conversion
Expand All @@ -19,9 +29,9 @@ test('GEOSBuildArea', async (t) => {
const wkt3 = 'POLYGON ((-1 -1, -1 -2, -2 -2, -2 -1, -1 -1))'

// Read the WKT strings into GEOS geometries
const geomPtr1 = geos.GEOSWKTReader_read(reader, wkt1)
const geomPtr2 = geos.GEOSWKTReader_read(reader, wkt2)
const geomPtr3 = geos.GEOSWKTReader_read(reader, wkt3)
const geomPtr1 = wktToGeom(reader, wkt1)
const geomPtr2 = wktToGeom(reader, wkt2)
const geomPtr3 = wktToGeom(reader, wkt3)

// Create a list of geometries
const geomPtrs = new Int32Array([geomPtr1, geomPtr2, geomPtr3])
Expand All @@ -36,7 +46,9 @@ test('GEOSBuildArea', async (t) => {
const areaPtr = geos.GEOSBuildArea(collectionPtr)

// Write the result geometry to a WKT string
const areaWkt = geos.GEOSWKTWriter_write(writer, areaPtr)
const areaWktPtr = geos.GEOSWKTWriter_write(writer, areaPtr)
const areaWkt = geos.Module.UTF8ToString(areaWktPtr)
geos.GEOSFree(areaWktPtr)

// Expected WKT string for the result geometry
const expectedWkt = 'MULTIPOLYGON (((-1 -2, -2 -2, -2 -1, -1 -1, -1 -2)), ((0 0, 0 1, 1 1, 1 0, 2 0, 2 0, 0 0, 0 0, 0 0)))'
Expand Down
11 changes: 9 additions & 2 deletions test/tests/GEOSClipByRect.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ test('GEOSClipByRect', (t) => {
geos.GEOSWKTWriter_setRoundingPrecision(writer, 0)

// Create a polygon geometry from a WKT string
const polygon = geos.GEOSWKTReader_read(reader, 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))')
const wkt = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))'
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const polygon = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Clip the polygon by a rectangle with xmin = 2, ymin = 2, xmax = 8, ymax = 8
const clipped = geos.GEOSClipByRect(polygon, 2, 2, 8, 8)

// Convert the clipped geometry to a WKT string
const clippedWkt = geos.GEOSWKTWriter_write(writer, clipped)
const clippedWktPtr = geos.GEOSWKTWriter_write(writer, clipped)
const clippedWkt = geos.Module.UTF8ToString(clippedWktPtr)
geos.GEOSFree(clippedWktPtr)

// Assert that the clipped geometry is equal to the expected WKT string
t.equal(clippedWkt, 'POLYGON ((2 2, 2 8, 8 8, 8 2, 2 2))')
Expand Down
10 changes: 8 additions & 2 deletions test/tests/GEOSConcaveHull.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ initGeosJs().then(geos => {
const wkt = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 8 2, 8 8, 2 8, 2 2))'

// Convert the WKT string to a GEOS geometry pointer
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Call the GEOSConvexHull function with the geometry pointer as the argument
// The function returns another geometry pointer for the convex hull
const hullPtr = geos.GEOSConcaveHull(geomPtr)

// Convert the convex hull pointer to a WKT string
const hullWkt = geos.GEOSWKTWriter_write(writer, hullPtr)
const hullWktPtr = geos.GEOSWKTWriter_write(writer, hullPtr)
const hullWkt = geos.Module.UTF8ToString(hullWktPtr)
geos.GEOSFree(hullWktPtr)

// Assert that the concave hull WKT string is equal to the expected value
t.equal(hullWkt, 'POLYGON ((2 8, 0 10, 8 8, 10 10, 10 0, 8 2, 0 0, 2 2, 2 8))')
Expand Down
14 changes: 12 additions & 2 deletions test/tests/GEOSContains.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ import test from 'tape'
import initGeosJs from '../../build/package/geos.esm.js'
const geos = await initGeosJs()

// Define a helper function to convert a WKT string to a GEOS geometry pointer
const wktToGeom = (reader, wkt) => {
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
return geomPtr
}

// Define some test cases for GEOSContains
const testCases = [
{
Expand Down Expand Up @@ -38,8 +48,8 @@ test('GEOSContains', (t) => {
// Loop through the test cases
for (const testCase of testCases) {
// Create the geometries from the WKT strings
const geom1 = geos.GEOSWKTReader_read(reader, testCase.geom1)
const geom2 = geos.GEOSWKTReader_read(reader, testCase.geom2)
const geom1 = wktToGeom(reader, testCase.geom1)
const geom2 = wktToGeom(reader, testCase.geom2)

// Call the GEOSContains function and get the result
const result = geos.GEOSContains(geom1, geom2)
Expand Down
10 changes: 8 additions & 2 deletions test/tests/GEOSConvexHull.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ initGeosJs().then(geos => {
const wkt = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 8 2, 8 8, 2 8, 2 2))'

// Convert the WKT string to a GEOS geometry pointer
const geomPtr = geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geomPtr = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)

// Call the GEOSConvexHull function with the geometry pointer as the argument
// The function returns another geometry pointer for the convex hull
const hullPtr = geos.GEOSConvexHull(geomPtr)

// Convert the convex hull pointer to a WKT string
const hullWkt = geos.GEOSWKTWriter_write(writer, hullPtr)
const hullWktPtr = geos.GEOSWKTWriter_write(writer, hullPtr)
const hullWkt = geos.Module.UTF8ToString(hullWktPtr)
geos.GEOSFree(hullWktPtr)

// Assert that the convex hull WKT string is equal to the expected value
t.equal(hullWkt, 'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))')
Expand Down
11 changes: 9 additions & 2 deletions test/tests/GEOSCoverageUnion.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ test('GEOSCoverageUnion', (t) => {
for (const testCase of testCases) {
// Convert the input WKT strings to GEOS geometries
const inputGeoms = testCase.input.map(wkt => {
return geos.GEOSWKTReader_read(reader, wkt)
const size = wkt.length + 1
const wktPtr = geos.Module._malloc(size)
geos.Module.stringToUTF8(wkt, wktPtr, size)
const geom = geos.GEOSWKTReader_read(reader, wktPtr)
geos.Module._free(wktPtr)
return geom
})

// Create a list of geometries
Expand All @@ -45,7 +50,9 @@ test('GEOSCoverageUnion', (t) => {
const outputGeomPtr = geos.GEOSCoverageUnion(collectionPtr)

// Convert the output GEOS geometry to a WKT string
const outputWkt = geos.GEOSWKTWriter_write(writer, outputGeomPtr)
const outputWktPtr = geos.GEOSWKTWriter_write(writer, outputGeomPtr)
const outputWkt = geos.Module.UTF8ToString(outputWktPtr)
geos.GEOSFree(outputWktPtr)

// Compare the output WKT with the expected output WKT
t.equal(outputWkt, testCase.output)
Expand Down

0 comments on commit ea2977c

Please sign in to comment.