GithubHelp home page GithubHelp logo

iniamudhan / react-bingmaps Goto Github PK

View Code? Open in Web Editor NEW
26.0 2.0 43.0 737 KB

Bingmaps in React.js

License: MIT License

JavaScript 97.70% CSS 0.65% HTML 1.66%
react-bingmaps bingmaps-api reactjs maps pushpin infobox-information

react-bingmaps's People

Contributors

eyu-dev avatar iniamudhan avatar united-site-services-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

react-bingmaps's Issues

Getting bounds of map

TY. I was wondering if you have any ideas how to get viewable bounds of map I was able to dynamically add info boxes but I can’t find any way to grab ref to component to getBounds. I need to use this information to search for other locations. TY

Support for localization?

Hi ,

I was wondering if there is support for localization.

https://bingmapsv8samples.azurewebsites.net/#Localize%20the%20Map%20(en-GB)

<script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap&setLang=en&setMkt=en-GB&key=[YOUR_BING_MAPS_KEY]' async defer></script>

Supporting the setLang and setMkt attributes

From looking at the code, it looks like you are attaching a script tag to the page if it doesn't exist, and then attaching a method to the global scope to handle the callback. Out of curiosity is there a way to avoid attaching it to the global scope? What happens if you want to load two of these maps on the same page but two different react components. What happens then..since now there will be two callbacks....won't there be issues?

I'm guessing for to include being able to set the lang and Mkt, would update the props to include this and with these props append to the generated url.

Thanks,
Derek

Move webpack related packages to devDependencies

A minor issue is that I am not using webpack-dev-server but react-binmaps is pulling in that dependency in, which right now has some other dependencies that are not compatible with node 10. But more broadly, I would think that all weback related dependencies should be in devDependencies.

https://webpack.js.org/guides/installation/ also says to put it in dev.

Thanks for maintaining this - it is really useful!

Pins don't always display on initial load.

Not sure why that is.

I have a list of buildings and when it load the pin doesn't display. But if I click through the buildings with causes the center location to update it start displaying.

Add Irregular Polygons

I'm working on a project that needs irregular polygons, so I copied your code and made a new method, added in props etc. so that you can pass in irregularPolygons (array of coordinates). I think it would be good to add this to the module. Didn't touch any of the rest of the code, just added irregularPolygon prop and createIrregularPolygons method that's similar to createRegularPolygons.
irregularPolygon is very similar to regularPolygon, except instead of taking in
"center":[13.0827, 80.2707],
"width": 200,
"height": 5,
"radius":10,
"points":2

it takes in "points": [array of coordinates, strings/floats supported]
With no need for radius, or number of points (number of points = length of array)

Hope this is helpful to anyone!

NOTE: To create Polylines you can simply create irregularPolygons with 2 sides, one for starting coordinate and one for ending coordinate. I've been using this throughout my project to make Polylines without any problems.

import React, { Component } from 'react';
import classSet from 'classnames';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';

var map = {},
    Microsoft,
    infobox = {},
    scriptURL = "https://www.bing.com/api/maps/mapcontrol?callback=bingmapsCallback",
    pendingProps = [];

