Cesium: display / hide Labels depending on the Zoom level - javascript

I want to hide map's labels when the zoom is increased above a certain level.
For this example, I want to hide all labels related to the collection1, after the zoom level of 5:
https://codepen.io/ollazarev/pen/XBWEEq
let viewer = new Cesium.Viewer('cesiumContainer', {
animation: false,
baseLayerPicker: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
timeline: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
});
let collection1 = new Cesium.LabelCollection();
collection1.add({
position: Cesium.Cartesian3.fromDegrees(-101.678, 57.7833),
text: 'Canada',
});
collection1.add({
position : Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222),
text: 'Philadelphia',
});
viewer.scene.primitives.add(collection1);
let collection2 = new Cesium.LabelCollection();
collection2.add({
position: Cesium.Cartesian3.fromDegrees(-74.0059728, 40.7127753),
text: 'New York',
});
collection2.add({
position : Cesium.Cartesian3.fromDegrees(-79.38318429999998, 43.653226),
text: 'Toronto',
});
viewer.scene.primitives.add(collection2);

Cesium's 3D camera isn't aware of "zoom levels" as such, but you can turn off labels after a certain distance away using translucencyByDistance.
For example, here's your demo again with translucencyByDistance added to each of the labels:
let viewer = new Cesium.Viewer('cesiumContainer', {
animation: false,
baseLayerPicker: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
timeline: false,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
});
let collection1 = new Cesium.LabelCollection();
collection1.add({
position: Cesium.Cartesian3.fromDegrees(-101.678, 57.7833),
text: 'Canada',
translucencyByDistance : new Cesium.NearFarScalar(6.0e7, 1.0, 7.0e7, 0.0)
});
collection1.add({
position : Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222),
text: 'Philadelphia',
translucencyByDistance : new Cesium.NearFarScalar(4.0e7, 1.0, 7.0e7, 0.0)
});
viewer.scene.primitives.add(collection1);
let collection2 = new Cesium.LabelCollection();
collection2.add({
position: Cesium.Cartesian3.fromDegrees(-74.0059728, 40.7127753),
text: 'New York',
translucencyByDistance : new Cesium.NearFarScalar(1.0e7, 1.0, 3.0e7, 0.0)
});
collection2.add({
position : Cesium.Cartesian3.fromDegrees(-79.38318429999998, 43.653226),
text: 'Toronto',
translucencyByDistance : new Cesium.NearFarScalar(3.0e7, 1.0, 5.0e7, 0.0)
});
viewer.scene.primitives.add(collection2);

Related

context menu Items in leaflet

I'm making a map using the Neshan platform.
I want to show context menu of a marker،
I have written this code but it's not displaying the context menu
myMap.on('click', function (e) {
marker = new L.Marker(e.latlng, {
contextmenu: true,
contextmenuItems: [
{
text: 'Marker item',
index: 0
},
{
separator: true,
index: 1
}
]
}).addTo(myMap);
});

Leaflet.Draw show distance in miles

When I draw / edit circles manually on a leaflet map using the draw plugin, their radius is shown in km even though I have the below settings which should show the radius in miles.
What am I doing wrong and what can I do to get the radius to show in miles?
map.addControl(new L.Control.Draw({
position: 'topright',
edit: {
featureGroup: drawnItems,
circle: {
metric: true,
feet: false
}
},
draw: {
circle: {
metric: true,
feet: false
}
}
}));
You need to set metric: false and feet: false
map.addControl(new L.Control.Draw({
position: 'topright',
edit: {
featureGroup: drawnItems,
circle: {
metric: false,
feet: false
}
},
draw: {
circle: {
metric: false,
feet: false
}
}
}));

Not able to delete selected polygon in ui-gmap-google-map

