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.
Related
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)
}
}
}
});
function start()
{
var lastcenter = map.getCenter();
for(var i = 0;i<2/*18937*/;i++)
{
var run = lastcenter;
var lat = run.lat()-(0.00018*i);
var lng = run.lng();
for(var j = 0;j<3/*11276*/;j++)
{
var rlng = lng+(0.00018*j);
run = {lat:lat,lng:rlng};
map.setCenter(run);
PrintMap();
}
}
}
**I try to cut many small square from google map,and wanna to setcenter to Visit every square and capture them but the program will setcenter at last point and cut many square for last point,How can i fix it....
demo:https://jsfiddle.net/awalker0215/u0s9kna1/1/
**
Both html2canvas and setCenter are asynchronous. So your code needs to "wait" until one call has been finished and then proceed further.
It could look something like this
<input type="button" value="startCut" onclick="moveMap()">
and
var i = 0, n = 3;
function moveMap()
{
google.maps.event.addListenerOnce(map, 'idle', function() {
printMap();
})
map.setCenter({lat: map.getCenter().lat() - 0.1, lng: map.getCenter().lng() - 0.1});
}
function printMap()
{
html2canvas(document.getElementById("map"),
{
useCORS: true,
onrendered: function(canvas)
{
document.body.appendChild(canvas);
document.body.appendChild(document.createElement("br"))
i++;
if (i < n) {
moveMap();
} else {
google.maps.event.clearListeners(map, 'idle');
}
}
})
}
The problem in this case is that the map sometimes is idle but tiles are still being loaded (note the last image). So it would be better to use timeout.
var i = 0, n = 3;
function moveMap()
{
map.setCenter({lat: map.getCenter().lat() - 0.1, lng: map.getCenter().lng() - 0.1});
setTimeout(function() {
printMap();
}, 200);
}
function printMap()
{
html2canvas(document.getElementById("map"),
{
useCORS: true,
onrendered: function(canvas)
{
document.body.appendChild(canvas);
document.body.appendChild(document.createElement("br"))
i++;
if (i < n) {
moveMap();
}
}
})
}
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)
I need to allow user to rotate bitmap features on map with OpenLayers.Control.ModifyFeature or another way as it work for Polygons or other geometry objects, except Point, but only for Point I can set "externalGraphic" with my bitmap. Example of ModifyFeature to rotation as I expected here: ModifyFeature example
When I add Vector with Point geometry and activate ModifyFeature there is no rotation tool showing - only drag-drop. I know what is a point, but I need to have tool for rotate bitmap features. It may be image on any another geometry object, but with custom image.
After long research I found an example in gis.stackexchange.com, and fix it.
Here is a code which works for me:
OpenLayers.Control.RotateGraphicFeature = OpenLayers.Class(OpenLayers.Control.ModifyFeature, {
rotateHandleStyle: null,
initialize: function(layer, options) {
OpenLayers.Control.ModifyFeature.prototype.initialize.apply(this, arguments);
this.mode = OpenLayers.Control.ModifyFeature.ROTATE; // This control can only be used to rotate the feature
this.geometryTypes = ['OpenLayers.Geometry.Point'] // This control can only be used to rotate point because the 'exteralGraphic' is a point style property
var init_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style.select);
this.rotateHandleStyle = OpenLayers.Util.extend(init_style, {
externalGraphic: "./static/resources/images/cross.png",
graphicWidth: 12,
graphicHeight: 12,
fillOpacity: 1
});
},
resetVertices: function() {
// You need to set yours renderIntent or use "vertex"
if (this.feature && this.feature.renderIntent == "vertex") {
var vertex = this.feature;
this.feature = this.backup_feature;
this.layer.destroyFeatures([this.radiusHandle], {silent: true});
this.collectRadiusHandle();
return;
}
if (this.dragControl.feature) {
this.dragControl.outFeature(this.dragControl.feature);
}
if (this.vertices.length > 0) {
this.layer.removeFeatures(this.vertices, {silent: true});
this.vertices = [];
}
if (this.virtualVertices.length > 0) {
this.layer.removeFeatures(this.virtualVertices, {silent: true});
this.virtualVertices = [];
}
if (this.dragHandle) {
this.layer.destroyFeatures([this.dragHandle], {silent: true});
this.dragHandle = null;
}
if (this.radiusHandle) {
this.layer.destroyFeatures([this.radiusHandle], {silent: true});
this.radiusHandle = null;
}
if (this.feature && this.feature.geometry &&
this.feature.geometry.CLASS_NAME != "OpenLayers.Geometry.Point") {
if ((this.mode & OpenLayers.Control.ModifyFeature.DRAG)) {
this.collectDragHandle();
}
if ((this.mode & (OpenLayers.Control.ModifyFeature.ROTATE |
OpenLayers.Control.ModifyFeature.RESIZE))) {
this.collectRadiusHandle();
}
if (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE) {
if (!(this.mode & OpenLayers.Control.ModifyFeature.RESIZE)) {
this.collectVertices();
}
}
}
this.collectRadiusHandle();
},
collectRadiusHandle: function() {
var scope = this,
feature = this.feature,
geometry = this.feature.geometry || this.backup_feature.geometry,
centroid = geometry.getCentroid().transform(this.WGS84_google_mercator, this.WGS84),
lon = centroid.x, lat = centroid.y;
if (this.feature.geometry) {
this.backup_feature = this.feature;
} else {
this.feature.geometry = this.backup_feature.geometry;
}
var originGeometry = new OpenLayers.Geometry.Point(lon, lat);
// radius geometry position.
var pixel_dis_x = 10,
pixel_dis_y = -10;
var rotationFeatureGeometry = new OpenLayers.Geometry.Point(lon+pixel_dis_x, lat+pixel_dis_y);
var rotationFeature = new OpenLayers.Feature.Vector(rotationFeatureGeometry, null, this.rotateHandleStyle);
var resize = (this.mode & OpenLayers.Control.ModifyFeature.RESIZE);
var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);
var rotate = (this.mode & OpenLayers.Control.ModifyFeature.ROTATE);
rotationFeatureGeometry.move = function(x, y) {
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
var dx1 = this.x - originGeometry.x;
var dy1 = this.y - originGeometry.y;
var dx0 = dx1 - x;
var dy0 = dy1 - y;
if (rotate) {
var a0 = Math.atan2(dy0, dx0);
var a1 = Math.atan2(dy1, dx1);
var angle = a1 - a0;
angle *= 180 / Math.PI;
var old_angle = feature.attributes.angle;
var new_angle = old_angle - angle;
feature.attributes.angle = new_angle;
// redraw the feature
scope.feature.layer.redraw.call(scope.feature.layer);
}
};
rotationFeature._sketch = true;
this.radiusHandle = rotationFeature;
this.radiusHandle.renderIntent = this.vertexRenderIntent;
this.layer.addFeatures([this.radiusHandle], {silent: true});
},
CLASS_NAME: "OpenLayers.Control.RotateGraphicFeature"
});
Style of your Vector may be as:
new OpenLayers.StyleMap({
"default": new OpenLayers.Style({
externalGraphic: "link/to/icon",
graphicHeight: "32px",
graphicWidth: "25px",
fillOpacity: 1,
rotation: "${angle}",
graphicZIndex: 1
})
})
UPD: I fixed it for OpenLayers 2.13.1
OpenLayers.Control.RotateGraphicFeature = OpenLayers.Class(OpenLayers.Control.ModifyFeature, {
rotateHandleStyle: null,
initialize: function (layer, options) {
OpenLayers.Control.ModifyFeature.prototype.initialize.apply(this, arguments);
this.mode = OpenLayers.Control.ModifyFeature.ROTATE; // This control can only be used to rotate the feature
this.geometryTypes = ['OpenLayers.Geometry.Point'] // This control can only be used to rotate point because the 'exteralGraphic' is a point style property
var init_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style.select);
this.rotateHandleStyle = OpenLayers.Util.extend(init_style, {
externalGraphic: "./static/resources/images/cross.png",
graphicWidth: 12,
graphicHeight: 12,
fillOpacity: 1
});
},
resetVertices: function () {
// You need to set yours renderIntent or use "vertex"
if (this.feature && this.feature.renderIntent == "vertex") {
var vertex = this.feature;
this.feature = this.backup_feature;
if (this.dragControl.feature) {
this.dragControl.outFeature(this.dragControl.feature);
}
this.layer.destroyFeatures([this.radiusHandle], {silent: true});
delete this.radiusHandle;
this.collectRadiusHandle();
return;
}
if (this.vertices.length > 0) {
this.layer.removeFeatures(this.vertices, {silent: true});
this.vertices = [];
}
if (this.virtualVertices.length > 0) {
this.layer.removeFeatures(this.virtualVertices, {silent: true});
this.virtualVertices = [];
}
if (this.dragHandle) {
this.layer.destroyFeatures([this.dragHandle], {silent: true});
this.dragHandle = null;
}
if (this.radiusHandle) {
this.layer.destroyFeatures([this.radiusHandle], {silent: true});
this.radiusHandle = null;
}
if (this.feature && this.feature.geometry &&
this.feature.geometry.CLASS_NAME != "OpenLayers.Geometry.Point") {
if ((this.mode & OpenLayers.Control.ModifyFeature.DRAG)) {
this.collectDragHandle();
}
if ((this.mode & (OpenLayers.Control.ModifyFeature.ROTATE |
OpenLayers.Control.ModifyFeature.RESIZE))) {
this.collectRadiusHandle();
}
if (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE) {
if (!(this.mode & OpenLayers.Control.ModifyFeature.RESIZE)) {
this.collectVertices();
}
}
}
this.collectRadiusHandle();
},
collectRadiusHandle: function () {
var scope = this,
feature = this.feature,
data = feature.attributes,
geometry = this.feature.geometry || this.backup_feature.geometry,
center = this.feature.geometry.bounds.getCenterLonLat();
centroid = geometry.getCentroid().transform(this.WGS84_google_mercator, this.WGS84),
lon = centroid.x, lat = centroid.y;
if (data.type && Tms.settings.roadObjectTypeSettings[data.type].NoAzimuth) {
return;
}
if (this.feature.geometry) {
this.backup_feature = this.feature;
} else {
this.feature.geometry = this.backup_feature.geometry;
}
var originGeometry = new OpenLayers.Geometry.Point(lon, lat);
var center_px = this.map.getPixelFromLonLat(center);
// you can change this two values to get best radius geometry position.
var pixel_dis_x = 20,
pixel_dis_y = 20;
var radius_px = center_px.add(pixel_dis_x, pixel_dis_y);
var rotation_lonlat = this.map.getLonLatFromPixel(radius_px);
var rotationFeatureGeometry = new OpenLayers.Geometry.Point(
rotation_lonlat.lon, rotation_lonlat.lat
);
var rotationFeature = new OpenLayers.Feature.Vector(rotationFeatureGeometry, null, this.rotateHandleStyle);
var resize = (this.mode & OpenLayers.Control.ModifyFeature.RESIZE);
var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);
var rotate = (this.mode & OpenLayers.Control.ModifyFeature.ROTATE);
rotationFeatureGeometry.move = function(x, y) {
OpenLayers.Geometry.Point.prototype.move.call(this, x, y);
var dx1 = this.x - originGeometry.x;
var dy1 = this.y - originGeometry.y;
var dx0 = dx1 - x;
var dy0 = dy1 - y;
if (rotate) {
var a0 = Math.atan2(dy0, dx0);
var a1 = Math.atan2(dy1, dx1);
var angle = a1 - a0;
angle *= 180 / Math.PI;
var old_angle = feature.attributes.angle;
var new_angle = old_angle - angle;
feature.attributes.angle = new_angle;
// redraw the feature
scope.feature.layer.redraw.call(scope.feature.layer);
}
};
rotationFeature._sketch = true;
this.radiusHandle = rotationFeature;
this.radiusHandle.renderIntent = this.vertexRenderIntent;
this.layer.addFeatures([this.radiusHandle], {silent: true});
},
CLASS_NAME: "OpenLayers.Control.RotateGraphicFeature"
});
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