class ReactBingmaps extends Component {
    constructor(props) {
        super(props);
        if(document.querySelector('script[src="' +scriptURL+ '"]') === null){
            this.loadScript(scriptURL);
            window.bingmapsCallback = function(){
                Microsoft = window.Microsoft;
                this.afterDependencyLoad(pendingProps);
            }.bind(this);
        }
    }
    componentDidMount(){
        if(Microsoft === null || Microsoft === undefined){
            pendingProps.push(this.props);
        }
        else{
            this.reactBingmaps(this.props, Microsoft);
        }
    }
    afterDependencyLoad(pendingProps){
        try{
            pendingProps.map((props) => this.reactBingmaps(props, Microsoft));
        }
        catch(exception){
            console.log("Error loading Microsoft bingmaps");
        }
    }
    componentWillUnmount(){
        try{
            let mapReference = this.props.id ? ('#' + this.props.id) : '.react-bingmaps';
            if(map[mapReference])
            //map[mapReference].dispose();

                map[mapReference] = undefined;
            infobox = {};
            pendingProps = [];
        }
        catch(exception){
            console.log(exception);
        }
    }
    loadScript(url){
        var script = document.createElement("script")
        script.type = "text/javascript";
        script.async = true;
        script.defer = true;
        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }
    componentWillReceiveProps(nextProps){
        let mapReference = nextProps.id ? ('#' + nextProps.id) : '.react-bingmaps';
        if(this.props.center !== nextProps.center){
            this.setMapCenter(nextProps.center, mapReference);
        }
        if(this.props.zoom !== nextProps.zoom){
            this.setMapZoom(nextProps.zoom, mapReference);
        }
        if(this.props.mapTypeId !== nextProps.mapTypeId){
            this.setMapTypeId(nextProps.mapTypeId, nextProps.center, nextProps.heading, mapReference);
        }
        if(this.props.navigationBarMode !== nextProps.navigationBarMode){
            this.setMapNavigationBarMode(nextProps.navigationBarMode, mapReference);
        }
        if(this.props.supportedMapTypes !== nextProps.supportedMapTypes){
            this.setMapSupportedMapTypes(nextProps.supportedMapTypes, mapReference);
        }
        if(this.props.disableStreetside !== nextProps.disableStreetside){
            this.setDisableStreetside(nextProps.disableStreetside, mapReference);
        }
        if(this.props.pushPins !== nextProps.pushPins){
            this.setPushPins(nextProps.pushPins, mapReference);
        }
        if(this.props.infoboxes !== nextProps.infoboxes){
            this.setInfoboxes(nextProps.infoboxes, "infoboxes", mapReference);
        }
        if(this.props.infoboxesWithPushPins !== nextProps.infoboxesWithPushPins){
            this.setInfoboxesWithPushPins(nextProps.infoboxesWithPushPins, "infoboxesWithPushPins", mapReference);
        }
        if(this.props.regularPolygons !== nextProps.regularPolygons){
            this.createRegularPolygons(nextProps.regularPolygons, mapReference);
        }
        if(this.props.irregularPolygons !== nextProps.irregularPolygons){
            this.setBoundary(nextProps.irregularPolygons, mapReference);
        }
        if(this.props.boundary !== nextProps.boundary){
            this.setBoundary(nextProps.boundary, mapReference);
        }

    }
    reactBingmaps(props,  Microsoft){
        const {
            bingmapKey,
            center,
            mapTypeId,
            zoom,
            navigationBarMode,
            supportedMapTypes,
            heading,
            pushPins,
            disableStreetside,
            infoboxes,
            infoboxesWithPushPins,
            getLocation,
            regularPolygons,
            irregularPolygons,
            boundary
        } = props;
        if(bingmapKey && Microsoft){
            let mapReference = props.id ? ('#' + props.id) : '.react-bingmaps';
            if(!map[mapReference]){
                map[mapReference] = new Microsoft.Maps.Map(mapReference, {
                    credentials: bingmapKey
                });
            }
            this.setMapCenter(center, mapReference);
            this.setMapTypeId(mapTypeId, center, heading, mapReference);
            this.setMapZoom(zoom, mapReference);
            this.setMapNavigationBarMode(navigationBarMode, mapReference);
            this.setMapSupportedMapTypes(supportedMapTypes, mapReference);
            this.setDisableStreetside(disableStreetside, mapReference);
            this.setPushPins(pushPins, mapReference);
            this.setInfoboxes(infoboxes, "infoboxes", mapReference);
            this.setInfoboxesWithPushPins(infoboxesWithPushPins, "infoboxesWithPushPins", mapReference);
            this.setGetLocation(getLocation, mapReference);
            this.createRegularPolygons(regularPolygons, mapReference);
            this.createIrregularPolygons(irregularPolygons, mapReference);
            this.setBoundary(boundary, mapReference);
        }
    }
    setMapCenter(center, mapReference){
        if(map[mapReference] && center && center[0] && center[1]){
            map[mapReference].setView({
                center: new Microsoft.Maps.Location(center[0], center[1])
            });
        }
    }
    setMapTypeId(mapTypeId, center, heading, mapReference){
        if(map[mapReference] && mapTypeId){
            let isBirdEyeAvailable = false;
            if(mapTypeId === "birdseye" && center && center[0] && center[1]){
                let location = new Microsoft.Maps.Location(center[0], center[1]);
                Microsoft.Maps.getIsBirdseyeAvailable(location, Microsoft.Maps.Heading[heading], (onResponse => { isBirdEyeAvailable = onResponse; }));
            }
            if(mapTypeId){
                map[mapReference].setView({
                    mapTypeId: isBirdEyeAvailable ? Microsoft.Maps.MapTypeId.birdseye : Microsoft.Maps.MapTypeId[mapTypeId]
                });
            }
        }
    }
    setMapZoom(zoom, mapReference){
        if(map[mapReference] && zoom){
            map[mapReference].setView({
                zoom: zoom
            });
        }
    }
    setMapNavigationBarMode(navigationBarMode, mapReference){
        if(map[mapReference] && navigationBarMode){
            map[mapReference].setView({
                navigationBarMode: navigationBarMode
            });
        }
    }
    setMapSupportedMapTypes(supportedMapTypes, mapReference){
        if(map[mapReference] && supportedMapTypes){
            map[mapReference].setView({
                supportedMapTypes: supportedMapTypes.map((id) => Microsoft.Maps.MapTypeId[id])
            });
        }
    }
    setDisableStreetside(disableStreetside, mapReference){
        if(map[mapReference] && disableStreetside){
            map[mapReference].setView({
                disableStreetside: disableStreetside
            });
        }
    }
    setPushPins(pushPins, mapReference){
        if(map[mapReference] && pushPins){
            for (var i = map[mapReference].entities.getLength() - 1; i >= 0; i--) {
                var pushpin = map[mapReference].entities.get(i);
                if (pushpin instanceof Microsoft.Maps.Pushpin) {
                    map[mapReference].entities.removeAt(i);
                }
            }
            for(var pushPinIndex = 0; pushPinIndex < pushPins.length; pushPinIndex++){
                if(pushPins[pushPinIndex].location && pushPins[pushPinIndex].location[0] && pushPins[pushPinIndex].location[1]) {
                    let location =  new Microsoft.Maps.Location(pushPins[pushPinIndex].location[0], pushPins[pushPinIndex].location[1]);
                    let option = pushPins[pushPinIndex].option ? pushPins[pushPinIndex].option : null
                    if(option && option.anchor && option.anchor[0] && option.anchor[1]){
                        option.anchor = new Microsoft.Maps.Point(option.anchor[0], option.anchor[1])
                    }
                    let pushpin = new Microsoft.Maps.Pushpin(location, option);
                    map[mapReference].entities.push(pushpin);
                    if(pushPins[pushPinIndex].addHandler){
                        Microsoft.Maps.Events.addHandler(pushpin, pushPins[pushPinIndex].addHandler.type,
                            function (callback, data) { this.MakeCallback(callback, data) }.bind(this, pushPins[pushPinIndex].addHandler.callback, pushPins[pushPinIndex].addHandler.callbackData));
                    }
                }
            }
        }
    }
    setInfoboxes(infoboxes, infoboxCreateType, mapReference){
        if(map[mapReference] && infoboxes){
            for (var i = 0; infobox[infoboxCreateType] && i < infobox[infoboxCreateType].length ; i++) {
                infobox[infoboxCreateType][i].setMap(null);
            }
            infobox[infoboxCreateType] = [];
            if(infoboxes){
                for(var infoboxIndex = 0; infoboxIndex < infoboxes.length; infoboxIndex++){
                    if(infoboxes[infoboxIndex].location && infoboxes[infoboxIndex].location[0] && infoboxes[infoboxIndex].location[1]) {
                        let location =  new Microsoft.Maps.Location(infoboxes[infoboxIndex].location[0], infoboxes[infoboxIndex].location[1]);
                        let option = infoboxes[infoboxIndex] ? infoboxes[infoboxIndex].option : null;
                        if(option.htmlContent){
                            option.htmlContent = ReactDOMServer.renderToStaticMarkup(option.htmlContent);
                        }
                        infobox[infoboxCreateType].push(new Microsoft.Maps.Infobox(location, option));
                        infobox[infoboxCreateType][infoboxIndex].setMap(map[mapReference]);
                        if(infoboxes[infoboxIndex].addHandler){
                            Microsoft.Maps.Events.addHandler(infobox[infoboxCreateType][infoboxIndex], infoboxes[infoboxIndex].addHandler.type,
                                function (callback, data) { this.MakeCallback(callback, data) }.bind(this, infoboxes[infoboxIndex].addHandler.callback, infoboxes[infoboxIndex].addHandler.callbackData));
                        }
                    }
                }
            }
        }
    }
    setInfoboxesWithPushPins(infoboxesWithPushPins, infoboxCreateType, mapReference){
        if(map[mapReference] && infoboxesWithPushPins){
            //Remove existing Infoboxes
            var i;
            for (i = 0; infobox[infoboxCreateType] && i < infobox[infoboxCreateType].length ; i++) {
                infobox[infoboxCreateType][i].setMap(null);
            }

            //Remove existing Pushpins
            for (i = map[mapReference].entities.getLength() - 1; i >= 0; i--) {
                var pushpin = map[mapReference].entities.get(i);
                if (pushpin instanceof Microsoft.Maps.Pushpin) {
                    map[mapReference].entities.removeAt(i);
                }
            }

            infobox[infoboxCreateType] = [];

            //Add Infoboxes with Pushpins
            if(infoboxesWithPushPins){
                for(var infoboxWithPushPinIndex = 0; infoboxWithPushPinIndex < infoboxesWithPushPins.length; infoboxWithPushPinIndex++){
                    if(infoboxesWithPushPins[infoboxWithPushPinIndex].location){
                        //Set Location
                        let location =  new Microsoft.Maps.Location(infoboxesWithPushPins[infoboxWithPushPinIndex].location[0], infoboxesWithPushPins[infoboxWithPushPinIndex].location[1]);

                        //Set Infobox Option
                        let infoboxOption = infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxOption ? infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxOption : null

                        //ConvertToHtml if Obj
                        if(infoboxOption.htmlContent){
                            infoboxOption.htmlContent = ReactDOMServer.renderToStaticMarkup(infoboxOption.htmlContent);
                        }

                        //If Handler added, initially hide Infobox
                        if(infoboxesWithPushPins[infoboxWithPushPinIndex].addHandler){
                            infoboxOption["visible"] = false;
                        }

                        //Set Pushpin Option
                        let pushPinOption = infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinOption ? infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinOption : null

                        //Initilize if anchor for Pushpin
                        if(pushPinOption.anchor && pushPinOption.anchor[0] && pushPinOption.anchor[1]){
                            pushPinOption.anchor = new Microsoft.Maps.Point(pushPinOption.anchor[0], pushPinOption.anchor[1])
                        }

                        //Set Infobox
                        infobox[infoboxCreateType].push(new Microsoft.Maps.Infobox(location, infoboxOption));
                        infobox[infoboxCreateType][infoboxWithPushPinIndex].setMap(map[mapReference]);

                        //Set Infobox Callback if any
                        if(infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxAddHandler){
                            Microsoft.Maps.Events.addHandler(infobox[infoboxCreateType][infoboxWithPushPinIndex], infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxAddHandler.type,
                                function (callback, data) { this.MakeCallback(callback, data) }.bind(this, infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxAddHandler.callback, infoboxesWithPushPins[infoboxWithPushPinIndex].infoboxAddHandler.callbackData));
                        }

                        //Set Pushpin
                        let pushpin = new Microsoft.Maps.Pushpin(location, pushPinOption);
                        map[mapReference].entities.push(pushpin);

                        //Set Pushpin Callback if any
                        if(infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinAddHandler){
                            Microsoft.Maps.Events.addHandler(pushpin, infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinAddHandler.type,
                                function (callback, data) { this.MakeCallback(callback, data) }.bind(this, infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinAddHandler.callback, infoboxesWithPushPins[infoboxWithPushPinIndex].pushPinAddHandler.callbackData));
                        }

                        //Set InfoboxesWithPushPins handler if any
                        if(infoboxesWithPushPins[infoboxWithPushPinIndex].addHandler){
                            this.setInfoboxesWithPushPinsHandler(infobox[infoboxCreateType][infoboxWithPushPinIndex], pushpin, infoboxesWithPushPins[infoboxWithPushPinIndex].addHandler);
                        }
                    }
                }
            }
        }
    }
    setGetLocation(getLocation, mapReference){
        if(map[mapReference] && getLocation){
            if(getLocation.addHandler){
                Microsoft.Maps.Events.addHandler(map[mapReference], getLocation.addHandler,
                    function (callback, e) {
                        let point = new Microsoft.Maps.Point(e.getX(), e.getY());
                        let location = e.target.tryPixelToLocation(point);
                        this.MakeCallback(callback, location);
                    }.bind(this, getLocation.callback)
                );
            }
            else{
                Microsoft.Maps.Events.addHandler(map[mapReference], "click",
                    function (callback, e) {
                        let point = new Microsoft.Maps.Point(e.getX(), e.getY());
                        let location = e.target.tryPixelToLocation(point);
                        this.MakeCallback(callback, location);
                    }.bind(this, getLocation.callback)
                );
            }
        }
    }
    setInfoboxesWithPushPinsHandler(infobox, pushpin, addHandler, mapReference){
        if(addHandler === "mouseover"){
            Microsoft.Maps.Events.addHandler(pushpin, addHandler, function () {
                infobox.setOptions({ visible: true });
            });
            Microsoft.Maps.Events.addHandler(pushpin, "mouseout", function () {
                infobox.setOptions({ visible: false });
            });
        }
        else{
            Microsoft.Maps.Events.addHandler(pushpin, addHandler, function () {
                infobox.setOptions({ visible: true });
            });
        }
    }
    MakeCallback(callback, data, mapReference){
        data ? callback(data) : callback();
    }
    createRegularPolygons(regularPolygons, mapReference){
        if(map[mapReference] && regularPolygons){
            for (var i = map[mapReference].entities.getLength() - 1; i >= 0; i--) {
                var regularPolygon = map[mapReference].entities.get(i);
                if (regularPolygon instanceof Microsoft.Maps.Polygon) {
                    map[mapReference].entities.removeAt(i);
                }
            }
            for(let regularPolygonIndex = 0; regularPolygonIndex < regularPolygons.length; regularPolygonIndex++){
                if(regularPolygons[regularPolygonIndex].center &&
                    regularPolygons[regularPolygonIndex].center[0] &&
                    regularPolygons[regularPolygonIndex].center[1])
                {
                    let location =  new Microsoft.Maps.Location(regularPolygons[regularPolygonIndex].center[0], regularPolygons[regularPolygonIndex].center[1]);
                    let radius = regularPolygons[regularPolygonIndex].radius ? regularPolygons[regularPolygonIndex].radius : 0;
                    let points = regularPolygons[regularPolygonIndex].points ? regularPolygons[regularPolygonIndex].points : 0;
                    let option = regularPolygons[regularPolygonIndex].option ? regularPolygons[regularPolygonIndex].option : {};

                    Microsoft.Maps.loadModule('Microsoft.Maps.SpatialMath', function () {
                        var locations = Microsoft.Maps.SpatialMath.getRegularPolygon(location, radius, points, Microsoft.Maps.SpatialMath.DistanceUnits.Miles);
                        var polygon = new Microsoft.Maps.Polygon(locations, option);
                        map[mapReference].entities.push(polygon);
                    });
                }
            }
        }
    }
    createIrregularPolygons(irregularPolygons, mapReference){
        if(map[mapReference] && irregularPolygons){
            for (var i = map[mapReference].entities.getLength() - 1; i >= 0; i--) {
                var irregularPolygon = map[mapReference].entities.get(i);
                if (irregularPolygon instanceof Microsoft.Maps.Polygon) {
                    map[mapReference].entities.removeAt(i);
                }
            }
            for(let irregularPolygonIndex = 0; irregularPolygonIndex < irregularPolygons.length; irregularPolygonIndex++){
                let points = irregularPolygons[irregularPolygonIndex].points ? irregularPolygons[irregularPolygonIndex].points : 0;
                let option = irregularPolygons[irregularPolygonIndex].option ? irregularPolygons[irregularPolygonIndex].option : {};
                var locations = [];
                for(let pointIndex = 0; pointIndex < points.length; pointIndex++) {
                    let point = points[pointIndex].map(String);
                    let latLong = point.join(",");
                    var location = Microsoft.Maps.Location.parseLatLong(latLong);
                    locations.push(location);
                }
                var polygon = new Microsoft.Maps.Polygon(locations, option);
                map[mapReference].entities.push(polygon);
            }
        }
    }
    setBoundary(boundary, mapReference){
        if(map[mapReference] && boundary){

            for (var i = map[mapReference].entities.getLength() - 1; i >= 0; i--) {
                var regularPolygon = map[mapReference].entities.get(i);
                if (regularPolygon instanceof Microsoft.Maps.Polygon) {
                    map[mapReference].entities.removeAt(i);
                }
            }

            // var boundaryLocation;
            // if(boundary.option &&
            // 	boundary.option.entityType &&
            // 		!(boundary.option.entityType.includes("Postcode"))){
            // 	boundaryLocation = new Microsoft.Maps.Location(boundary.location[0], boundary.location[1]);
            // }
            // else{
            // 	boundaryLocation = boundary.location
            // }

            var boundaryLocation = boundary.location ? boundary.location : null;

            var geoDataRequestOptions = boundary.option ? boundary.option : {};
            var polygonStyle = boundary.polygonStyle ? boundary.polygonStyle : null;
            var search = boundary.search ? boundary.search : null;
            if(!search && boundaryLocation){
                Microsoft.Maps.loadModule('Microsoft.Maps.SpatialDataService', function () {
                    Microsoft.Maps.SpatialDataService.GeoDataAPIManager.getBoundary(boundaryLocation, geoDataRequestOptions, map[mapReference], function (data) {
                        if (data.results && data.results.length > 0) {
                            map[mapReference].entities.push(data.results[0].Polygons);
                        }
                    }, polygonStyle, function errCallback(networkStatus, statusMessage) {
                        console.log(networkStatus);
                        console.log(statusMessage);
                    });
                });
            }
            else{
                Microsoft.Maps.loadModule(['Microsoft.Maps.SpatialDataService', 'Microsoft.Maps.Search'], function () {
                    var searchManager = new Microsoft.Maps.Search.SearchManager(map[mapReference]);
                    var geocodeRequest = {
                        where: search,
                        callback: function (geocodeResult) {
                            if (geocodeResult && geocodeResult.results && geocodeResult.results.length > 0) {
                                map[mapReference].setView({ bounds: geocodeResult.results[0].bestView });
                                Microsoft.Maps.SpatialDataService.GeoDataAPIManager.getBoundary(geocodeResult.results[0].location, geoDataRequestOptions, map[mapReference], function (data) {
                                    if (data.results && data.results.length > 0) {
                                        map[mapReference].entities.push(data.results[0].Polygons);
                                    }
                                }, polygonStyle, function errCallback(networkStatus, statusMessage) {
                                    console.log(networkStatus);
                                    console.log(statusMessage);
                                });
                            }
                        },
                    };
                    searchManager.geocode(geocodeRequest);
                });
            }
        }
    }
    render() {
        return(
            <div id = {this.props.id} className = { classSet('react-bingmaps', this.props.className) }>
            </div>
        );
    }
}