I am able to draw multiple polygon by using Google Draw manager. Now I am not able to select specific polygon from multiple polygon and delete and edit it. Also not able to get new array after edit or delete.
My demo.js code is as follows :
$scope.map = {
center: { latitude: 19.997454, longitude: 73.789803 },
zoom: 10,
//mapTypeId: google.maps.MapTypeId.ROADMAP,
//radius: 15000,
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: true, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: false, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
control: {},
refresh: "refreshMap",
options: { scrollwheel: true },
Polygon: {
visible: true,
editable: true,
draggable: true,
geodesic: true,
stroke: {
weight: 3,
color: 'red'
}
},
source: {
id: 'source',
coords: {
'latitude': 19.9989551,
'longitude': 73.75095599999997
},
options: {
draggable: false,
icon: 'assets/img/person.png'
}
},
isDrawingModeEnabled: true
};
$scope.drawingManagerOptions = {
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
//google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
]
},
circleOptions: {
fillColor: '#BCDCF9',
fillOpacity:0.5,
strokeWeight: 2,
clickable: false,
editable: true,
zIndex: 1
},
polygonOptions: {
fillColor: '#BCDCF9',
strokeColor: '#57ACF9',
fillOpacity: 0.5,
strokeWeight: 2,
clickable: false,
editable: true,
zIndex: 1
}
};
var coords = [];
var polygon;
$scope.eventHandler = {
polygoncomplete: function (drawingManager, eventName, scope, args) {
polygon = args[0];
var path = polygon.getPath();
for (var i = 0 ; i < path.length ; i++) {
coords.push({
latitude: path.getAt(i).lat(),
longitude: path.getAt(i).lng()
});
}
},
};
$scope.removeShape = function () {
google.maps.event.clearListeners(polygon, 'click');
google.maps.event.clearListeners(polygon, 'drag_handler_name');
polygon.setMap(null);
}
And My HTML code is as follows :
<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options" control="map.control">
<ui-gmap-marker coords="map.source.coords"
options="map.source.options"
idkey="map.source.id">
</ui-gmap-marker>
<ui-gmap-drawing-manager options="drawingManagerOptions" control="drawingManagerControl" events="eventHandler"></ui-gmap-drawing-manager>
</ui-gmap-google-map>
You can find polygon image for reference:
Now I want to select one of polygon from following image and want to delete or update it.
Some help will be really appreciable.
By the ui-google-map plugin's drawing manager doc, you could get the google.maps.drawing.DrawingManager object by the control attributes (putting there an object)
<ui-gmap-drawing-manager control="drawingManagerControl" options="drawingManagerOptions"></ui-gmap-drawing-manager>
and
$scope.drawingManagerControl = {};
//Now get the drawingManager object
var drawingManager = $scope.drawingManagerControl.getDrawingManager();
Having this object is the main work.
Now you can look on everything you need. For your case you need the overlaycomplete events, it will listen for every time you have drawn a shape (=> polygon , circle, polyline)
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
});
newShape is the new shape drawn, polygon in your case, so you can use it like a Polygon object and can use all you need in this reference.
Now I want to select one of polygon from following image and want to
delete or update it.
For it, we'll distinct the polygon selected, by assigning it in a global variable: eg var selectedShape;
And now, Add a click event listener for this drawn polygon and update it as the selectedShape, and now to delete or update, you can use the selectedShape variable.
var selectedShape;
... ...
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
google.maps.event.addListener(newShape, 'click', function() {
selectedShape = newShape;
});
});
Finally you can delete the selected shape by setting his map to null selectedShape.setMap(null); and update the shape by setting it editable to true shape.setEditable(true);
And finally to make these click event possible you need to add clickable options to true for all shape.
PS: Use the IsReady Service to have map ready before working on it
Working plunker: https://embed.plnkr.co/qfjkT2lOu2vkATisGbw7/
Update:
But how to get all co-ordinates of multiple polygon after edit or
draw.
you already have this in your script, in polygonecomplete ($scope.eventHandler). Now you can add it in overlaycomplete events listener, and for everytime you updated the shape (see code bellow)
But challenge is how to identify which polygon is edited on the
map and how to update that specific polygon from my array
You can push in an array for each shape created and could manage it:
...
var allShapes = []; //the array contains all shape, to save in end
....
//get path coords: I use your code there
function getShapeCoords(shape) {
var path = shape.getPath();
var coords = [];
for (var i = 0; i < path.length; i++) {
coords.push({
latitude: path.getAt(i).lat(),
longitude: path.getAt(i).lng()
});
}
return coords;
}
....
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
var newShape = e.overlay;
google.maps.event.addListener(newShape, 'click', function() {
selectedShape = newShape;
});
...
// get coordinate of the polygon
var shapeCoords = getShapeCoords(newShape);
// pushing this shape to allShapes array
allShapes.push(newShape);
});
in the delete function you can delete id by the index of the selectedShape
//delete selected shape
function deleteSelectedShape() {
if (!selectedShape) {
alert("There are no shape selected");
return;
}
var index = allShapes.indexOf(selectedShape);
allShapes.splice(index, 1);
selectedShape.setMap(null);
}
Now you have the allShapes array, and in the end you can loop it then get for each coordinates and save in your db.
I updated the plunker and added some debug log do show you.
This snipet from github could help:
https://github.com/beekay-/gmaps-samples-v3/blob/master/drawing/drawing-tools.html

