Openlayers: How to tell if a layer is available on the map - vector

I have a doubt. In openlayers, how should I know if a layer or map was added or not? For example, I have a layer control, to see if that layer is visible on the map.
In Leaflet I use it like this
my_layer_leaflet.on("add",function(){
);
And in openlayers?
var my_layer_openlayers = new ol.layer.Vector({
title: 'MyLayer',
visible: false,
style: new ol.style.Style({
image: new ol.style.Icon( ({
anchor: [0.5, 26],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'legend/image.png'
}))
}),
source: new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent) {
return layer_geoserver;
},
strategy: ol.loadingstrategy.all,
})
});

Place a single layer in a layerGroup an add a listener to the "change:layergroup" event:
var baseLayerGroup = new ol.layer.Group({layers: [layer_geoserver]});
map.on("change:layergroup", function() {console.log("LayerGroup changed.")});
map.setLayerGroup(baseLayerGroup);

Related

How to add outline for a GeometryInstance or PolygonGeometry in Cesiumjs

I need to draw outline to the polygon primitive drawn with following code :
scene.primitives.add( new Cesium.ClassificationPrimitive({
geometryInstances : new Cesium.GeometryInstance({
geometry : new Cesium.PolygonGeometry({
polygonHierarchy : new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray(coords)
),
height : height
}),
attributes : {
color: color,
},
id : id,
description : "Highlight Object",
})
}));
Is there any way to draw outline to a polygon primitive? I am aware that it can be added with Entities but the requirement is to use primitives.
Any help is much appreciated.
You can use PolylineCollection as a separate primitive for outline.
I created a demo in Sandcastle showing this use case:
var viewer = new Cesium.Viewer('cesiumContainer');
var coords = [
-72.0, 40.0,
-70.0, 35.0,
-75.0, 30.0,
-70.0, 30.0,
-68.0, 40.0
];
var cartesian = Cesium.Cartesian3.fromDegreesArray(coords);
var color = Cesium.Color.DARKRED;
var outlineColor = Cesium.Color.GOLD;
var polygonPrimitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
id: 'polygon',
geometry: Cesium.PolygonGeometry.createGeometry(
new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(cartesian)
})
)
}),
appearance: new Cesium.MaterialAppearance({
material: new Cesium.Material.fromType('Color', {
color: color
})
}),
asynchronous: false
});
var polylinePrimitive = new Cesium.PolylineCollection();
polylinePrimitive.add({
positions: cartesian,
width: 3.0,
loop: true,
material: new Cesium.Material.fromType('Color', {
color: outlineColor
})
});
var primitives = viewer.scene.primitives;
primitives.add(polygonPrimitive);
primitives.add(polylinePrimitive);

Openlayers 3 Reproject EPSG:4326 vector to EPSG:3857

I am needing to transform GeoJSON vector data from EPSG:4326 to EPSG:3857...
I have a map...
var olMapDiv = document.getElementById('olmap');
control.map = new ol.Map({
target: olMapDiv,
renderer: 'canvas',
layers: layers,
interactions: ol.interaction.defaults({
altShiftDragRotate: false,
dragPan: false,
rotate: false
}).extend([new ol.interaction.DragPan({ kinetic: null })]),
pixelRatio: 1,
loadTilesWhileAnimating: true,
loadTilesWhileInteracting: true,
view: view
});
and a view...
var view = new ol.View({
// make sure the view doesn't go beyond the 22 zoom levels of Google Maps
maxZoom: 21,
projection: 'EPSG:3857',
center: [0, 0],
zoom: 0
});
I define my geoJson Object...
var geoJsonObj = {
'type': 'Feature',
'geometry': JSON.parse(shape),
'name': 'V',
'id': V.vID
}
I try to read the features into a open layers Vector object and provide projection parameters...
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geoJsonObj, {defaultDataProjection:"EPSG:4326",featureProjection:"EPSG:3857"})
});
Then I use the "vectorSource" above in a new Vector layer...
vectors = new ol.layer.Vector({
title: V.vID,
source: vectorSource,
id: V.vID,
name: 'V',
label: response.VList[key].Acres,
fill: response.VList[key].Shade,
stroke: defaultStrokeHex,
style: function (feature, resolution) {
var text = resolution * 100000 < 10 ? response.VList[key].Acres : '';
if (text != "") {
styleCache[text] = [new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#319FD3',
width: 1
}),
text: new ol.style.Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new ol.style.Fill({
color: '#000'
}),
stroke: new ol.style.Stroke({
color: '#fff',
width: 3
})
}),
fill: new ol.style.Fill({
color: rcisWebMapUtilities.convertHex(response.VList[key].Shade, '0.5')
})
})];
}
else if (text == "") {
styleCache[text] = [new ol.style.Style({
fill: new ol.style.Fill({
color: rcisWebMapUtilities.convertHex(response.VList[key].Shade, '0.5')
})
})
]
} return styleCache[text];
}
});
No matter what I do I either see the vector drawn...but in EPSG:4326 or nothing loads...
I've spent way too much time trying to figure out how to get OpenLayers3 to do this...Any help is greatly appreciated!!
If you use EPSG:4326 in your view then your geojson vector declaration should be
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
dataProjection: 'EPSG:4326',
featureProjection:'EPSG:4326' })
});
If you use EPSG:3857 in your view use this:
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
dataProjection: 'EPSG:4326',
featureProjection:'EPSG:3857' })
});
Just to explain dataProjection is the source coords. Means the epsg of your coordinates within the geojson file. While featureProjection is the EPSG of your view and thus the EPSG of your map. Means is the EPSG original coords should be trasformed.
So try to remember this rule: featureProjection and ol.View projection declaration should be equal.
Note that I am assuming your geojson coords are projected in EPSG:4326.

