Skip to content

Commit 087f421

Browse files
committed
here's the basic set-up
1 parent a308619 commit 087f421

File tree

6 files changed

+25333
-0
lines changed

6 files changed

+25333
-0
lines changed

LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Copyright (c) 2009, Stamen Design
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
* Redistributions of source code must retain the above copyright
7+
notice, this list of conditions and the following disclaimer.
8+
* Redistributions in binary form must reproduce the above copyright
9+
notice, this list of conditions and the following disclaimer in the
10+
documentation and/or other materials provided with the distribution.
11+
* Neither the name of the <organization> nor the
12+
names of its contributors may be used to endorse or promote products
13+
derived from this software without specific prior written permission.
14+
15+
THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
16+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
19+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

index.html

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
<html>
2+
<head>
3+
<title>Vector Map JS</title>
4+
5+
<script type="text/javascript" src="vectormap.js"></script>
6+
<script type="text/javascript" src="osm.js"></script>
7+
<script type="text/javascript" src="logic.js"></script>
8+
9+
<script type="text/javascript">
10+
11+
// import our namespaces so this code is clearer
12+
for (var prop in com.stamen.osm) window[prop] = com.stamen.osm[prop];
13+
for (var prop in com.stamen.vectormap) window[prop] = com.stamen.vectormap[prop];
14+
for (var prop in com.stamen.logic) window[prop] = com.stamen.logic[prop];
15+
16+
window.onload = function() {
17+
18+
var http = new XMLHttpRequest();
19+
http.open("GET","map.xml",true); // TODO: accept path as a query string?
20+
21+
http.onreadystatechange = function () {
22+
if (http.readyState != 4) return;
23+
24+
if (http.status != 200 && http.status != 304) {
25+
// TODO: deal with these errors?
26+
//return;
27+
}
28+
29+
var osm = new OSM(http.responseXML);
30+
render(osm);
31+
}
32+
33+
http.send(null);
34+
};
35+
36+
function render(osm) {
37+
38+
console.log('initing Map...');
39+
var t = new Date().getTime();
40+
41+
var styles = [
42+
43+
new Style('water area', [
44+
new Rule(whereEquals('natural', 'water'), [
45+
new PolygonSymbolizer({
46+
fill: '#8fcce4',
47+
fillOpacity: 1.0
48+
}),
49+
new LineSymbolizer({
50+
stroke: '#84a7bd',
51+
strokeWidth: 2.0,
52+
strokeOpacity: 1.0,
53+
strokeLineJoin: 'round',
54+
strokeLineCap: 'round',
55+
strokeDashArray: 'none'
56+
})
57+
])
58+
]),
59+
60+
new Style('citylike area', [
61+
new Rule(null, [
62+
new PolygonSymbolizer({
63+
fill: '#aaaaaa', // FIXME
64+
fillOpacity: 1.0
65+
}),
66+
new LineSymbolizer({
67+
stroke: '#808080', // FIXME
68+
strokeWidth: 1.0,
69+
strokeOpacity: 1.0,
70+
strokeLineJoin: 'round',
71+
strokeLineCap: 'round',
72+
strokeDashArray: 'none'
73+
})
74+
])
75+
]),
76+
77+
new Style('parking area', [
78+
new Rule(OR(hasProperty('amenity'), hasProperty('building')), [
79+
new PolygonSymbolizer({
80+
fill: '#aaaaaa',
81+
fillOpacity: 1.0
82+
}),
83+
new LineSymbolizer({
84+
stroke: '#808080',
85+
strokeWidth: 1.0,
86+
strokeOpacity: 1.0,
87+
strokeLineJoin: 'round',
88+
strokeLineCap: 'round',
89+
strokeDashArray: 'none'
90+
})
91+
])
92+
]),
93+
94+
new Style('parklike area', [
95+
new Rule(whereIn('leisure', [ 'park', 'playground' ]), [
96+
new PolygonSymbolizer({
97+
fill: '#9cd168',
98+
fillOpacity: 1.0
99+
}),
100+
new LineSymbolizer({
101+
stroke: '#9cd168',
102+
strokeWidth: 1.0,
103+
strokeOpacity: 1.0,
104+
strokeLineJoin: 'round',
105+
strokeLineCap: 'round',
106+
strokeDashArray: 'none'
107+
})
108+
])
109+
]),
110+
111+
new Style('road outline major', [
112+
new Rule(whereEquals("highway", "motorway"), [
113+
new LineSymbolizer({
114+
stroke: '#15377b',
115+
strokeWidth: 8.0,
116+
strokeOpacity: 1.0,
117+
strokeLineJoin: 'round',
118+
strokeLineCap: 'round',
119+
strokeDashArray: 'none'
120+
})
121+
]),
122+
new Rule(whereEquals("highway", "motorway_link"), [
123+
new LineSymbolizer({
124+
stroke: '#808080',
125+
strokeWidth: 8.0,
126+
strokeOpacity: 1.0,
127+
strokeLineJoin: 'round',
128+
strokeLineCap: 'round',
129+
strokeDashArray: 'none'
130+
})
131+
]),
132+
new Rule(whereEquals("highway", "secondary"), [
133+
new LineSymbolizer({
134+
stroke: '#bfc08f',
135+
strokeWidth: 14.0,
136+
strokeOpacity: 1.0,
137+
strokeLineJoin: 'round',
138+
strokeLineCap: 'round',
139+
strokeDashArray: 'none'
140+
})
141+
]),
142+
new Rule(whereEquals("highway", "primary"), [
143+
new LineSymbolizer({
144+
stroke: '#b6b08e',
145+
strokeWidth: 14.0,
146+
strokeOpacity: 1.0,
147+
strokeLineJoin: 'round',
148+
strokeLineCap: 'round',
149+
strokeDashArray: 'none'
150+
})
151+
])
152+
// TODO: trunk?
153+
]),
154+
155+
new Style('road inline major', [
156+
new Rule(whereEquals("highway", "motorway"), [
157+
new LineSymbolizer({
158+
stroke: '#ea5e5d',
159+
strokeWidth: 6.0,
160+
strokeOpacity: 1.0,
161+
strokeLineJoin: 'round',
162+
strokeLineCap: 'round',
163+
strokeDashArray: 'none'
164+
})
165+
]),
166+
new Rule(whereEquals("highway", "motorway_link"), [
167+
new LineSymbolizer({
168+
stroke: '#f09765',
169+
strokeWidth: 6.0,
170+
strokeOpacity: 1.0,
171+
strokeLineJoin: 'round',
172+
strokeLineCap: 'round',
173+
strokeDashArray: 'none'
174+
})
175+
]),
176+
new Rule(whereEquals("highway", "secondary"), [
177+
new LineSymbolizer({
178+
stroke: '#fdfede',
179+
strokeWidth: 12.0,
180+
strokeOpacity: 1.0,
181+
strokeLineJoin: 'round',
182+
strokeLineCap: 'round',
183+
strokeDashArray: 'none'
184+
})
185+
]),
186+
new Rule(whereEquals("highway", "primary"), [
187+
new LineSymbolizer({
188+
stroke: '#fceaa3',
189+
strokeWidth: 12.0,
190+
strokeOpacity: 1.0,
191+
strokeLineJoin: 'round',
192+
strokeLineCap: 'round',
193+
strokeDashArray: 'none'
194+
})
195+
])
196+
// TODO: trunk?
197+
]),
198+
199+
new Style('road outline minor', [
200+
new Rule(null, [
201+
new LineSymbolizer({
202+
stroke: '#808080',
203+
strokeWidth: 5.0,
204+
strokeOpacity: 1.0,
205+
strokeLineJoin: 'round',
206+
strokeLineCap: 'round',
207+
strokeDashArray: 'none'
208+
})
209+
])
210+
]),
211+
212+
new Style('road inline minor', [
213+
new Rule(null, [
214+
new LineSymbolizer({
215+
stroke: '#ffffff',
216+
strokeWidth: 3.0,
217+
strokeOpacity: 1.0,
218+
strokeLineJoin: 'round',
219+
strokeLineCap: 'round',
220+
strokeDashArray: 'none'
221+
})
222+
])
223+
]),
224+
225+
new Style('path outline', [
226+
new Rule(null, [
227+
new LineSymbolizer({
228+
stroke: '#ffffff',
229+
strokeWidth: 4.0,
230+
strokeOpacity: 0.3,
231+
strokeLineJoin: 'round',
232+
strokeLineCap: 'round',
233+
strokeDashArray: 'none' // TODO: dashOnLength: 2, dashOffLength: 4
234+
235+
})
236+
])
237+
]),
238+
239+
new Style('path inline', [
240+
new Rule(null, [
241+
new LineSymbolizer({
242+
stroke: '#4e6439',
243+
strokeWidth: 2.0,
244+
strokeOpacity: 0.7,
245+
strokeLineJoin: 'round',
246+
strokeLineCap: 'round',
247+
strokeDashArray: 'none' // TODO: dashOnLength: 2, dashOffLength: 4
248+
})
249+
])
250+
]),
251+
252+
new Style('road labels major', [
253+
new Rule(whereEquals("highway", "secondary"), [
254+
new TextSymbolizer({
255+
fill: '#000000',
256+
size: 11.0
257+
})
258+
]),
259+
new Rule(whereEquals("highway", "primary"), [
260+
new TextSymbolizer({
261+
fill: '#000000',
262+
size: 11.0
263+
})
264+
])
265+
]),
266+
267+
new Style('road labels minor', [
268+
new Rule(null, [
269+
new TextSymbolizer({
270+
fill: '#404040',
271+
size: 8.0
272+
})
273+
])
274+
])
275+
];
276+
277+
console.log('styles created in', new Date().getTime() - t, 'ms');
278+
t = new Date().getTime();
279+
280+
var highwayCases = {
281+
'motorway' : 4,
282+
'motorway_link': 4,
283+
'trunk' : 3,
284+
'primary': 3,
285+
'secondary': 2,
286+
'tertiary': 1,
287+
'_default': 0
288+
}
289+
290+
var layers = [
291+
new Layer([ "citylike area" ],
292+
new DataSource(osm.areas.filter( AND( whereEquals('building', null),
293+
OR( whereIn('amenity', [ 'school', 'college', 'university', 'library', 'hospital' ]),
294+
whereIn('landuse', [ 'industrial', 'commercial' ]),
295+
whereIn('aeroway', [ 'apron' ]) ) ) ).sort(compareDescending('z_order' /*'way_area'*/)))
296+
),
297+
new Layer([ "parklike area" ],
298+
new DataSource(osm.areas.filter( AND( whereEquals('building', null),
299+
OR( whereIn('amenity', [ 'park' ]),
300+
whereIn('landuse', [ 'recreation_ground', 'greenfield', 'cemetery' ]),
301+
whereIn('leisure', [ 'park', 'pitch', 'track', 'golf_course', 'common', 'playground', 'garden', 'plaza' ]) ) ) ) )
302+
),
303+
new Layer([ "parking area" ],
304+
new DataSource(osm.areas.filter( AND( whereEquals('building', null), whereIn('amenity', [ 'parking' ]) ) ) )
305+
),
306+
new Layer([ "water area" ],
307+
new DataSource(osm.areas.filter( OR( whereIn('landuse', [ 'reservoir', 'water' ]),
308+
whereIn('natural', [ 'lake', 'water', 'land' ]) ) ) )
309+
),
310+
new Layer([ "path outline" ],
311+
new DataSource(osm.ways.filter( whereIn('highway', [ 'footpath', 'footway', 'steps', 'pedestrian', 'path', 'cycleway' ]) ) )
312+
),
313+
new Layer([ "road outline minor" ],
314+
new DataSource(osm.ways.filter( whereIn('highway', [ 'residential', 'unclassified', 'service', 'minor', 'road', 'tertiary' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
315+
),
316+
new Layer([ "road outline major" ],
317+
new DataSource(osm.ways.filter( whereIn('highway', [ 'secondary', 'trunk', 'primary', 'motorway', 'motorway_link' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
318+
),
319+
new Layer([ "path inline" ],
320+
new DataSource(osm.ways.filter( whereIn('highway', [ 'footpath', 'footway', 'steps', 'pedestrian', 'path', 'cycleway' ]) ) )
321+
),
322+
new Layer([ "road inline minor" ],
323+
new DataSource(osm.ways.filter( whereIn('highway', [ 'residential', 'unclassified', 'service', 'minor', 'road', 'tertiary' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
324+
),
325+
new Layer([ "road inline major" ],
326+
new DataSource(osm.ways.filter( whereIn('highway', [ 'secondary', 'trunk', 'primary', 'motorway', 'motorway_link' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
327+
)/*,
328+
new Layer([ "road labels major" ],
329+
new DataSource(osm.ways.filter( whereIn('highway', [ 'secondary', 'trunk', 'primary', 'motorway', 'motorway_link' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
330+
),
331+
new Layer([ "road labels minor" ],
332+
new DataSource(osm.ways.filter( whereIn('highway', [ 'residential', 'unclassified', 'service', 'minor', 'road', 'tertiary' ] ) ).sort( compareByCase( 'highway', highwayCases ) ) )
333+
)*/
334+
];
335+
336+
console.log('layers created in', new Date().getTime() - t, 'ms');
337+
t = new Date().getTime();
338+
339+
////////// TODO/FIXME still not really sure where projection should happen
340+
341+
var lonScale = 640 / (osm.bounds.maxLon - osm.bounds.minLon);
342+
var latScale = 640 / (osm.bounds.maxLat - osm.bounds.minLat);
343+
for (var i = 0; i < osm.nodes.length; i++) {
344+
var coord = osm.nodes[i].geometry.coordinates;
345+
var x = lonScale * (coord[0] - osm.bounds.minLon);
346+
var y = latScale * (coord[1] - osm.bounds.minLat);
347+
y = 640 - y;
348+
coord[0] = x;
349+
coord[1] = y;
350+
}
351+
352+
console.log('nodes projected in', new Date().getTime() - t, 'ms');
353+
354+
//////////
355+
356+
var map = new Map('#dbeee9', layers, styles);
357+
map.render(document.getElementById('canvas'));
358+
359+
}
360+
361+
</script>
362+
363+
364+
</head>
365+
<body>
366+
<h1>Client-side Map Styling with Javascript and the HTML &lt;canvas&gt; Element</h1>
367+
<canvas id="canvas" width="640" height="640" style="border: 1px solid gray"></canvas>
368+
<p>The above map is styled dynamically in the browser using a javascript implementation of the core architecture of the open source <a href="http://mapnik.org">mapnik</a> library. (Implemented by eye-balling the XML and reading the wiki, mainly).</p>
369+
<p>This page loads 1.5Mb of uncompressed raw XML output - please allow a little time for delivery. Tested in Firefox 3.0 and Safari 4.0 only.</p>
370+
<p>Map data is licensed <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a> by <a href="http://www.openstreetmap.org">OpenStreetMap.org</a> contributors.</p>
371+
</body>
372+
</html>

0 commit comments

Comments
 (0)