Changeset 26084 in osm for applications/viewer/jmapviewer/src
- Timestamp:
- 2011-06-01T03:55:44+02:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
r25376 r26084 8 8 import java.util.ArrayList; 9 9 import java.util.List; 10 import java.util.Locale; 10 11 import java.util.concurrent.Callable; 11 12 import java.util.concurrent.Executors; 12 13 import java.util.concurrent.Future; 14 import java.util.regex.Pattern; 13 15 14 16 import javax.imageio.ImageIO; 17 import javax.xml.parsers.DocumentBuilder; 18 import javax.xml.parsers.DocumentBuilderFactory; 19 import javax.xml.parsers.ParserConfigurationException; 20 import javax.xml.xpath.XPath; 21 import javax.xml.xpath.XPathConstants; 22 import javax.xml.xpath.XPathExpression; 23 import javax.xml.xpath.XPathExpressionException; 24 import javax.xml.xpath.XPathFactory; 15 25 16 26 import org.openstreetmap.gui.jmapviewer.Coordinate; 17 import org.xml.sax.Attributes; 18 import org.xml.sax.InputSource; 27 import org.w3c.dom.Document; 28 import org.w3c.dom.Node; 29 import org.w3c.dom.NodeList; 19 30 import org.xml.sax.SAXException; 20 import org.xml.sax.XMLReader;21 import org.xml.sax.helpers.DefaultHandler;22 import org.xml.sax.helpers.XMLReaderFactory;23 31 24 32 public class BingAerialTileSource extends AbstractOsmTileSource { 25 33 private static String API_KEY = "Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU"; 26 34 private static Future<List<Attribution>> attributions; 35 private String imageUrlTemplate; 36 private Integer imageryZoomMax; 37 private String[] subdomains; 38 39 private static final Pattern subdomainPattern = Pattern.compile("\\{subdomain\\}"); 40 private static final Pattern quadkeyPattern = Pattern.compile("\\{quadkey\\}"); 41 private static final Pattern culturePattern = Pattern.compile("\\{culture\\}"); 27 42 28 43 public BingAerialTileSource() { 29 super("Bing Aerial Maps", "http://e cn.t2.tiles.virtualearth.net/tiles/");44 super("Bing Aerial Maps", "http://example.com/"); 30 45 31 46 if (attributions == null) { 32 47 attributions = Executors.newSingleThreadExecutor().submit(new Callable<List<Attribution>>() { 33 48 public List<Attribution> call() throws Exception { 34 return loadAttributionText(); 49 List<Attribution> attrs = null; 50 int waitTime = 1; 51 do { 52 53 try { 54 attrs = loadAttributionText(); 55 System.out.println("Successfully loaded Bing attribution data."); 56 return attrs; 57 } catch(IOException e) { 58 System.err.println("Could not connect to Bing API. Will retry in " + waitTime + " seconds."); 59 Thread.sleep(waitTime * 1000L); 60 waitTime *= 2; 61 } 62 63 } while(true); 35 64 } 36 65 }); … … 46 75 } 47 76 48 class AttrHandler extends DefaultHandler { 49 50 private String string; 51 private Attribution curr; 52 private List<Attribution> attributions = new ArrayList<Attribution>(); 53 private double southLat; 54 private double northLat; 55 private double eastLon; 56 private double westLon; 57 private boolean inCoverage = false; 58 59 @Override 60 public void startElement(String uri, String stripped, String tagName, Attributes attrs) throws SAXException { 61 if ("ImageryProvider".equals(tagName)) { 62 curr = new Attribution(); 63 } else if ("CoverageArea".equals(tagName)) { 64 inCoverage = true; 65 } 66 } 67 68 @Override 69 public void characters(char[] ch, int start, int length) throws SAXException { 70 string = new String(ch, start, length); 71 } 72 73 @Override 74 public void endElement(String uri, String stripped, String tagName) throws SAXException { 75 if ("ImageryProvider".equals(tagName)) { 76 attributions.add(curr); 77 } else if ("Attribution".equals(tagName)) { 78 curr.attribution = string; 79 } else if (inCoverage && "ZoomMin".equals(tagName)) { 80 curr.minZoom = Integer.parseInt(string); 81 } else if (inCoverage && "ZoomMax".equals(tagName)) { 82 curr.maxZoom = Integer.parseInt(string); 83 } else if (inCoverage && "SouthLatitude".equals(tagName)) { 84 southLat = Double.parseDouble(string); 85 } else if (inCoverage && "NorthLatitude".equals(tagName)) { 86 northLat = Double.parseDouble(string); 87 } else if (inCoverage && "EastLongitude".equals(tagName)) { 88 eastLon = Double.parseDouble(string); 89 } else if (inCoverage && "WestLongitude".equals(tagName)) { 90 westLon = Double.parseDouble(string); 91 } else if ("BoundingBox".equals(tagName)) { 92 curr.min = new Coordinate(southLat, westLon); 93 curr.max = new Coordinate(northLat, eastLon); 94 } else if ("CoverageArea".equals(tagName)) { 95 inCoverage = false; 96 } 97 string = ""; 98 } 99 } 100 101 private List<Attribution> loadAttributionText() { 77 @Override 78 public String getTileUrl(int zoom, int tilex, int tiley) throws IOException { 79 int t = (zoom + tilex + tiley) % subdomains.length; 80 String subdomain = subdomains[t]; 81 82 String url = new String(imageUrlTemplate); 83 url = subdomainPattern.matcher(url).replaceAll(subdomain); 84 url = quadkeyPattern.matcher(url).replaceAll(computeQuadTree(zoom, tilex, tiley)); 85 86 return url; 87 } 88 89 private List<Attribution> loadAttributionText() throws IOException { 102 90 try { 103 URL u = new URL("http://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial /0,0?zl=1&mapVersion=v1&key="104 + API_KEY + "&include=ImageryProviders&output=xml");91 URL u = new URL("http://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&output=xml&key=" 92 + API_KEY); 105 93 URLConnection conn = u.openConnection(); 106 94 107 // This is not JOSM! Do not use anything other than standard JRE classes within this package!108 // See package.html for details109 //conn.setConnectTimeout(Main.pref.getInteger("imagery.bing.load-attribution-text.timeout", 4000));110 111 95 InputStream stream = conn.getInputStream(); 112 96 113 XMLReader parser = XMLReaderFactory.createXMLReader(); 114 AttrHandler handler = new AttrHandler(); 115 parser.setContentHandler(handler); 116 parser.parse(new InputSource(stream)); 117 //System.err.println("Added " + handler.attributions.size() + " attributions."); 118 return handler.attributions; 119 } catch (IOException e) { 120 System.err.println("Could not open Bing aerials attribution metadata."); 97 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 98 DocumentBuilder builder = factory.newDocumentBuilder(); 99 Document document = builder.parse(stream); 100 101 XPathFactory xPathFactory = XPathFactory.newInstance(); 102 XPath xpath = xPathFactory.newXPath(); 103 imageUrlTemplate = xpath.compile("//ImageryMetadata/ImageUrl/text()").evaluate(document); 104 imageUrlTemplate = culturePattern.matcher(imageUrlTemplate).replaceAll(Locale.getDefault().toString()); 105 imageryZoomMax = Integer.parseInt(xpath.compile("//ImageryMetadata/ZoomMax/text()").evaluate(document)); 106 107 NodeList subdomainTxt = (NodeList) xpath.compile("//ImageryMetadata/ImageUrlSubdomains/string/text()").evaluate(document, XPathConstants.NODESET); 108 subdomains = new String[subdomainTxt.getLength()]; 109 for(int i = 0; i < subdomainTxt.getLength(); i++) { 110 subdomains[i] = subdomainTxt.item(i).getNodeValue(); 111 } 112 113 XPathExpression attributionXpath = xpath.compile("Attribution/text()"); 114 XPathExpression coverageAreaXpath = xpath.compile("CoverageArea"); 115 XPathExpression zoomMinXpath = xpath.compile("ZoomMin/text()"); 116 XPathExpression zoomMaxXpath = xpath.compile("ZoomMax/text()"); 117 XPathExpression southLatXpath = xpath.compile("BoundingBox/SouthLatitude/text()"); 118 XPathExpression westLonXpath = xpath.compile("BoundingBox/WestLongitude/text()"); 119 XPathExpression northLatXpath = xpath.compile("BoundingBox/NorthLatitude/text()"); 120 XPathExpression eastLonXpath = xpath.compile("BoundingBox/EastLongitude/text()"); 121 122 NodeList imageryProviderNodes = (NodeList) xpath.compile("//ImageryMetadata/ImageryProvider").evaluate(document, XPathConstants.NODESET); 123 List<Attribution> attributions = new ArrayList<Attribution>(imageryProviderNodes.getLength()); 124 for (int i = 0; i < imageryProviderNodes.getLength(); i++) { 125 Node providerNode = imageryProviderNodes.item(i); 126 127 String attribution = attributionXpath.evaluate(providerNode); 128 129 NodeList coverageAreaNodes = (NodeList) coverageAreaXpath.evaluate(providerNode, XPathConstants.NODESET); 130 for(int j = 0; j < coverageAreaNodes.getLength(); j++) { 131 Node areaNode = coverageAreaNodes.item(j); 132 Attribution attr = new Attribution(); 133 attr.attribution = attribution; 134 135 attr.maxZoom = Integer.parseInt(zoomMaxXpath.evaluate(areaNode)); 136 attr.minZoom = Integer.parseInt(zoomMinXpath.evaluate(areaNode)); 137 138 Double southLat = Double.parseDouble(southLatXpath.evaluate(areaNode)); 139 Double northLat = Double.parseDouble(northLatXpath.evaluate(areaNode)); 140 Double westLon = Double.parseDouble(westLonXpath.evaluate(areaNode)); 141 Double eastLon = Double.parseDouble(eastLonXpath.evaluate(areaNode)); 142 attr.min = new Coordinate(southLat, westLon); 143 attr.max = new Coordinate(northLat, eastLon); 144 145 attributions.add(attr); 146 } 147 } 148 149 return attributions; 121 150 } catch (SAXException e) { 122 151 System.err.println("Could not parse Bing aerials attribution metadata."); 123 152 e.printStackTrace(); 153 } catch (ParserConfigurationException e) { 154 e.printStackTrace(); 155 } catch (XPathExpressionException e) { 156 e.printStackTrace(); 124 157 } 125 158 return null; … … 128 161 @Override 129 162 public int getMaxZoom() { 130 return 22; 131 } 132 133 @Override 134 public String getExtension() { 135 return ("jpeg"); 136 } 137 138 @Override 139 public String getTilePath(int zoom, int tilex, int tiley) throws IOException { 140 try { 141 if (attributions.get() == null) 142 throw new IOException("Cannot load Bing attribution"); 143 String quadtree = computeQuadTree(zoom, tilex, tiley); 144 return "/tiles/a" + quadtree + "." + getExtension() + "?g=587"; 145 } catch (Exception e) { 146 throw new IOException("Cannot load Bing attribution", e); 147 } 163 if(imageryZoomMax != null) 164 return imageryZoomMax; 165 else 166 return 22; 148 167 } 149 168
Note:
See TracChangeset
for help on using the changeset viewer.