How to include image to twig using Openlayers 3 script in symfony 2.8?

How to include image to twig using Openlayers 3 script in symfony 2.8 ?
Nor asset, nor referencing from root, nor referencing from the current directory does not work.
src: "{{ asset('bundles/meeting/images/google-map-pointer-grey.svg') }}" // does not work
src: "{{ asset('/bundles/meeting/images/google-map-pointer-grey.svg') }}" // does not work
src: "/bundles/meeting/images/google-map-pointer-grey.svg" // from root directory also does no work
src: "../../../images/google-map-pointer-grey.svg" // referencing from the current directory also does no work
Code is from the example :
http://openlayers.org/en/v3.2.1/examples/drag-features.html
I just have used different map, which works and is displayed, used only one feature - point with different coordinates, which does not work, it is not displayed on the map.
//twig template
<script>
window.onload = function() {
var lat = document.getElementById('edit_form.latitude').value;
var lon = document.getElementById('edit_form.longitude').value;
var pointM = [ parseFloat(lon), parseFloat(lat) ];
var pointMWebMercator = ol.proj.fromLonLat( pointM, 'EPSG:3857' );
console.log( ' pointMWebMercator m= '+ pointMWebMercator);
var pointFeature = new ol.Feature(new ol.geom.Point(pointMWebMercator));
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([new app.Drag()]),
target: 'Openmap', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
size: [200, 200],
layers: [
new ol.layer.Tile({ source: new ol.source.OSM() }),
new ol.layer.Vector({
source: new ol.source.Vector({
features: [pointFeature]
}),
style: new ol.style.Style({
image: new ol.style.Icon( ({
// #type {olx.style.IconOptions}
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.95,
src: "{{ asset('bundles/meeting/images/google-map-pointer-grey.svg') }}" // does not work
// src: "{{ asset('/bundles/meeting/images/google-map-pointer-grey.svg') }}" // does not work
// src: "/bundles/meeting/images/google-map-pointer-grey.svg" // from root directory also does no work
// src: "../../../images/google-map-pointer-grey.svg" // referencing from the current directory also does no work
}) ),
// A leading slash tells the browser to start at the root directory.
//// i can get the root directory from//print_r("SERVER[DOCUMENT_ROOT]".$_SERVER['DOCUMENT_ROOT']);
//// for symfony it is project/web
// If you don't have the leading slash, you're referencing from the current directory.
// If you add two dots before the leading slash, it means you're referencing the parent of the current directory.
stroke: new ol.style.Stroke({
width: 3,
color: [255, 0, 0, 1]
}),
fill: new ol.style.Fill({
color: [0, 0, 255, 0.6]
})
})
})
],
view: new ol.View({
center: pointMWebMercator,
zoom: 14
})
});
Twig has nothing to do with embedding openlayers. As it's a javascript library.
Twig executes and generates HTML in server side. OpenLayer script is supposed to be executed in client side.
Also, The openlayers document is pretty self explanatory.

Dragging Markers in Leaflet in Meteors realtime-environment

