Leaflet / Leaflet.VectorGrid

Display gridded vector data (sliced GeoJSON or protobuf vector tiles) in Leaflet 1.0.0
591 stars 192 forks source link

Apply esri styling #147

Open imosapatryk opened 6 years ago

imosapatryk commented 6 years ago

Is it possible to apply esri styling? For example provided from this url: esri style.

IvanSanchez commented 6 years ago

It might be possible, but not out of the box yet. Parsing stylesheets is certainly a nice feature to have, but we haven't had any time to work on the mapbox branch for parsing mapbox stylesheets just yet.

wfield-CUNY commented 4 years ago

Here's a snippet with my work around. (In case you're wondering, I store the array of layers and add them to the map a little later in the code.) "layer" is an object I manually create in a config file with info about each layer such as the url to the tiles and the legend styles.

this.mapLayers[layer.name] = new L.vectorGrid.protobuf( layer.url, { vectorTileLayerStyles: { "Tracts2013wgs84_HTCchoropleth_wide": function (_props, _zoom) { return { weight: 0, fillColor: layer.legend[_props._symbol - 1].swatch.color, fillOpacity: 1, fill: true } } } })

joelhickok commented 4 years ago

As of today, this is how I deal with parsing style for custom Esri Vector Tile Layers. It's a little more streamlined that what @wfield-CUNY discusses.

I make an HTTP request to get the style JSON and loop over the layers property to create a style object that is friendly to Leaflet.VectorGrid constructor. This approach can handle unknown layer names, unless you need to apply dynamic logic that references a layer name directly, like I do below.

 const url = "https://tiles.arcgis.com/tiles/rQj5FcfuWPllzwY8/arcgis/rest/services/Parcel_Viewer_Basemap/VectorTileServer/resources/styles/root.json";

    const prepareStyle = async () => {
      // object to store layer descriptions
      const vectorTileLayerStyles = {};

      // get the actual JSON style file from the ArcGIS REST endpoint
      const { data } = await axios.get(url);

      // loop over the layers property specifically for the JSON style
      data.layers.forEach(layer => {
        // only work with layers that are 'type === line', in this case.
        // Modify as needed, but ArcGIS Vector labels do not work for me in the current version
        const layerName = layer["source-layer"];
        if (layer.type === "line") {
          // add layer to style placeholder using layer name property
          vectorTileLayerStyles[layerName] = {
            weight: layerName === "TaxParcels" ? 2 : 5, // dynamic weight assignment
            color: layer.paint["line-color"],
            opacity: 1
          };
        } else {
          // if the layer type is not a line, make the layer transparent
          vectorTileLayerStyles[layerName] = {
            opacity: 0
          };
        }
      });

      return vectorTileLayerStyles;
    };

    const friendlyStyleObject = await prepareStyle();

    // friendlyStyleObject can be used in the constructor options for VectorGrid

    console.log(friendlyStyleObject['TaxParcels']);

    /*
      Expected console.log output:
      {
        weight: 2, 
        color: "rgba(207,198,165,0.9)", 
        opacity: 1
      }
    */
dpraimeyuu commented 4 years ago

Hi! Big thanks @joelhickok for your exemplary code - I need to tweak it a bit to support fill and symbol layer types. There's one thing I don't know how to implement in terms of parsing mapbox styles - filters.

@IvanSanchez could you give me some hints if its possible to use them as styles input for protobuf instance?

RibhuRoy commented 2 years ago

Hi @IvanSanchez, any update on the previous question, if it's possible to use filters as styles input? Thanks!