Search code examples
javascriptazure-maps

Azure maps cluster position discrepancies


I've got a list of positions that I retrieve from an ms endpoint like so:
https://atlas.microsoft.com/search/fuzzy/json?top=100&typeahead=true&subscription-key=subscription-key&api-version=1&query=Leeds
The user then selects one of the proposed addresses and the position provided by this endpoint is then used to be displayed on a map that uses clusters. So for Leeds for example, I have the following: -1.548567, 53.801277

However, when I create the clusters in the clusterRenderCallback function I provide upon creating the HtmlMarkerLayer, I get positions that are close to the ones I've provided, but different and I have no idea how or why.

so the code would look something like:
First I create the dataSource

dataSource = new atlas.source.DataSource(null, {
  //Tell the data source to cluster point data.
  cluster: true
});
map.sources.add(dataSource);

Then I manage the cluster creation inside the HtmlMarkerLayer creation:

clusterRenderCallback: function (id, position, properties) {
  var cluster = new atlas.HtmlMarker({
    position: position, // different position to that which I have provided
    htmlContent: `<div>${properties.point_count_abbreviated}</div>`,
    values: properties,
  });

  map.events.add('click', cluster, clusterClicked);

  return cluster;
}

And here I create points to add to my data source:

let features = list.map(x => new atlas.data.Feature(new atlas.data.Point(new atlas.data.Position(x.lon, x.lat)), x));
dataSource.add(features);

The position I receive for the Leeds cluster for example is -1.549072265625, 53.80065082633024, even though I had 2 poisitions in Leeds, both made out of the same coordinates: -1.548567, 53.801277
It seems like there's some sort of mechanism inside the atlas code that "fixes" the provided coordinates; anyone knows how to stop this or what am I doing wrong here?

==EDIT 02/05==

ok, so following @rbrundritt answer, here the last bit of code I should have added, showing what we do once the cluster is clicked:

function clusterClicked(e) {
  var cluster = e.target;

  datasource.getClusterExpansionZoom(cluster.properties.cluster_id).then(function (zoom) {

    map.setCamera({
      center: cluster.getOptions().position,
      zoom: zoom
    });
  });

}

And this is where we have our problem with this discrepancy- clicking on the cluster zooms in to the zoom level where the cluster breaks; however, since we centre the map to the cluster position, the pin position, being different to the cluster one, is not being seen in the map on that zoom level (ie 3 afair). On top of that we have no way of knowing inside the context of this function to what pin does the cluster corresponds, this leaves us with a buggy behaviour.


Solution

  • Ok, so I wasn't aware of what the datasource.getClusterLeaves method was returning (I've simply mistaken the leaves for the verb leaving). This is what I was looking for, so my code now looks like this:

    function inSamePosition(pos1, pos2) {
      return pos1.data.geometry.coordinates[0] == pos2.data.geometry.coordinates[0] 
        && pos1.data.geometry.coordinates[1] == pos2.data.geometry.coordinates[1];
    }
    
    function clusterClicked(e) {
      var cluster = e.target;
      (cluster.properties.cluster_id, Number.POSITIVE_INFINITY, 0).then(pins => {
        let position = pins.every(p => inSamePosition(p, pins[0])) ? pins[0]['data'].geometry.coordinates : null;
        datasource.getClusterExpansionZoom(cluster.properties.cluster_id).then(function (zoom) {
          map.setCamera({
            center: position ? position : cluster.getOptions().position,
            zoom: zoom
          });
        });
      })
    }