export default ReactBingmaps;

ReactBingmaps.propTypes = {
    bingmapKey: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
    center: PropTypes.arrayOf(PropTypes.number),
    mapTypeId: PropTypes.string,
    navigationBarMode: PropTypes.string,
    supportedMapTypes: PropTypes.arrayOf(PropTypes.string),
    heading: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
    zoom: PropTypes.number,
    pushPins: PropTypes.arrayOf(
        PropTypes.shape({
            location: PropTypes.arrayOf(PropTypes.number),
            option: PropTypes.object,
            addHandler: PropTypes.shape({
                "type" : PropTypes.string,
                "callback" : PropTypes.func
            })
        })
    ),
    disableStreetside: PropTypes.bool,
    infoboxes: PropTypes.arrayOf(
        PropTypes.shape({
            location: PropTypes.arrayOf(PropTypes.number),
            option: PropTypes.object,
            addHandler: PropTypes.shape({
                "type" : PropTypes.string,
                "callback" : PropTypes.func
            })
        })
    ),
    infoboxesWithPushPins: PropTypes.arrayOf(
        PropTypes.shape({
            location: PropTypes.arrayOf(PropTypes.number),
            addHandler: PropTypes.string,
            infoboxOption: PropTypes.object,
            pushPinOption: PropTypes.object,
            infoboxAddHandler: PropTypes.shape({
                "type" : PropTypes.string,
                "callback" : PropTypes.func
            }),
            pushPinAddHandler: PropTypes.shape({
                "type" : PropTypes.string,
                "callback" : PropTypes.func
            })
        })
    ),
    getLocation: PropTypes.object,
    regularPolygons: PropTypes.arrayOf(
        PropTypes.shape({
            center: PropTypes.arrayOf(PropTypes.number),
            radius: PropTypes.number,
            points: PropTypes.number,
            option: PropTypes.object
        })
    ),
    boundary: PropTypes.shape({
        location: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.number), PropTypes.arrayOf(PropTypes.string) ]),
        option: PropTypes.object,
        polygonStyle: PropTypes.object,
        search: PropTypes.string,
    })

}
ReactBingmaps.defaultProps = {
    bingmapKey: undefined,
    center: undefined,
    mapTypeId: undefined,
    navigationBarMode: undefined,
    supportedMapTypes: undefined,
    heading: 0,
    pushPins: undefined,
    disableStreetside: true,
    infoboxes: undefined,
    infoboxesWithPushPins: undefined,
    zoom: undefined,
    getLocation: undefined,
    regularPolygons: undefined,
    boundary: undefined
}

