Showing posts with label google maps. Show all posts
Showing posts with label google maps. Show all posts

Thursday, December 9, 2010

Threads and Web Applications

Say you have a standalone (non-web) application where you want to show images. Suppose the images don't have dependencies among each other, so you can load and show each image in a separate thread.
Now say you want to design the same thing as a web application. To make things more concrete, suppose you want to build an application that shows a map of a region as a set (matrix) of tiles, each tile being displayed in a certain, predetermined part of the viewer. Let's call this application randomly 'google maps'.
So we'll have a servlet - say we build this with Java technology - that talks to a certain service from which it gets the corresponding tiles and then generates the page showing these tiles in their proper positions. It is tempting to take the same approach as in the standalone application and let the servlet run threads, each of them dealing with a tile. However, we know running threads from servlets calls for trouble (I'll write about that in separate posts).

So, what to do ? Well, the idea is to run the requests for the tiles in parallel as Ajax requests from - for example, a JavaScript piece of code residing in a JSP page. Each such Ajax request invokes the servlet to retrieve the desired tile. Thus, the servlet remains "pure", unpolluted with dangerous threads and we leave the parallelism and all the other optimizations in the hands of the web container.

Monday, June 7, 2010

Mashup with Google Maps or How to Call Java from JavaScript


You can simply embed Java code with the usual notation and even expressions (< % = expression % >) in JavaScript used in JSP.

Below is an example of how to do that. The code creates some Java arrays (between <% and %>) and uses them in Javascript in order to show markers on a Google map. You can see it in action here (choose trip Customizer and play with it).
The code talks for itself, so here it is:

<HEAD>

<title>Customize you trip !</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAyBigJTywiIxNM2cWUWhcFxR-sC-25ycSkOaRk1LgFwDltfgq9BRvhFBXWyducVZRhIvJw2DLcsPUdg"
type="text/javascript"></script>
<script type="text/javascript">

//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(45.29, 25.56), 6);
var coords = new Array();

<%
int[] coordsX = (int[])(request.getSession().getAttribute("coordsX"));
int[] coordsY = (int[])(request.getSession().getAttribute("coordsY"));
String[] locations = (String[])(request.getSession().getAttribute("locations"));
if ((coordsX == null) || (coordsX.length == 0)) {
coordsX = new int[1];
coordsX[0] = 0;
coordsY = new int[1];
coordsY[0] = 0;
}
for (int i = 0; i < coordsX.length; i++) {
if (
(coordsY[i] < 2967) &&
(coordsY[i] > 2021) &&
(coordsX[i] < 4823) &&
(coordsX[i] > 4362)
) {
%>
var coord = new GLatLng(
<%= (float)coordsX[i]/100 %>,
<%= (float)coordsY[i]/100 %>);
var marker = new GMarker(coord);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml("<b><%= locations[i] %></b>");
});
map.addOverlay(marker);
coords[<%= i %>] = coord;
<%
}
}
%>
var polyline = new GPolyline(coords, "#ff0000", 10);
map.addOverlay(polyline);


// define the crosshair tile layer and its required functions
var crossLayer = new GTileLayer(new GCopyrightCollection(""), 0, 15);
crossLayer.getTileUrl = function(tile, zoom) {
return "./include/tile_crosshairs.png";
}
crossLayer.isPng = function() {return true;}

// Create a new map type incorporating the tile layer
var layerTerCross = [ G_PHYSICAL_MAP.getTileLayers()[0], crossLayer ];
var mtTerCross = new GMapType(
layerTerCross,
G_PHYSICAL_MAP.getProjection(),
"Ter+");
map.addMapType(G_PHYSICAL_MAP);
map.addMapType(mtTerCross);
map.addControl(new GLargeMapControl())

var mapControl = new GHierarchicalMapTypeControl();
// Set up map type menu relationships
mapControl.clearRelationships();
mapControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels", false);
mapControl.addRelationship(G_PHYSICAL_MAP, mtTerCross, "Crosshairs");
// Add control after you've specified the relationships
map.addControl(mapControl);
}
}
//]]>
</script>
</HEAD>

In the code above, "map" is actually a div:



<div id="map" style="width: 700px; height: 400px"></div>



In case you're wondering how this mix of JSP, JavaScript and Java actually works, let's start with the JSP: as we know, JSP runs on the server side and gets translated into a servlet. Thus, the code between < % and % >, including the one inside JavaScript, is textually copied into the servlet code,  since it is just Java code. The resulting servlet will generate HTML, so it will also dynamically generate the JavaScript code (which you can see in your browser by viewing the page source). The generated JavaScript code will have the for loop expanded with actual values for the coordinates and it will execute on the client side, in the browser.
That's all, folks.