I want draggable markers on a Leaflet map and distribute their new locations in realtime to the clients. I use meteor. To achieve this I observe the marker-collection.
This is what I've tried so far but it crashes when I drag one marker. The selected marker disappears as it should but it won't rerender the markersGroup on the map.
var newMarker;
var markers = [];
Happening.find({}).observe({
added: function(marker) {
var myIcon;
myIcon = L.icon({
iconUrl: "icon_33997.svg"
});
newMarker = L.marker([marker.location.coordinates[1],marker.location.coordinates[0]], {
icon: myIcon,
_id: marker._id,
draggable: true
});
newMarker.on('dragend', function (e){
var newCoords = this.getLatLng();
var happeningOld = Happening.find({_id: e.target.options._id}).fetch();
return Happening.update({_id: e.target.options._id}, {
item: happeningOld[0].item,
location: {
type: 'Point',
coordinates: [newCoords.lng, newCoords.lat]
},
time: Date.now(),
owner: happeningOld[0].owner
});
});
markers[newMarker.options._id] = newMarker;
markersGroup.addLayer(newMarker);
return map.addLayer(markersGroup);
},
changed: function(marker){
map.removeLayer(markersGroup);
markersGroup.removeLayer(markers[marker._id]);
markersGroup.addLayer(markers[marker._id]);
return map.addLayer(markersGroup);
}
});
This is the crash-report:
Exception in queued task: L.DistanceGrid.prototype._sqDist#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
L.DistanceGrid.prototype.getNearObject#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
L.MarkerClusterGroup<._addLayer#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
L.MarkerClusterGroup<.addLayers/l<#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
o.Util.bind/<#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:37
L.MarkerClusterGroup<.addLayers#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
L.MarkerClusterGroup<.onAdd#http://localhost:3000/packages/leaflet-markercluster.js?d3d9bebcb9f8a1b1711174aea16a51003ba02d10:36
o.Map<._layerAdd#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:37
o.Map<.addLayer#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:37
Template.map.rendered/<.changed#http://localhost:3000/where-to-go.js?1b666a1c77f7d81e0212a2c65aa72a9d570b4dac:287
LocalCollection._observeFromObserveChanges/observeChangesCallbacks.changed#http://localhost:3000/packages/minimongo.js?4ee0ab879b747ffce53b84d2eb80d456d2dcca6d:3845
LocalCollection._CachingChangeObserver/self.applyChange.changed#http://localhost:3000/packages/minimongo.js?4ee0ab879b747ffce53b84d2eb80d456d2dcca6d:3750
.observeChanges/wrapCallback/</<#http://localhost:3000/packages/minimongo.js?4ee0ab879b747ffce53b84d2eb80d456d2dcca6d:374
.runTask#http://localhost:3000/packages/meteor.js?148e9381d225ecad703f4b858769b636ff7a2537:576
.flush#http://localhost:3000/packages/meteor.js?148e9381d225ecad703f4b858769b636ff7a2537:604
.drain#http://localhost:3000/packages/meteor.js?148e9381d225ecad703f4b858769b636ff7a2537:612
LocalCollection.prototype.update#http://localhost:3000/packages/minimongo.js?4ee0ab879b747ffce53b84d2eb80d456d2dcca6d:732
#http://localhost:3000/packages/mongo-livedata.js?cf17a2975aa7445f0db2377c2af07e5efc240958:730
.apply/ret<#http://localhost:3000/packages/livedata.js?7f11e3eaafcbe13d80ab0fb510d25d9595e78de2:3818
.withValue#http://localhost:3000/packages/meteor.js?148e9381d225ecad703f4b858769b636ff7a2537:794
.apply#http://localhost:3000/packages/livedata.js?7f11e3eaafcbe13d80ab0fb510d25d9595e78de2:3810
Meteor.Collection.prototype[name]#http://localhost:3000/packages/mongo-livedata.js?cf17a2975aa7445f0db2377c2af07e5efc240958:531
Template.map.rendered/<.added/<#http://localhost:3000/where-to-go.js?1b666a1c77f7d81e0212a2c65aa72a9d570b4dac:272
o.Mixin.Events.fireEvent#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:37
o.Handler.MarkerDrag<._onDragEnd#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:40
o.Mixin.Events.fireEvent#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:37
o.Draggable<._onUp#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:39
o.DomEvent.addListener/s#http://localhost:3000/packages/leaflet.js?ad7b569067d1f68c7403ea1c89a172b4cfd68d85:39
Ok, nearly got it. The thing is that the error is created by the MarkerCluster plugin. When I exclude it, it works with the following approach:
var newMarker;
Happening.find({}).observe({
added: function(marker) {
markerInit(marker);
markers[newMarker.options._id] = newMarker;
return map.addLayer(newMarker)
},
changed: function(marker){
map.removeLayer(markers[marker._id]);
markerInit(marker);
markers[newMarker.options._id] = newMarker;
map.addLayer(markers[marker._id]);
}
});
markerInit() sets up the markers like my code before does. I'm still not sure how to get it with MarkerCluster working.

