arcgis-JS polyline path to follow a div on DRAG - javascript

I have this almost working; but instead of it following the kendo modal when dragged, it's following the mouse pointer at all times...
So, currently it's following the mouse pointer and so is the modal; but this is horrible for usability so would just like to stay with and follow the modal on the standard click and drag.
attempt A.) Below is the JavaScript, here is the live demo CodePen. The line should always be with the modal for point B, which it's doing; but the modal should only be movable on drag.
require([
"esri/Map",
"esri/views/MapView",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/geometry/support/webMercatorUtils",
"dojo/dom",
],
function init (Map, MapView, Graphic, GraphicsLayer, webMercatorUtils, dom) {
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-80.96135253906438, 35.9411934679851],
zoom: 3
});
var graphicsLayer = new GraphicsLayer();
map.add(graphicsLayer);
var simpleLineSymbol = {
type: "simple-line",
color: [13,121,190, .9],
style: "short-dash",
width: 3
};
var coordinatesAx;
var coordinatesAy;
var coordinatesBx ;
var coordinatesBy;
var moveAlong = false;
var windowElem;
view.when(function(){
view.on("pointer-move", showCoordinates);
});
// NEW: Stop/start moving the modal along with the pointer by map click
view.when(function(){
view.on("click", function () { moveAlong = !moveAlong;});
});
coordinatesAx = -80.96135253906438;
coordinatesAy = 35.9411934679851;
document.getElementById("modal").onclick = function fun() {
windowElem = document.querySelector('.k-window');
moveAlong = true;
// Bind Kendo dialog dragstart to movement
$("#dialog").data('kendoWindow').bind("dragstart", function (ev) {
//graphicsLayer.removeAll();
moveAlong = true;
showCoordinates(ev);
})
}
function showCoordinates(evt) {
var point = view.toMap({x: evt.x, y: evt.y});
var mp = webMercatorUtils.webMercatorToGeographic(point);
dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
coordinatesBx = mp.x.toFixed(3);
coordinatesBy = mp.y.toFixed(3);
var polyline = {
type: "polyline",
paths: [
[coordinatesAx, coordinatesAy],
[coordinatesBx, coordinatesBy]
]
};
var polylineGraphic = new Graphic({
geometry: polyline,
symbol: simpleLineSymbol
})
if (moveAlong) {
if (graphicsLayer.graphics.items.length < 0) {
graphicsLayer.add(polylineGraphic)
} else {
// Recreate the line and reposition the modal
graphicsLayer.removeAll();
graphicsLayer.add(polylineGraphic)
windowElem.style.top = evt.y + 0 + "px";
windowElem.style.left = evt.x + 0 + "px";
}
}
}
});
Attempt B.) Update: I have tried going with this logic I found; although I believe it's arcgis 3.3.. and still can't get it to integrate into my CodePen prototype. Anyways I think this is the logic; just can't seem to get it right.
$profileWindow = $("#" + elem).parents(".outter-div-wrapper");
profileWindowOffset = $profileWindow.offset();
profileWindowWidth = $profileWindow.outerWidth();
profileWindowHeight = $profileWindow.outerHeight();
screenPointTopLeft = new Point(profileWindowOffset.left, profileWindowOffset.top, app.ui.mapview.map.spatialReference);
screenPointTopRight = new Point(profileWindowOffset.left + profileWindowWidth, profileWindowOffset.top, app.ui.mapview.map.spatialReference);
screenPointBottomLeft = new Point(profileWindowOffset.left, profileWindowOffset.top + profileWindowHeight, app.ui.mapview.map.spatialReference);
screenPointBottomRight = new Point(profileWindowOffset.left + profileWindowWidth, profileWindowOffset.top + profileWindowHeight, app.ui.mapview.map.spatialReference);
arrayOfCorners.push(screenPointTopLeft);
arrayOfCorners.push(screenPointTopRight);
arrayOfCorners.push(screenPointBottomLeft);
arrayOfCorners.push(screenPointBottomRight);
//convert to screenpoint
graphicsScreenPoint = esri.geometry.toScreenPoint(app.ui.mapview.map.extent, app.ui.mapview.map.width, app.ui.mapview.map.height, self.mapPoint_);
//find closest Point
profileWindowScreenPoint = this.findClosest(arrayOfCorners, graphicsScreenPoint);
//convert from screen point to map point
profileWindowClosestMapPoint = app.ui.mapview.map.toMap(profileWindowScreenPoint);
mapProfileWindowPoint.push(profileWindowClosestMapPoint.x);
mapProfileWindowPoint.push(profileWindowClosestMapPoint.y);
And here is the CodePen with the above attempt added.