Traffic Layer

Is it possible to add the traffic layer in the version that is currently available?

Multiple pushpin handlers

Could you add the ability to pass multiple handlers to a pushpin? I'd like to do a hover-type event but can't without both mouseover and mouseout.

The boundary prop type check seems wrong

The code is using:

location: _propTypes2.default.oneOfType([_propTypes2.default.arrayOf(_propTypes2.default.number), _propTypes2.default.arrayOf(_propTypes2.default.string)]),

However, the boundary can be an array of two item types - a string ('location name') or a Location.
see: Microsoft.Maps.SpatialDataService.GeoDataAPIManager.getBoundary

Location is simple class that has:
latitude | number | The latitude of the location.
longitude | number | The longitude of the location.

When passing in an array that contains a Location object, the propcheck fails.

How to get a reference to map instance?

I want to do this: map.setView({bounds: LocationRect, zoom: number }). Is there a way to do it declaratively, or could I get a ref to the underlying map instance so I can change it imperatively ?

Can't Display Truck Route Directions

I've been messing with the Bing Maps API with Postman and comparing what react-bingmaps is sending and it appears that for whatever reason, when routeMode is set to truck, Bing Maps will return an error if isViaPoint is set to null. I've tried to set it to true, 1, 0, "1", "0", "true", "false"`, but any falsy value is being automatically set to null in the code.

An easy fix would be to replace this:

var isViaPoint = wayPoints[wayPointsIndex].isViaPoint ? wayPoints[wayPointsIndex].isViaPoint : null;

with this:

var isViaPoint = wayPoints[wayPointsIndex].isViaPoint !== undefined ? wayPoints[wayPointsIndex].isViaPoint : null;

That way, users can pass falsy values and it will be passed on to the Bing Maps API as they intend.

Alternatively, if anyone knows how to get this to work without modifying the repo, I'm all ears.

componentWillReceiveProps need update

This is a message I get from my console :

Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

  • Move data fetching code or side effects to componentDidUpdate.
  • If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
  • Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run npx react-codemod rename-unsafe-lifecycles in your project source folder.

Please update the following components: ReactBingmaps

InfoBoxes with ReactRouter's Link do not get Router context

Meteor app with React:

<Router>
  <Switch>
    <Route exact path={"/"} render={() => <Home {...props} />} />
  </Switch>
</Router>

Home.js

const Marker = ({_id, name}) => (<Link to={`/city/${_id}`}>{name}</Link>);

const Home = ({cities}) => {
  const infoBoxes = cities.map(({_id, name}) => ({
    location: city.address.location,
    option: {
      htmlContent: <Marker key={_id} name={name} _id={_id} />,
    }
  }));
  return(<ReactBingmaps infoboxes={infoBoxes} />);
}

HomeContainer = withTracker(props => ({ cities: Cities.find().fetch() })(Home)

This code runs fine if you replace <Link /> with <a />, but I would like to use <Link /> to prevent reloading the page.

Problem

When I use inside an Infobox Marker, I get this error in the console:

Warning: Failed context type:
The context `router` is marked as required in `Component`,
but its value is `undefined`.
    in Link
    in Marker

and from the BingMaps component:

Error loading Microsoft bingmaps Error: You should not use <Link> outside a <Router>

Failed fixes

I tried to solve this by wrapping <Marker /> in react-router's withRouter, but it did not solve the problem, I obviously got this error:

Error loading Microsoft bingmaps Error:
You should not use <Route> or withRouter() outside a <Router>

Question

Is it possible to render the infoboxes differently?

Inspiration: I previously used the npm package google-map-react where it is possible to place React components as children inside the <Map /> component to render them as markers/infoboxes on the map. Maybe the Bing API limits your options?

Missing Event on pushpin click

No parameters appear to be getting passed to the callback handler for a pushpin clickeEvent

i.e.
addHandler: { type: 'click', callback: this.onMapPinClicked }

Since no event is being passed to the callback, can't identify which pin was clicked.

OnLoad callback

Would it be possible to add some OnLoad callback which would have Microsoft object from window and reference map object as the parameters ?

This would be very helpful, because any missing functionality could be added inside host react component.

What I mean is something like this:

		if(!map[mapReference]){
			map[mapReference] = new Microsoft.Maps.Map(mapReference, {
				credentials: bingmapKey
			});
			if(props.onLoad){
				props.onLoad(Microsoft, map[mapReference]);
			}
		}

Clear polylines

Is there any way to expose the clear layers method to enable users to clear the directions Polylines. Currently if I remove direction waypoints the polyLines do not get removed?

Cannot read property 'join' of undefined

Hi,

first of all, great work!

Im getting the error "Uncaught TypeError: Cannot read property 'join' of undefined" in file ReactBingmaps.js at line 110. Removing the "join()" from the center fixes the problem for me.

I am lacking deeper insights on what "center.join()" used to do or how bing maps handles it now, but on first sight it seemed to work just fine removing it.

Thanks

Using Custom Imagery

@iniamudhan Hi. In MapTypeId documentation there is a type Mercator which allows us to use custom imagery. I tried to understand how it works but no luck. Is it possible? Can you please shed light on how it can be used?

Map is not loading , No errors in console. Any help?

`import React, { Component } from 'react';
import { ReactBingmaps } from 'react-bingmaps';

