I donnot know how to draw multiple wholes into a polygon with Nokia Maps API v2.
Here is an example in Google Maps API v3
Nokia Maps API v2#Polygon
Any help would be much appreciated,Thanks!
The HERE Maps API doesn't support cutouts directly, so the best way to do this is to build up the annulus in parts - e.g. the bottom half and the top half in separate objects. If you ensure that the lineWidth property of the Polygons is zero then you won't get an outline.
The following creates a rectangle with a hole as shown - just increase the number of points to make a ring.
// Set of initial geo coordinates to create the purple polyline
var points = [
new nokia.maps.geo.Coordinate(50.0, 8.0),
new nokia.maps.geo.Coordinate(50.1, 8.0),
new nokia.maps.geo.Coordinate(50.1, 8.1),
new nokia.maps.geo.Coordinate(50.0, 8.1),
new nokia.maps.geo.Coordinate(50.0, 8.0)
];
// Transparent purple polyline
map.objects.add(new nokia.maps.map.Polyline(
points,
{
pen: {
strokeColor: "#22CA",
lineWidth: 5
}
}
));
// Transparent green polygon with black border
map.objects.add(new nokia.maps.map.Polygon(
[
new nokia.maps.geo.Coordinate(50.0, 8.0),
new nokia.maps.geo.Coordinate(50.1, 8.0),
new nokia.maps.geo.Coordinate(50.1, 8.02),
new nokia.maps.geo.Coordinate(50.0, 8.02)
],
{
pen: { strokeColor: "#000", lineWidth: 0 },
brush: { color: "#2C2A" }
}
));
map.objects.add(new nokia.maps.map.Polygon(
[
new nokia.maps.geo.Coordinate(50.0, 8.08),
new nokia.maps.geo.Coordinate(50.1, 8.08),
new nokia.maps.geo.Coordinate(50.1, 8.1),
new nokia.maps.geo.Coordinate(50.0, 8.1)
],
{
pen: { strokeColor: "#000", lineWidth: 0 },
brush: { color: "#2C2A" }
}
));
map.objects.add(new nokia.maps.map.Polygon(
[
new nokia.maps.geo.Coordinate(50.0, 8.02),
new nokia.maps.geo.Coordinate(50.02, 8.02),
new nokia.maps.geo.Coordinate(50.02, 8.08),
new nokia.maps.geo.Coordinate(50.0, 8.08)
],
{
pen: { strokeColor: "#000", lineWidth: 0 },
brush: { color: "#2C2A" }
}
));
map.objects.add(new nokia.maps.map.Polygon(
[
new nokia.maps.geo.Coordinate(50.1, 8.02),
new nokia.maps.geo.Coordinate(50.08, 8.02),
new nokia.maps.geo.Coordinate(50.08, 8.08),
new nokia.maps.geo.Coordinate(50.1, 8.08)
],
{
pen: { strokeColor: "#000", lineWidth: 0 },
brush: { color: "#2C2A" }
}
));
Related
Openlayers Draw Interaction
Above is the link to the Openlayers interaction that I'm using. I want to use this interaction to limit users to only draw a north aligned bounding box. Out of the box that's not how the Draw interaction functions. Is there a way to enforce the drawing to be that of a north aligned bounding box? Or is there a means of making the draw interaction behave as the Extent Interaction?
Openlayers Extent Interaction
I'm using the latest version of Openlayers and here is my draw interaction configuration:
const styles = [
new Style({
stroke: new Stroke({
color: '#017e01',
width: 2.25,
}),
fill: new Fill({
color: 'rgba(36, 37, 42, .25)',
}),
}),
];
const source = new VectorSource();
const vector = new VectorLayer({
projection: 'ESPG4326',
source,
style: new Style({
fill: new Fill({
color: 'rgba(36, 37, 42, .25)',
}),
stroke: new Stroke({
color: '#017e01',
width: 2,
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: '#017e01',
}),
}),
}),
});
const draw = new Draw({
style: styles,
source,
condition: olEvents.shiftKeyOnly,
type: 'Polygon',
});
I'm trying to code a modified version of this example.
Using vanilla Javascript all is working fine, but now I'm trying to move it to React and the popup doesn't follow the map when I zoom in or zoom out the map. I suppose that the popup is not linked to the map overlay, but it's totally disconnected from it and this should be the problem, but I don't know how to fix it:
This is my code:
import 'ol/ol.css';
import React, { Component } from "react";
import ReactDOM from 'react-dom';
import Map from 'ol/Map';
import View from 'ol/View';
import Overlay from 'ol/Overlay';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
import { OSM, Vector as VectorSource } from 'ol/source';
import { Circle as CircleStyle, Icon, Fill, Stroke, Style, Text } from 'ol/style';
import GeoJSON from 'ol/format/GeoJSON';
import * as olExtent from 'ol/extent';
import $ from 'jquery';
import 'bootstrap';
import markerLogo from './marker.png';
class PublicMap extends Component {
constructor(props) {
super(props);
var shapeDisciplinare = this.props.geoJson;
var iconStyle = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: markerLogo
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff', width: 2
})
})
});
var getStyles = function (feature) {
var myStyle = {
'Point': iconStyle,
'Polygon': new Style({
stroke: new Stroke({
color: 'blue',
width: 3
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)'
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff', width: 2
}),
text: feature.getProperties().denominazione
})
})
};
return [myStyle[feature.getGeometry().getType()]];
};
var raster = new TileLayer({
source: new OSM()
});
var source = new VectorSource();
var vector = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new Stroke({
color: '#ffcc33',
width: 2
}),
image: new CircleStyle({
radius: 7,
fill: new Fill({
color: '#ffcc33'
})
})
})
});
vector.setZIndex(1);
this.olmap = new Map({
layers: [raster, vector],
target: null,
view: new View({
center: [-11000000, 4600000],
zoom: 4
})
});
var reader = new GeoJSON({
defaultDataProjection: 'EPSG:3857',
Projection: 'EPSG:3857'
});
var projector = {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
};
let shapeDisciplinareJson = JSON.parse(shapeDisciplinare);
var vectorSource = new VectorSource({
features: reader.readFeatures(shapeDisciplinareJson, projector)
});
var vectorLayer = new VectorLayer({
source: vectorSource,
style: getStyles
});
this.state = { vs: vectorSource, vl: vectorLayer };
}
componentDidMount() {
this.olmap.setTarget("map");
var extent = olExtent.createEmpty();
extent = olExtent.extend(extent, this.state.vs.getExtent());
this.olmap.addLayer(this.state.vl);
this.olmap.getView().fit(extent, this.olmap.getSize());
this.olmap.getView().setZoom(8);
var element = document.getElementById('popup');
this.popup = new Overlay({
element: ReactDOM.findDOMNode(this).querySelector('#popup'),
positioning: 'bottom-center',
stopEvent: false,
offset: [0, -50]
});
// display popup on click
this.olmap.on('click', (evt) => {
var feature = this.olmap.forEachFeatureAtPixel(evt.pixel,
(feature) => {
return feature;
});
if (feature) {
var coordinates = feature.getGeometry().getCoordinates();
//if lenght is 2, then is a gps location, otherwise a shape
if (coordinates.length === 2) {
this.popup.setOffset([0, -50]);
this.popup.setPosition(coordinates);
} else {
this.popup.setOffset([0, 0]);
this.popup.setPosition(evt.coordinate);
}
this.olmap.addOverlay(this.popup);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.getProperties().denominazione
});
$(element).attr('data-content', feature.getProperties().denominazione);
$(element).popover('show');
} else {
$(element).popover('hide');
}
});
// change mouse cursor when over marker
this.olmap.on('pointermove', (e) => {
if (e.dragging) {
$(element).popover('hide');
return;
}
var pixel = this.olmap.getEventPixel(e.originalEvent);
var hit = this.olmap.hasFeatureAtPixel(pixel);
this.olmap.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
}
componentWillUnmount() {
this.map.setTarget(null);
}
render() {
return (
<div id="map" style={{ width: "100%", height: "360px" }}>
<div id="popup"></div>
</div>
);
}
}
export default PublicMap;
How can I delete a created shape in Google Map DrawingManager?
<DrawingManager
// defaultDrawingMode={google.maps.drawing.OverlayType.}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
// google.maps.drawing.OverlayType.POLYLINE,
// google.maps.drawing.OverlayType.RECTANGLE,
],
},
circleOptions: {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
draggable: true,
editable: true,
},
polygonOptions: {
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.3,
draggable: true,
editable: true,
},
}}
onOverlayComplete={this.handleOverlayComplete}
/>
When creating an shape via drawing manager (google map), after creating it, I want to delete that one but I'm having difficulties on that one.
ReactJS
To manipulate drawn shapes the following approach could be considered:
introduce shapes variable to keep a reference to drawn shapes:
class Map extends Component {
constructor(props) {
super(props);
this.shapes = [];
}
//...
}
once overlaycomplete event is triggered, save drawn shape:
handleOverlayComplete(e) {
const shape = e.overlay;
shape.type = e.type;
google.maps.event.addListener(shape, "click", () => {
this.toggleSelection(shape);
});
this.toggleSelection(shape);
this.shapes.push(shape)
}
and finally drawn shapes could be deleted from map like this:
deleteShapes() {
this.state.shapes.forEach(shape => shape.setMap(null));
}
Here is a demo for your reference
Note: in the provided demo to delete shapes:
select stop drawing mode by clicking hand cursor button
click map (outside bounds of shape)
I'm using Angular-Leaflet-directive and geojson for my markers and I'm having difficulties adding custom markers. I am able to style line/polygons using the style property but no such luck with adding custom icons
e.g. styling line/polygons
angular.extend($scope, {
geojson: {
data: data,
style: {
fillColor: "green",
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
}
}
});
e.g. attempting to add custom icons for my markers:
var myIcons = {
div_icon: {
type: 'div',
iconSize: [12, 12],
html: '<circle cx="10" cy="10" r="8" stroke="black" stroke-width="1" fill="green" />',
popupAnchor: [0, 0]
},
redPin: {
iconUrl: 'images/mapPinRed.png',
iconSize: [38, 95],
iconAnchor: [22, 94]
}
};
angular.extend($scope, {
geojson: {
data:data,
style: {icon: myIcons.redPin}
}
});
It turns out that in angular-leaflet-directive_v0.7.6 there is no "pointToLayer" for the geojson data, added "pointToLayer:geojson.pointToLayer"
eg angular-leaflet-directive
//...
geojson.options = {
style: geojson.style,
onEachFeature: onEachFeature,
pointToLayer:geojson.pointToLayer
};
It turns out that v0.8 has this feature
e.g. adding the icon
var myIcon = { iconUrl:'images/mapPinRed.png',
iconSize:[25, 25],
iconAnchor:[12, 0]})
};
angular.extend($scope, {
geojson: {
data:data,
style:
function (feature) {return {};},
pointToLayer: function(feature, latlng) {
return new L.marker(latlng, {icon: L.icon(myIcon);
},
onEachFeature: function (feature, layer) {
layer.bindPopup("number: " +feature.properties.something);
}
} //geojson
});
launch: function() {
// The following is accomplished with the Google Map API
var position = new google.maps.LatLng(12.9833, 77.5833), //Sencha HQ
infowindow = new google.maps.InfoWindow({
content: 'bengaluru'
}),
//Tracking Marker Image
image = new google.maps.MarkerImage(
'resources/images/point.png',
new google.maps.Size(32, 31),
new google.maps.Point(0, 0),
new google.maps.Point(16, 31)
),
shadow = new google.maps.MarkerImage(
'resources/images/shadow.png',
new google.maps.Size(64, 52),
new google.maps.Point(0, 0),
new google.maps.Point(-5, 42)
),
trackingButton = Ext.create('Ext.Button', {
iconMask: true,
iconCls: 'locate'
}),
trafficButton = Ext.create('Ext.Button', {
iconMask: true,
pressed: true,
iconCls: 'maps'
}),
toolbar = Ext.create('Ext.Toolbar', {
docked: 'top',
ui: 'light',
defaults: {
iconMask: true
},
items: [
{
xtype:'button',
id:'calculate',
text:'calculate',
handler:function(){
alert('hello');
}
}
]
});
var mapdemo = Ext.create('Ext.Map', {
mapOptions : {
center : new google.maps.LatLng(37.381592, 122.135672), //nearby San Fran
zoom : 12,
mapTypeId : google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
plugins : [
new Ext.plugin.google.Tracker({
trackSuspended: true, //suspend tracking initially
allowHighAccuracy: false,
marker: new google.maps.Marker({
position: position,
title: 'My Current Location',
shadow: shadow,
icon: image
})
}),
new Ext.plugin.google.Traffic()
],
listeners: {
maprender: function(comp, map) {
var marker = new google.maps.Marker({
position: position,
title : 'Sencha HQ',
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
setTimeout(function() {
map.panTo(position);
}, 1000);
}
}
});
Any ideas how can i measure distance between two destinations whose latitude and longitude are know........
this code is taken from the example provided by the sencha touch2 with little modification.
Its for sencha touch 2
try google.maps.geometry.spherical.computeDistanceBetween(from:LatLng, to:LatLng, radius?:number)
radius is the earth's radius = 6371000 metres (average)