manubb / Leaflet.PixiOverlay

Bring Pixi.js power to Leaflet maps
MIT License
463 stars 85 forks source link

Add a Geojson in the map #84

Closed joaoVictorBAlves closed 1 year ago

joaoVictorBAlves commented 1 year ago

Hello, I'm João Victor, and I'm trying to use this lib to add geojsons to my map, but I'm not succeeding. In the documentation, there is no specifying how to do it. Could you help me?

helder-a-reis commented 1 year ago

Some of the examples actually use GeoJSON https://manubb.github.io/Leaflet.PixiOverlay/leg-t2.html (well, it's TopoJSON which is an extension of GeoJSON)

joaoVictorBAlves commented 1 year ago

Some of the examples actually use GeoJSON https://manubb.github.io/Leaflet.PixiOverlay/leg-t2.html (well, it's TopoJSON which is an extension of GeoJSON)

Hello guy, i found a way to add geojson based in these files. the problem is that the documentation doesn't have a good specification of pixi.js uses to draw a geojson. However I found a way that uses the library and the pixi.js library to draw polygons through geojson data:

This is a hook i created that draw the poligon using geojson data:

import "leaflet-pixi-overlay/L.PixiOverlay";
import "pixi.js";
import * as d3 from "d3"

const useCreatePolygon = (data, map, escala = undefined, escalaVar = undefined, pixiContainer) => {
    // POLÍGONOS
    var firstDraw = true;
    var pixiOverlay = L.pixiOverlay((utils) => {
        var container = utils.getContainer();
        var renderer = utils.getRenderer();
        var project = utils.latLngToLayerPoint;
        var colorescala = d3.scaleLinear()
            .domain([0, 33, 66, 100])
            .range(["#D2DFFF", "#7D96E8", "#577DE8", "#295FFF"]);
        PIXI.utils.clearTextureCache();

        const drawPoly = (color, alpha) => {
            return (poly, properties) => {
                var shape = new PIXI.Polygon(poly[0].map(function (point) {
                    var proj = project([point[1], point[0]]);
                    return new PIXI.Point(proj.x, proj.y);
                }));
                var pixiPolygon = new PIXI.Graphics();
                pixiPolygon.beginFill(color, alpha);
                pixiPolygon.drawShape(shape);
                pixiPolygon.lineStyle(0.5, 0x000000);
                pixiPolygon.drawShape(shape);

                if (poly.length > 1) {
                    for (var i = 1; i < poly.length; i++) {
                        var hole = new PIXI.Polygon(poly[i].map(function (point) {
                            var proj = project([point[1], point[0]]);
                            return new PIXI.Point(proj.x, proj.y);
                        }));
                        pixiPolygon.drawShape(hole);
                        pixiPolygon.lineStyle(0.5, 0x000000);
                        pixiPolygon.drawShape(hole);
                        pixiPolygon.addHole();
                    }
                }
                // OnClick
                pixiPolygon.interactive = true;
                pixiPolygon.cursor = 'pointer';
                pixiPolygon.on('pointerdown', onClick);
                function onClick() {
                    console.log(`${properties.NM_BAIRRO} [${escalaVar}]: ${properties[escalaVar]}`)
                }
                container.addChild(pixiPolygon);
            };
        }

        if (firstDraw) {
            var geojson = data
            geojson.features.forEach(function (feature, index) {
                var alpha, color;
                var tint = d3.color(colorescala(100)).rgb();;
                if (feature.properties[escalaVar] !== undefined) {
                    var valor = feature.properties[escalaVar]
                }
                if (escala !== undefined) {
                    if (valor < escala) {
                        tint = d3.color(colorescala(0)).rgb();
                    } else if (valor > escala && valor < escala * 2) {
                        tint = d3.color(colorescala(33)).rgb();
                    } else if (valor > escala * 2 && valor < escala * 3) {
                        tint = d3.color(colorescala(66)).rgb();
                    } else if (valor > escala * 3) {
                        tint = d3.color(colorescala(100)).rgb();
                    }
                }

                color = 256 * (tint.r * 256 + tint.g) + tint.b;
                alpha = 0.5;
                if (feature.geometry === null) return;

                if (feature.geometry.type === 'Polygon') {
                    drawPoly(color, alpha)(feature.geometry.coordinates, feature.properties);
                } else if (feature.geometry.type == 'MultiPolygon') {
                    feature.geometry.coordinates.forEach(drawPoly(color, alpha));
                }
            });
        }
        firstDraw = false;
        renderer.render(container);
    }, pixiContainer);
    pixiOverlay.addTo(map);
}

export default useCreatePolygon;

This is a code in a Map component i use this hook to create a polygon on the map

if (mapContainerRef.current) {
            // MAPA
            mapState = (L.map(mapContainerRef.current).setView(coordenatesState, zoomState)); // Chicago origins
            const mapTiles = '//stamen-tiles-{s}.a.ssl.fastly.net/toner/{z}/{x}/{y}.png';
            const osmCPLink = '<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>';
            const mapCPLink = '<a href="http://maps.stamen.com/toner">Stamen Design</a>';
            L.tileLayer(mapTiles, {
                attribution: `${osmCPLink} | ${mapCPLink}`,
                detectRetina: false,
                minZoom: minzoom,
                maxZoom: maxZoom,
                noWrap: false,
                subdomains: 'abc'
            }).addTo(mapState);

            var pixiContainer = new PIXI.Container();
            // Gera polígono com ou sem choropleth
            let variable;
            if (dataState) {
                if (dataState.features[0].properties[choroplethVariableState] !== undefined) {
                    variable = choroplethVariableState;
                }
                useCreatePolygon(dataState, mapState, choroplethScale, variable, pixiContainer);
            }
joaoVictorBAlves commented 1 year ago

For more information i created a repo that uses a lot of feutures in the React Projecet based in leaflet-pixi-overlay LINK