Java tutorial
/* * Copyright (C) 2014 team-cachebox.de * * Licensed under the : GNU General Public License (GPL); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.gnu.org/licenses/gpl.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package CB_Locator.Map; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.mapsforge.core.graphics.Bitmap; import org.mapsforge.core.graphics.GraphicFactory; import org.mapsforge.core.model.Tile; import org.mapsforge.map.datastore.MultiMapDataStore; import org.mapsforge.map.datastore.MultiMapDataStore.DataPolicy; import org.mapsforge.map.layer.labels.TileBasedLabelStore; import org.mapsforge.map.layer.renderer.IDatabaseRenderer; import org.mapsforge.map.layer.renderer.MF_DatabaseRenderer; import org.mapsforge.map.layer.renderer.MixedDatabaseRenderer; import org.mapsforge.map.layer.renderer.RendererJob; import org.mapsforge.map.model.DisplayModel; import org.mapsforge.map.reader.MapFile; import org.mapsforge.map.reader.header.MapFileInfo; import org.mapsforge.map.rendertheme.ExternalRenderTheme; import org.mapsforge.map.rendertheme.XmlRenderTheme; import org.mapsforge.map.rendertheme.rule.CB_RenderThemeHandler; import org.mapsforge.map.rendertheme.rule.RenderThemeFuture; import org.slf4j.LoggerFactory; import CB_Locator.LocatorSettings; import CB_Locator.Map.Layer.MapType; import CB_Locator.Map.Layer.Type; import CB_UI_Base.GL_UI.Controls.PopUps.ConnectionError; import CB_UI_Base.GL_UI.GL_Listener.GL; import CB_UI_Base.graphics.GL_RenderType; import CB_Utils.Log.Log; import CB_Utils.Util.FileIO; import CB_Utils.Util.HSV_Color; import CB_Utils.Util.IChanged; import CB_Utils.fileProvider.File; import CB_Utils.fileProvider.FileFactory; /** * @author ging-buh * @author Longri */ public abstract class ManagerBase { final static org.slf4j.Logger log = LoggerFactory.getLogger(ManagerBase.class); public static ManagerBase Manager = null; public static int PROCESSOR_COUNT; // == nr of threads for getting tiles (mapsforge) private final DisplayModel DISPLAY_MODEL; private final int CONECTION_TIME_OUT = 15000;// 15 sec private final int CONECTION_TIME_OUT_MESSAGE_INTERVALL = 60000;// 1min public static long NumBytesLoaded = 0; public static int NumTilesLoaded = 0; public static int NumTilesCached = 0; public ArrayList<PackBase> mapPacks = new ArrayList<PackBase>(); public ArrayList<TmsMap> tmsMaps = new ArrayList<TmsMap>(); public ArrayList<Layer> layers = new ArrayList<Layer>(); private final DefaultLayerList DEFAULT_LAYER = new DefaultLayerList(); private boolean mayAddLayer = false; // add only during startup (why?) public ManagerBase(DisplayModel displaymodel) { Manager = this; //PROCESSOR_COUNT = 1; // = Runtime.getRuntime().availableProcessors(); PROCESSOR_COUNT = Runtime.getRuntime().availableProcessors(); DISPLAY_MODEL = displaymodel; LocatorSettings.CurrentMapLayer.addChangedEventListener(new IChanged() { @Override public void isChanged() { Layer layer = getOrAddLayer(LocatorSettings.CurrentMapLayer.getValue(), "", ""); if (layer.isMapsForge()) initMapDatabase(layer); } }); } public abstract PackBase CreatePack(String file) throws IOException; /** * Ld ein Map Pack und fgt es dem Manager hinzu * * @param file * @return * true, falls das Pack erfolgreich geladen wurde, sonst false */ public boolean LoadMapPack(String file) { try { PackBase pack = CreatePack(file); layers.add(pack.layer); mapPacks.add(pack); // Nach Aktualitt sortieren Collections.sort(mapPacks); return true; } catch (Exception exc) { } return false; } public Layer getOrAddLayer(String[] Name, String friendlyName, String url) { if (Name[0] == "OSM" || Name[0] == "") Name[0] = "Mapnik"; for (Layer layer : layers) { if (layer.Name.equalsIgnoreCase(Name[0])) { //add aditional if (Name.length > 1) { for (int i = 1; i < Name.length; i++) { for (Layer la : layers) { if (la.Name.equalsIgnoreCase(Name[i])) { layer.addMapsforgeLayer(la); } } } } return layer; } } if (mayAddLayer) { Layer newLayer = new Layer(MapType.ONLINE, Type.normal, Name[0], Name[0], url); layers.add(newLayer); return newLayer; } else { if (layers != null && layers.size() > 0) { LocatorSettings.CurrentMapLayer.setValue(layers.get(0).getNames()); return layers.get(0); // ist wahrscheinlich Mapnik und sollte immer tun } return null; } } public class ImageData { public int[] PixelColorArray; public int width; public int height; } public abstract TileGL LoadLocalPixmap(Layer layer, Descriptor desc, int ThreadIndex); protected abstract ImageData getImagePixel(byte[] img); protected abstract byte[] getImageFromData(ImageData imgData); /** * Load Tile from URL and save to MapTile-Cache * * @param layer * @param tile * @return */ public boolean cacheTile(Layer layer, Descriptor tile) { if (layer == null) return false; // Gibts die Kachel schon in einem Mappack? Dann kann sie bersprungen werden! for (PackBase pack : mapPacks) if (pack.layer == layer) if (pack.Contains(tile) != null) return true; String filename = layer.GetLocalFilename(tile); // String path = layer.GetLocalPath(tile); String url = layer.GetUrl(tile); // Falls Kachel schon geladen wurde, kann sie bersprungen werden synchronized (this) { if (FileIO.FileExists(filename)) return true; } // Kachel laden // set the connection timeout value to 15 seconds (15000 milliseconds) final HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, CONECTION_TIME_OUT); HttpClient httpclient = new DefaultHttpClient(httpParams); HttpResponse response = null; HttpGet GET = new HttpGet(url); try { response = httpclient.execute(GET); StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() == HttpStatus.SC_OK) { ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); synchronized (this) { // Verzeichnis anlegen if (!FileIO.createDirectory(filename)) return false; // Datei schreiben FileOutputStream stream = new FileOutputStream(filename, false); out.writeTo(stream); stream.close(); } NumTilesLoaded++; // Global.TransferredBytes += result.Length; // ..more logic } else { // Closes the connection. response.getEntity().getContent().close(); // throw new IOException(statusLine.getReasonPhrase()); return false; } /* * webRequest = (HttpWebRequest)WebRequest.Create(url); webRequest.Timeout = 15000; webRequest.Proxy = Global.Proxy; webResponse * = webRequest.GetResponse(); if (!webRequest.HaveResponse) return false; responseStream = webResponse.GetResponseStream(); * byte[] result = Global.ReadFully(responseStream, 64000); // Verzeichnis anlegen lock (this) if (!Directory.Exists(path)) * Directory.CreateDirectory(path); // Datei schreiben lock (this) { stream = new FileStream(filename, FileMode.CreateNew); * stream.Write(result, 0, result.Length); } NumTilesLoaded++; Global.TransferredBytes += result.Length; */ } catch (Exception ex) { // Check last Error for this URL and post massage if the last > 1 min. String URL = GET.getURI().getAuthority(); boolean PostErrorMassage = false; if (LastRequestTimeOut.containsKey(URL)) { long last = LastRequestTimeOut.get(URL); if ((last + CONECTION_TIME_OUT_MESSAGE_INTERVALL) < System.currentTimeMillis()) { PostErrorMassage = true; LastRequestTimeOut.remove(URL); } } else { PostErrorMassage = true; } if (PostErrorMassage) { LastRequestTimeOut.put(URL, System.currentTimeMillis()); ConnectionError INSTANCE = new ConnectionError(layer.Name + " - Provider"); GL.that.Toast(INSTANCE); } return false; } /* * finally { if (stream != null) { stream.Close(); stream = null; } if (responseStream != null) { responseStream.Close(); * responseStream = null; } if (webResponse != null) { webResponse.Close(); webResponse = null; } if (webRequest != null) { * webRequest.Abort(); webRequest = null; } GC.Collect(); } */ return true; } HashMap<String, Long> LastRequestTimeOut = new HashMap<String, Long>(); /** * for night modus * * The matrix is stored in a single array, and its treated as follows: [ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t ] <br> * <br> * When applied to a color [r, g, b, a], the resulting color is computed as (after clamping) <br> * R' = a*R + b*G + c*B + d*A + e;<br> * G' = f*R + g*G + h*B + i*A + j;<br> * B' = k*R + l*G + m*B + n*A + o;<br> * A' = p*R + q*G + r*B + s*A + t;<br> * * @param matrix * @return */ public static ImageData getImageDataWithColormatrixManipulation(float[] matrix, ImageData imgData) { int[] data = imgData.PixelColorArray; for (int i = 0; i < data.length; i++) { data[i] = HSV_Color.colorMatrixManipulation(data[i], matrix); } return imgData; } public void LoadTMS(String string) { try { TmsMap tmsMap = new TmsMap(string); if ((tmsMap.name == null) || (tmsMap.url == null)) { return; } tmsMaps.add(tmsMap); layers.add(new TmsLayer(Type.normal, tmsMap)); } catch (Exception ex) { } } public void LoadBSH(String string) { try { BshLayer layer = new BshLayer(Type.normal, string); layers.add(layer); } catch (Exception ex) { } } private void getFiles(ArrayList<String> files, ArrayList<String> mapnames, String directory) { File dir = FileFactory.createFile(directory); String[] dirFiles = dir.list(); if (dirFiles != null && dirFiles.length > 0) { for (String tmp : dirFiles) { String FilePath = directory + "/" + tmp; String ttt = tmp.toLowerCase(); if (ttt.endsWith("pack") || ttt.endsWith("map") || ttt.endsWith("xml") || ttt.endsWith("bsh")) { if (!mapnames.contains(tmp)) { files.add(FilePath); mapnames.add(tmp); Log.debug(log, "add: " + tmp); } } } } } public void initMapPacks() { layers.clear(); mayAddLayer = true; layers.addAll(DEFAULT_LAYER); ArrayList<String> files = new ArrayList<String>(); ArrayList<String> mapnames = new ArrayList<String>(); Log.debug(log, "dirOwnMaps = " + LocatorSettings.MapPackFolderLocal.getValue()); getFiles(files, mapnames, LocatorSettings.MapPackFolderLocal.getValue()); // if the Folder is changed, the user wants to use only this one // Log.debug(log, "dirDefaultMaps = " + LocatorSettings.MapPackFolder.getDefaultValue()); // getFiles(files, mapnames, LocatorSettings.MapPackFolder.getDefaultValue()); Log.debug(log, "dirGlobalMaps = " + LocatorSettings.MapPackFolder.getValue()); getFiles(files, mapnames, LocatorSettings.MapPackFolder.getValue()); if (files != null) { if (files.size() > 0) { for (String file : files) { if (FileIO.GetFileExtension(file).equalsIgnoreCase("pack")) { LoadMapPack(file); } if (FileIO.GetFileExtension(file).equalsIgnoreCase("map")) { java.io.File f = new java.io.File(FileFactory.createFile(file).getAbsolutePath()); MapFile mapFile; try { mapFile = new MapFile(f); } catch (Exception e) { log.error("INIT MAPPACKS", e); continue; } //check type of mapsforge MapFileInfo info = mapFile.getMapFileInfo(); MapType mapType = MapType.MAPSFORGE; if (info.comment != null && info.comment.contains("FZK")) { mapType = MapType.FREIZEITKARTE; } String Name = FileIO.GetFileNameWithoutExtension(file); Layer layer = new Layer(mapType, Type.normal, Name, Name, file); MultiMapDataStore md = new MultiMapDataStore(DataPolicy.RETURN_FIRST); md.addMapDataStore(mapFile, false, false); MapFileInfo mf = mapFile.getMapFileInfo(); if (mf != null) { try { md.close(); layer.boundingBox = mf.boundingBox; ManagerBase.Manager.layers.add(layer); } catch (Exception e) { Log.err(log, "Get boundingbox " + Name, e); } } else Log.err(log, "Problem open " + Name); } if (FileIO.GetFileExtension(file).equalsIgnoreCase("xml")) { ManagerBase.Manager.LoadTMS(file); } if (FileIO.GetFileExtension(file).equalsIgnoreCase("bsh")) { ManagerBase.Manager.LoadBSH(file); } } } } mayAddLayer = false; } public ArrayList<Layer> getLayers() { return layers; } // ########################################################################## // Mapsforge 0.6.0 // ########################################################################## MultiMapDataStore mapDatabase[] = null; IDatabaseRenderer databaseRenderer[] = null; Bitmap tileBitmap = null; File mapFile = null; XmlRenderTheme renderTheme; public float textScale = 1; public static float DEFAULT_TEXT_SCALE = 1; public static final String INTERNAL_CAR_THEME = "internal-car-theme"; private boolean invertToNightTheme; // not yet implemented? private RenderThemeFuture renderThemeFuture; public void setRenderTheme(String themePathAndName, boolean invert) { invertToNightTheme = invert; if (themePathAndName == null) { Log.debug(log, "Use RenderTheme CB_InternalRenderTheme.OSMARENDER"); renderTheme = CB_InternalRenderTheme.OSMARENDER; } else { Log.debug(log, "Use RenderTheme " + themePathAndName); if (themePathAndName.equals(INTERNAL_CAR_THEME)) { renderTheme = CB_InternalRenderTheme.DAY_CAR_THEME; } else { try { File file = FileFactory.createFile(themePathAndName); if (file.exists()) { java.io.File themeFile = new java.io.File(file.getAbsolutePath()); renderTheme = new ExternalRenderTheme(themeFile); } else { Log.err(log, themePathAndName + " not found!"); renderTheme = CB_InternalRenderTheme.OSMARENDER; } } catch (FileNotFoundException e) { Log.err(log, "Load RenderTheme", "Error loading RenderTheme!", e); renderTheme = CB_InternalRenderTheme.OSMARENDER; } } } try { CB_RenderThemeHandler.getRenderTheme(getGraphicFactory(DISPLAY_MODEL.getScaleFactor()), DISPLAY_MODEL, renderTheme); } catch (Exception e) { Log.err(log, "RenderTheme: ", e); renderTheme = CB_InternalRenderTheme.OSMARENDER; } if (databaseRenderer == null) { databaseRenderer = new IDatabaseRenderer[PROCESSOR_COUNT]; } else { for (int i = 0; i < PROCESSOR_COUNT; i++) { databaseRenderer[i] = null; } } this.renderThemeFuture = new RenderThemeFuture(this.getGraphicFactory(DISPLAY_MODEL.getScaleFactor()), this.renderTheme, this.DISPLAY_MODEL); new Thread(this.renderThemeFuture).start(); } public TileGL getMapsforgePixMap(Layer layer, Descriptor desc, int ThreadIndex) { // Log.debug(log, "getTile " + layer.Name + " " + desc); // Mapsforge 0.4.0 if ((mapDatabase == null)) { initMapDatabase(layer); } Tile tile = new Tile(desc.getX(), desc.getY(), (byte) desc.getZoom(), 256); RendererJob rendererJob = new RendererJob(tile, mapDatabase[ThreadIndex], this.renderThemeFuture, DISPLAY_MODEL, textScale, false, false); TileBasedLabelStore labelStore = null; if (databaseRenderer[ThreadIndex] == null) { GL_RenderType RENDERING_TYPE = LocatorSettings.MapsforgeRenderType.getEnumValue(); switch (RENDERING_TYPE) { case Mapsforge: databaseRenderer[ThreadIndex] = new MF_DatabaseRenderer(mapDatabase[ThreadIndex], getGraphicFactory(DISPLAY_MODEL.getScaleFactor()), MF_DatabaseRenderer.firstLevelTileCache, labelStore, true, true); break; case Mixing: databaseRenderer[ThreadIndex] = new MixedDatabaseRenderer(mapDatabase[ThreadIndex], getGraphicFactory(DISPLAY_MODEL.getScaleFactor()), MF_DatabaseRenderer.firstLevelTileCache, labelStore, false, true); break; default: databaseRenderer[ThreadIndex] = new MF_DatabaseRenderer(mapDatabase[ThreadIndex], getGraphicFactory(DISPLAY_MODEL.getScaleFactor()), MF_DatabaseRenderer.firstLevelTileCache, labelStore, true, true); break; } } if (databaseRenderer[ThreadIndex] == null) return null; try { TileGL tileGL = databaseRenderer[ThreadIndex].execute(rendererJob); return tileGL; } catch (Exception e) { e.printStackTrace(); } return null; } private void initMapDatabase(Layer layer) { mapFile = FileFactory.createFile(layer.Url); java.io.File file = new java.io.File(mapFile.getAbsolutePath()); MapFile mapforgeMapFile = new MapFile(file); if (mapDatabase == null) mapDatabase = new MultiMapDataStore[PROCESSOR_COUNT]; for (int i = 0; i < PROCESSOR_COUNT; i++) { if (mapDatabase[i] == null) { mapDatabase[i] = new MultiMapDataStore(DataPolicy.DEDUPLICATE); } else { mapDatabase[i].clearMapDataStore(); } mapDatabase[i].addMapDataStore(mapforgeMapFile, false, false); //if the layer has more then one map, so add all files if (layer.hasAdidionalMaps()) { for (Layer addLayer : layer.getAdditionalMaps()) { File addMapFile = FileFactory.createFile(addLayer.Url); java.io.File addFile = new java.io.File(addMapFile.getAbsolutePath()); MapFile addMapforgeMapFile = new MapFile(addFile); mapDatabase[i].addMapDataStore(addMapforgeMapFile, false, false); } } } Log.debug(log, "Open MapsForge Map: " + layer.Name); } public abstract GraphicFactory getGraphicFactory(float ScaleFactor); }