Skip to content

Commit

Permalink
Fix polygon layer (#105)
Browse files Browse the repository at this point in the history
* Fix polygon layer

* bump beta version
  • Loading branch information
kylebarron authored Feb 9, 2024
1 parent bfde800 commit b8b2cde
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 20 deletions.
11 changes: 7 additions & 4 deletions examples/polygon/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import DeckGL, { Layer, PickingInfo } from "deck.gl/typed";
import { GeoArrowPolygonLayer } from "@geoarrow/deck.gl-layers";
import * as arrow from "apache-arrow";

const GEOARROW_POLYGON_DATA = "http://localhost:8080/small.feather";
// const GEOARROW_POLYGON_DATA = "http://localhost:8080/small.feather";

const GEOARROW_POLYGON_DATA = "http://localhost:8080/nybb.feather";

const INITIAL_VIEW_STATE = {
latitude: 40.63403641639511,
longitude: -111.91530172951025,
latitude: 40.71,
// longitude: -111.9,
longitude: -74.0,
zoom: 9,
bearing: 0,
pitch: 0,
Expand Down Expand Up @@ -59,7 +62,7 @@ function Root() {
data: table,
getFillColor: [0, 100, 60, 160],
getLineColor: [255, 0, 0],
lineWidthMinPixels: 0.1,
lineWidthMinPixels: 1,
extruded: false,
wireframe: true,
// getElevation: 0,
Expand Down
10 changes: 7 additions & 3 deletions examples/polygon/generate_data.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import geopandas as gpd
import pyarrow.feather as feather
from lonboard.geoarrow.geopandas_interop import geopandas_to_geoarrow
from lonboard import SolidPolygonLayer


def main():
gdf = gpd.read_file("Utah.geojson.zip", engine="pyogrio")
table = geopandas_to_geoarrow(gdf)
feather.write_feather(table, "utah.feather", compression="uncompressed")
layer = SolidPolygonLayer.from_geopandas(gdf)
feather.write_feather(layer.table, "utah.feather", compression="uncompressed")

gdf = gpd.read_file(gpd.datasets.get_path("nybb"))
layer = SolidPolygonLayer.from_geopandas(gdf)
feather.write_feather(layer.table, "nybb.feather", compression="uncompressed")


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"examples/*"
],
"name": "@geoarrow/deck.gl-layers",
"version": "0.3.0-beta.11",
"version": "0.3.0-beta.12",
"type": "module",
"description": "",
"source": "src/index.ts",
Expand Down
96 changes: 84 additions & 12 deletions src/polygon-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,82 @@ import { getGeometryVector } from "./utils.js";
import { GeoArrowExtraPickingProps, getPickingInfo } from "./picking.js";
import { ColorAccessor, FloatAccessor, GeoArrowPickingInfo } from "./types.js";
import { EXTENSION_NAME } from "./constants.js";
import { validateAccessors } from "./validate.js";
import { GeoArrowSolidPolygonLayer } from "./solid-polygon-layer.js";
import { GeoArrowPathLayer } from "./path-layer.js";

/**
* Get the exterior of a PolygonVector or PolygonData as a MultiLineString
*
* Note that casting to a MultiLineString is a no-op of the underlying data
* structure. For the purposes of the PolygonLayer we don't want to cast to a
* LineString because that would change the number of rows in the table.
*/
export function getPolygonExterior(
input: ga.vector.PolygonVector,
): ga.vector.MultiLineStringVector;
export function getPolygonExterior(
input: ga.data.PolygonData,
): ga.data.MultiLineStringData;

export function getPolygonExterior(
input: ga.vector.PolygonVector | ga.data.PolygonData,
): ga.vector.MultiLineStringVector | ga.data.MultiLineStringData {
if ("data" in input) {
return new arrow.Vector(input.data.map((data) => getPolygonExterior(data)));
}

return input;
}

/**
* Get the exterior of a MultiPolygonVector or MultiPolygonData
*
* Note that for the purposes of the PolygonLayer, we don't want to change the
* number of rows in the table. Instead, we convert each MultiPolygon to a
* single MultiLineString, combining all exteriors of each contained Polygon
* into a single united MultiLineString.
*
* This means that we need to condense both two offset buffers from the
* MultiPolygonVector/Data (geomOffsets and polygonOffsets) into a single
* `geomOffsets` for the new MultiLineStringVector/Data.
*/
export function getMultiPolygonExterior(
input: ga.vector.MultiPolygonVector,
): ga.vector.MultiLineStringVector;
export function getMultiPolygonExterior(
input: ga.data.MultiPolygonData,
): ga.data.MultiLineStringData;

export function getMultiPolygonExterior(
input: ga.vector.MultiPolygonVector | ga.data.MultiPolygonData,
): ga.vector.MultiLineStringVector | ga.data.MultiLineStringData {
if ("data" in input) {
return new arrow.Vector(
input.data.map((data) => getMultiPolygonExterior(data)),
);
}

const geomOffsets: Int32Array = input.valueOffsets;
const polygonData = ga.child.getMultiPolygonChild(input);
const polygonOffsets: Int32Array = polygonData.valueOffsets;
const lineStringData = ga.child.getPolygonChild(polygonData);

const resolvedOffsets = new Int32Array(geomOffsets.length);
for (let i = 0; i < resolvedOffsets.length; ++i) {
// Perform the lookup
resolvedOffsets[i] = polygonOffsets[geomOffsets[i]];
}

return arrow.makeData({
type: new arrow.List(polygonData.type.children[0]),
length: input.length,
nullCount: input.nullCount,
nullBitmap: input.nullBitmap,
child: lineStringData,
valueOffsets: resolvedOffsets,
});
}

/** All properties supported by GeoArrowPolygonLayer */
export type GeoArrowPolygonLayerProps = Omit<
PolygonLayerProps,
Expand Down Expand Up @@ -97,6 +169,11 @@ const defaultProps: DefaultProps<GeoArrowPolygonLayerProps> = {
const defaultLineColor: [number, number, number, number] = [0, 0, 0, 255];
const defaultFillColor: [number, number, number, number] = [0, 0, 0, 255];

/** The `GeoArrowPolygonLayer` renders filled, stroked and/or extruded polygons.
*
* GeoArrowPolygonLayer is a CompositeLayer that wraps the
* GeoArrowSolidPolygonLayer and the GeoArrowPathLayer.
*/
export class GeoArrowPolygonLayer<
ExtraProps extends {} = {},
> extends CompositeLayer<Required<GeoArrowPolygonLayerProps> & ExtraProps> {
Expand All @@ -119,12 +196,12 @@ export class GeoArrowPolygonLayer<
return this._renderLayers(polygonVector);
}

const MultiPolygonVector = getGeometryVector(
const multiPolygonVector = getGeometryVector(
table,
EXTENSION_NAME.MULTIPOLYGON,
);
if (MultiPolygonVector !== null) {
return this._renderLayers(MultiPolygonVector);
if (multiPolygonVector !== null) {
return this._renderLayers(multiPolygonVector);
}

const geometryColumn = this.props.getPolygon;
Expand All @@ -147,16 +224,11 @@ export class GeoArrowPolygonLayer<
): Layer<{}> | LayersList | null {
const { data: table } = this.props;

if (this.props._validate) {
assert(ga.vector.isPolygonVector(geometryColumn));
validateAccessors(this.props, table);
}

let getPath: ga.vector.LineStringVector | ga.vector.MultiLineStringVector;
let getPath: ga.vector.MultiLineStringVector;
if (ga.vector.isPolygonVector(geometryColumn)) {
getPath = ga.algorithm.getPolygonExterior(geometryColumn);
getPath = getPolygonExterior(geometryColumn);
} else if (ga.vector.isMultiPolygonVector(geometryColumn)) {
getPath = ga.algorithm.getMultiPolygonExterior(geometryColumn);
getPath = getMultiPolygonExterior(geometryColumn);
} else {
assert(false);
}
Expand Down

0 comments on commit b8b2cde

Please sign in to comment.