Enhancing the sencha touch example, p=mjansen,bartvde,fredj,pgiraud, (Closes #3101)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@11483 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
pgiraud
2011-02-25 12:12:20 +00:00
parent 4a4d9b29cd
commit 99f0376c8f
8 changed files with 370 additions and 125 deletions
+3
View File
@@ -12,6 +12,9 @@ OpenLayers/Layer/Bing.js
OpenLayers/Control/TouchNavigation.js OpenLayers/Control/TouchNavigation.js
OpenLayers/Control/Geolocate.js OpenLayers/Control/Geolocate.js
OpenLayers/Control/ZoomPanel.js OpenLayers/Control/ZoomPanel.js
OpenLayers/Control/Attribution.js
OpenLayers/Layer/Vector.js
OpenLayers/Renderer/SVG.js
[exclude] [exclude]
Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

+88 -74
View File
@@ -5,12 +5,30 @@
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>OpenLayers with Sencha Touch</title> <title>OpenLayers with Sencha Touch</title>
<script src="../lib/OpenLayers.js"></script> <script src="../lib/OpenLayers.js?mobile"></script>
<link rel="stylesheet" href="style.mobile.css" type="text/css"> <link rel="stylesheet" href="style.mobile.css" type="text/css">
<link rel="stylesheet" href="http://dev.sencha.com/deploy/touch/resources/css/sencha-touch.css"> <link rel="stylesheet" href="http://dev.sencha.com/deploy/touch/resources/css/sencha-touch.css">
<script src="http://dev.sencha.com/deploy/touch/sencha-touch.js"></script> <script src="http://dev.sencha.com/deploy/touch/sencha-touch.js"></script>
<script src="mobile-sencha.js"></script>
<script src="mobile.js"></script> <script src="mobile.js"></script>
<style> <style>
.searchList {
min-height: 150px;
}
.close-btn {
position: absolute;
right: 10px;
top: 10px;
}
img.minus {
-webkit-mask-image: url(img/minus1.png);
}
img.layers {
-webkit-mask-image: url(img/list.png);
}
.gx-layer-item {
margin-left: 10px;
}
#map { #map {
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -26,44 +44,12 @@
</style> </style>
<script> <script>
new Ext.Application({ var app = new Ext.Application({
name: "ol", name: "ol",
launch: function() { launch: function() {
this.viewport = new Ext.Panel({ this.viewport = new Ext.Panel({
fullscreen: true, fullscreen: true,
dockedItems: [{ dockedItems: [{
dock: "top",
xtype: "toolbar",
ui: "light",
layout: {
pack: "center"
},
defaults: {
ui: "plain",
iconMask: true
},
items: [{
iconCls: "arrow_left",
handler: function() {
pan(-0.25, 0);
}
}, {
iconCls: "arrow_up",
handler: function() {
pan(0, -0.25);
}
}, {
iconCls: "arrow_down",
handler: function() {
pan(0, 0.25);
}
}, {
iconCls: "arrow_right",
handler: function() {
pan(0.25, 0);
}
}]
}, {
dock: "bottom", dock: "bottom",
xtype: "toolbar", xtype: "toolbar",
ui: "light", ui: "light",
@@ -71,54 +57,82 @@
pack: "center" pack: "center"
}, },
items: [{ items: [{
xtype: "segmentedbutton", iconCls: "search",
items: [{ iconMask: true,
text: "navigate", handler: function(){
pressed: true // this is the app
}, { if (!app.searchFormPopupPanel) {
text: "point", app.searchFormPopupPanel = new App.SearchFormPopupPanel({
id: "point" map: map
}, {
text: "line",
id: "line"
}, {
text: "poly",
id: "poly"
}, {
text: "modify",
id: "mod"
}],
listeners: {
toggle: function(container, button, pressed) {
Ext.each(map.getControlsByClass(/DrawFeature/), function(control) {
control.deactivate();
}); });
map.getControlsBy("id", "mod-control")[0].deactivate();
if (pressed) {
var id = button.id + "-control";
var control = map.getControlsBy("id", id)[0];
if (control) {
control.activate();
}
}
} }
app.searchFormPopupPanel.show('pop');
}
}, {
iconCls: "locate",
iconMask: true,
handler: function() {
var geolocate = map.getControlsBy("id", "locate-control")[0];
if (geolocate.active) {
geolocate.getCurrentLocation();
} else {
geolocate.activate();
}
}
}, {
xtype: "spacer"
}, {
iconMask: true,
iconCls: "add",
handler: function() {
map.zoomIn();
}
}, {
iconMask: true,
iconCls: "minus",
handler: function() {
map.zoomOut();
}
}, {
xtype: "spacer"
}, {
iconMask: true,
iconCls: "layers",
handler: function() {
if (!app.popup) {
app.popup = new Ext.Panel({
floating: true,
modal: true,
centered: true,
hideOnMaskTap: true,
width: 240,
items: [{
xtype: 'app_layerlist',
map: map
}],
scroll: 'vertical'
});
}
app.popup.show('pop');
} }
}] }]
}], }],
items: [{ items: [
xtype: "component", {
scroll: false, xtype: "component",
monitorResize: true, scroll: false,
id: "map", monitorResize: true,
listeners: { id: "map",
render: init, listeners: {
resize: function() { render: init,
if (window.map) { resize: function() {
map.updateSize(); if (window.map) {
map.updateSize();
}
} }
} }
} }
}] ]
}); });
} }
}); });
+198
View File
@@ -0,0 +1,198 @@
Ext.ns('App');
/**
* The model for the geonames records used in the search
*/
Ext.regModel('Geonames', {
fields: ['countryName', 'toponymName', 'name', 'lat', 'lng']
});
/**
* Custom class for the Search
*/
App.SearchFormPopupPanel = Ext.extend(Ext.Panel, {
map: null,
floating: true,
modal: true,
centered: true,
hideOnMaskTap: true,
width: Ext.is.Phone ? undefined : 400,
height: Ext.is.Phone ? undefined : 400,
scroll: false,
layout: 'fit',
fullscreen: Ext.is.Phone ? true : undefined,
url: 'http://ws.geonames.org/searchJSON?',
errorText: 'Sorry, we had problems communicating with geonames.org. Please try again.',
errorTitle: 'Communication error',
maxResults: 6,
featureClass: "P",
createStore: function(){
this.store = new Ext.data.Store({
model: 'Geonames',
proxy: {
type: 'scripttag',
timeout: 5000,
listeners: {
exception: function(){
this.hide();
Ext.Msg.alert(this.errorTitle, this.errorText, Ext.emptyFn);
},
scope: this
},
url: this.url,
reader: {
type: 'json',
root: 'geonames'
}
}
});
},
doSearch: function(searchfield, evt){
var q = searchfield.getValue();
this.store.load({
params: {
featureClass: this.featureClass,
maxRows: this.maxResults,
name_startsWith: encodeURIComponent(q)
}
});
},
onItemTap: function(dataView, index, item, event){
var record = this.store.getAt(index);
var lon = record.get('lng');
var lat = record.get('lat');
var lonlat = new OpenLayers.LonLat(lon, lat);
map.setCenter(lonlat.transform(gg, sm), 12);
this.hide("pop");
},
initComponent: function(){
this.createStore();
this.resultList = new Ext.List({
scroll: 'vertical',
cls: 'searchList',
loadingText: "Searching ...",
store: this.store,
itemTpl: '<div>{name} ({countryName})</div>',
listeners: {
itemtap: this.onItemTap,
scope: this
}
});
this.formContainer = new Ext.form.FormPanel({
scroll: false,
items: [{
xtype: 'button',
cls: 'close-btn',
ui: 'decline-small',
text: 'Close',
handler: function(){
this.hide();
},
scope: this
}, {
xtype: 'fieldset',
scroll: false,
title: 'Search for a place',
items: [{
xtype: 'searchfield',
label: 'Search',
placeHolder: 'placename',
listeners: {
action: this.doSearch,
scope: this
}
},
this.resultList
]
}]
});
this.items = [{
xtype: 'panel',
layout: 'fit',
items: [this.formContainer]
}];
App.SearchFormPopupPanel.superclass.initComponent.call(this);
}
});
App.LayerList = Ext.extend(Ext.List, {
map: null,
createStore: function(){
Ext.regModel('Layer', {
fields: ['id', 'name', 'visibility', 'zindex']
});
var data = [];
Ext.each(this.map.layers, function(layer){
if (layer.displayInLayerSwitcher === true) {
var visibility = layer.isBaseLayer ? (this.map.baseLayer == layer) : layer.getVisibility();
data.push({
id: layer.id,
name: layer.name,
visibility: visibility,
zindex: layer.getZIndex()
});
}
});
return new Ext.data.Store({
model: 'Layer',
sorters: 'zindex',
data: data
});
},
initComponent: function(){
this.store = this.createStore();
this.itemTpl = new Ext.XTemplate(
'<tpl if="visibility == true">',
'<img width="20" src="img/check-round-green.png">',
'</tpl>',
'<tpl if="visibility == false">',
'<img width="20" src="img/check-round-grey.png">',
'</tpl>',
'<span class="gx-layer-item">{name}</span>'
);
this.listeners = {
itemtap: function(dataview, index, item, e){
var record = dataview.getStore().getAt(index);
var layer = this.map.getLayersBy("id", record.get("id"))[0];
if (layer.isBaseLayer) {
this.map.setBaseLayer(layer);
}
else {
layer.setVisibility(!layer.getVisibility());
}
record.set("visibility", layer.getVisibility());
}
};
this.map.events.on({
"changelayer": this.onChangeLayer,
scope: this
});
App.LayerList.superclass.initComponent.call(this);
},
findLayerRecord: function(layer){
var found;
this.store.each(function(record){
if (record.get("id") === layer.id) {
found = record;
}
}, this);
return found;
},
onChangeLayer: function(evt){
if (evt.property == "visibility") {
var record = this.findLayerRecord(evt.layer);
record.set("visibility", evt.layer.getVisibility());
}
}
});
Ext.reg('app_layerlist', App.LayerList);
+79 -49
View File
@@ -1,16 +1,27 @@
// API key for http://openlayers.org. Please get your own at
// http://bingmapsportal.com/ and use that instead.
var apiKey = "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf";
// initialize map when page ready // initialize map when page ready
var map; var map;
var gg = new OpenLayers.Projection("EPSG:4326"); var gg = new OpenLayers.Projection("EPSG:4326");
var sm = new OpenLayers.Projection("EPSG:900913"); var sm = new OpenLayers.Projection("EPSG:900913");
function init() { var init = function () {
// layer for drawn features var vector = new OpenLayers.Layer.Vector("Vector Layer", {});
var vector = new OpenLayers.Layer.Vector();
var geolocate = new OpenLayers.Control.Geolocate({
id: 'locate-control',
geolocationOptions: {
enableHighAccuracy: false,
maximumAge: 0,
timeout: 7000
}
});
// create map // create map
map = new OpenLayers.Map({ map = new OpenLayers.Map({
div: "map", div: "map",
theme: null,
projection: sm, projection: sm,
units: "m", units: "m",
numZoomLevels: 18, numZoomLevels: 18,
@@ -19,59 +30,78 @@ function init() {
-20037508.34, -20037508.34, 20037508.34, 20037508.34 -20037508.34, -20037508.34, 20037508.34, 20037508.34
), ),
controls: [ controls: [
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.TouchNavigation({ new OpenLayers.Control.TouchNavigation({
dragPanOptions: { dragPanOptions: {
interval: 0, // non-zero kills performance on some mobile phones interval: 0, // non-zero kills performance on some mobile phones
enableKinetic: true enableKinetic: true
} }
}), }),
new OpenLayers.Control.Attribution(), geolocate
new OpenLayers.Control.DrawFeature(
vector, OpenLayers.Handler.Point, {id: "point-control"}
),
new OpenLayers.Control.DrawFeature(
vector, OpenLayers.Handler.Path, {id: "line-control"}
),
new OpenLayers.Control.DrawFeature(
vector, OpenLayers.Handler.Polygon, {id: "poly-control"}
),
new OpenLayers.Control.ModifyFeature(vector, {id: "mod-control"}),
new OpenLayers.Control.ZoomPanel()
], ],
layers: [new OpenLayers.Layer.OSM(), vector], layers: [
center: new OpenLayers.LonLat(0, 0), new OpenLayers.Layer.OSM("OpenStreetMap", null, {
zoom: 1 transitionEffect: 'resize'
}),
new OpenLayers.Layer.Bing({
key: apiKey,
type: "Road",
// custom metadata parameter to request the new map style - only useful
// before May 1st, 2011
metadataParams: {
mapVersion: "v1"
},
name: "Bing Road",
transitionEffect: 'resize'
}),
new OpenLayers.Layer.Bing({
key: apiKey,
type: "Aerial",
name: "Bing Aerial",
transitionEffect: 'resize'
}),
new OpenLayers.Layer.Bing({
key: apiKey,
type: "AerialWithLabels",
name: "Bing Aerial + Labels",
transitionEffect: 'resize'
}),
vector
]
}); });
map.zoomToMaxExtent();
// attempt to get position var style = {
if (window.navigator && navigator.geolocation) { fillOpacity: 0.1,
navigator.geolocation.getCurrentPosition( fillColor: '#000',
updatePosition, strokeColor: '#f00',
function failure(error) { strokeOpacity: 0.6
OpenLayers.Console.log(error.message); };
}, geolocate.events.register("locationupdated",this,function(e) {
{ vector.removeAllFeatures();
enableHighAccuracy: true vector.addFeatures([
} new OpenLayers.Feature.Vector(
); e.point,
} {},
{
graphicName: 'cross',
strokeColor: '#f00',
strokeWidth: 2,
fillOpacity: 0,
pointRadius: 10
}
),
new OpenLayers.Feature.Vector(
OpenLayers.Geometry.Polygon.createRegularPolygon(
new OpenLayers.Geometry.Point(e.point.x, e.point.y),
e.position.coords.accuracy/2,
50,
0
),
{},
style
)
]);
map.zoomToExtent(vector.getDataExtent());
});
}; };
// get position if possible
var position;
function updatePosition(pos) {
position = pos;
var lon = position.coords.longitude;
var lat = position.coords.latitude;
OpenLayers.Console.log("position: lon " + lon + ", lat " + lat);
map.setCenter(
new OpenLayers.LonLat(lon, lat).transform(gg, sm)
);
}
function pan(fx, fy) {
var size = map.getSize();
map.pan(size.w * fx, size.h * fy);
}