Attention! Do you have any ideas for reorganizing and updating the Mapki? Please leave a note here. Thank you!
Java Tile Cutter
From Google Mapki
[edit] Tiler.java
package com.ti.gmap;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
/**
* Tiler - generates tiles and html
*
* <br/> Usage: java com.ti.gmap.Tiler directory imagefile
*
* @author Eric
*
*/
public class Tiler {
/**
* @param args
* @throws IOException
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.out.println("Usage: java " + Tiler.class.getName()
+ " <dir> <file> <key>");
return;
}
File dir = new File(args[0]);
File file = new File(args[1]);
String gmapApiKey = args[2];
Tiler tiler = new Tiler();
tiler.tile(dir, file, gmapApiKey);
}
private File outputDir;
private String filePrefix;
private String fileSuffix;
private ImageWriter imageWriter;
private int maxZoom;
private String gmapApiKey;
private int imageSize;
private ImageTypeSpecifier imageType;
private static final int TILE_SIZE = 256;
private static final int TILE_QUAD = 128;
private int calcMaxZoom(int size) {
int zoom = 0;
size >>= 8;
while (size > 1) {
size >>= 1;
++zoom;
}
return zoom;
}
private String getFileName(int z, int y, int x) {
return filePrefix + "_" + z + "_" + y + "_" + x + "." + fileSuffix;
}
private void html(int z) throws IOException {
int max = 1 << z;
File file = new File(outputDir, filePrefix + "_" + z + ".html");
PrintWriter out = new PrintWriter(file);
out.println("<html>");
out.println("<body>");
out.println("<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">");
for (int y = 0; y < max; y++) {
out.println("<tr>");
for (int x = 0; x < max; x++) {
final String fileName = getFileName(z, y, x);
out.println("<td><img src=\"" + fileName
+ "\" border=\"0\" /></td>");
}
out.println("</tr>");
}
out.println("</table>");
out.println("</body>");
out.println("</html>");
out.close();
}
public void tile(File dir, File file, String gmapApiKey) throws IOException {
tile(dir, file, gmapApiKey, file.getName(), file.lastModified());
}
public void tile(File dir, File file, String gmapApiKey, String fileName,
long lastModified) throws IOException {
this.outputDir = dir;
this.gmapApiKey = gmapApiKey;
int p = fileName.lastIndexOf('.');
this.filePrefix = fileName.substring(0, p);
this.fileSuffix = fileName.substring(p + 1);
ImageInputStream imageInputStream = ImageIO
.createImageInputStream(file);
Iterator<ImageReader> imageReaders = ImageIO
.getImageReaders(imageInputStream);
ImageReader imageReader = imageReaders.next();
imageReader.setInput(imageInputStream);
int imageIndex = imageReader.getMinIndex();
Iterator<ImageWriter> imageWriters = ImageIO
.getImageWritersBySuffix(fileSuffix);
imageWriter = imageWriters.next();
Iterator<ImageTypeSpecifier> imageTypes = imageReader
.getImageTypes(imageIndex);
imageType = imageTypes.next();
int width = imageReader.getWidth(imageIndex);
int height = imageReader.getHeight(imageIndex);
imageSize = Math.max(width, height);
maxZoom = calcMaxZoom(imageSize);
ImageReadParam readParam = imageReader.getDefaultReadParam();
map();
for (int i = 0; i <= maxZoom; i++) {
html(i);
}
int floorSize = 2048;
if (imageSize < floorSize) {
floorSize = imageSize;
}
Rectangle floorRegion = new Rectangle(0, 0, floorSize, floorSize);
final int tileSize = 256;
Rectangle tileRegion = new Rectangle(0, 0, tileSize, tileSize);
final int tileFloorLength = floorSize / tileSize;
Point tile = new Point(0, 0);
Point floor = new Point(0, 0);
for (floor.y = 0, floorRegion.y = 0; floorRegion.y < imageSize; floor.y += tileFloorLength, floorRegion.y += floorSize) {
for (floor.x = 0, floorRegion.x = 0; floorRegion.x < imageSize; floor.x += tileFloorLength, floorRegion.x += floorSize) {
readParam.setSourceRegion(floorRegion);
BufferedImage img = imageReader.read(imageIndex, readParam);
for (tile.y = 0, tileRegion.y = 0; tile.y < tileFloorLength; tile.y++, tileRegion.y += tileSize) {
for (tile.x = 0, tileRegion.x = 0; tile.x < tileFloorLength; tile.x++, tileRegion.x += tileSize) {
BufferedImage tileImage = img.getSubimage(tileRegion.x,
tileRegion.y, tileRegion.width,
tileRegion.height);
String tileName = getFileName(maxZoom,
floor.y + tile.y, floor.x + tile.x);
System.out.println(tileName);
File tileFile = new File(outputDir, tileName);
write(tileImage, tileFile);
}
}
}
}
imageReader.dispose();
imageReader = null;
imageInputStream.close();
imageInputStream = null;
BufferedImage bi = tile(0, 0, 0);
bi.flush();
imageWriter.dispose();
imageWriter = null;
}
private void map() throws IOException {
String html = getResourceAsString("map.html");
String mapJs = getResourceAsString("map.js");
String initJs = "";
initJs += "var tilePrefix='" + filePrefix + "';\n";
initJs += "var tileSuffix='" + fileSuffix + "';\n";
initJs += "var tileMaxZoom=" + maxZoom + ";\n";
html = html.replace("%GMAP_KEY%", gmapApiKey);
html = html.replace("%INIT_JS%", initJs);
html = html.replace("%MAP_JS%", mapJs);
File file = new File(outputDir, "index.html");
PrintWriter out = new PrintWriter(file);
out.print(html);
out.close();
}
private String getResourceAsString(String name) {
InputStream in = getClass().getResourceAsStream(name);
return convertStreamToString(in);
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
BufferedImage tile(int tx, int ty, int tz) throws IOException {
final String fileName = getFileName(tz, ty, tx);
final File file = new File(outputDir, fileName);
if (tz == maxZoom) {
return ImageIO.read(file);
}
BufferedImage img = imageType.createBufferedImage(TILE_SIZE, TILE_SIZE);
tz += 1;
tx <<= 1;
ty <<= 1;
Graphics2D g = (Graphics2D) img.getGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
draw(g, tx, ty, tz, 0, 0);
draw(g, tx + 1, ty, tz, TILE_QUAD, 0);
draw(g, tx, ty + 1, tz, 0, TILE_QUAD);
draw(g, tx + 1, ty + 1, tz, TILE_QUAD, TILE_QUAD);
write(img, file);
System.out.println(fileName);
return img;
}
private void draw(Graphics2D g, int tx, int ty, int tz, int x, int y)
throws IOException {
BufferedImage bi = tile(tx, ty, tz);
g.drawImage(bi, x, y, TILE_QUAD, TILE_QUAD, null);
bi.flush();
}
private void write(BufferedImage img, File file) throws IOException {
ImageOutputStream output = ImageIO.createImageOutputStream(file);
imageWriter.setOutput(output);
try {
imageWriter.write(img);
output.close();
} catch (IOException e) {
if (output != null) {
try {
output.close();
} catch (IOException e1) {
}
}
if (file.exists()) {
file.delete();
}
throw e;
}
}
}
[edit] map.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<title></title>
<script
src="http://maps.google.com/maps?file=api&v=2&key=%GMAP_KEY%"
type="text/javascript"></script>
<script type="text/javascript">
%INIT_JS%
%MAP_JS%
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map_canvas" style="height: 800px"></div>
</body>
</html>
[edit] map.js
// ====== Create the Euclidean Projection for the flat map ======
// == Constructor ==
function EuclideanProjection(a){
this.pixelsPerLonDegree=[];
this.pixelsPerLonRadian=[];
this.pixelOrigo=[];
this.tileBounds=[];
var b=256;
var c=1;
for(var d=0;d<a;d++){
var e=b/2;
this.pixelsPerLonDegree.push(b/360);
this.pixelsPerLonRadian.push(b/(2*Math.PI));
this.pixelOrigo.push(new GPoint(e,e));
this.tileBounds.push(c);
b*=2;
c*=2;
}
};
// == Attach it to the GProjection() class ==
EuclideanProjection.prototype = new GProjection();
// == A method for converting latitudes and longitudes to pixel coordinates ==
EuclideanProjection.prototype.fromLatLngToPixel=function(a,b){
var c=Math.round(this.pixelOrigo[b].x+a.lng()*this.pixelsPerLonDegree[b]);
var d=Math.round(this.pixelOrigo[b].y+(-2*a.lat())*this.pixelsPerLonDegree[b]);
return new GPoint(c,d);
};
// == a method for converting pixel coordinates to latitudes and longitudes ==
EuclideanProjection.prototype.fromPixelToLatLng=function(a,b,c){
var d=(a.x-this.pixelOrigo[b].x)/this.pixelsPerLonDegree[b];
var e=-0.5*(a.y-this.pixelOrigo[b].y)/this.pixelsPerLonDegree[b];
return new GLatLng(e,d,c);
};
// == a method that checks if the x,y value is in range ==
EuclideanProjection.prototype.tileCheckRange=function(a,b,c){
var d=this.tileBounds[b];
return 0 <= a.y && a.y < d
&& 0 <= a.x && a.x < d;
};
// == a method that returns the width of the tilespace ==
EuclideanProjection.prototype.getWrapWidth=function(zoom) {
return this.tileBounds[zoom]*256;
};
function load() {
if (!GBrowserIsCompatible()) {
return;
}
var projection = new EuclideanProjection(tileMaxZoom+1);
// create a custom picture layer
var customTileLayer = new GTileLayer(null, 0, tileMaxZoom, {
isPng :(tileSuffix=='png'),
tileUrlTemplate :(tilePrefix + '_{Z}_{Y}_{X}.' + tileSuffix)
});
var customMap = new GMapType( [ customTileLayer ], projection, "floormap");
map = new GMap2(document.getElementById("map_canvas"), {
mapTypes : [ customMap ]
});
map.addControl(new GLargeMapControl());
map.enableScrollWheelZoom();
map.enableContinuousZoom();
// initialize map
map.setCenter(new GLatLng(0, 0), 0);
}
