jeremiak / geotiff2geojson

CLI tool to convert a GeoTIFF image into a GeoJSON FeatureCollection of Point features
10 stars 0 forks source link

Couple of suggestions: support for pixel is area, optimization, set up bot to get latest EPSG indices #3

Open matafokka opened 2 years ago

matafokka commented 2 years ago

Hey, cool stuff you've made! And thank you for using geotiff-geokeys-to-proj4, glad it's useful!

Ok, back to the business.

Support for Pixel is Area

In GeoTIFF, pixel can represent either a point or an area (a polygon). Your tool already covers points, you might want to add support for an area and provide an option to choose what should be in a result.

You can do checking by calling image.pixelIsArea(). Then you have to calculate positions of four points of a pixel. You already have top left corner:

point = {
    x: crsX * projObj.coordinatesConversionParameters.x,
    y: crsY * projObj.coordinatesConversionParameters.y,
}

To get other corners, add pixel size by X or Y to this coordinate, for example, bottom right corner:

const bottomRight = {
    x: (crsX + xSize) * projObj.coordinatesConversionParameters.x,
    y: (crsY + ySize) * projObj.coordinatesConversionParameters.y
}
const projectedBottomRightCorner = projection.forward(bottomRight);

Warning: don't use rectangles to represent converted coordinates!

Performance optimization

Replace color0.forEach() with for loop at line 46, it'll speed up reading. Function call overhead is significant when such many calls are required.

Remove lines 61-65 at index.mjs, they're doing the same thing and were here for an example.

EPSG indices

I'll update my library from time to time, you might want to set up dependabot or some stuff like that to get latest EPSG indices. Though, I suppose, nothing crucial would happen, if you'll use older indices.

jeremiak commented 1 year ago

Hey @matafokka! Thanks for the feedback, ideas, and for geotiff-geokeys-to-proj4!

I think I got the perf optimization you recommended integrated and released in v1.3.1 but I'm pretty lost about how to deal with the .pixelIsArea() behavior. I think I get that you can call image.pixelIsArea() to determine if the GeoTIFF has point or polygon data in it, but I'm unsure how to group the pixels into groups/polygons if .pixelIsArea() returns true. Any chance you have some resources you might point me towards so I can better understand it?

matafokka commented 1 year ago

Hi, @jeremiak , thanks for the kind words! And sorry for the answer delay, didn't check my email in a while :)

TLDR: No definite answer, just options, have no idea what you actually need :D

With pixel-is-area you have following options:

  1. Always treat pixels as points.

  2. Use pixels' borders as polygon edges like so:

image

  1. Store pixels as separate polygons like so:

image

  1. Store pixels' corners like so:

image

  1. Incorporate an interpolation algorithm like so:

image image

There might be more options that just didn't occur to me :)

There's no right or wrong approach to this problem. What fits best should be determined by the user based on what they're going to do with the data.

I don't know which options fit your library and your users, so it's up to you to decide what to implement.

Also, seems like I initially wanted to suggest options 2 and/or 4.

As for resources, I'd suggest referring to a specific field of geomatics to see how imagery is used. Uses differ from just displaying an image to a complex analysis and transformation.

You also may want to consider how you'll handle topology, i.e. when two images initially have common borders will it stay true after your library has transformed them.

jeremiak commented 1 year ago

Thanks for the detailed write up @matafokka! I'll think about how I can implement it, it would definitely be useful!