Try replacing the JS in your codepen with this code. Needs a bit of work but I think it basically does what you want.
What I changed was to hook into dragstart and dragend of the modal, and use a mouse motion event handler on the document when dragging the modal. I used the document because the events wouldn't get through the dialog to the view behind it.
require([
"esri/Map",
"esri/views/MapView",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/geometry/support/webMercatorUtils",
"dojo/dom",
],
function init(Map, MapView, Graphic, GraphicsLayer, webMercatorUtils, dom) {
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-80.96135253906438, 35.9411934679851],
zoom: 3
});
var graphicsLayer = new GraphicsLayer();
map.add(graphicsLayer);
var simpleLineSymbol = {
type: "simple-line",
color: [13, 121, 190, .9],
style: "short-dash",
width: 3
};
// These were const arrays (??)
var coordinatesAx;
var coordinatesAy;
var coordinatesBx;
var coordinatesBy;
// Chane to true after the dialog is open and when modal starts dragging
var moveAlong = false;
var windowElem;
// view.when(function () {
// view.on("pointer-move", showCoordinates);
// });
// NEW: Stop/start moving the modal along with the pointer by map click
// view.when(function(){
// view.on("click", function () { moveAlong = !moveAlong;});
// });
coordinatesAx = -80.96135253906438;
coordinatesAy = 35.9411934679851;
document.getElementById("modal").onclick = function fun() {
windowElem = document.querySelector('.k-window');
// moveAlong = true;
// Bind Kendo dialog dragstart to movement
$("#dialog").data('kendoWindow').bind("dragstart", function (ev) {
//graphicsLayer.removeAll();
moveAlong = true;
console.log("Dragging");
showCoordinates(ev);
document.addEventListener("mousemove", showCoordinates);
}).bind("dragend", function (ev) {
moveAlong = false;
document.removeEventListener("mousemove", showCoordinates);
console.log("end Dragging");
}).bind("close", function (ev) {
console.log("Close. TODO clear line");
})
}
function showCoordinates(evt) {
var point = view.toMap({ x: evt.x, y: evt.y });
var mp = webMercatorUtils.webMercatorToGeographic(point);
dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
coordinatesBx = mp.x.toFixed(3);
coordinatesBy = mp.y.toFixed(3);
var polyline = {
type: "polyline",
paths: [
[coordinatesAx, coordinatesAy],
[coordinatesBx, coordinatesBy]
]
};
var polylineGraphic = new Graphic({
geometry: polyline,
symbol: simpleLineSymbol
})
if (moveAlong) {
if (graphicsLayer.graphics.items.length < 0) {
graphicsLayer.add(polylineGraphic)
} else {
// Recreate the line and reposition the modal
graphicsLayer.removeAll();
graphicsLayer.add(polylineGraphic)
}
}
}
});

Related

How to get lat/lng values from openlayers map

