How to add a custom geolocate me button in Mapbox GL JS? - javascript

I am trying to add a custom Geolocate me button to my map and it kind of works, however only if I also add the standard icon from Mapbox. The code below works, but if I remove the line map.addControl(geolocate, 'top-right');, my left button stops working.
// Initialize the geolocate control.
var geolocate = new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
});
// Add the control to the map.
map.addControl(geolocate, 'top-right');
class ToggleControl {
constructor(options) {
this._options = Object.assign({}, this._options, options)
}
onAdd(map, cs) {
this.map = map;
this.container = document.createElement('div');
this.container.className = `${this._options.className}`;
const button = this._createButton('monitor_button')
this.container.appendChild(button);
return this.container;
}
onRemove() {
this.container.parentNode.removeChild(this.container);
this.map = undefined;
}
_createButton(className) {
const el = window.document.createElement('button')
el.className = className;
el.textContent = 'Use my location';
el.addEventListener('click', (e) => {
geolocate.trigger();
}, false)
return el;
}
}
const toggleControl = new ToggleControl({
className: 'mapboxgl-ctrl'
})
map.addControl(toggleControl, 'top-left')
screenshot - in blue is what I want to keep, in Red to remove

Instead of creating new mapboxgl.GeolocateControl Instance, you can extend mapboxgl.GeolocateControl Class like below:
class ToggleControl extends mapboxgl.GeolocateControl {
_onSuccess(position) {
this.map.flyTo({
center: [position.coords.longitude, position.coords.latitude],
zoom: 17,
bearing: 0,
pitch: 0
});
}
onAdd(map, cs) {
this.map = map;
this.container = document.createElement('div');
this.container.className = `mapboxgl-ctrl`;
const button = this._createButton('monitor_button')
this.container.appendChild(button);
return this.container;
}
_createButton(className) {
const el = window.document.createElement('button')
el.className = className;
el.textContent = 'Use my location';
el.addEventListener('click', () => {
this.trigger();
});
this._setup = true;
return el;
}
}
const toggleControl = new ToggleControl({})
map.addControl(toggleControl, 'top-left')
Other Helpful links:
Mapbox gl Class URL: Have a look https://github.com/mapbox/mapbox-gl-js/blob/520a4ca3b9d260693f1e7f4af30d8b91c8f8bb08/src/ui/control/geolocate_control.js#L97-L565
How to wrap a ui control (mapbox geolocation control)

