1

I am trying to add two icons to the map and add border to these two icons. However, only one icon gets the border and other icon does not even show up on the map. It is the same with more than two icons, only first icon shows on the map with border, remaining icon don't even show up. This is an issue of the style function in the vector layer because when i remove it, the icons appear. However i want all the icons to have the border. Please help !!!

var activeColor = "red";


@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
  iconFeatures:Feature = [];
  ngOnInit(){



    var iconFeature = new Feature({
      geometry: new Point([0, 0]),
      color: 'green',
      scale: 0.1,
      imgSrc: "assets/non_transparent.jpg"

    });
    iconFeature.set("style",this.createStyle(iconFeature.get("imgSrc"),undefined));

    this.iconFeatures.push(iconFeature);



 var iconFeature2 = new Feature({
          geometry: new Point([100, 100]),
          color: 'green',
          scale: 0.1,
          imgSrc: "assets/non_transparent.jpg"

        });


 iconFeature2.set("style",this.createStyle(iconFeature2.get("imgSrc"),undefined));

        this.iconFeatures.push(iconFeature2);

    var map = new Map({
      layers: [
        new TileLayer({
          source: new OSM()
        })
      ],
      target: document.getElementById("map"),
      view: new View({
        center: [0, 0],
        zoom: 3
      })
    });

    var vectorSource= new VectorSource({
      features:this.iconFeatures,
      wrapX: false

    });
    console.log("Entering vector layer");

    var vectorLayer = new VectorLayer({
      source: vectorSource,
      style: function(feature) {
        console.log("inside style function");
        if (feature.get("color") !== activeColor) {
          var initStyle = feature.get("initStyle");
          if (!initStyle) {
            initStyle = feature.get("style");
            feature.set("initStyle", initStyle);
          }
          var image = initStyle.getImage().getImage();

          if (image.width > 0) {
            console.log("inside width > 0");

            var canvas = document.createElement("canvas");
            var ctx = canvas.getContext("2d"); //this method returns an object that provides methods and properties for drawing on the canvas. eg: text, line, boxes, circles, and more

            var dArr = [-1,-1, 0,-1, 1,-1, -1,0, 1,0, -1,1, 0,1, 1,1], // offset array
            s = 100,  // thickness scale
            i = 0,  // iterator
            x = 6,  // final position
            y = 6;

            // fill with color


            //set new canvas dimentions adjusted for border
            canvas.width = image.width + s + s;
            canvas.height = image.height + s + s ;

            // draw images at offsets from the array scaled by s
            for (; i < dArr.length; i += 2){
              ctx.drawImage(image, x + dArr[i] * s, y + dArr[i + 1] * s);
            }


            // fill with color
            ctx.globalCompositeOperation = "source-in";
            ctx.fillStyle = activeColor;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // draw original image in normal mode
            ctx.globalCompositeOperation = "source-over";
            ctx.drawImage(image, x, y); //, image.width, image.height);


            //create new openlayers icon style from canvas
            var newStyle = new Style({
              image: new Icon(
                /** @type {olx.style.IconOptions} */ ({
                  crossOrigin: "anonymous",
                  src: undefined,
                  img: canvas,
                  imgSize: canvas
                    ? [canvas.width, canvas.height]
                    : undefined,
                  scale: feature.get('scale')
                })
              )
            });

            feature.set("style", newStyle);
            feature.set("color", activeColor);

          }
        }
        return feature.get("style");

      }
    });
    map.addLayer(vectorLayer);

}



  public createStyle(src, img) {
    return new Style({
      image: new Icon({
        anchor: [0.5, 0.96],
        crossOrigin: "anonymous",
        src: src,
        img: img,
        imgSize: img ? [img.width, img.height] : undefined,
        scale: 1
      })
    });
  }
}

1 Answer 1

1

If not specified otherwise, coordinates passed to OpenLayers functions are expected to be in default CRS, which is projected EPSG:3857.

You center your view and your first feature on Null Island [0, 0]. Then you place your second feature at [100, 100] in projected map meters. At zoom 3 this is practically the same position as the first feature and you get impression that only one feature is shown.

You either have to set second feature at something like [100000, 100000] to notice the difference in position, or use [lon,lat] coordinates and transform them to projected ones with ol.proj.fromLonLat([lon, lat]).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.