Click on Leaflet marker to open image in fancybox

I am having some problems getting a fancybox gallery to load correctly when clicking on a marker within a leaflet map. I have got to the stage where I can trigger the event, but I am stuck with only getting a fancybox error message within the frame. I ran through the same workflow today with google maps api and got the same result, so there must be something I am doing wrong in calling fancybox. I have searched and searched but can't find an answer anywhere detailing my specific issue, which as I am new to JavaScript is surely a user error. My code is as follows:
//Array of locations
var locations = [
['Big Ben', 51.500625, -0.124624, 2, 'www.image1url.com/image1.jpg'],
['Tower Bridge', 51.506776, -0.074603, 1, 'www.image2url.com/image2.jpg'],
['London Eye', 51.503325, -0.119543, 3, 'www.image3url.com/image3.jpg']
];
//Calling the map
var map = L.map('map').setView([51.508529, -0.109949], 14);
mapLink =
'OpenStreetMap';
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + mapLink + ' Contributors',
maxZoom: 18,
}).addTo(map);
//Looping through the array to create the markers
for (i = 0; i < locations.length; i++) {
marker = new L.marker([locations[i][1], locations[i][2]], {
title: (locations[i][0]),
})
.addTo(map)
.on('click', function() {
$.fancybox({
href: locations[4],
width: 1000,
maxHeight: 666,
fitToView: true,
autoSize: false,
type: 'iframe',
padding: 0,
openEffect: 'elastic',
openSpeed: 150,
aspectRatio: true,
closeEffect: 'elastic',
closeSpeed: 150,
closeClick: true,
iframe: {
scrolling: 'no'
},
preload: true
});
});
}
Thanks in advance for any help
EDIT I've added a JSFiddle here: Fancybox on Leaflet Marker
Most probably, your error comes from this line of code:
href: locations[4]
The links are located in a nested array, and to access them you'll have to use:
href: locations[i][4]
UPDATE
OK, based on your JSFiddle, I've got a solution. You'll have to create a layer group and store the markers in it. Then, to access the 4th property of the locations array, you'll have to identify the position of the marker inside the layerGroup array.
//create a layergroup to store the markers inside it
var group = L.layerGroup().addTo(map)
for (i = 0; i < locations.length; i++) {
marker = new L.marker([locations[i][1], locations[i][2]], {
title: (locations[i][0]),
opacity: 1
})
.addTo(group) //add the markers to the group
marker.on('click', function() {
markerArray = group.getLayers(); //get an array with all the markers
//see which marker from the group was clicked and store the value for later use
position = markerArray.indexOf(group.getLayer(this._leaflet_id));
$.fancybox({
//acccess the locations array using the previously stored value
href: locations[position][4],
width: 1000,
maxHeight: 666,
fitToView: true,
autoSize: false,
type: 'iframe',
padding: 0,
openEffect: 'elastic',
openSpeed: 150,
aspectRatio: true,
closeEffect: 'elastic',
closeSpeed: 150,
closeClick: true,
iframe: {
scrolling: 'no'
},
preload: true
});
});
}
Here's an updated JSFiddle: http://jsfiddle.net/pufanalexandru/8mLxm820/2/