You can easily add custom button in mapBox .
add some css:
.map_btn{position: absolute; top: 25; width: 36px;height:36px;border-radius:50%;border:none;float:right;margin-right:5px;zindex:111;left:85%;background:#e8faa7;}
add the button
<button class="map_btn"><img src="loc1.png" width=30/>
</button>
<div id="map"></div>
Add your code to your button
$('.map_btn').click(function(e)
{
app.preloader.show();
getLocation() ;
});

Related

Unable to drag and drop marker on map using PIXI JS and Leaflet Mapping API

I have loaded Markers Or Lat/Long Points on Map using Leaflet.PixiOverlay
Now I have two requirements
Drag and Drop an existing marker/point (PIXI.Sprite) on to the other marker/point
Drag and Drop an existing marker/point (PIXI.Sprite) to another location on map.
I have tried following approach but it is not working
/**
* In the below for loop identify the marker on which mouse down event has occurred.
* In the 'mouseup' event on map, change the position of the selected marker
*
* **Marker here is PIXI.Sprite**
*/
for (var i = 0; i < markersLength; i++) {
var marker = new PIXI.Sprite(texture);
marker.interactive = true;
marker.buttonMode = true;
marker.on('mousedown', (event) => {
self.map.dragging.disable();
marker['dragging'] = true;
self.selectedMarker = marker;
console.log('event mousedown on marker ', event);
});
marker.on('mouseup', (event) => {
marker['dragging'] = false;
console.log('event mouseup on marker ', event);
});
marker.on('mouseupoutside', (event) => {
//marker['dragging'] = false;
console.log('event mouseupoutside on marker ', event);
self.map.dragging.enable();
})
markerArr.push(marker);
childContainer.addChild(marker);
}
/**
* mouseup event on map should move selected marker but it doesnot
*
*/
this.map.on('mouseup', (event) => {
if (this.selectedMarker) {
let markerCoords = this.latLngToLayerPoint(event.latlng, this.map.getZoom());
this.selectedMarker.position.x = markerCoords.x;
this.selectedMarker.position.y = markerCoords.y;
this.selectedMarker = null;
}
})
In order to drag or move the marker with mouse move I did following.
First created PIXI Overlay Layer
var pixiOverlayOptions = {
doubleBuffering: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window['MSStream'],
autoPreventDefault: false,
}
var pixiContainer = new PIXI.Container();
pixiContainer.interactive = true;
pixiContainer.buttonMode = true;
var pixiOverlay = L.pixiOverlay(function (utils, event) {
var zoom = utils.getMap().getZoom();
var container = utils.getContainer();
var renderer = utils.getRenderer();
var project = utils.latLngToLayerPoint;
var layerPointToLatLng = utils.layerPointToLatLng;
var getScale = utils.getScale;
var invScale = 1 / getScale();
var interaction = renderer.plugins.interaction;
switch (event.type) {
// all other events
...
case 'add':{
var texture = resources['markerImage']
var markerSprite = new PIXI.Sprite(texture);
invScale = 1 / getScale(utils.getMap().getZoom());
markerSprite.scale.set(invScale);
markerSprite.on('mousedown', (event) => {
this.mouseDownOnPoint(event, this);
});
container.addChild(markerSprite);
renderer.render(container);
}
break;
case 'pointDrag': {
let latlng = event.latlng;
let newCoords = project([latlng.lat, latlng.lng]);
let marker = container.children[0];
marker.x = newCoords.x;
marker.y = newCoords.y;
invScale = 1 / getScale(utils.getMap().getZoom());
marker.scale.set(invScale);
renderer.render(container);
}
break;
}
},pixiContainer, pixiOverlayOptions);
pixiOverlay.addTo(map);
Here few things are important
Marking Pixi Container with interactive as true and buttonMode as true
Adding autoPreventDefault as false in layer option object, which is passed to layer
Adding a 'mousedown' event handler, which actually marks the marker which is clicked.
Define function for handling 'mousedown' event on marker, see map dragging is disabled here
function mouseDownOnPoint(event, self) {
self.map.dragging.disable();
self.mouseDownOnSelectedMarker = event.currentTarget;
}
Define function for redrawing layer
function redraw(data: { type: PixiLayerEvents, [key: string]: any }) {
pixiOverlay.redraw(data);
}
Add 'mousemove' handler on map, which actually calls redraw function with 'pointDrag' event
map.on('mousemove', (event: L.LeafletMouseEvent) => {
if (this.mouseDownOnSelectedMarker) {
this.redraw({ type: 'pointDrag', latlng: event.latlng });
}
});
Inside 'pointDrag' event, marker position is continuously changed along with mouse move on map.
Once the 'mouseup' event occurs, just mark the 'mouseDownOnSelectedMarker' as null and enable map dragging
map.on('mouseup', (event: L.LeafletMouseEvent) => {
if (this.mouseDownOnSelectedMarker) {
this.mouseDownOnSelectedMarker = null;
}
map.dragging.enable();
})

How to use leaflet-indoor plugin and draggable object in leaflet.1.0.3

When using leaflet v0.7.7 then leaflet-indoor works perfectly.
After updating to leaflet v1.0.3 markers become draggable, but now leaflet-indoor is not working.
Moreover, leaflet itself is throwing an error:
TypeError: Cannot read property 'call' of undefined
const MapController = function() {
// Containers
var $window = $(window),
mapEl = document.getElementById('map-base'),
mapFileName = window.mapFile,
resourceSidebar = document.getElementById('resourceSidebar'),
detailSidebar = document.getElementById('detailSidebar');
// Links
var addResource = document.querySelectorAll('[data-add-resource]');
setHeight();
// Create map perimeter
// console.log(window);
var view = window.mapDefaultView.split(',');
var map = new L.Map(mapEl, {
center: new L.LatLng(parseFloat(view[0]),parseFloat(view[1])),
zoom: parseFloat(window.mapDefaultZoom),
zoomControl: true
});
makePerimeter()
L.marker([parseFloat(view[0]),parseFloat(view[1])], {
draggable: true,
icon: L.divIcon({
iconSize: null,
html: "<div style='padding:1rem'>Hi</div>"
})
}).addTo(map);
// Not draggable
// Just here for visual reference
// when dragging marker
var circle = L.circle([parseFloat(view[0]),parseFloat(view[1])],100000).addTo(map);
L.control.mousePosition().addTo(map);
// Set heights on the main containers
function setHeight() {
var winHeight = $window.height()+'px';
mapEl.style.height = winHeight;
resourceSidebar.style.height = winHeight;
detailSidebar.style.height = winHeight;
}
// Open the detail sidebar
function toggleDetailSidebar() {
var el = detailSidebar;
if (el.classList.contains('active')) {
el.classList.remove('active');
} else {
el.classList.add('active');
}
}
// Create Perimeter, Guides, and Sections
function makePerimeter() {
$.get(window.mapDataFilePath, function(data) {
var baseLayer = new L.Indoor(data, {
getLevel: function(feature) {
if (feature.properties.relations.length === 0)
return null;
return feature.properties.relations[0].reltags.level;
},
onEachFeature: function(feature, layer) {
layer.bindPopup(JSON.stringify(feature.properties, null, 4));
},
style: function(feature) {
var fill = '#fafafa',
stroke = '#4d4d4d',
part = feature.properties.tags.buildingpart;
switch (part) {
case 'guide':
fill = '#eee';
stroke = '#eee';
break;
case 'section':
fill = 'transparent';
stroke = 'transparent';
break;
}
return {
fillColor: fill,
weight: 1,
color: stroke,
fillOpacity: 1
};
}
});
baseLayer.setLevel("0");
baseLayer.addTo(map);
var levelControl = new L.Control.Level({
level: "0",
levels: baseLayer.getLevels()
});
// Connect the level control to the indoor layer
levelControl.addEventListener("levelchange", baseLayer.setLevel, baseLayer);
levelControl.addTo(map);
perimeterWasMade()
});
}
function perimeterWasMade() {
// Save map view/zoom in hash, so it presists on refresh
var saveView = new L.Hash(map);
// Some other plugins I was messing around with
// Leave commented for now
//L.control.polylineMeasure({imperial: true}).addTo(map);
//L.control.mousePosition().addTo(map);
// 6' booth example
// This is the correct w/h of a 6'w booth that is 4'h
// except it is rotated incorrectly.
// It should be wider than it is tall.
var bounds = [
[ -0.0807 , 12.8787 ],
[ -0.0807 , 13.2845 ],
[ 0.5284 , 13.2845 ],
[ 0.5284 , 12.8787 ]
];
var booth = L.polygon(bounds, {color: 'red', weight: 1})
booth.addTo(map);
// Load booths
loadObjects()
}
function loadObjects() {
// load booths and prizes onto the map
loadJSON("booths.json", function(response) {
var actual_JSON = JSON.parse(response);
$.each(actual_JSON,function(i,val){
if (val.coordinate != undefined && val.size != null)
{
var size = val.size.split('x');
var marker = L.marker([val.coordinate.x,val.coordinate.y], {
id: val.id,
draggable: true,
icon: L.divIcon({
iconSize: null,
html: "<div style='height:"+size[0]+"; width="+size[1]+";'><div style=' padding:5px 10px;'>"+val.vendor.industry +" </div><span style='text-align:center;display:block;border-top:4px solid #888;'>"+val.vendor.name+"</span></div>"
})
}).addTo(map);
// label.dragging.enable();
marker.on('drag', function(event){
console.log("position");
});
//also display booths using leaflet.label
// var label = new L.Label();
// label.setContent("<div style='height:"+size[0]+"; width="+size[1]+";'><div style=' padding:5px 10px;'>"+val.vendor.industry +" </div><span style='text-align:center;display:block;border-top:4px solid #888;'>"+val.vendor.name+"</span></div>");
// label.setLatLng([val.coordinate.x,val.coordinate.y]);
// map.showLabel(label);
}
})
});
}
map.on('click', function(e) {
//alert(e.latlng);
});
// Catch click on resource in sidebar
if (addResource.length > 0) {
addResource.each(function() {
this.addEventListener('click', function(e) {
e.preventDefault();
mapEl.classList.add('adding-booth');
});
});
}
}

trying to show chessboard js in odoo form widget, no error no pieces

Hi i´m trying to show chessboardjs on a form view in odoo backend, I finally make the widget to show the board, but the pieces are hidden, I don´t know why because seems to work fine, except for the pieces. If I use dragable : true in the options and move a hidden piece then the board is rendered with all the pieces. do I´m missing something, on my code that the chessboard its not rendered well??
here is mi widget code:
(function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
openerp.chess_base = function (instance, local) {
local.YourWidgetClassName = instance.web.form.FormWidget.extend({
start: function () {
this.$el.append('<div id="board" style="width: 300px">BOARD GOES HERE</div>'); // creating the board in the DOM
this.onBoard();
},
onBoard: function (position, orientation) {
if (!position) {
this.position = 'start'
} else {
this.position = position
}
if (!orientation) {
this.orientation = 'white'
} else {
this.orientation = orientation
}
this.el_board = this.$('#board');
this.cfg = {
position: this.position,
orientation: this.orientation,
draggable: false,
pieceTheme: '/chess_base/static/img/chesspieces/wikipedia/{piece}.png'
};
this.board = ChessBoard(this.el_board, this.cfg);
}
});
instance.web.form.custom_widgets.add('widget_tag_name', 'instance.chess_base.YourWidgetClassName');
}
})(openerp);
I don't know why but this solve the issue, if someone have an explanation to me please ...
(function (instance) {
var _t = instance.web._t,
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
openerp.chess_base = function (instance, local) {
local.ShowBoard = instance.web.form.FormWidget.extend({
start: function () {
this.$el.append('<div id="board" style="width: 300px">BOARD GOES HERE</div>');
this.show_board();
},
show_board: function () {
var Game = new instance.web.Model("chess.game"),
record_id = this.field_manager.datarecord.id,
record_name = this.field_manager.datarecord.name,
self = this;
self.el_board = self.$('#board');
Game.query(['pgn']).filter([['id', '=', record_id], ['name', '=', record_name]]).all().then(function (data) {
console.log(data);
self.cfg = {
position: data[0].pgn,
orientation: 'white',
pieceTheme: '/chess_base/static/img/chesspieces/wikipedia/{piece}.png'
};
ChessBoard(self.el_board, self.cfg);
});
}
});
instance.web.form.custom_widgets.add('board', 'instance.chess_base.ShowBoard');
}
})(openerp);

