Skip to content
Newer
Older
100644 340 lines (293 sloc) 11.9 KB
3675745 @camillol added MapView
authored Oct 14, 2011
1 import processing.opengl.*;
2 import com.modestmaps.*;
3 import com.modestmaps.core.*;
4 import com.modestmaps.geo.*;
5 import com.modestmaps.providers.*;
d727a20 @camillol background rendering of buffers
authored Oct 29, 2011
6 import java.util.concurrent.*;
3675745 @camillol added MapView
authored Oct 14, 2011
7
8 class MapView extends View {
9 InteractiveMap mmap;
d46044f @pjimen5 UFOInfoBox+LimitMapZoom
pjimen5 authored Oct 21, 2011
10 float zoomValue = 4;
11 float minZoom = 4;
95ab44d @pjimen5 SighingsDetailsViewUpdates
pjimen5 authored Oct 23, 2011
12 float maxZoom = 15;
60a76c2 @pjimen5 InformationalBox
pjimen5 authored Oct 22, 2011
13 int minPointSize= 5;
14 int maxPointSize = 45;
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 28, 2011
15 int minIconSize= 10;
f051126 @pjimen5 DrawingSightings+SizeIconsAccordingZoom
pjimen5 authored Oct 19, 2011
16 int maxIconSize = 25;
17 int minDistSize = 1;
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 29, 2011
18 int maxDistSize = 150;
e9fc876 @pjimen5 AddedDetailViewForSightings
pjimen5 authored Oct 21, 2011
19 Sighting clickedSighting;
60a76c2 @pjimen5 InformationalBox
pjimen5 authored Oct 22, 2011
20 Place clickedPlace;
3675745 @camillol added MapView
authored Oct 14, 2011
21
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
22 int MAX_BUFFERS_TO_KEEP = 64;
23
24
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
25 Map<Coordinate, Future<PGraphics>> buffers;
26 ExecutorService bufferExec;
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
27 boolean USE_BUFFERS = true;
afeb1eb @camillol experimental buffer for map overlay
authored Oct 22, 2011
28
24fbd23 @camillol only draw places in area that needs to be drawn
authored Oct 25, 2011
29 double TILE_EXPAND_FACTOR = 0.05; // as a fraction of the tile size
30
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
31
3675745 @camillol added MapView
authored Oct 14, 2011
32 MapView(float x_, float y_, float w_, float h_)
33 {
34 super(x_, y_, w_, h_);
35 mmap = new InteractiveMap(papplet, new Microsoft.HybridProvider(), w, h);
d46044f @pjimen5 UFOInfoBox+LimitMapZoom
pjimen5 authored Oct 21, 2011
36 // mmap = new InteractiveMap(papplet, new Microsoft.AerialProvider());
37 /* String template = "http://{S}.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png";
38 String[] subdomains = new String[] { "otile1", "otile2", "otile3", "otile4"}; // optional
39 mmap = new InteractiveMap(papplet, new TemplatedMapProvider(template, subdomains));*/
40
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
41 mmap.MAX_IMAGES_TO_KEEP = 64;
afeb1eb @camillol experimental buffer for map overlay
authored Oct 22, 2011
42 mmap.setCenterZoom(new Location(39,-98), int(zoomValue));
43
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
44 buffers = new LinkedHashMap<Coordinate, Future<PGraphics>>(MAX_BUFFERS_TO_KEEP, 0.75, true) {
45 protected boolean removeEldestEntry(Entry<Coordinate, Future<PGraphics>> eldest) {
46 if (size() > MAX_BUFFERS_TO_KEEP) {
47 eldest.getValue().cancel(true);
48 this.remove(eldest.getKey());
49 }
50 return false;
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
51 }
52 };
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
53 bufferExec = Executors.newSingleThreadExecutor();
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
54 }
55
56348f4 @camillol reload sighting counts only
authored Oct 25, 2011
56 void rebuildOverlay()
57 {
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
58 for (Future<PGraphics> future : buffers.values()) {
59 future.cancel(true);
60 }
56348f4 @camillol reload sighting counts only
authored Oct 25, 2011
61 buffers.clear();
62 }
63
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
64 void drawOverlay()
65 {
66 double sc = mmap.sc;
67 double tx = mmap.tx;
68 double ty = mmap.ty;
69
70 // translate and scale, from the middle
71 pushMatrix();
72 translate(width/2, height/2);
73 scale((float)sc);
74 translate((float)tx, (float)ty);
75
76 // find the bounds of the ur-tile in screen-space:
77 float minX = screenX(0,0);
78 float minY = screenY(0,0);
79 float maxX = screenX(mmap.TILE_WIDTH, mmap.TILE_HEIGHT);
80 float maxY = screenY(mmap.TILE_WIDTH, mmap.TILE_HEIGHT);
81
82 int zoom = mmap.getZoom();
83 int cols = (int)pow(2,zoom);
84 int rows = (int)pow(2,zoom);
85
86 // find start and end columns
87 // println("minX " + minX + " maxX " + maxX + " cols " + cols);
88 int minCol = (int)floor(cols * (0-minX) / (maxX-minX));
3dcf3e8 @camillol overlay with chicago location
authored Oct 23, 2011
89 int maxCol = (int)ceil(cols * (w-minX) / (maxX-minX)) - 1;
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
90 int minRow = (int)floor(rows * (0-minY) / (maxY-minY));
3dcf3e8 @camillol overlay with chicago location
authored Oct 23, 2011
91 int maxRow = (int)ceil(rows * (h-minY) / (maxY-minY)) - 1;
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
92
93 minCol = constrain(minCol, 0, cols);
94 maxCol = constrain(maxCol, 0, cols);
95 minRow = constrain(minRow, 0, rows);
96 maxRow = constrain(maxRow, 0, rows);
97
98 scale(1.0f/pow(2, zoom));
99 int count = 0;
100 for (int col = minCol; col <= maxCol; col++) {
101 for (int row = minRow; row <= maxRow; row++) {
102 // source coordinate wraps around the world:
103 Coordinate coord = mmap.provider.sourceCoordinate(new Coordinate(row,col,zoom));
104
105 // let's make sure we still have ints:
106 coord.row = round(coord.row);
107 coord.column = round(coord.column);
108 coord.zoom = round(coord.zoom);
109
110 if (!buffers.containsKey(coord))
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
111 buffers.put(coord, bufferExec.submit(new BufferMaker(coord)));
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
112
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
113 if (buffers.get(coord).isDone()) {
114 try {
115 PGraphics img = buffers.get(coord).get();
116 image(img, coord.column*mmap.TILE_WIDTH, coord.row*mmap.TILE_HEIGHT, mmap.TILE_WIDTH, mmap.TILE_HEIGHT);
117 } catch (InterruptedException e) {
118 println(e);
119 } catch (ExecutionException e) {
120 println(e);
121 }
122 }
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
123 count++;
124 }
125 }
126 popMatrix();
127 // println("images: " + count + " col " + minCol + " " + maxCol + " rows " + minRow + " " + maxRow);
128 }
129
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
130 void applyMapToTileMatrix(PGraphics buffer, Coordinate tileCoord) {
131 buffer.translate(-tileCoord.column * mmap.TILE_WIDTH, -tileCoord.row * mmap.TILE_HEIGHT);
132 buffer.scale(pow(2, tileCoord.zoom));
133 buffer.translate(-(float)mmap.tx, -(float)mmap.ty);
134 buffer.scale(1.0/(float)mmap.sc);
135 buffer.translate(-mmap.width/2, -mmap.height/2);
136 }
137
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
138 PGraphics makeOverlayBuffer(Coordinate coord) {
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
139 // println("makebuf: " + coord);
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
140 PGraphics buf = createGraphics(mmap.TILE_WIDTH, mmap.TILE_HEIGHT, JAVA2D);
141 buf.beginDraw();
24fbd23 @camillol only draw places in area that needs to be drawn
authored Oct 25, 2011
142 /* if ((coord.row + coord.column) % 2 == 0) {
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
143 buf.background(255,0,0,128);
144 }
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
145 buf.text(coord.toString(), 50, 50);*/
3dcf3e8 @camillol overlay with chicago location
authored Oct 23, 2011
146
147 // we want to be compatible with drawing code that calls mmap.locationPoint
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
148 applyMapToTileMatrix(buf, coord);
24fbd23 @camillol only draw places in area that needs to be drawn
authored Oct 25, 2011
149
150 // only draw places inside this tile, but with a little margin to account for markers that cross tile boundaries
151 Location loc1 = mmap.provider.coordinateLocation(coord);
152 Coordinate coord2 = new Coordinate(coord.row + 1, coord.column + 1, coord.zoom);
153 Location loc2 = mmap.provider.coordinateLocation(coord2);
154
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 29, 2011
155 drawPlaces(buf, placesInRect(cityTree, loc1, loc2, TILE_EXPAND_FACTOR));
2e33fd5 @pjimen5 animationWithTimer
pjimen5 authored Oct 29, 2011
156 if (showAirports)
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 30, 2011
157 drawAirports(buf,placesInRect(airportTree,loc1,loc2,TILE_EXPAND_FACTOR));
2e33fd5 @pjimen5 animationWithTimer
pjimen5 authored Oct 30, 2011
158 if (showMilitaryBases)
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 30, 2011
159 drawMilitaryBases(buf,placesInRect(militaryBaseTree,loc1,loc2,TILE_EXPAND_FACTOR));
2e33fd5 @pjimen5 animationWithTimer
pjimen5 authored Oct 30, 2011
160 if (showWeatherStation)
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 30, 2011
161 drawWeatherStations(buf,placesInRect(weatherStationTree,loc1,loc2,TILE_EXPAND_FACTOR));
3dcf3e8 @camillol overlay with chicago location
authored Oct 23, 2011
162
d4325f8 @camillol tiled map overlay
authored Oct 23, 2011
163 buf.endDraw();
164 return buf;
3675745 @camillol added MapView
authored Oct 14, 2011
165 }
166
d727a20 @camillol background rendering of buffers
authored Oct 30, 2011
167 class BufferMaker implements Callable<PGraphics> {
168 Coordinate coord;
169 BufferMaker(Coordinate coord)
170 {
171 this.coord = coord;
172 }
173
174 PGraphics call()
175 {
176 return makeOverlayBuffer(coord);
177 }
178 }
179
3675745 @camillol added MapView
authored Oct 14, 2011
180 void drawContent()
181 {
ff69b0a @camillol added mouse wheel support to map
authored Oct 19, 2011
182 imageMode(CORNER); // modestmaps needs this - I sent a patch, but who knows when it'll be committed
3675745 @camillol added MapView
authored Oct 14, 2011
183 mmap.draw();
9874feb @camillol drag map, fix map positioning
authored Oct 19, 2011
184
ac40bd5 @camillol optional tiled buffering
authored Oct 23, 2011
185 if (USE_BUFFERS) drawOverlay();
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 29, 2011
186 else{
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 30, 2011
187 drawPlaces(papplet.g, cityMap.values());
188 drawAirports(papplet.g, airportMap.values());
2e33fd5 @pjimen5 animationWithTimer
pjimen5 authored Oct 30, 2011
189 drawMilitaryBases(papplet.g,militaryBaseMap.values());
190 drawWeatherStations(papplet.g,weatherStationMap.values());
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 29, 2011
191
192 }
193
b77cea0 @pjimen5 CallUpdateCitiesWhenSettingsChange
pjimen5 authored Oct 24, 2011
194 drawPlacesInformationBox();
195
9874feb @camillol drag map, fix map positioning
authored Oct 20, 2011
196 }
197
ff69b0a @camillol added mouse wheel support to map
authored Oct 20, 2011
198 boolean contentMouseWheel(float lx, float ly, int delta)
199 {
10e05a6 @pjimen5 lastupdates
pjimen5 authored Oct 25, 2011
200 if ( ly > (settingsView.y+settingsView.h) && ly < (sightingDetailsView.y)){
201 float sc = 1.0;
202 if (delta < 0) {
203 sc = 1.05;
204 }
205 else if (delta > 0) {
206 sc = 1.0/1.05;
207 }
208 float mx = lx - w/2;
209 float my = ly - h/2;
210 mmap.tx -= mx/mmap.sc;
211 mmap.ty -= my/mmap.sc;
212 if (mmap.sc*sc > 16 && mmap.sc*sc < 900){
213 mmap.sc *= sc;
214 zoomValue = ceil(map((int)mmap.sc,16,900,minZoom,maxZoom));
215 }
216 mmap.tx += mx/mmap.sc;
217 mmap.ty += my/mmap.sc;
ff69b0a @camillol added mouse wheel support to map
authored Oct 20, 2011
218 }
219 return true;
220 }
e9fc876 @pjimen5 AddedDetailViewForSightings
pjimen5 authored Oct 21, 2011
221
b77cea0 @pjimen5 CallUpdateCitiesWhenSettingsChange
pjimen5 authored Oct 25, 2011
222 boolean contentClicked(float px, float py)
e9fc876 @pjimen5 AddedDetailViewForSightings
pjimen5 authored Oct 21, 2011
223 {
b77cea0 @pjimen5 CallUpdateCitiesWhenSettingsChange
pjimen5 authored Oct 25, 2011
224 if (clickedPlace == null){
225 detailsAnimator.target(height);
226 }
227 else if (sightingDetailsView.place!=clickedPlace){
228 sightingDetailsView.place = clickedPlace;
2202254 @camillol isolated DB access layer
authored Oct 29, 2011
229 sightingDetailsView.setSightings(data.sightingsForCity(mapv.clickedPlace));
b77cea0 @pjimen5 CallUpdateCitiesWhenSettingsChange
pjimen5 authored Oct 25, 2011
230 detailsAnimator.target(height-200);
231 }
232
e9fc876 @pjimen5 AddedDetailViewForSightings
pjimen5 authored Oct 21, 2011
233 return true;
234 }
235
9874feb @camillol drag map, fix map positioning
authored Oct 20, 2011
236 boolean mouseDragged(float px, float py)
237 {
10e05a6 @pjimen5 lastupdates
pjimen5 authored Oct 25, 2011
238 if ( py > (settingsView.y+settingsView.h) && py < (sightingDetailsView.y)){
239 mmap.mouseDragged();
240 }
241 return true;
3675745 @camillol added MapView
authored Oct 14, 2011
242 }
f051126 @pjimen5 DrawingSightings+SizeIconsAccordingZoom
pjimen5 authored Oct 20, 2011
243
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 29, 2011
244 void drawAirports(PGraphics buffer, Iterable<Place> airports){
245 buffer.imageMode(CENTER);
246 buffer.noStroke();
247 buffer.fill(airportAreaColor,40);
248 for (Place airport : airports) {
249 float pointSize = map(zoomValue, minZoom, maxZoom, minDistSize, maxDistSize);
250 float iconSize = map(zoomValue,minZoom,maxZoom,minIconSize,maxIconSize);
251 Point2f p = mmap.locationPoint(airport.loc);
252 buffer.ellipse(p.x,p.y,pointSize,pointSize);
253 buffer.image(airplaneImage,p.x,p.y,iconSize,iconSize);
254 }
f051126 @pjimen5 DrawingSightings+SizeIconsAccordingZoom
pjimen5 authored Oct 20, 2011
255 }
256
d8ca394 @pjimen5 DrawingMilitaryBases
pjimen5 authored Oct 28, 2011
257 void drawMilitaryBases(PGraphics buffer, Iterable<Place> militaryBases){
258 buffer.imageMode(CENTER);
259 buffer.noStroke();
1b99571 @pjimen5 DrawingWeatherStations
pjimen5 authored Oct 28, 2011
260 buffer.fill(militaryBaseColor,40);
d8ca394 @pjimen5 DrawingMilitaryBases
pjimen5 authored Oct 29, 2011
261 for (Place militaryBase : militaryBases) {
262 float pointSize = map(zoomValue, minZoom, maxZoom, minDistSize, maxDistSize);
263 float iconSize = map(zoomValue,minZoom,maxZoom,minIconSize,maxIconSize);
264 Point2f p = mmap.locationPoint(militaryBase.loc);
265 buffer.ellipse(p.x,p.y,pointSize,pointSize);
266 buffer.image(militaryBaseImage,p.x,p.y,iconSize,iconSize);
267 }
268 }
269
1b99571 @pjimen5 DrawingWeatherStations
pjimen5 authored Oct 29, 2011
270 void drawWeatherStations(PGraphics buffer, Iterable<Place> weatherStations){
271 buffer.imageMode(CENTER);
272 buffer.noStroke();
273 buffer.fill(weatherStationColor,40);
274 for (Place weatherStation : weatherStations) {
275 float pointSize = map(zoomValue, minZoom, maxZoom, minDistSize, maxDistSize);
276 float iconSize = map(zoomValue,minZoom,maxZoom,minIconSize,maxIconSize);
277 Point2f p = mmap.locationPoint(weatherStation.loc);
278 buffer.ellipse(p.x,p.y,pointSize,pointSize);
279 buffer.image(weatherStationImage,p.x,p.y,iconSize,iconSize);
280 }
281 }
282
24fbd23 @camillol only draw places in area that needs to be drawn
authored Oct 25, 2011
283 void drawPlaces(PGraphics buffer, Iterable<Place> places) {
afeb1eb @camillol experimental buffer for map overlay
authored Oct 22, 2011
284 buffer.imageMode(CENTER);
44698ff @pjimen5 filterByUFOType+DrawingAirports
pjimen5 authored Oct 29, 2011
285 buffer.strokeWeight(0.8);
24fbd23 @camillol only draw places in area that needs to be drawn
authored Oct 25, 2011
286 for (Place place : places) {
430e863 @pjimen5 yearQuery
pjimen5 authored Oct 25, 2011
287 if (place.sightingCount > 0){
288 float maxPointValue = map(zoomValue, minZoom, maxZoom, minPointSize, maxPointSize);
289 float dotSize = map(place.sightingCount, minCountSightings, maxCountSightings, minPointSize, maxPointValue);
290 Point2f p = mmap.locationPoint(place.loc);
10e05a6 @pjimen5 lastupdates
pjimen5 authored Oct 25, 2011
291 if (place.typeOfSightingCount > 1)
a35b242 @pjimen5 DrawingDifferentSightings
pjimen5 authored Oct 25, 2011
292 buffer.ellipse(p.x, p.y, dotSize, dotSize);
293 else
294 buffer.image((sightingTypeMap.get(place.sightingType)).icon, p.x, p.y, dotSize, dotSize);
295
430e863 @pjimen5 yearQuery
pjimen5 authored Oct 25, 2011
296 }
a675529 @camillol simplified data loading
authored Oct 22, 2011
297 }
298 }
299
60a76c2 @pjimen5 InformationalBox
pjimen5 authored Oct 22, 2011
300 void drawPlacesInformationBox() {
301 imageMode(CENTER);
b748dec @camillol only scan points around cursor for overlay
authored Oct 25, 2011
302
303 float maxPointValue = map(zoomValue, minZoom, maxZoom, minPointSize, maxPointSize);
304 Location loc1 = mmap.pointLocation(mouseX - maxPointValue, mouseY - maxPointValue); // TODO: use local coordinates (although they're identical in this app)
305 Location loc2 = mmap.pointLocation(mouseX + maxPointValue, mouseY + maxPointValue);
306
706cecd @pjimen5 Map+Tree updates
pjimen5 authored Oct 30, 2011
307 for (Place place : placesInRect(cityTree,loc1, loc2, 0.0)) {
c90ff16 @pjimen5 RetrievedPlaces&SightingsByDateTime
pjimen5 authored Oct 25, 2011
308 if (place.sightingCount > 0){
309 float dotSize = map(place.sightingCount, minCountSightings, maxCountSightings, minPointSize, maxPointValue);
310 Point2f p = mmap.locationPoint(place.loc);
311 if (dist(mouseX,mouseY,p.x,p.y) < dotSize/2 && p.y > (settingsView.y+settingsView.h) && p.y < (sightingDetailsView.y)){
312 textSize(normalFontSize);
313 strokeWeight(1);
314 String textToPrint = "Click on it to see details";
315 String numOfSightings = "Total # of sightings = " + str(place.sightingCount);
316 if (textToPrint.length() < place.name.length())
317 textToPrint = place.name;
318 if (textToPrint.length() < numOfSightings.length())
319 textToPrint = numOfSightings;
320 fill(infoBoxBackground);
321 float w_ = textWidth(textToPrint)+10;
322 float x_ = (p.x+w_ > w)?w-w_-5:p.x;
a4a5056 @pjimen5 ChangeFont
pjimen5 authored Oct 28, 2011
323 float h_ = (textAscent() + textDescent()) * 3 + 15;
c90ff16 @pjimen5 RetrievedPlaces&SightingsByDateTime
pjimen5 authored Oct 26, 2011
324 float y_ = (p.y+h_ > sightingDetailsView.y)?sightingDetailsView.y-h_-5:p.y;
325 rect(x_,y_,w_,h_);
326 fill(textColor);
327 text(place.name, x_ + (w_ - textWidth(place.name))/2 ,y_+5);
328 text(numOfSightings,x_ + (w_ - textWidth(numOfSightings))/2, (y_+ h_/3)+5);
329 textSize(smallFontSize);
a4a5056 @pjimen5 ChangeFont
pjimen5 authored Oct 29, 2011
330 text("Click on it to see details",x_+5,y_+h_-12);
c90ff16 @pjimen5 RetrievedPlaces&SightingsByDateTime
pjimen5 authored Oct 26, 2011
331 if (mousePressed){
332 clickedPlace = place;
333 }
334 }
335 }
336 }
d46044f @pjimen5 UFOInfoBox+LimitMapZoom
pjimen5 authored Oct 21, 2011
337 }
3675745 @camillol added MapView
authored Oct 14, 2011
338 }
339
Something went wrong with that request. Please try again.