drag marker outside map to html element

Is there an easy way to drag a google maps marker outside the map area onto another html dom element. I have tried allot of things and looks like the only way is to hack through and create a duplicate marker in jquery and just have it hover over the current marker so it appears you have dragged it off the map.
any suggestions welcome!
Example Fiddle: http://jsfiddle.net/y3YTS/26/
want to drag the marker onto the red box
Here is solution with your hack
http://jsfiddle.net/H4Rp2/38/
var someData = [
{
'name': 'Australia',
'location': [-25.274398, 133.775136]
},
{
'name': 'La Svizra',
'location': [46.818188, 8.227512]
},
{
'name': 'España',
'location': [40.463667, -3.74922]
},
{
'name': 'France',
'location': [46.227638, 2.213749]
},
{
'name': 'Ireland',
'location': [53.41291, -8.24389]
},
{
'name': 'Italia',
'location': [41.87194, 12.56738]
},
{
'name': 'United Kingdom',
'location': [55.378051, -3.435973]
},
{
'name': 'United States of America',
'location': [37.09024, -95.712891]
},
{
'name': 'Singapore',
'location': [1.352083, 103.819836]
}
];
var gDrag = {
jq: {},
item: {},
status: 0,
y: 0,
x: 0
}
$(function(){
/*Google map*/
var mapCenter = new google.maps.LatLng(51.9226672, 4.500363500000049);
var map = new google.maps.Map(
document.getElementById('map'),
{
zoom: 4,
draggable: true,
center: mapCenter
}
);
if(someData){
gDrag.jq = $('#gmarker');
/*LOOP DATA ADN CREATE MARKERS*/
var markers = [];
for(var i = 0; i < someData.length; i++){
markers.push(
new google.maps.Marker({
map: map,
draggable: false,
raiseOnDrag: false,
title: someData[i].name,
icon: 'http://icons.iconarchive.com/icons/aha-soft/standard-city/48/city-icon.png',
position: new google.maps.LatLng(someData[i].location[0], someData[i].location[1]),
})
);
//Block mouse with our invisible gmarker
google.maps.event.addListener(markers[i], 'mouseover', function(e){
if(!gDrag.jq.hasClass('ui-draggable-dragging')){
gDrag.item = this;
gDrag.jq.offset({
top: gDrag.y - 10,
left: gDrag.x - 10
});
}
});
}
gDrag.jq.draggable({
start: function(event, ui){
console.log(gDrag.item.getIcon())
gDrag.jq.html('<img src="'+gDrag.item.getIcon()+'" />');
gDrag.item.setVisible(false);
},
stop: function(event, ui){
gDrag.jq.html('');
/*Chech if targed was droped in our dropable area*/
if(gDrag.status){
gDrag.item.setVisible(false);
}else{
gDrag.item.setVisible(true);
}
}
});
$(document).mousemove(function(event){
gDrag.x = event.pageX;
gDrag.y = event.pageY;
});
$("#dropzone").droppable({
accept: "#gmarker",
activeClass: "drophere",
hoverClass: "dropaccept",
drop: function(event, ui, item){
gDrag.status = 1;
$(this).addClass("ui-state-highlight").html("Dropped!");
}
});
}
});
You've probably already accomplished this, but just in case someone else is looking, here is a good starting place. This demo takes a marker that is off a map and allows you to drop it on the map. You want to do the reverse, but the concept is the same. Get the mouse location on mouseup event and then replace the marker's map with an html marker in that spot

Categories

Resources