Polyline drawn is showing below buildings - mapkit

The polyline is drawn showing below building.
(source: gifyu.com)
How can I get the polyline top of all layers
please suggest
adding polyline as
var coordinates = locationsArrToAdd.map({ (location: CLLocation!) -> CLLocationCoordinate2D in
return location.coordinate
})
let polyline = MKPolyline(coordinates: &coordinates, count: locationsArrToAdd.count)
self.mapView.addOverlays([polyline], level: .aboveLabels)

According to Apple, the highest available level you can add an overlay to is the MKOverlayLevel.aboveOverlays constant you are currently using. However, their documentation states that this will:
Place the overlay above map labels, shields, or point-of-interest icons but below annotations and 3D projections of buildings.
From what I can see, the best solution is to disabled buildings in 3D mode, so that your polylines are visible:
self.mapView.showsBuildings = false

Related

ArcGIS API: Drawing circle fixing center

I am using ArcGIS API v4.8 and the drawing tools to draw circle on my map.
1 issue I notice is when I draw a circle, the center of the circle moves when I move my mouse resizing the circle rather than fixed at the point of the 1st mouse click starts:
How do I fix the center regardless of how I move the radius of the circle? What is missing in my code?
const options = {view, layer: tempGraphicsLayer, pointSymbol, polylineSymbol, polygonSymbol}
let sketchViewModel = new SketchViewModel(options)
let drawCircleButton = document.getElementById('circleButton')
drawCircleButton.onclick = function () {
clear()
isDrawLine = false
sketchViewModel.create('polygon', {mode: 'click'})
sketchViewModel.create('circle')
}
EDIT:
I have found a similar sample, choose the Draw Circle tool, start drawing a circle on the map, you will notice that the center of the circle moves when you move your mouse, I want it to fix the center instead.
The problem when the center moves along with your mouse move is that the circle drawn is not accurate, as I want to start with the center of the circle I want, the circle can expand outward but the center should not move.
That is because the circle, in the given example, is being draw inside the square object. Basically your start and end point are representing corners, not the center point and outer layer of the circle. So every time you expand circle object, it expands from one corner, while the rest is dragging along your mouse.
Visual example:
There are workarounds for this of course. I've made a small sample code of one of the possible ways to draw a circle from a fixed center point.
https://jsfiddle.net/wLd46g8k/9/
Basically I used an ArcGis JS API 4.x constructor called Circle, where you pass a starting point and radius. In my example I've calculated the radius from these two points.
function drawCircle(){//draws the circle
graphicsLayer.graphics.removeAll();
var graphic = new Graphic({
geometry: new Circle({//circle constructor
center: startPoint,//pass the pointer-down event X Y as a starting point
radius: Math.floor(Math.sqrt(Math.pow(startPoint.x - endPoint.x, 2) + Math.pow(startPoint.y - endPoint.y, 2)))
}), //calculates endpoint distance from the startpoint and pass it as a radius
symbol: {//circle design
type: "simple-fill",
color: "orange",
style: "solid",
outline:{
color:"darkorange",
width:4
}
}
});
graphicsLayer.graphics.add(graphic);//adds the circle
};

Can I get an Unclickable geoxml3 Shadow Layer that sits entirely behind a Clickable Marker Layer?

