google-map icon indicating copy to clipboard operation
google-map copied to clipboard

fit-to-marker no longer correctly centers map on search updates

Open ghost opened this issue 9 years ago • 10 comments

Hi there,

I'm trying to implement google-map, google-map-marker and google -map-search

<google-map-search global-search="true" map="{{map}}" query="{{searchPlace}}" results="{{results}}"></google-map-search>

<google-map map="{{map}}" api-key="XXX" fit-to-markers>
      <template is="dom-repeat" items="{{results}}" as="marker">
        <google-map-marker latitude="{{marker.latitude}}" longitude="{{marker.longitude}}">
          <h2>{{marker.name}}</h2>
          <span>{{marker.formatted_address}}</span>
        </google-map-marker>
      </template>
</google-map>

When launching a first search on a place, I juste do :

this.searchPlace = <my search>;

And after that, the map update his center to focus on the marker, but if I do another search immediatly, the marker update his position, but the map stay with the same center. Should I do something specific after/before performing a search to be sure that the center of the map is updated?

thanks

ghost avatar Jun 14 '16 15:06 ghost

Update :

  • if I search "lille" and then "paris" map will not update his center
  • if I search "pizza" and then "lille" map will update his center

Another question about the image. I've seen an new element like this one each time i perfom a search, what is it?

<div draggable="false" class="gm-style-cc" style="-webkit-user-select: none; height: 14px; line-height: 14px; z-index: 0; position: absolute; bottom: 127px; right: 0px;"><div style="opacity: 0.7; width: 100%; height: 100%; position: absolute;"><div style="width: 1px;"></div><div style="width: auto; height: 100%; margin-left: 1px; background-color: rgb(245, 245, 245);"></div></div><div style="position: relative; padding-right: 6px; padding-left: 6px; font-family: Roboto, Arial, sans-serif; font-size: 10px; color: rgb(68, 68, 68); white-space: nowrap; direction: ltr; text-align: right; vertical-align: middle; display: inline-block; padding-bottom: 0px;"></div></div>

map

ghost avatar Jun 14 '16 15:06 ghost

I believe you should also data bind latitude/longitude on the map element itself (e.g set it to the lat/lng of one of the marker results).

ebidel avatar Jun 14 '16 16:06 ebidel

Yep, it's seem working, but to be honest I don't really understand ... The code I provided is not complete, here is the "full" version

    <google-map-search global-search="true" map="[[map]]" query="{{searchPlace}}" results="{{results}}"></google-map-search>

    <google-map map="{{map}}" api-key="XXX" fit-to-markers>

      <template id="sitesRepeat" is="dom-repeat" items="{{sitesMarkers}}" as="marker">
        <google-map-marker latitude="{{marker.lat}}" longitude="{{marker.long}}" title="{{marker.title}}"></google-map-marker>
      </template>

      <template is="dom-repeat" items="{{resultsMarker}}" as="marker">
        <google-map-marker latitude="{{marker.lat}}" longitude="{{marker.long}}" title="{{marker.title}}">
          <h2>{{marker.name}}</h2>
          <span>{{marker.formatted_address}}</span>
        </google-map-marker>
      </template>

    </google-map>

As you see I don't have only one dom-repeat, but two (for the moment, at the end it will be 4 dom-repeat)

For the one which use the sitesMarkers variables, here the function which fill the array

_onSiteUpdate : function _onSiteUpdate (evt) {
        var sites = evt.detail,
            i = sites.length,
            // clone
            tmpSitesArr = _.clone(this.sitesMarkers, true);

        while (i--) {
          // on regarde s'il existe, et son index si oui
          var index = _.findIndex(tmpSitesArr, function (s) {
            return s.siteId == sites[i].id
          });

          if (sites[i].add) {
            // ajout, et un index existe, mise à jour 
            if (index != -1) {
              tmpSitesArr[index] = {
                "lat" : sites[i].position.y,
                "long" : sites[i].position.x,
                "title" : sites[i].name
              };
            } else {
              // ajout, mais pas d'index, création
              tmpSitesArr.push({
                "lat" : sites[i].position.y,
                "long" : sites[i].position.x,
                "title" : sites[i].name
              });
            }
          } else {
            // suppression, et un index existe, on supprime 
            if (index != -1) {
              tmpSitesArr.splice(index, 1);
            }
          }
        }
        this.set("sitesMarkers", tmpSitesArr);
      },

With this function, each time I update my sitesMarkers array, the map will always update his center, without doing anything. But not with the search results, and I really don't understand what's the difference.

I try to build the "same" function for the results, but without the lat/long binding on the map, the problem stay here

_onSearchResult : function _onSearchResult (evt) {
        var results = evt.detail,
            i = results.length,
            tmpArr = [];

        this.set("resultsMarker", []);

        while (i--) {
          tmpArr.push({
            "lat" : results[i].latitude,
            "long" : results[i].longitude,
            "title" : results[i].name
          });
        }

        this.set("resultsMarker", tmpArr);
      },

What's the difference? Thanks a lot

ghost avatar Jun 15 '16 06:06 ghost

Actually, I see you're using fit-to-markers, which means the map should update it's center automatically. No need to set the lat/lng or (data bind them) explicitly.

Hmm, http://jsbin.com/vaqocuvagu/edit?html,output updates for me.

ebidel avatar Jun 15 '16 19:06 ebidel

Sorry for the long answer ...

The problem is here on your jsbin too

With the pre-filled value "pizza" it works. Search for "paris" after that, it works too. Search for "tokyo" and marker is updated, but not the map center.

But if you launch another search for (again) "pizza", the map center will update

ghost avatar Jun 24 '16 09:06 ghost

I see. Yea, that does repo for me. Thanks for posting the steps.

ebidel avatar Jul 07 '16 23:07 ebidel

Not working in Shadow DOM either.

motss avatar Jul 14 '16 14:07 motss

Any news about this issue?

ghost avatar Nov 17 '16 10:11 ghost

up !

ghost avatar Apr 04 '17 13:04 ghost

@bastienarm Not the most elegant work-around, but this should help

ready() {
  this.addEventListener('google-map-search-results', e => this._updateCenter(e));
}

/**
  * Update the map center on search result changes
  * @param e
  * @private
  */
_updateCenter(e) {
  let $map = this.$$("google-map");
  if ($map) {
    this.async(() => {
      if ($map.fitToMarkers) {
        $map._fitToMarkersChanged();
      } else {
        $map._updateCenter();
      }
    }, 30);
  }
}

dwalters18 avatar Aug 09 '17 19:08 dwalters18