openlayers 3 custom controls in typescript

The js code below adds custom controls to openlayers map
/**
* Define a namespace for the application.
*/
window.app = {};
var app = window.app;
//
// Define rotate to north control.
//
/**
* #constructor
* #extends {ol.control.Control}
* #param {Object=} opt_options Control options.
*/
app.RotateNorthControl = function(opt_options) {
var options = opt_options || {};
var anchor = document.createElement('a');
anchor.href = '#rotate-north';
anchor.innerHTML = 'N';
var this_ = this;
var handleRotateNorth = function(e) {
// prevent #rotate-north anchor from getting appended to the url
e.preventDefault();
this_.getMap().getView().setRotation(0);
};
anchor.addEventListener('click', handleRotateNorth, false);
anchor.addEventListener('touchstart', handleRotateNorth, false);
var element = document.createElement('div');
element.className = 'rotate-north ol-unselectable';
element.appendChild(anchor);
ol.control.Control.call(this, {
element: element,
target: options.target
});
};
ol.inherits(app.RotateNorthControl, ol.control.Control);
//
// Create map, giving it a rotate to north control.
//
var map = new ol.Map({
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}).extend([
new app.RotateNorthControl()
]),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
renderer: exampleNS.getRendererFromQueryString(),
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2,
rotation: 1
})
});
But I'm working on project using TypeScript instead javascript, and don't know how to make that work in typescript code.
Here's some part of code for openlayers map in typescript:
import openLayers = require('openLayers');
class OpenLayersMapProvider implements MapProvider {
map: openLayers.Map;
constructor(elementid: string, zoom: number = 8, tilesUrl?: string) {
var RotateNorthControl = function (opt_options) {
var options = opt_options || {};
var anchor = document.createElement('a');
anchor.href = '#rotate-north';
anchor.innerHTML = 'BUTTON';
var handleRotateNorth = function (e) {
prevent #rotate-north anchor from getting appended to the url
e.preventDefault();
this_.getMap().getView().setRotation(0);
};
anchor.addEventListener('click', null, false);
anchor.addEventListener('touchstart', null, false);
var element = document.createElement('div');
element.className = 'rotate-north ol-unselectable';
element.appendChild(anchor);
openLayers.control.Control.call(this, {
element: element,
target: this
});
//openLayers.inherits(RotateNorthControl(), openLayers.control.Control);
layers = [new openLayers.layer.Tile({
source: new openLayers.source.XYZ({
url: tilesUrl + '/{z}/{y}/{x}'
})
}),
this.vector, this.features]
this.map = new openLayers.Map({
target: elementid,
controls: openLayers.control.defaults().extend([
new openLayers.control.FullScreen(),
, new RotateNorthControl(???)
]),
interactions: openLayers.interaction.defaults().extend([this.select, this.modify]),
layers: layers,
view: new openLayers.View({
center: openLayers.proj.transform([9.66495667, 55.18794717], 'EPSG:4326', 'EPSG:3857'),
zoom: zoom
})
});
source: openLayers.source.Vector;
vector: openLayers.layer.Vector;
features: openLayers.layer.Vector;
}
export = OpenLayersMapProvider;
Does anyone know what is equivalent of window.app in typescript?
And how to do openLayers.inherits(RotateNorthControl(), openLayers.control.Control);? I only know that I need add something to the openlayers.d.ts file.
Thanx very much in advance for any help
A sample of custom control with typescript and ol3
export class MyControl extends ol.control.Control {
constructor() {
super({});
let button = document.createElement('button');
button.type = 'button';
button.className = 'ol-control';
button.innerHTML = 'N';
let element = document.createElement('div');
element.className = 'ol-feature ol-control';
element.appendChild(button);
ol.control.Control.call(this, {
element: element
});
button.addEventListener('click', () => this.click());
}
click() {
console.log('click');
console.log(this.getMap());
}
}
Does anyone know what is equivalent if window.app in typescript?
Hint : Define a namespace for the application.
Typescript supports this with the concept of module. So
JavaScript:
window.app = {};
var app = window.app;
app.RotateNorthControl = function(opt_options) {
would be TypeScript:
module app{
export var RotateNorthControl = function(opt_options) {
/// so on and so forth
}
how to do openLayers.inherits(RotateNorthControl(), openLayers.control.Control);
Use extends in TypeScript classes:
class RotateNorthControl extends openLayers.control.Control
You will need to rethink the purpose of RotateNorthControl from being a function to being a class.
Create a new class (as a separate TS-file) like so:
import { Control, defaults as defaultControls } from 'ol/control';
export class RotatControl extends Control {
constructor() {
super({});
var button = document.createElement('button');
button.innerHTML = 'N';
var element = document.createElement('div');
element.className = 'blahclass';
element.appendChild(button);
Control.call(this, {
element: element
});
button.addEventListener('click', this.rotate.bind(this), false);
}
rotate() {
super.getMap().getView().setRotation(0);
};
}
Then import this control in your component - you dont't need t feed the constructor any arguments at all.

Google maps v3: clustering with custom markers

I'm trying to use MarkerClusterer to clusterize the markers on my map.
The problem is that I'm not using default markers (google.maps.Marker), but instead a custom class which hinerits from google.maps.OverlayView.
Unfortunately it seems that the library has been developed assuming the use of basic markers, in fact I get errors because my class does not implement methods defined in google.maps.Marker.
Is it possible to use the MarkerClusterer by keeping my custom markers?
EDIT: it was a lot easier than I expected, I solved by implementing 2 methods in my custom class:
setVisible() and getPosition()
in order to help others the following is my complete interface (without full implementation):
BFPushpin = function(config)
{
this.setMap(config.map);
this.set("position", config.position);
// other settings...
};
// my class extends google.maps.OverlayView
BFPushpin.prototype = new google.maps.OverlayView();
BFPushpin.prototype.getBounds = function()
{
return new google.maps.LatLngBounds(this.position, this.position);
};
BFPushpin.prototype.getPoint = function()
{
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
BFPushpin.prototype.getSuperContainer = function()
{
var panes = this.getPanes();
return jQuery(panes ? panes.overlayImage : "");
};
BFPushpin.prototype.getContainer = function()
{
// return inner container
};
BFPushpin.prototype._generatePopupContent = function()
{
// return markup for the popupwindow
};
BFPushpin.prototype._addListeners = function()
{
// add handlers for the pushpin
};
BFPushpin.prototype.onAdd = function()
{
// customize content here
};
BFPushpin.prototype.onRemove = function()
{
// remove pin container here
};
BFPushpin.prototype.draw = function()
{
// set display style here
};
BFPushpin.prototype.setVisible = function(visible)
{
// set display block or hidden
};
BFPushpin.prototype.getPosition = function()
{
return this.position;
};
Or just define the functions that the MarkerClusterer expects on the marker. setMap and getPosition() and some other ones.
You should probably define your new marker class in such a way that it also inherits from google.maps.Marker (i.e. that it implements its interface). It is logical that MarkerClusterer uses this interface - it has to suppose the markers are markers in order to work with them :-)
Hopefully this will also help people trying to get this solution to work. Thanks #daveoncode for the example. I was able to modify it to get it working for me:
renderMap() {
const mapProperties = {
center: new google.maps.LatLng(34.0234, -84.6155),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.mapElement.nativeElement, mapProperties);
let markers = [];
for (let i=0; i<this._sitesList.length; i++) {
let bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon)
);
let position = new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon);
let html = this.makeHtmlForSitePanel(i, this._sitesList[i]); // I have a function to return html for my OverlayView panels here.
markers.push( this.generateSitePanel(bounds, html, this.map, position) );
}
var markerCluster = new MarkerClusterer(this.map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
generateSitePanel(bounds, html, map, position) {
SitePanel.prototype = new google.maps.OverlayView();
function SitePanel (bounds, html, map, position) {
this.bounds_ = bounds;
this.set('position', position);
this.html_ = html;
this.map_ = map;
this.div_ = null;
this.setMap(map);
}
SitePanel.prototype.getBounds = function() {
return new google.maps.LatLngBounds(this.position, this.position);
};
SitePanel.prototype.getPoint = function() {
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
SitePanel.prototype.getSuperContainer = function(){
var panes = this.getPanes();
return $(panes ? panes.overlayImage : '');
};
SitePanel.prototype.getContainer = function()
{
// return inner container
// I don't have anything for this one
};
SitePanel.prototype.getPosition = function() {
return this.position;
};
SitePanel.prototype.onAdd = function() {
var div = document.createElement('div');
div.className = 'tooltip-container-';
div.innerHTML = this.html_;
div.style.position = 'absolute';
this.div_ = div;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
};
SitePanel.prototype.draw = function() {
var overlayProjection = this.getProjection();
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 20 + 'px';
};
SitePanel.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
return new SitePanel(bounds, html, map, position);
}

Categories

Resources