In order to have markers that are clickable and marker shadows that are not, I'm setting up two geoxml3 parsers, one for the markers and one for the shadows. That works, but I'm hoping that having two layers will also let me keep the shadow of one marker from falling on another marker. It's a subtle thing, but having a visually horizontal shadow overlaid on a visually vertical marker undercuts the 3-D effect. And in a cluster of markers, things get pretty murky down among the marker stems.
Now, I get that icons are rendered from north to south, so that an icon will peek over the top of an overlapping icon to the south of it. What I was expecting was that each parser would create its own layer, in the sense that a marker layer would appear entirely in front of a preceding shadow layer, with no shadow falling on any marker. It sure looks, though, like the parsers are working north to south down both "layers" at the same time. It seems like for each point they render the shadow image and then the corresponding marker image before moving down to the next point. If the next marker is pretty close to the southwest of the previous marker, its shadow image falls onto that previous marker.
To make sure I wasn't seeing some sort of illusion, as an exercise I put together a map with a couple of big, overlapping shadowed markers. What I'd hope for would be to have the images layered, bottom to top:
East Greenland Shadow
Greenland Shadow
East Greenland Marker
Greenland Marker
Instead, they appear to be layered:
East Greenland Shadow
East Greenland Marker
Greenland Shadow
Greenland Marker
with the Greenland Shadow falling on the East Greenland Marker.
So, can I get all of the markers to appear, collectively, in front of all the shadows? I can't track it down at the moment, but I believe I saw a list of standard Google Maps layers somewhere, which included something like a non-clickable "Shadow Layer". When I create a google.maps.KmlLayer with standard icons, the API automatically pulls up the corresponding shadow images and places those on what I guess is the Shadow Layer, which sits entirely behind the KmlLayer I asked for.
In my current project, I need a geoxml3 marker layer, so I can programatically access the placemarks. Since I can actually work with 32x32 icons, in this case I can just fall back to using a KmlLayer for the shadows, but for future reference it would be great to have the option of a non-clickable geoxml3 layer that sits entirely behind a clickable layer. Is there a way to do that? Would that be a matter of somehow rendering onto that Google Maps Shadow Layer?
Here's the script:
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(71, -45),
zoom: 4,
preserveViewport: true
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
// Shadow Layer
var shadow = new geoXML3.parser({
map: map,
zoom: false,
markerOptions: {clickable: false}
});
shadow.parse('greenland_shadow_5.kml');
// Marker Layer
var blues = new geoXML3.parser({
map: map,
singleInfoWindow: true,
zoom: false,
suppressDirections: true,
markerOptions: {
shape: {
type: 'circle',
coords: [38,38,38]
}
}
});
blues.parse('greenland_5.kml');
}
google.maps.event.addDomListener(window, 'load', initialize);
The two KML files are identical except for the IconStyles:
<IconStyle>
<Icon>
<href>bluemarker_76x128.png</href>
<scale>1.0</scale>
</Icon>
<hotSpot x="38" y="0" xunits="pixels" yunits="pixels" />
</IconStyle>
versus:
<IconStyle>
<Icon>
<href>markershadow_188x128.png</href>
<scale>1.0</scale>
</Icon>
<hotSpot x="96" y="0" xunits="pixels" yunits="pixels" />
</IconStyle>
You could take the "MarkerShadow" class and use it to make a layer of just shadows. and make a layer with just markers: proof of concept
- disadvantage: processes the same KML twice.
I can think of 4 options for you:
Put your shadows in a separate KML file and display them using the native google.maps.KmlLayer, that should put them underneath all the google.maps.Marker objects, which is what geoxml3 uses to render the icons. The issue with KmlLayer is that it does not support scaling, all icons are scaled to 64x64 and if they can't be, they are replaced by the default blue icon. KmlLayer is rendered in the overlayLayer pane.
create custom "markers" using Custom Overlays that support combining a marker image with a shadow image. Used to be supported natively by the Google Maps Javascript API v3, but they removed that functionality with the "visual refresh". It looks like the "shadowPane" still exists (at least for now), you could put all the shadows there.
overlayShadow contains the marker shadows. It may not receive DOM events. (Pane 2).
mapPanes reference
Use the zIndex option of the google.maps.Marker object to put the shadows below the markers. Put all the shadows at zIndex = 0 (so they are on the bottom, then use an algorithm to put the markers in their default orientations:
zIndex: Math.round(latlng.lat()*-100000)<<5
"manually" add a shadow to the markers in a custom "createMarker" function (append the shadow image to the shadowPane)
proof of concept marker with shadow

THREE.js rotating camera around an object using orbit path

I am struggling in solving this problem.
On my scene, I have a camera which looks at the center of mass of an object. I have a some buttons that enable to set camera position on particular view (front view, back view,...) along a invisible sphere that surroung the object (constant radius).
When I click on the button, i would like the camera to move from its start position to the end position along the sphere surface. When camera moves I would like it to keep fixing center of mass of the object.
Has anyone have a clue on how to achieve this?
Thanks for help!
If you are happy/prefer to use basic trigonometry then in your initialisation section you could do this:
var cameraAngle = 0;
var orbitRange = 100;
var orbitSpeed = 2 * Math.PI/180;
var desiredAngle = 90 * Math.PI/180;
...
camera.position.set(orbitRange,0,0);
camera.lookAt(myObject.position);
Then in your render/animate section you could do this:
if (cameraAngle == desiredAngle) { orbitSpeed = 0; }
else {
cameraAngle += orbitSpeed;
camera.position.x = Math.cos(cameraAngle) * orbitRange;
camera.position.y = Math.sin(cameraAngle) * orbitRange;
}
Of course, your buttons would modify what the desiredAngle was (0°, 90°, 180° or 270° presumably), you need to rotate around the correct plane (I am rotating around the XY plane above), and you can play with the orbitRange and orbitSpeed until you hare happy.
You can also modify orbitSpeed as it moves along the orbit path, speeding up and slowing down at various cameraAngles for a smoother ride. This process is called 'tweening' and you could search on 'tween' or 'tweening' if you want to know more. I think Three.js has tweening support but have never looked into it.
Oh, also remember to set your camera's far property to be greater than orbitRadius or you will only see the front half of your object and, depending on what it is, that might look weird.

Google maps api user can select area

I want to create a local map for my city where people can cover area with polygons and get their latitude and longitude
For Example there is a world map and someone come and he wanted to cover us then he can simply cover it and get its latitude and longitude of corners or borders
Is there any way or example i searched about it on google and Site both but didn't get Anything
Sorry I've no Codes i want idea, code or something helpful.
A simple search yielded http://www.the-di-lab.com/polygon/ and you can find a lot more samples at http://code.google.com/apis/maps/documentation/javascript/demogallery.html.
Unfortunately the above demo is a minified js. But the essential part of drawing a polygon (area) on google maps is to
1. load the map
2. trap the click events and the position (lat/lon)
3. draw lines
4. Finally when a double click is received, close the polygon
I unfortunately do not have a ready made sample in hand.
The answers here are quite outdated.
Google Maps now have a drawing library, This library allows the user to insert markers, circles, polygons and other types as well.
You can find an example on it here. And the library reference here.
And the documentation here.
It seems there is a simpler solution now. From the same demo gallery link that Muthu shared earlier look for user editable shapes. Below is a sample code from this link that draws a rectangle and allows user to edit the shape further
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 44.5452, lng: -78.5389},
zoom: 9
});
var bounds = {
north: 44.599,
south: 44.490,
east: -78.443,
west: -78.649
};
// Define a rectangle and set its editable property to true.
var rectangle = new google.maps.Rectangle({
bounds: bounds,
editable: true
});
rectangle.setMap(map);
}
Also here is an example on jsfiddle that extends above to generalized polygon and below is the code from the link
var editablePolygon = new google.maps.Polygon({
paths: coords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
editable: true });
Attached is a screenshot (after dragging one midpoint node in the triangle)
I think you need to use GeoChart
https://developers.google.com/chart/interactive/docs/gallery/geochart?csw=1. It can cover certain regions or areas

