3

I am trying to add map markers dynamically to the map using ng-repeat inside ng-map as follows,

<div id="map-canvas">
    <ng-map default-style="true">
        <marker id='ID{{school.id}}' ng-repeat="school in vm.schools" position="{{school.location}}" on-click="vm.showDetail(school)" icon="assets/img/marker-excellent.png">
        </marker>

        <info-window id="marker-info">
            <div ng-non-bindable="">
                <h5>{{vm.school.name}}</h5>
            </div>
        </info-window>
    </ng-map>
</div>

Here this creates multiple markers with the same marker icon. I want to use different marker icons based on the value of {{school.rating}}. However I am not able to figure out how to change the marker icon url based on the value of rating while the ng-repeat is in action to render the markers on the map.

Currently, I am doing the following, but I think this is an inefficient method of doing it.

<div id="map-canvas">
    <ng-map default-style="true">
        <marker id='ID{{school.id}}' ng-if="school.overallRating >= 4.5" ng-repeat="school in filteredSchools = (search.schools | filter:boardsFilter)" position="{{school.location}}" on-click="search.showDetail(school)" icon="assets/img/marker-excellent.png">
        </marker>

        <marker id='ID{{school.id}}' ng-if="school.overallRating < 4.5 && school.overallRating >= 3.5" ng-repeat="school in filteredSchools = (search.schools | filter:boardsFilter)" position="{{school.location}}" on-click="search.showDetail(school)" icon="assets/img/marker-good.png">
        </marker>

        <marker id='ID{{school.id}}' ng-if="school.overallRating < 3.5 && school.overallRating >= 2.0" ng-repeat="school in filteredSchools = (search.schools | filter:boardsFilter)" position="{{school.location}}" on-click="search.showDetail(school)" icon="assets/img/marker-average.png">
        </marker>

        <info-window id="marker-info">
            <div ng-non-bindable="">
                <h5>{{vm.school.name}}</h5>
            </div>
        </info-window>
    </ng-map>
</div>

Here, I have put multiple marker directives each having ng-repeat but different conditions using ng-if

I am wondering if there is a more efficient way to do it using a single marker directive with ng-repeat

Avi
  • 1,070
  • 1
  • 15
  • 28
  • Have you already tried to add a field to school object (such as 'marker_type') containing info about the marker to be rendered and then bind the icon attribute to this field? (eg icon="assets/img/{{school.marker_type}}.png") – beaver Dec 25 '15 at 16:19
  • This will not give the required functionality as the marker type is dynamic and depends on the rating. Hence the DB cannot store a marker type for each school row. Even if it does store it, it will have to be continously monitored to be updated in case the rating value changes. So this is not a dynamic solution. – Avi Dec 30 '15 at 06:05
  • Yes, but I think data from DB could be retrieved from a backend service which could associate dynamically (calculate) a 'marker_type' field to each record (school). However the solution proposed by Vadim Gremyachev is a good client side approach. – beaver Dec 30 '15 at 07:39

1 Answers1

5

You could introduce a function to display marker icon per item (school rating) as demonstrated below.

Working example

var app = angular.module('appMaps', ['ngMap']);
app.controller('mapCtrl', function () {
    var vm = this;


    vm.schools = [
       { id: 1, name : "Brisbane", location: [-33.867396, 151.206854], overallRating: 3.2 },
        { id: 2, name: "Sydney", location: [-27.46758, 153.027892], overallRating: 4.6 },
        { id: 3, name: "Perth", location: [-31.953159, 115.849915], overallRating: 3.5 }
    ];


    vm.getIcon = function (school) {
        var iconsTable = {
            2: "http://google.com/mapfiles/ms/micons/green.png",
            3: "http://google.com/mapfiles/ms/micons/yellow.png",
            4: "http://google.com/mapfiles/ms/micons/orange.png",
            5: "http://google.com/mapfiles/ms/micons/red.png",
        }

        var iconUrl = iconsTable[Math.round(school.overallRating)]
        if (iconUrl)
            return iconUrl;
        return "http://google.com/mapfiles/ms/micons/blue.png";
    };

});
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<div ng-app="appMaps" ng-controller="mapCtrl as vm">
        <map center="[-24.667856, 133.630694]" zoom="4">
            <marker id='ID{{school.id}}' ng-repeat="school in vm.schools" position="{{school.location}}" icon="{{vm.getIcon(school)}}"  >
            </marker>
            
        </map>
</div>

JSFiddle

Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193