class BingMaps extends Component {

render() {
    return (

        <div>
            sdfsdf

<ReactBingmaps

          bingmapKey = "KEY"
          center = {[13.0827, 80.2707]}
         
         
        > 
        </ReactBingmaps>
            </div>

    )
}

}

export default BingMaps;

`

Error when unmounting

Hi, I am getting an error again when unmounting and sometimes it starts an infinite loop. Like this:
screen shot 2018-05-02 at 1 42 44 pm

I tried to create a codepen here to repro it:
https://codesandbox.io/s/1oym36pxj3

If you go there and open a console and hide the map, you should see the error.

Thanks again for developing this!

Directions Text on Map

I'm using the new directions feature and I'm seeing the destination on the map twice. Screenshot below.
In addition, any way to remove the text from the map?

screen shot 2018-06-21 at 10 44 12 am

Error when calling `viewchangeend` handler

<ReactBingmaps
          bingmapKey={appConstants.bingMapsKey}
          getLocation={{addHandler: 'viewchangeend', callback: location => console.log(location)}} />

Whenever the user moves the map, this results in the following error:

ReactBingmaps.js:390 Uncaught TypeError: e.getX is not a function
    at ReactBingmaps.<anonymous> (ReactBingmaps.js:390)
    at Array.u.callback (79c5b4f3.js?bu=rms+answers+MapsSDK+AnonymousBegin*SDKPluginStart*SDKInfoboxOverlay*Infobox*SDKColor*TileSource*TileLayer*Module*Layer*EntityCollection*Events*SDKPrimitiveTemplateSelector*UserMouseEventArgs*PixelReference*Pushpin*SDKPolygon*SDKPolyline*TestDataGenerator*CustomOverlay*GroundOverlay*AnimatedTileLayer*MapsTilePrimer*SDKMap*PointCompression*DeprecatedClass*SDKPluginEnd*AnonymousEnd:1)
    at n.invoke (60f87994.js?bu=rms+answers+MapsSDK+AnonymousBegin*MapCore.en*MapCoreBegin*LabelOptions*LocalStorageCache*Gimme*GimmeWrapper*evPromise*ExternalPromise*StaticPromise*LruCache*Point*Rectangle*NAARectangle*ResourceManager*Anchor*Size*Binding*EventBinding*Observable*ObservableObject*ObservableObjectChangedArgs*ObservableCollection*Debug*DelayLoadedObject*JSEvent*Dispatcher*WorkDispatcher*Iterator*ElementSizeHelper*GimmeExt*GimmeTransition*Helper*PerfState*ClientPerf*LoggingWrapper*LoggerConstants*Network*ThrottledEventInvoker*ObjectPool*StaticObjectPool*FixedSizeObjectPool*OrderedDictionary*PooledImage*Url*MapCoreMiddle*NavigationBarMode*NavigationBarOrientation*TransformCurve*CurveKey*Curve*Color*CurveVector4*CurveColor*Vector4*DiscreteRange*DiscreteRangeCollectionSpline*MapLayer*CopyrightProvider*CopyrightProviderService*CustomMapStyleManager*MapFrameManager*LayerFrameManager*GoalCounter*FrameEventAggregator*DataMonitor*MapFrameData*LayerFrameData*Clipper*CompositePrimitiveSet*DataLoader*FixedPrimitiveSet*Overlay*ImageryMapLayer*SimpleSceneContributor*VectorMapLayer*BasicMapAnimation*MapViewAnimator*BoundsAccumulator*CombinedLayerCollection*ConstrainViewArgs*LatLonCrs*LocationRect*Matrix2D*MapInstrumentationManager*PerfV2Logger*Map*MapHelper*MapMath*MapLocation*WeightedMapLocation*MapType*MapTypeChangeArgs*MapTypeCollection*MapTypeId*MapView*MapQuadrant*PrimitiveOverlayHelper*OverlayBehavior*GeometryGeneralizer*SimplePointPrimitive*SimpleLinePrimitive*SimpleAreaPrimitive*MoveableSimplePointPrimitive*TargetViewChangeArgs*VectorMath*ViewChangeArgs*ZoomLevel*ZoomAroundLocationAnimator*ZoomEventArgs*OverviewMapMode*MapAuthentication*PublicApi*InternalApi*AnonymousEnd:1)
    at n._raiseViewChangeEndEvent (79c5b4f3.js?bu=rms+answers+MapsSDK+AnonymousBegin*SDKPluginStart*SDKInfoboxOverlay*Infobox*SDKColor*TileSource*TileLayer*Module*Layer*EntityCollection*Events*SDKPrimitiveTemplateSelector*UserMouseEventArgs*PixelReference*Pushpin*SDKPolygon*SDKPolyline*TestDataGenerator*CustomOverlay*GroundOverlay*AnimatedTileLayer*MapsTilePrimer*SDKMap*PointCompression*DeprecatedClass*SDKPluginEnd*AnonymousEnd:1)
    at Array.<anonymous> (79c5b4f3.js?bu=rms+answers+MapsSDK+AnonymousBegin*SDKPluginStart*SDKInfoboxOverlay*Infobox*SDKColor*TileSource*TileLayer*Module*Layer*EntityCollection*Events*SDKPrimitiveTemplateSelector*UserMouseEventArgs*PixelReference*Pushpin*SDKPolygon*SDKPolyline*TestDataGenerator*CustomOverlay*GroundOverlay*AnimatedTileLayer*MapsTilePrimer*SDKMap*PointCompression*DeprecatedClass*SDKPluginEnd*AnonymousEnd:1)
    at n.invoke (60f87994.js?bu=rms+answers+MapsSDK+AnonymousBegin*MapCore.en*MapCoreBegin*LabelOptions*LocalStorageCache*Gimme*GimmeWrapper*evPromise*ExternalPromise*StaticPromise*LruCache*Point*Rectangle*NAARectangle*ResourceManager*Anchor*Size*Binding*EventBinding*Observable*ObservableObject*ObservableObjectChangedArgs*ObservableCollection*Debug*DelayLoadedObject*JSEvent*Dispatcher*WorkDispatcher*Iterator*ElementSizeHelper*GimmeExt*GimmeTransition*Helper*PerfState*ClientPerf*LoggingWrapper*LoggerConstants*Network*ThrottledEventInvoker*ObjectPool*StaticObjectPool*FixedSizeObjectPool*OrderedDictionary*PooledImage*Url*MapCoreMiddle*NavigationBarMode*NavigationBarOrientation*TransformCurve*CurveKey*Curve*Color*CurveVector4*CurveColor*Vector4*DiscreteRange*DiscreteRangeCollectionSpline*MapLayer*CopyrightProvider*CopyrightProviderService*CustomMapStyleManager*MapFrameManager*LayerFrameManager*GoalCounter*FrameEventAggregator*DataMonitor*MapFrameData*LayerFrameData*Clipper*CompositePrimitiveSet*DataLoader*FixedPrimitiveSet*Overlay*ImageryMapLayer*SimpleSceneContributor*VectorMapLayer*BasicMapAnimation*MapViewAnimator*BoundsAccumulator*CombinedLayerCollection*ConstrainViewArgs*LatLonCrs*LocationRect*Matrix2D*MapInstrumentationManager*PerfV2Logger*Map*MapHelper*MapMath*MapLocation*WeightedMapLocation*MapType*MapTypeChangeArgs*MapTypeCollection*MapTypeId*MapView*MapQuadrant*PrimitiveOverlayHelper*OverlayBehavior*GeometryGeneralizer*SimplePointPrimitive*SimpleLinePrimitive*SimpleAreaPrimitive*MoveableSimplePointPrimitive*TargetViewChangeArgs*VectorMath*ViewChangeArgs*ZoomLevel*ZoomAroundLocationAnimator*ZoomEventArgs*OverviewMapMode*MapAuthentication*PublicApi*InternalApi*AnonymousEnd:1)
    at t._raisePanStoppedEvent (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at t._doPostLinearInertiaWork (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at t._inertiaCallback (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at n._callback (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at n.stop (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at n._onTimerTick (4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1)
    at 4f9ad353.js?bu=rms+answers+MapsSDK+AnonymousBegin*Navigation*MapDelay.en*MapDelayPluginStart*TransitLandmarkOverlay*SharingImage*Permalink*DefaultPrimitiveCriteria*IRoutePolylineOptions*IRoutePushpinOptions*ITransitPushpinOptions*RoutePolyline*RoutePushpin*ListDataSource*KeyProvider*BrowserKeyProvider*PointerProvider*BrowserPointerProvider*MapInteractionKeyboardState*MapInteraction*MapModeStateHistory*PrintContent*BrowserHistoryManager*HashBasedHistory*HistoryWrapper*NavigationControl*AerialBirdsEyeTransitionManager*NavigationBar*MePoi*NavigationButton*NavigationButtonTemplate*NavigationHelper*RotateControl*GeochainControl*GeochainOverlay*GeochainTemplate*GeochainSegment*GeochainManager*LocateMeControl*LocateMeErrorDialog*SelectorControl*MapInteractionBehavior*OverlayManager*NavigationBarOverlay*GlobalDataEventHandler*ImageFromCssHelper*DataHandlerKeys*IDirectionsTaskState*Waypoint*CollectionEnumerators*OverlayEntity*OverlayDataEntityAction*TaskTypes*TaskDataHandlerHelper*LocalSearchEntity*RecommendationEntity*Geocoder*ReverseGeocoder*GeolocationProvider*ManipulationDelta*Inertia*PointerTrail*ManipulationDeltaTrail*SSAutoEntryBehavior*SSAutoEntryBubblePickerOverlay*SSBootstrapper*SSModeBootstrapper*SSMiniOverlay*SSMiniBootstrapper*SSDirectionsOverlay*SSDirectionsBootstrapper*SSLocalDetailsBootstrapper*SSCoverageBehavior*SSBubblePickerOverlay*SSLoggerConstants*SSPerfConstants*ZoomInButton*ZoomOutButton*MapTypeSwitcherButton*TrafficToggleButton*RadialMenu*MapTypeButton*MapTypeButtonTemplate*GeneralMapTypeButton*RoadButton*AerialButton*BirdseyeButton*StreetsideButton*OrdnanceSurveyButton*SeasonalButton*GrayscaleButton*CanvasDarkButton*CanvasLightButton*SymbolicNightButton*WinterButton*LabelToggleButton*BirdseyeV2ExitButton*BirdseyeV2InfoExitControl*LandmarksManager*LandmarksOverlay*CityPolygonManager*TravelAttractionEntity*MapDelayPluginEnd*AnonymousEnd*ExternalPromise:1
    at mapcontrol?callback=bingmapsCallback:3
    at wrapped (raven.js:377)

Custom pushpins?

Do you support custom image pushpins? I had a look at the source code and I don't see anything related to the icon field and I tested it unsuccessfully but it's possible I did something wrong.

Unable to re-center the map

I am using this component to render 3 -4 maps on a page. Each get rendered properly but the push pin I added get rendered not in focus of map eventhough I kept same coordinates for center. How to refresh map so that map can render again with new center?

Add Pushpins after load

How can I add Pushpins (With infoboxes) after the map has loaded?

I bound the "infoboxesWithPushPins" to my state, but when my state changed, it did not add the pin.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.