Google Maps zoom gets overridden, when using a kml file

How do I specify zoom level for google maps in a kml file or why is it that my zoom level gets over ridden when I load this file. My question is actually how do I control zoom of a map for the following link:
http://code.google.com/apis/maps/documentation/javascript/examples/layer-kml-features.html
By default, the map is centered and zoomed to the bounding box of the contents of the kml layer.
You can change the default behaviour with preserveViewport property of google.maps.KmlLayerOptions object. If you set it to true the map isn't centered and zoomed.
In the example, use:
var nyLayer = new google.maps.KmlLayer(
'http://www.searcharoo.net/SearchKml/newyork.kml',
{
suppressInfoWindows: true,
map: map,
preserveViewport: true
});
If you want to center and zoom to the contents of the kml layer later, use:
var bounds = nyLayer.getDefaultViewport();
map.fitBounds(bounds);
EDIT:
If you want the map to be always centered (but not zoomed) when the kml layer is loaded, utilize defaultviewport_changed event of the google.maps.KmlLayer object. You have to set the map center to the center of the kml layer default viewport. The event is triggered when the contents of the kml layer are loaded and its default viewport is computed.
google.maps.event.addListener(nyLayer, 'defaultviewport_changed', function() {
var bounds = nyLayer.getDefaultViewport();
map.setCenter(bounds.getCenter());
});