Sencha Touch: Ext.Map within TabPanel

I'm quite new to sencha touch. The goal is to create an app which has a TabPanel containing four Tabs, one of them should be a map (the others are a NestedList and two Panels working like a charm). I've tried to make the map card like
NPApp.views.Mapcard = Ext.extend(Ext.Map, { ...
where I ended up with getting really strange results like some views are overlapping and no map is shown.
The second try was to creating a Panel, embed it into the TabPanel and add a map to the panel, where I get this error:
Uncaught TypeError: Cannot read property 'ROADMAP' of undefined;
sencha-touch-debug.js:24840
I've already tried to change the mapType to google.map.MapTypeID like mentioned in the Google Map API V3, no success there.
I just can't get the hang on it, hope you can give me some hints!
The App:
NPApp = new Ext.Application({
name: "NPApp",
title: "NextPuff",
icon: 'images/icon.png',
tabletStartupScreen: 'images/index_default.jpg',
phoneStartupScreen: 'images/index_default.jpg',
launch: function() {
this.views.viewport = new this.views.Viewport();
this.views.homecard = this.views.viewport.getComponent('navi');
}
});
The Viewport:
NPApp.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
store: NPApp.npstore,
initComponent: function() {
Ext.apply(this, {
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{ xtype: 'homecard', stretch: true},
{ xtype: 'searchcard', id: 'navi' },
{ xtype: 'mapcard' },
{ xtype: 'morecard' }
]
});
NPApp.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});
The Mapcard:
NPApp.views.Mapcard = Ext.extend(Ext.Panel, {
title: "Map",
iconCls: "map",
initComponent: function() {
var npMap = new Ext.Map({
title: 'Map',
useCurrentLocation: true,
listeners: {
centerchange : function(comp, map){
// refreshMap(map);
}
},
mapOptions : {
mapTypeControl : false,
navigationControl : false,
streetViewControl : false,
backgroundColor: 'transparent',
disableDoubleClickZoom: true,
zoom: 17,
draggable: false,
keyboardShortcuts: false,
scrollwheel: false
}
});
Ext.apply(this, {
defaults: {
styleHtmlContent: true
},
items: [npMap]
});
NPApp.views.Homecard.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('mapcard', NPApp.views.Mapcard);
Sencha 1.1.0; Google JavaScript Maps API V3; Safari 5.1
I have a similar application running. Your tabpanel is perfect. All you need to alter is your map code.... Try this instead :
var map = new Ext.Map({
mapOptions : {
center : center,
zoom : 20,
mapTypeId : google.maps.MapTypeId.HYBRID,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.DEFAULT
}
},
listeners : {
maprender : function(comp, map){
var marker = new google.maps.Marker({
position: center,
//title : 'Sencha HQ',
map: map
});
setTimeout( function(){map.panTo (center);} , 1000);
}
},
geo:new Ext.util.GeoLocation({
autoUpdate:true,
maximumAge: 0,
timeout:2000,
listeners:{
locationupdate: function(geo) {
center = new google.maps.LatLng(geo.latitude, geo.longitude);
if (map.rendered)
map.update(center)
else
map.on('activate', map.onUpdate, map, {single: true, data: center});
},
locationerror: function ( geo,
bTimeout,
bPermissionDenied,
bLocationUnavailable,
message) {
if(bLocationUnavailable){
alert('Your Current Location is Unavailable on this device');
}
else{
alert('Error occurred.');
}
}
}
})
});
This creates the map object and sets the center to ur current location. Now you need to dock this object inside an Ext.extend(Ext.Panel({}) object. Ive tried directly creating the map object but it needs a panel to display on.
So you're panel code should go something like so:
NPApp.views.Mapcard = new Ext.extend(Ext.Panel({
iconCls : 'map',
title : 'Map',
layout: 'card',
ui: 'light',
items: [map],
listeners:{
}
});
)
It took me ages of going thru a dozen or more examples to make the current location work. This is a combination of several codes and a bunch of stuff in the Google API.
Lemme know if you have any more questions about Google Maps or directions.
Cheers :)
Sasha

Resources