OpenLayers 3 in Qooxdoo Mobile App - qooxdoo

In preparation for the upcoming OpenLayers 3 release, I tried to get the basic map example to work in a Qooxdoo mobile app.
I used the Qooxdoo mobileshowcase demo map as a starting point, but after many hours of trying I cannot get the map to appear.
For brevity, I included the ol3 css
<link rel="stylesheet" href="http://ol3js.org/en/master/css/ol.css" type="text/css">
I left the whole Maps.js class the same except replaced the mapUri with the OL3 one:
_mapUri : "http://ol3js.org/en/master/build/ol.js",
and then replaced _loadMapLibrary with:
_loadMapLibrary : function() {
var req = new qx.bom.request.Script();
req.onload = function() {
var map = new ol.Map({
target: 'osmMap',
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
})
],
view: new ol.View({
center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
}.bind(this);
req.open("GET", this._mapUri);
req.send();
},
it seems like it should work...

The trick was to add these two lines:
mapContainer.setId("map");
mapContainer.addCssClass("map");
in this override:
// overridden
_createScrollContainer : function()
{
// MapContainer
var layout = new qx.ui.mobile.layout.VBox().set(
{
alignX : "center",
alignY : "middle"
});
var mapContainer = new qx.ui.mobile.container.Composite(layout);
mapContainer.setId("map");
mapContainer.addCssClass("map");
return mapContainer;
},

Related

Limit Area to 10km from the center point - OpenLayers Map

I am using OpenLayers Library for Showing some specific points on Map. I want to show only 10km area from the center point. Can any one help me doing this?
Here is the snippet of my code.
var map = new Map({
layers: [
new TileLayer({
source: new OSM()
}),
vectorLayer
],
target: 'map',
view: new View({
center: transform([19.83752162, 52.09696925], 'EPSG:4326', 'EPSG:3857'),
zoom: 12,
})
});
To achieve this you have to do some pre-processing before map initializing.
1- Make feature from center coordinates.
let pointFeature = new ol.Feature(
new ol.geom.Point(transform([19.83752162, 52.09696925], 'EPSG:4326', 'EPSG:3857'))
);
2- Get extent of above created feature.
let poitnExtent = pointFeature.getGeometry().getExtent();
3- Buffer the extent to your desired radius.
let bufferedExtent = new ol.extent.buffer(poitnExtent, raduis goes here (In meters));
4- Use this buffered extent to initialize map.
var map = new Map({
layers: [
new TileLayer({
source: new OSM()
}),
vectorLayer
],
target: 'map',
view: new View({
center: transform([19.83752162, 52.09696925], 'EPSG:4326', 'EPSG:3857'),
extent: bufferedExtent,
zoom: 12,
})
});

LeafletJS not loading all tiles until moving map

I am trying to load a simple leaflet map in my Ionic 2 app. Unfortunately not all tiles are loaded currectly until a moving the map.
this.map = new L.Map('mainmap', {
zoomControl: false,
center: new L.LatLng(40.731253, -73.996139),
zoom: 12,
minZoom: 4,
maxZoom: 19,
layers: [this.mapService.baseMaps.OpenStreetMap],
attributionControl: false
});
There are a couple of solutions for this problem:
1- Add "./node_modules/leaflet/dist/leaflet.css" in the styles array in `angular.json'.
2- Invalidate size when a map is ready:
onMapReady(map: L.Map) {
setTimeout(() => {
map.invalidateSize();
}, 0);
}
Add this to your template:
<div style="height: 300px;"
leaflet
(leafletMapReady)="onMapReady($event)">
</div>
And this will bind onMapReady method which you have in your component.
3- Install Leaflet typings for Typescript:
npm install --save-dev #types/leaflet
Vanilla JavaScript:
1- Validate the size of map:
onMapReady(map: L.Map) {
setTimeout(() => {
map.invalidateSize();
}, 0);
}
2- Add leaflet stylesheet leaflet/dist/leaflet.css in the <head> of your document.
this work for me fine :
this.map = L.map('map');
const self = this;
this.map.on("load",function() { setTimeout(() => {
self.map.invalidateSize();
}, 1); });
this.map.setView([36.3573539, 59.487427], 13);
Just put the creation of the map into the Ionic ionViewDidEnter lifecycle method. Much cleaner than any setTimeout hack ;)
import { Map, tileLayer } from 'leaflet';
...
ionViewDidEnter(): void {
this.map = new Map('map', {
center: [48.1351, 11.5819],
zoom: 3
});
const tiles = tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
minZoom: 3,
attribution: '© OSM'
});
tiles.addTo(this.map);
}

How to change map in openlayer example with own geoJson map?

I want to use the pre coded example popup http://openlayers.org/en/latest/examples/popup.html for MY map. I have a .shp (shape file) converted to GEOJSON format. I want the code to be replaced for adding same type of pop up to my map.
note:i altered this code n changed url. but this doesn't work.
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileJSON({
url: 'http://api.tiles.mapbox.com/v3/' +
'mapbox.natural-earth-hypso-bathy.json',
crossOrigin: 'anonymous'
})
})
],
overlays: [overlay],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});

Making JointJs & Backbone/Marionette work with collections (HTML items inside)

Let me know if you can help me out somehow, i'm kind of struggling to get my head around.
Starting with some Marionette application logics:
app.js
//basic setup
this.Graph = new joint.dia.Graph;
this.Paper = new joint.dia.Paper({ width: 640, height: 480, model: this.Graph });
// [...] lots of code
//adding elements
app.Elements.add(element);
So far so good. Now the tricky part. I want a collection.
JointCollectionView.js
module.exports = Marionette.CollectionView.extend({
tagName: 'div',
className: 'row',
childView: JointView,
addChild: function(child, ChildView, index){
//does that make sense?
app.Graph.addCell(child);
//should i add it to collection?
if (child.shouldBeShown()) {
return Marionette.CollectionView.prototype.addChild.call(this, child, ChildView, index);
}
},
getChildView: function(item) {
return app.Graph.getCell(item);
}
//[...]
})
Now even more tricky. How do i handle the joint-view to make it work with collections and also display html elements?
JointView.js
module.exports = joint.dia.ElementView.extend({ /* ?!?!?! */ });
//OR ?
module.exports = Marionette.ItemView.extend({
jointElementView: null, //this will be like above somewhere else...
initialize: function(options){
jointElementView = new JointElementView({ /* ... */ });
}
})
I'm no JointJS expert, but your implementation looks perfect.
You want to use the second option:
JointView.js
module.exports = Marionette.ItemView.extend({
template: _.template("");
jointElementView: null, //this will be like above somewhere else...
initialize: function(options){
this.jointElementView = new JointElementView({ /* ... */ });
}
});
since a Marionette.CollectionView expects a Marionette view (sp. a Marionette.ItemView or descendent [LayoutView/CompositeView]).
What I would add to JointView.js is a method to inject the result from this.jointElementView into the JointView.js html. So, add a property to it, like:
onRender: function () {
this.$el.append(this.jointElementView.el); // Where this.jointElementView.el is the JointJS view html
}
With the help of #seebiscuit i looked much deeper into jointjs and narrowed down how i should approach this problem (You didn't seem to be interested in the points though, so i'll answer myself)
The following files were edited:
app.js (changed, important!)
//this step is necessary to create these element before the paper is created.
//Make jointjs GLOBAL!!!!!!
joint.shapes.html = {};
joint.shapes.html.Element = require('views/Element'); //this dude im gonna use to create the elements
joint.shapes.html.ElementView = require('views/ElementView'); //this badboy will fire when i create those elements. MAGIC!
//basic setup
this.Graph = new joint.dia.Graph;
this.Paper = new joint.dia.Paper({ width: 640, height: 480, model: this.Graph });
// [...] lots of code
//adding elements
app.Elements.add(element);
JointCollectionView.js (beauti-/simplyfied)
module.exports = Marionette.CollectionView.extend({
tagName: 'div',
className: 'row',
childView: JointView,
onRender: function(){
// jointjs' paper is added here long after jointjs custom element init.
this.el.appendChild(app.Paper.el);
},
onDestroy: function(){
// removal of the paper is done here
this.el.removeChild(app.Paper.el);
},
buildChildView: function(child, JointView, childViewOptions){
// add model, jointjs' paper and graph into JointView's options
var options = _.extend({model: child}, childViewOptions);
options = _.extend({paper: app.Paper, graph: app.Graph}, options);
return new JointView(options);
}
//[...]
})
JointView.js (magic here!)
module.exports = Marionette.ItemView.extend({
tagName: 'div',
className: 'html-element',
template: "#agentTmpl",
// store here just in case
cell: null,
// [...]
initialize: function() {
// initialize joinjs element-shape here
Marionette.bindEntityEvents(this, this.model, this.modelEvents);
if(this.cell == null){
//notice `el: this.el` This will actually pass the option el to ElementView. Surprised?
//Yeah me too. From there i can do with the dom-element whatever i want
this.cell = new joint.shapes.html.Element({ el: this.el, position: { x: 80, y: 80 }, size: { width: 250 } });
}
},
onRender: function(){
// after rendering add cell to graph
this.options.graph.addCell(this.cell);
},
onDestroy: function(){
// after removal remove cell from graph
this.cell.remove();
}
});
Element.js
ElementView.js
For simplicity more or less like here: http://www.jointjs.com/tutorial/html-elements
To summarize what actually happens is: whenever a new Element is created ElementView will fire all necessary event (initialize, render & whatnot). From there you can manipulate the drawn svg elements or overlap (similar to the tutorial) with my previously created JointView's html. I basically put my JointView dom-element over the SVG which is drawn by jointjs.
There you go. Fixed!

openlayers inside qooxdoo JS framework

i´m using the openlayers drawing example inside my mobile JS (qooxdoo) app and all works fine except that the drawing cursor is above the viewport
so I can draw but I don´t see the cursor and I can only see the drawing after I scroll down.
I have used this qooxdoo example as a base. I have also added all the css rules from the openlayers example to my qooxdoo styles.
Seems like a css position issue, but I can´t seem to find it.
Any help would be appreciated.
/**
* Loads JavaScript library which is needed for the map.
*/
_loadMapLibrary: function() {
var self = this;
var req = new qx.bom.request.Script();
var options = {
singleTile: true,
ratio: 1,
isBaseLayer: true,
wrapDateLine: true,
getURL: function() {
var center = self._map.getCenter().transform("EPSG:3857", "EPSG:4326"),
size = self._map.getSize();
return [
this.url, "&center=", center.lat, ",", center.lon, "&zoom=", self._map.getZoom(), "&size=", size.w, "x", size.h].join("");
}
};
req.onload = function() {
var vector = new OpenLayers.Layer.Vector('Vector Layer', {
styleMap: new OpenLayers.StyleMap({
temporary: OpenLayers.Util.applyDefaults({
pointRadius: 16
}, OpenLayers.Feature.Vector.style.temporary)
})
});
// OpenLayers' EditingToolbar internally creates a Navigation control, we
// want a TouchNavigation control here so we create our own editing toolbar
var toolbar = new OpenLayers.Control.Panel({
displayClass: 'olControlEditingToolbar'
});
toolbar.addControls([
// this control is just there to be able to deactivate the drawing
// tools
new OpenLayers.Control({
displayClass: 'olControlNavigation'
}), new OpenLayers.Control.ModifyFeature(vector, {
vertexRenderIntent: 'temporary',
displayClass: 'olControlModifyFeature'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Point, {
displayClass: 'olControlDrawFeaturePoint'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Path, {
displayClass: 'olControlDrawFeaturePath'
}), new OpenLayers.Control.DrawFeature(vector, OpenLayers.Handler.Polygon, {
displayClass: 'olControlDrawFeaturePolygon'
})]);
var osm = new OpenLayers.Layer.OSM();
osm.wrapDateLine = false;
map = new OpenLayers.Map({
div: 'googleMap',
projection: 'EPSG:900913',
numZoomLevels: 18,
controls: [
new OpenLayers.Control.TouchNavigation({
dragPanOptions: {
enableKinetic: true
}
}), new OpenLayers.Control.Zoom(), toolbar],
layers: [osm, vector],
center: new OpenLayers.LonLat(0, 0),
zoom: 1,
theme: null
});
// activate the first control to render the "navigation icon"
// as active
toolbar.controls[0].activate();
}
req.open("GET", this._mapUri);
req.send();
},
Please check the z-Index of the cursor's class. The best way is to modify the z-Index through Chrome's debugger console or Firebug.
Is there any live example of your application available?

Resources