Search code examples
angularjsgoogle-maps-api-3angular-google-mapsng-map

Setting different map marker icons based on value of ng-repeat variable


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


Solution

  • 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