openlayers / ol-mapbox-style

Use Mapbox Style objects with OpenLayers
https://unpkg.com/ol-mapbox-style/dist/examples/index.html
BSD 2-Clause "Simplified" License
348 stars 120 forks source link

olms with arcgis vector tile - Sprite failure #95

Open ssisman14 opened 6 years ago

ssisman14 commented 6 years ago

Hı , I am using olms to load arcgis style in my ol vector tile. I have two basic problems.

1) Some icons do not appear in a certain zoom range. just max appears at zoom level.

in fact ==> esri

ol-mapbox-style ==> sh

2) some icons do not appear in the correct position.

in fact ==> esri 2

ol-mapbox-style ==> sh2

Help me with your suggestions :)

ahocevar commented 6 years ago

Please share the code you use to create the OpenLayers / ol-mapbox-style map in the above screenshots.

ssisman14 commented 6 years ago

"cbsdell4.ibb.gov.tr" server access is off

var vTileLayer = new ol.layer.VectorTile({
            renderMode: 'vector',
            reload: Infinity,
            declutter : true,
            source: new ol.source.VectorTile({
              cacheSize: 512,
              format: new ol.format.MVT(),
              url: 'https://cbsdell4.ibb.gov.tr/server/rest/services/Hosted/RehberVT/VectorTileServer/tile/{z}/{y}/{x}.pbf',
                    maxZoom: 26,
            }),
            id: "vTileLayer",

              tilePixelRatio: 8,
          });
     var vLayer = new ol.layer.Vector({
            style: function(feature) {
              return feature.get('style');
            },
            source: new ol.source.Vector(),
            zIndex: 3,
            id: "vLayer",
          });
      var map = new ol.Map({
        layers: [ vLayer ],
        target: 'map',
        view: new ol.View({
          center: [3223224.4636233835, 5014301.391308421],
          zoom: 11,
          minZoom: 8,
          maxZoom: 22,
        }),
      });

    function GetRoot(name){
      for(var i in root.layers) {
          if(root.layers[i]["source-layer"] === name) {
            return root.layers[i];
          }
        }
    }

var root;
var rootPath = "https://cbsdell4.ibb.gov.tr/server/rest/services/Hosted/RehberVT/VectorTileServer/resources/styles/root.json";
var spritePath = "https://cbsdell4.ibb.gov.tr/server/rest/services/Hosted/RehberVT/VectorTileServer/resources/sprites/sprite.json";
var pngPath = "https://cbsdell4.ibb.gov.tr/server/rest/services/Hosted/RehberVT/VectorTileServer/resources/sprites/sprite.png";
    $.ajax({
      type: "GET",
      url: spritePath,
      success: function(spriteData) {
        $.ajax({
          type: "GET",
          url: rootPath,
          success: function(rootData) {
            root = rootData;
            mb2olstyle(vTileLayer, rootData, 'esri', undefined, spriteData, pngPath);
            map.addLayer(vTileLayer);
          }
        });
      }
    });
ahocevar commented 6 years ago

When debugging rendering, try using the apply() function of ol-mapbox-style to get the most accurate rendering with the correct tile grid configuration. Then verify your result against that. Things that come to mind:

Other (probably unrelated) things I noticed:

ssisman14 commented 6 years ago

I'm having difficulty implementing the apply() function.

root.json ==> https://codeshare.io/2jo7YR

Synthian commented 4 years ago

Here to bump a 2 year old thread - I have created a minimal example: https://jsfiddle.net/n9cpd5q7/4/

When you load this fiddle, you should be centered on an example of the labels being not placed in the correct location. Route 79 labels should be on the dark grey road. There are other examples around the map in seemingly random places.

Additionally, ArcGIS vector maps often don't have tiles for the lower zoom levels - the client is expected to only request up to z = 15 (for example) and then use that data for the lower levels. We can manually manage this by setting maxZoom on the VectorTileSource, but it appears that is not possible with apply or olms

Jared-Miller commented 4 years ago

When calculating the midpoint of a MultiLineString, it is interpolating as though the start and end coordinates are for a LineString.

https://github.com/openlayers/ol-mapbox-style/blob/ac13bf5edbcc07964fd2541758ca1b43ab0c30e9/src/stylefunction.js#L464-L472

Using getFlatMidpoints() here would improve the label position for MultiLineStrings that have a midpoint that isn't on any segments and is equivalent to calling getFlatMidpoint() for LineStrings, based on the render feature in OpenLayers.

Since this solution only uses the midpoint of the first segment in the MultiLineString, it may also place labels strangely on a line with many segments. A slightly less naive solution could use the midpoint of all segments in the line and select the closest midpoint on a segment.

The complete solution for this issue likely involves similar work as #230. Rather than setting a single midpoint geometry on the style for a given feature, it would need to contain all the potential segments and determine in the OpenLayers core which ones should be used.

ahocevar commented 4 years ago

To improve the situation, the easiest solution is to use getFlatMidpoint for LineString geometries and getFlatMidpoints with only the first midpoint for MultiLineString geometries. Anyone willing to provide a pull request?