I want to get lat/lon of marker on the openlayers map:
...
var dragVectorC = new OpenLayers.Control.DragFeature(vectorLayer, {
onComplete: function (feature) {
var lonlat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
alert(lonlat.lat + ', ' + lonlat.lon);
But value that I get is:
5466016.2318036, 2328941.4188153
I have tried different ways to transform it but I always missing something.
What am I doing wrong?
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.OSM("Simple OSM Map");
var vector = new OpenLayers.Layer.Vector('vector');
map.addLayers([layer, vector]);
map.setCenter(
new OpenLayers.LonLat(-71.147, 42.472).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 12
);
var pulsate = function (feature) {
var point = feature.geometry.getCentroid(),
bounds = feature.geometry.getBounds(),
radius = Math.abs((bounds.right - bounds.left) / 2),
count = 0,
grow = 'up';
var resize = function () {
if (count > 16) {
clearInterval(window.resizeInterval);
}
var interval = radius * 0.03;
var ratio = interval / radius;
switch (count) {
case 4:
case 12:
grow = 'down'; break;
case 8:
grow = 'up'; break;
}
if (grow !== 'up') {
ratio = -Math.abs(ratio);
}
feature.geometry.resize(1 + ratio, point);
vector.drawFeature(feature);
count++;
};
window.resizeInterval = window.setInterval(resize, 50, point, radius);
};
var geolocate = new OpenLayers.Control.Geolocate({
bind: false,
geolocationOptions: {
enableHighAccuracy: false,
maximumAge: 0,
timeout: 7000
}
});
map.addControl(geolocate);
var firstGeolocation = true;
geolocate.events.register("locationupdated", geolocate, function (e) {
vector.removeAllFeatures();
var circle = new OpenLayers.Feature.Vector(
OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(e.point.x, e.point.y),
e.position.coords.accuracy / 2,
40,
0
),
{},
style
);
vector.addFeatures([
new OpenLayers.Feature.Vector(
e.point,
{},
{
graphicName: '', // cross
strokeColor: '', // #f00
strokeWidth: 2,
fillOpacity: 0,
pointRadius: 10
}
),
circle
]);
if (firstGeolocation) {
map.zoomToExtent(vector.getDataExtent());
pulsate(circle);
firstGeolocation = false;
this.bind = true;
}
// create marker
var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
var feature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(e.point.x, e.point.y),
{ some: 'data' },
{ externalGraphic: 'http://opportunitycollaboration.net/wp-content/uploads/2013/12/icon-map-pin.png', graphicHeight: 48, graphicWidth: 48 });
vectorLayer.addFeatures(feature);
map.addLayer(vectorLayer);
var dragVectorC = new OpenLayers.Control.DragFeature(vectorLayer, {
onComplete: function (feature) {
alert('x=' + feature.geometry.x + ', y=' + feature.geometry.y);
}
});
map.addControl(dragVectorC);
dragVectorC.activate();
});
geolocate.events.register("locationfailed", this, function () {
OpenLayers.Console.log('Location detection failed');
});
var style = {
fillColor: '#000',
fillOpacity: 0,
strokeWidth: 0
};
$(window).load(function () {
initMap();
});
function initMap() {
vector.removeAllFeatures();
geolocate.deactivate();
geolocate.watch = false;
firstGeolocation = true;
geolocate.activate();
}
You need to turn the point geometry's X,Y into a LonLat then transform it from your map's projection into WGS84 aka EPSG:4326 to get a 'conventional' lon/lat:
var dragVectorC = new OpenLayers.Control.DragFeature(vectorLayer, {
onComplete: function (feature) {
var lonlat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y).transform(
map.getProjectionObject(),
new OpenLayers.Projection("EPSG:4326")
))
alert(lonlat.lat + ', ' + lonlat.lon)
2022 update:
import { toLonLat } from 'ol/proj'
let lonLat = toLonLat(coordinates)

How can I add a custom HTML map marker to a Nokia HERE map?

From what I'm reading of the documentation on Nokia maps I can add custom marker using a vector based drawing API:
http://developer.nokia.com/Community/Wiki/HERE_Maps_API_-_How_to_create_custom_graphics_marker
You can create custom graphic markers but only based on a sprite:
http://heremaps.github.io/examples/examples.html#sprite-markers
Or you can add their own markers:
http://developer.nokia.com/Community/Wiki/HERE_Maps_API_-_How_to_add_map_markers
But is there any way to provide an HTML snippet to position on the map like a map marker? That is how other map libraries work so I can completely control the map marker in HTML/CSS. I already have map markers I would like to use that are styled in HTML/CSS and would not like to duplicate that styling in custom JS.
If you are intent on using styled, injected HTML, it would be possible to create a series of custom components (one for each marker) and attach them to the map. This would inject a block level element for each component which you could style as you see fit.
This is not entirely dissimilar to the simple GroundOverlay component I used to use before the ImgTileProvider class was exposed in the API - it injects a <IMG> element and resizes on zoomLevel (which you will probably need to remove) , but still effectively attaches a piece of HTML to a specific anchor point on the map.
For most simple applications I would usually use Markers (with or without my own iconography) or Infobubbles though. These lead to a more responsive and standard UI and don't clutter the map.
function extend(B, A) {
function I() {}
I.prototype = A.prototype;
B.prototype = new I();
B.prototype.constructor = B;
}
function GroundOverlay(url, boundingBox) {
nokia.maps.map.component.Component.call(this);
this.init(url, boundingBox);
}
extend(GroundOverlay,
nokia.maps.map.component.Component);
GroundOverlay.prototype.init = function (url, boundingBox) {
var that = this;
that.overlayDiv = document.createElement('div');
that.overlayDiv.style.position = 'absolute';
that.overlayDiv.style.cursor = 'default';
that.overlayImage = document.createElement('img');
that.overlayImage.id = 'groundoverlay';
that.overlayDiv.appendChild(that.overlayImage);
that.set('url', url);
that.set('boundingBox', boundingBox);
that.set('visible', true);
that.set('opacity', 1);
that.addOverlay = function () {
var isVisible = that.get('visible'),
bbox,
topLeft,
bottomRight;
if (isVisible === false) {
that.overlayDiv.style.display = 'none';
} else {
bbox = that.get('boundingBox');
topLeft = that.map.geoToPixel(bbox.topLeft);
bottomRight = that.map.geoToPixel(bbox.bottomRight);
that.overlayDiv.style.display = 'block';
that.overlayDiv.style.left = topLeft.x + 'px';
that.overlayDiv.style.top = topLeft.y + 'px';
that.overlayDiv.style.width = (bottomRight.x - topLeft.x) + 'px';
that.overlayDiv.style.height = (bottomRight.y - topLeft.y) + 'px';
that.overlayImage.src = that.get('url');
that.overlayImage.style.width = (bottomRight.x - topLeft.x) + 'px';
that.overlayImage.style.height = (bottomRight.y - topLeft.y) + 'px';
that.overlayImage.style.opacity = that.get('opacity');
}
};
that.addObserver('opacity', that.addOverlay);
that.addObserver('visible', that.addOverlay);
that.addObserver('url', that.addOverlay);
that.addObserver('boundingBox', that.addOverlay);
that.eventHandlers = {
dragListener : function (evt) {
var newGeo = that.map.pixelToGeo(
that.map.width / 2 - evt.deltaX,
that.map.height / 2 - evt.deltaY
);
that.map.set('center', newGeo);
evt.stopPropagation();
},
dblClickListener : function (evt) {
evt.target = this.parentNode.parentNode;
that.map.dispatch(evt);
},
mouseWheelListener : function (evt) {
evt.target = this.parentNode.parentNode;
that.map.dispatch(evt);
}
};
};
GroundOverlay.prototype.attach = function (map) {
this.map = map;
var controls = map.getUIContainer().firstChild,
child = controls.firstChild;
controls.insertBefore(this.overlayDiv, child);
map.addObserver('center', this.addOverlay);
map.addObserver('zoomLevel', this.addOverlay);
if (!this.evtTarget) {
this.evtTarget = nokia.maps.dom.EventTarget(
document.getElementById('groundoverlay')
).enableDrag();
this.evtTarget.addListener('drag', this.eventHandlers.dragListener);
this.evtTarget.addListener('dblclick', this.eventHandlers.dblClickListener);
this.evtTarget.addListener('mousewheel', this.eventHandlers.mouseWheelListener);
this.addOverlay();
}
};
GroundOverlay.prototype.detach = function (map) {
this.map = null;
map.removeObserver('center', this.addOverlay);
map.removeObserver('zoomLevel', this.addOverlay);
this.overlayDiv.parentNode.removeChild(this.overlayDiv);
};
GroundOverlay.prototype.getId = function () {
return 'GroundOverlay';
};
GroundOverlay.prototype.getVersion = function () {
return '1.0.0';
};

google maps listener only running once

I am having some difficulties where my listeners appear to cancel each other out only when I set a rectangle to the map, but not when I call an alert or anything else.
This works perfectly:
google.maps.event.addDomListener(document.getElementById("overlay" + me), 'click', function () {
displayMessage(me); //displays the current overlay index on screen (IE 1 of 30)
});
The above simply displays the index of the overlay on the map (IE 1 of 30). It works at every overlay clicked with the proper overlay index.
This not so much:
google.maps.event.addDomListener(document.getElementById("overlay" + me), 'click', function () {
alert("Called");
curOverlayRectangle.setOptions(overlayRectangleOptions); //defined by C# to js
curOverlayRectangle.setBounds(incomingOverlayBounds[me]);
curOverlayRectangle.setMap(map);
alert("Finished");
});
The above is supposed to add a rectangle over the overlay already on the map. What it actually does is add the rectangle for the first overlay clicked, but then if I click another overlay, nothing happens.
It appears that the listener is never called because once I click the first overlay, it goes through and says finished with the rectangle drawn. I then proceed to click another overlay and no alert occurs...
I have been working on this for quite some time, please help! Thanks!
EDIT1:
//get is simply the index
function tempAddListener(get) {
//alert("adding: " + get);
if (document.getElementById("overlay" + get) != null) { //check to see if div is there
google.maps.event.addDomListener(document.getElementById("overlay" + get), 'click', function () {
displayMessage("listener fired at overlay: " + get); //if enabled, works fine
//displayOverlayRectangle(incomingOverlayBounds[get]); //if enabled, listener fires but seems to delete all my other listeners for the overlays
});
} else {
//could not find the div
}
}
Edit2
//took out all defines
//#region geoObjs
var incomingOverlayBounds = [];
var incomingOverlaySourceURL = [];
var incomingOverlayRotation = [];
var incomingOverlayRectangle = [];
function initOverlays(){
//most of these are taken out
incomingOverlayBounds[0] = new google.maps.LatLngBounds( new google.maps.LatLng(29.7883456702236,-82.384843759249), new
incomingOverlayRotation[16] = 0;
incomingOverlayBounds[17] = new google.maps.LatLngBounds( new google.maps.LatLng(29.4715356702236,-82.3839748493845), new google.maps.LatLng(29.51265,-82.33674));
incomingOverlaySourceURL[17] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_20.jpg";
incomingOverlayRotation[17] = 0;
incomingOverlayBounds[18] = new google.maps.LatLngBounds( new google.maps.LatLng(29.4584356702236,-82.3840587432067), new google.maps.LatLng(29.49955,-82.33683));
incomingOverlaySourceURL[18] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_21.jpg";
incomingOverlayRotation[18] = 0;
incomingOverlayBounds[19] = new google.maps.LatLngBounds( new google.maps.LatLng(29.4431556702236,-82.4158516259991), new google.maps.LatLng(29.48427,-82.36863));
incomingOverlaySourceURL[19] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_022.jpg";
incomingOverlayRotation[19] = 0;
incomingOverlayBounds[20] = new google.maps.LatLngBounds( new google.maps.LatLng(29.4593656702236,-82.4157191765652), new google.maps.LatLng(29.50048,-82.36849));
incomingOverlaySourceURL[20] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_023.jpg";
incomingOverlayRotation[20] = 0;
incomingOverlayBounds[21] = new google.maps.LatLngBounds( new google.maps.LatLng(29.4736856702236,-82.4151858519302), new google.maps.LatLng(29.5148,-82.36795));
incomingOverlaySourceURL[21] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_024.jpg";
incomingOverlayRotation[21] = 0;
incomingOverlaySourceURL[51] = "http://ufdcimages.uflib.ufl.edu/UF/00/07/17/26/00027/12001_1968_2KK_054.jpg";
incomingOverlayRotation[51] = 0;
displayIncomingOverlays();
}
//#endregion
function initialize() {
//initialize google map objects
map = new google.maps.Map(document.getElementById(gmapPageDivId), gmapOptions); //initialize map
initOverlays(); //initialize all the incoming overlays
}
var incomingOverlayBounds = [];
var incomingOverlaySourceURL = [];
var incomingOverlayRotation = [];
var overlays = [];
function displayIncomingOverlays() {
for (var i = 0; i < incomingOverlayBounds.length; i++) {
overlaysOnMap[i] = new CustomOverlay(incomingOverlayBounds[i], incomingOverlaySourceURL[i], map, incomingOverlaySourceURL[i]);
overlaysOnMap[i].setMap(map);
//displayOverlayRectangle(incomingOverlayBounds[i]); //add all the rectangles
}
}
function CustomOverlay(bounds, image, map, rotation) {
//iterate here
overlayCount++;
// Now initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
preservedRotation = rotation;
if (overlayPrevious != null) {
overlayPrevious.setMap(null);
}
// We define a property to hold the image's div. We'll
// actually create this div upon receipt of the onAdd()
// method so we'll leave it null for now.
this.div_ = null;
}
CustomOverlay.prototype.onAdd = function () {
if (overlayPrevious != null) {
overlayPrevious.setMap(null);
}
// Note: an overlay's receipt of onAdd() indicates that
// the map's panes are now available for attaching
// the overlay to the map via the DOM.
// Create the DIV and set some basic attributes.
var div = document.createElement("div");
div.id = "overlay" + overlaysOnMap.indexOf(this);
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
div.style.opacity = preserveOpacity;
// Create an IMG element and attach it to the DIV.
var img = document.createElement('img');
img.src = incomingOverlaySourceURL[overlaysOnMap.indexOf(this)]; //this.image
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
//get the index
var overlayIndex = overlaysOnMap.indexOf(this);
// Set the overlay's div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map's panes.
// We'll add this overlay to the overlayLayer pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
//add the listener
tempAddListener(overlayIndex);
};
CustomOverlay.prototype.draw = function () {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We'll use these coordinates to resize the DIV.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's DIV to fit the indicated dimensions.
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 'px';
div.style.width = (ne.x - sw.x) + 'px';
div.style.height = (sw.y - ne.y) + 'px';
//for a preserved rotation
if (preservedRotation != 0) {
//keepRotate(preservedRotation);
}
};
//CustomOverlay.prototype.onRemove = function () {
// this.div_.parentNode.removeChild(this.div_);
// this.div_ = null;
//};
function tempAddListener(get) {
alert("div: "+document.getElementById("overlay" + get).innerHTML);
alert("adding with index: " + get);
if (document.getElementById("overlay" + get) != null) { //check to see if div is there
google.maps.event.addDomListener(document.getElementById("overlay" + get), 'click', function () {
alert("listener fired at overlay: " + get);
displayOverlayRectangle(incomingOverlayBounds[get]);
//alert(incomingOverlayBounds[get]);
//overlayRectangles[get] = displayOverlayRectangle(incomingOverlayBounds[get]);
//overlayRectangles[get].setMap(map);
});
} else {
//could not find the div
}
}
function displayOverlayRectangle(bounds) {
//2do: set drawing manager, set mode, match listeners of rectangle
var tempOverlayRectangle = new google.maps.Rectangle();
var tempOverlayRectangleOptions = {
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.1,
editable: true,
draggable: true,
//strokeOpacity: 0.2,
//strokeWeight: 1,
//fillOpacity: 0.0,
zindex: 5
};
tempOverlayRectangle.setOptions(tempOverlayRectangleOptions);
tempOverlayRectangle.setBounds(bounds);
tempOverlayRectangle.setMap(map);
google.maps.event.addListener(tempOverlayRectangle, "click", function () {
alert("can't touch this");
});
//return tempOverlayRectangle;
//tempOverlayRectangle.setOptions(tempOverlayRectangleOptions);
//tempOverlayRectangle.setBounds(bounds);
//tempOverlayRectangle.setMap(map);
}
//start this whole mess once
google.maps.event.addDomListener(window, 'load', initialize);
</script>
<div id="googleMap"></div>
UPDATE
It appears that any map code on the listener will invalidate the other listeners. (IE I tried it with the following code and it still only ran once)
google.maps.event.addDomListener(document.getElementById("overlay" + get), 'click', function () {
if (map.getMapTypeId() == 'TERRAIN') {
map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
} else {
map.setMapTypeId(google.maps.MapTypeId.TERRAIN);
}
});
SOLVED
Bottom line, the overlay I was creating could not be accessed appropriately by the DOM. Thus, I created an invisible rectangle to overlay on top of my overlay which can be accessed.
Snippet:
var incomingOverlayBounds = []; //defined in c# to js on page
var incomingOverlaySourceURL = []; //defined in c# to js on page
var incomingOverlayRotation = []; //defined in c# to js on page
var ghostOverlayRectangle = []; //holds ghost overlay rectangles (IE overlay hotspots)
var ghostOverlayRectangleOptions = { //define options for ghost rectangle
strokeColor: "#FF0000", //color doesnt matter
strokeOpacity: 0.0, //make border invisible
strokeWeight: 1, //should not matter?
fillColor: "#FF0000", //color doesnt matter
fillOpacity: 0.0, //make fill transparent
editable: false, //just to be sure?
draggable: false, //just to be sure?
zindex: 6 //perhaps higher?
};
var visibleOverlayRectangleOptions = { //define options for visible rectangle
strokeColor: "#FF0000", //for testing (red)
strokeOpacity: 0.8, //for testing
strokeWeight: 2, //for testing
fillColor: "#FF0000", //for testing (red)
fillOpacity: 0.1, //for testing
editable: true, //sobek standard
draggable: true, //sobek standard
//strokeOpacity: 0.2, //sobek standard
//strokeWeight: 1, //sobek standard
//fillOpacity: 0.0, //sobek standard
zindex: 5 //sobek standard
};
var visibleOverlayRectangle = new google.maps.Rectangle(); //init maybe move to array later
//Displays all the overlays sent from the C# code. Also calls displayGhostOverlayRectangle.
function displayIncomingOverlays() {
//go through and display overlays as long as there is an overlay to display
for (var i = 0; i < incomingOverlayBounds.length; i++) {
overlaysOnMap[i] = new CustomOverlay(incomingOverlayBounds[i], incomingOverlaySourceURL[i], map, incomingOverlayRotation[i]);
overlaysOnMap[i].setMap(map); //set the overlay to the map
displayGhostOverlayRectangle(incomingOverlayBounds[i],i); //add all the ghost rectangles
}
}
//Displays an invisible rectangle on top of the overlay div (creates a hotspot). This rectangle is used as a psuedo listener if the 'overlay div' is clicked. This solved issue of creating listener for overlay div directly.
//Supporting URL: http://stackoverflow.com/questions/17025240/google-maps-listener-only-running-once
function displayGhostOverlayRectangle(ghostBounds,ghostIndex) {
ghostOverlayRectangle[ghostIndex] = new google.maps.Rectangle(); //init rect
ghostOverlayRectangle[ghostIndex].setOptions(ghostOverlayRectangleOptions); //set options
ghostOverlayRectangle[ghostIndex].setBounds(ghostBounds); //set bounds
ghostOverlayRectangle[ghostIndex].setMap(map); //set to map
//create the listener for this ghost rectangle
google.maps.event.addListener(ghostOverlayRectangle[ghostIndex], 'click', function () {
displayVisibleOverlayRectangle(ghostBounds, ghostIndex); //add the visible rectangles
});
}
//Displays the visible rectangle which is used to edit an overlay. Called by the ghost listener.
function displayVisibleOverlayRectangle(bounds, overlayIndex) {
visibleOverlayRectangle.setOptions(visibleOverlayRectangleOptions);
visibleOverlayRectangle.setBounds(bounds);
visibleOverlayRectangle.setMap(map);
}
//Starts the creation of a custom overlay div which contains a rectangular image.
//Supporting URL: https://developers.google.com/maps/documentation/javascript/overlays#CustomOverlays
function CustomOverlay(bounds, image, map, rotation) {
overlayCount++; //iterate how many overlays have been drawn
this.bounds_ = bounds; //set the bounds
this.image_ = image; //set source url
this.map_ = map; //set to map
preservedRotation = rotation; //set the rotation
this.div_ = null; //defines a property to hold the image's div. We'll actually create this div upon receipt of the onAdd() method so we'll leave it null for now.
}
//Continues support for adding an custom overlay
//Supporting URL: https://developers.google.com/maps/documentation/javascript/overlays#CustomOverlays
// Note: an overlay's receipt of onAdd() indicates that the map's panes are now available for attaching the overlay to the map via the DOM.
CustomOverlay.prototype.onAdd = function () {
// Create the DIV and set some basic attributes.
var div = document.createElement("div");
div.id = "overlay" + overlaysOnMap.indexOf(this);
div.style.borderStyle = 'none';
div.style.borderWidth = '0px';
div.style.position = 'absolute';
div.style.opacity = preserveOpacity;
// Create an IMG element and attach it to the DIV.
var img = document.createElement('img');
img.src = incomingOverlaySourceURL[overlaysOnMap.indexOf(this)]; //this.image
img.style.width = '100%';
img.style.height = '100%';
img.style.position = 'absolute';
div.appendChild(img);
// Set the overlay's div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map's panes.
// We'll add this overlay to the overlayLayer pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
};
//Continues support for adding an custom overlay
//Supporting URL: https://developers.google.com/maps/documentation/javascript/overlays#CustomOverlays
CustomOverlay.prototype.draw = function () {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We'll use these coordinates to resize the DIV.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's DIV to fit the indicated dimensions.
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 'px';
div.style.width = (ne.x - sw.x) + 'px';
div.style.height = (sw.y - ne.y) + 'px';
//for a preserved rotation
if (preservedRotation != 0) {
keepRotate(preservedRotation);
}
};
//Not currently used
//Supporting URL: https://developers.google.com/maps/documentation/javascript/overlays#CustomOverlays
CustomOverlay.prototype.onRemove = function () {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};

gmappanel move to the marker coordinate - EXTJS 4

function addDoctorLocation(options)
{
var gm = Ext.getCmp('mygooglemap');
var mpoint = new google.maps.LatLng(options.lat,options.lng);
var marker = gm.addMarker(mpoint,options.marker,false,false, options.listeners);
// move the map to the mark and adjust the zoom level at here
}
tree.on('checkchange', function(node){
var data = node.data;
if (data.checked == true){
lati = 5.391788482666016;
longi = 100.29693603515625;
var options = {
lat:lati,
lng:longi,
marker: {title:"Hello World!"},
listeners: {
click: function(e){
}
}
}
addDoctorLocation(options);
}
})
Question
how to move the map to marker there and adjust the zoom level?
gm.setCenter(mpoint);
gm.setZoom(8);
See the methods section of google.maps.Map class here: https://developers.google.com/maps/documentation/javascript/reference?hl=en#Map

Circle radius with Driving Directions in Bing Maps

I'm currently developing a web site that are using Bing Maps. I'm using the Bing Maps Version 7. I have created a fully functional driving directions function. Which works like this:
The user rightclicks on the map, where doesn't matter. Then a context menu is brought up, where the user can chose between two alternatives. Which is: Align Start and Align Finish.
As you might understand those functions are creating a way-point on the locations of where the user right-clicked. Also a radius circle is aligned on respective way-point. Both start and finish way-points are dragable / movable, which means that the user can move the way-points around. The problem is that when the user moves one of the way-points the radius circle isn't moving also, which not is weird because I have not created a function for that yet. I don't think that is hard to do, but I don't know how to get the new position of the moved way-point. I'm posting my code. So I do really need some help with making this "RadiusCircleMove".
Here is my Javascript Code:
var map = null;
var directionsManager;
var directionsErrorEventObj;
var directionsUpdatedEventObj;
var startPosition;
var checkpointPosition;
var finishPosition;
var popuplat;
var popuplon;
var waypointType;
var startcircle;
var checkpointcircle;
var finishcircle;
var startcirclelat;
var startcirclelon;
var checkpointcirclelat;
var checkpointcirclelon;
var finishcirclelat;
var finishcirclelon;
$(document).ready(function () {
//this one line will disable the right mouse click menu
$(document)[0].oncontextmenu = function () { return false; }
GetMap();
});
function GetMap() {
map = new Microsoft.Maps.Map(document.getElementById("myMap"), { credentials: "Enter Bing Key Here", zoom: 4, center: new Microsoft.Maps.Location(45, -100) });
Microsoft.Maps.registerModule("BMv7.AdvancedShapes", "BMv7.AdvancedShapes.min.js");
Microsoft.Maps.loadModule("BMv7.AdvancedShapes");
//map.AttachEvent("onclick", ShowPopupMenu);
Microsoft.Maps.Events.addHandler(map, 'click', RemovePopupMenu);
Microsoft.Maps.Events.addHandler(map, 'rightclick', ShowPopupMenu);
}
function ShowPopupMenu(e) {
var point = new Microsoft.Maps.Point(e.getX(), e.getY());
popuplat = e.target.tryPixelToLocation(point).latitude
popuplon = e.target.tryPixelToLocation(point).longitude
var menu = document.getElementById('popupmenu');
menu.style.display = 'block'; //Showing the menu
menu.style.left = e.pageX + "px"; //Positioning the menu
menu.style.top = e.pageY + "px";
}
function RemovePopupMenu() {
document.getElementById("popupmenu").style.display = 'none';
}
function createDirectionsManager() {
var displayMessage;
if (!directionsManager) {
directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
//displayMessage = 'Directions Module loaded\n';
//displayMessage += 'Directions Manager loaded';
}
//alert(displayMessage);
directionsManager.resetDirections();
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', function () {} );
}
function createDrivingRoute() {
if (!directionsManager) { createDirectionsManager(); }
directionsManager.resetDirections();
// Set Route Mode to driving
directionsManager.setRequestOptions({ routeMode: Microsoft.Maps.Directions.RouteMode.driving });
if (waypointType == "start") {
addDefaultPushpin();
startPosition = new Microsoft.Maps.Directions.Waypoint({ location: new Microsoft.Maps.Location(popuplat, popuplon) });
startcirclelat = popuplat;
startcirclelon = popuplon;
}
if (waypointType == "checkpoint") {
addDefaultPushpin();
checkpointPosition = new Microsoft.Maps.Directions.Waypoint({ location: new Microsoft.Maps.Location(popuplat, popuplon) });
checkpointcirclelat = popuplat;
checkpointcirclelon = popuplon;
}
if (waypointType == "finish") {
finishPosition = new Microsoft.Maps.Directions.Waypoint({ location: new Microsoft.Maps.Location(popuplat, popuplon) });
finishcirclelat = popuplat;
finishcirclelon = popuplon;
directionsManager.addWaypoint(startPosition);
directionsManager.addWaypoint(checkpointPosition);
directionsManager.addWaypoint(finishPosition);
directionsManager.calculateDirections();
deletePushpin();
CreateStartCircle();
CreateCheckpointCircle();
CreateFinishCircle();
}
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({ itineraryContainer: document.getElementById('directionsItinerary') });
//alert('Calculating directions...');
}
function createDirections() {
if (!directionsManager) {
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', { callback: createDrivingRoute });
}
else {
createDrivingRoute();
}
}
function AddStartPosition() {
waypointType = "start";
createDirections();
RemovePopupMenu();
}
function AddCheckpointPosition() {
waypointType = "checkpoint";
createDirections();
RemovePopupMenu();
}
function AddFinishPosition() {
waypointType = "finish";
createDirections();
RemovePopupMenu();
}
function addDefaultPushpin() {
var pushpin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(popuplat, popuplon));
map.entities.push(pushpin);
}
function deletePushpin() {
for (var i = map.entities.getLength() - 1; i >= 0; i--) {
var pushpin = map.entities.get(i);
if (pushpin instanceof Microsoft.Maps.Pushpin) {
map.entities.removeAt(i);
};
}
}
function CreateStartCircle() {
startcircle = DecStartCircle();
map.entities.push(startcircle);
}
function CreateCheckpointCircle() {
checkpointcircle = DecCheckpointCircle();
map.entities.push(checkpointcircle);
}
function CreateFinishCircle() {
finishcircle = DecFinishCircle();
map.entities.push(finishcircle);
}
/***** Start Circle ****/
function DecStartCircle() {
var polygonOptions = {
fillColor: new Microsoft.Maps.Color(100, 0, 0, 255),
strokeColor: new Microsoft.Maps.Color(100, 255, 0, 0)
};
return new BMv7.AdvanceShapes.Circle(new Microsoft.Maps.Location(startcirclelat, startcirclelon), 80000, polygonOptions);
}
/***** Checkpoint Circle ****/
function DecCheckpointCircle() {
var polygonOptions = {
fillColor: new Microsoft.Maps.Color(100, 0, 0, 255),
strokeColor: new Microsoft.Maps.Color(100, 255, 0, 0)
};
return new BMv7.AdvanceShapes.Circle(new Microsoft.Maps.Location(checkpointcirclelat, checkpointcirclelon), 80000, polygonOptions);
}
/***** Finish Circle ****/
function DecFinishCircle() {
var polygonOptions = {
fillColor: new Microsoft.Maps.Color(100, 0, 0, 255),
strokeColor: new Microsoft.Maps.Color(100, 255, 0, 0)
};
return new BMv7.AdvanceShapes.Circle(new Microsoft.Maps.Location(finishcirclelat, finishcirclelon), 80000, polygonOptions);
}
I believe you need to actually implement your DirectionsUpdated event. Your code contains the following empty function:
directionsUpdatedEventObj = Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', function () {} );
You shouldn't be doing anything with the map until the directions have completed loading. Once they have loaded, then you can do the following:
Clear all map entities map.entities.clear(); which removes all previous polylines and polygons
Then reset directions: directionsManager.resetDirections(); to clear the current directions (otherwise you'll see waypoints appended).
Then get all of the waypoints from the directions module directionsManager.getAllWaypoints();
Now plot your three circles.
Your problem is one of timing and correct sequencing.

Categories