+ Antworten
Ergebnis 1 bis 5 von 5

Thema: Review eines Programms mit OSM-Abfragen

  1. #1
    Unregistered
    Gast/Guest
    EDIT: Abgetrennt von https://forum.byte-welt.net/java-for...-abfragen.html

    Hallo,

    lange war in diesem Thread nichts mehr zu lesen. Daher belebe ich ihn mal wieder. Ich habe mich an ein kleines Programm gemacht, dass die Anforderungen (weitgehend) erfüllt. Neben OSM kommt auch Google zum Einsatz, einfach, weil die OSM-Daten nicht immer Vollständig sind.

    Ich würde mich freuen, wenn ihr Euch das Programm einmal anschauen könntet und gegebenenfalls Tipps habt wie man es noch verbessern kann. Ich stehe was Java betrifft noch ziemlich am Anfang und bin froh noch das eine oder andere dazu zu lernen.

    Java Code:
    1.  
    2. import java.io.BufferedReader;
    3. import java.io.FileOutputStream;
    4. import java.io.InputStream;
    5. import java.io.OutputStream;
    6. import java.net.HttpURLConnection;
    7. import java.net.URL;
    8. import java.net.URLEncoder;
    9. import java.util.ArrayList;
    10. import java.util.logging.Level;
    11. import java.util.logging.Logger;
    12. import javax.xml.xpath.XPath;
    13. import javax.xml.xpath.XPathExpression;
    14. import javax.xml.xpath.XPathFactory;
    15. import javax.xml.xpath.XPathConstants;
    16. import javax.xml.parsers.DocumentBuilderFactory;
    17. import javax.xml.parsers.DocumentBuilder;
    18. import org.w3c.dom.Document;
    19. import org.w3c.dom.NodeList;
    20. import org.w3c.dom.Node;
    21. import java.io.File;
    22. import java.io.IOException;
    23. import java.io.InputStreamReader;
    24. import java.text.DecimalFormat;
    25. import java.util.Collections;
    26. import java.util.Comparator;
    27. import java.util.HashMap;
    28. import java.util.Map;
    29. import java.util.Scanner;
    30. import javax.xml.parsers.ParserConfigurationException;
    31. import org.w3c.dom.NamedNodeMap;
    32. import org.xml.sax.SAXException;
    33.  
    34.  
    35.  
    36. public class Geodaten {  
    37.  
    38.    
    39.   public static void main(String[] args) throws Exception
    40.   {
    41.  
    42.    Geodaten start = new Geodaten();
    43.    
    44.   }
    45.  
    46.   //Hauptprogramm
    47.   public Geodaten() throws IOException {
    48.    
    49.     BufferedReader br = new BufferedReader(isr);  
    50.     Scanner antwort  = new Scanner(System.in);
    51.     Scanner currentline;
    52.     //Initialization
    53.     boolean endloop=false;
    54.      // Begruessung
    55.     System.out.println("Hallo, wollen Sie etwas suchen?");
    56.    
    57.     // Schleife
    58.     while (!endloop){
    59.             currentline=new Scanner(antwort.nextLine().toLowerCase());
    60.         if (currentline.findInLine("nein")==null){
    61.             System.out.print("Was suchen Sie? ");
    62.             String art = br.readLine();
    63.             art = art(art);            
    64.             System.out.print("Wo suchen Sie es?");
    65.             String ort = br.readLine();
    66.             sucheLatUndLon(ort,art);
    67.             System.out.print("Wollen Sie weitersuchen?");
    68.         }
    69.         else {                                      
    70.         System.out.println("Auf wiedersehen.");  
    71.         endloop=true;
    72.                  }
    73.                         }
    74.     }
    75.  
    76.     private String art (String art){
    77.        
    78.         /*
    79.         Suchmöglichkeiten
    80.         bar
    81.         cafe
    82.         biergarten
    83.         pub
    84.         car_rental
    85.         car_sharing
    86.         car_wash
    87.         dentist
    88.         dentist
    89.         pharmacy
    90.         doctors
    91.         bank
    92.         atm
    93.         fuel
    94.         ice_cream
    95.         restaurant
    96.         fast_food
    97.         brothel
    98.         stripclub
    99.         swingerclub
    100.         casino
    101.         theatre
    102.         nightclub
    103.         planetarium
    104.         gym
    105.         post_office
    106.         register_office
    107.         sauna
    108.         social_facility
    109.         bus_station
    110.         grit_bin
    111.         clock
    112.         hunting_stand
    113.         telephone
    114.         vending_machine
    115.         waste_disposal
    116.         fire_station
    117.         school
    118.         college
    119.         kindergarten
    120.         parking
    121.         place_of_worship
    122.         bbq
    123.         bench
    124.         fire_station
    125.         */
    126.  
    127.         art = art.toLowerCase();
    128.         art = art.replace("oder", "|");
    129.        
    130.        
    131.         return art;
    132.     }
    133.  
    134.      
    135.     private void sucheLatUndLon(String ort, String art){
    136.  
    137.    
    138.     try {
    139.         //Eingabe Prüfen
    140.         String zahl = "[0-9]*";
    141.         String regex = zahl+"."+zahl+","+zahl+"."+zahl;
    142.        
    143.         //Falls Lat+Lon
    144.         if (ort.matches(regex)) {
    145.             ort = ort;
    146.         }
    147.         //Falls Adresse --> Umwandeln
    148.         else{
    149.             try {
    150.                 System.setProperty("java.net.useSystemProxies", "true");
    151.                 String latLongs[] = getLatLongPositions(ort);                
    152.                 ort = latLongs[0]+","+latLongs[1];
    153.             } catch (Exception ex) {
    154.                 Logger.getLogger(Geodaten.class.getName()).log(Level.SEVERE, null, ex);
    155.             }
    156.            
    157.         }
    158.        
    159.         //Liste erstellen
    160.         ArrayList <GeodatenObjekte> geoobjekte = new ArrayList <>();
    161.        
    162.         //String zerlegen
    163.         String[] stringResult = ort.split(",");
    164.         //Ausgangspositionen
    165.         double lat = Double.parseDouble(stringResult[0]);
    166.         double lon = Double.parseDouble(stringResult[1]);
    167.         //Entfernung in Metern
    168.         double wert = 750;
    169.         //Werte berechnen
    170.         quadratBerechnen(lat, lon, geoobjekte, wert, art);  
    171.        
    172.         //Nach Entfernung sortieren
    173.         Collections.sort(geoobjekte, Entfernung);  
    174.        
    175.         if (geoobjekte.isEmpty()){
    176.             System.out.println("Es wurde leider nichts gefunden");
    177.         }
    178.         else {
    179.             //Ein Fund
    180.             if(geoobjekte.size() == 1){
    181.                 //Eingangssatz
    182.                 String ausgabe = "Am nächsten ist die " + geoobjekte.get(0).getName() + ". Sie ist " + einheitAngeben(geoobjekte.get(0).getDistanz()) + ".";
    183.                 System.out.println(ausgabe);
    184.                
    185.             }
    186.             //Mehrere Funde
    187.             else{
    188.                
    189.                 String ausgabe = "Am nächsten ist die " + geoobjekte.get(0).getName() + ". Insgesamt existieren " + geoobjekte.size() + " Möglichkeiten im nähreren Umkreis. Ich erstelle eine Liste.";
    190.                 System.out.println(ausgabe);
    191.                
    192.                 int z = 1;
    193.                 for (GeodatenObjekte i : geoobjekte){
    194.                     ausgabe = z+ ". " + i.getName()+" : " + i.getOrt() + " (Distanz: " + einheitAngeben(i.getDistanz())+")";
    195.                    
    196.                     System.out.println(ausgabe);
    197.                     z = z+1;
    198.                 }
    199.             }
    200.            
    201.         }
    202.             Logger.getLogger(Geodaten.class.getName()).log(Level.SEVERE, null, ex);
    203.         }
    204.      }
    205.    
    206.     //Richtige Einheit angeben
    207.     private static String einheitAngeben(double distanz){
    208.         String einheitAngeben = null;
    209.        
    210.         if (distanz == 0){
    211.             einheitAngeben = "direkt dort";
    212.         }
    213.         else if (distanz < 1){
    214.             distanz = distanz * 1000;          
    215.             einheitAngeben = gerichteteZahl(distanz) + " Meter entfernt";
    216.         }
    217.         else {
    218.               einheitAngeben = gerichteteZahl(distanz) + " Kilometer entfernt";
    219.         }
    220.        
    221.         return einheitAngeben;
    222.     }
    223.    
    224.     //Komma nur falls nötig
    225.     private static String gerichteteZahl(double distanz){
    226.         String gerichteteZahl;
    227.        
    228.         if( (distanz - (int)distanz) == 0){
    229.             int i = (int)distanz;
    230.             gerichteteZahl = i+"";
    231.         }  
    232.         else{
    233.             DecimalFormat format = new DecimalFormat("###000.##");  
    234.             gerichteteZahl = format.format(new Double(distanz))+"";
    235.         }
    236.        
    237.         return gerichteteZahl;
    238.     }  
    239.    
    240.       //Adresse in Lat und Lon
    241.     private static String[] getLatLongPositions(String address) throws Exception
    242.       {
    243.         int responseCode = 0;
    244.         String api = "http://maps.googleapis.com/maps/api/geocode/xml?address=" + URLEncoder.encode(address, "UTF-8") + "&sensor=true";
    245.  
    246.         URL url = new URL(api);
    247.         HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
    248.         httpConnection.connect();
    249.         responseCode = httpConnection.getResponseCode();
    250.         if(responseCode == 200)
    251.         {
    252.           DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();;
    253.           Document document = builder.parse(httpConnection.getInputStream());
    254.           XPathFactory xPathfactory = XPathFactory.newInstance();
    255.           XPath xpath = xPathfactory.newXPath();
    256.           XPathExpression expr = xpath.compile("/GeocodeResponse/status");
    257.           String status = (String)expr.evaluate(document, XPathConstants.STRING);
    258.           if(status.equals("OK"))
    259.           {
    260.              expr = xpath.compile("//geometry/location/lat");
    261.              String latitude = (String)expr.evaluate(document, XPathConstants.STRING);
    262.              expr = xpath.compile("//geometry/location/lng");
    263.              String longitude = (String)expr.evaluate(document, XPathConstants.STRING);
    264.              return new String[] {latitude, longitude};
    265.           }
    266.           else
    267.           {
    268.              System.out.println("Es wurden leider keine passenden Daten gefunden.");
    269.           }
    270.         }
    271.         return null;
    272.       }
    273.    
    274.     //Quadrat berechnen
    275.     private void quadratBerechnen(double lat, double lon, ArrayList <GeodatenObjekte> geoobjekte, double wert, String art) throws IOException, ParserConfigurationException, SAXException{
    276.  
    277.       try {
    278.           //Erdradius
    279.           double r=6371000;
    280.          
    281.           //Berechnung
    282.           //Oberen Wert
    283.           double latOben = lat + (wert/r) * 180/Math.PI;
    284.           double lonOben = lon + (wert/(r*Math.cos(Math.PI*lat/180))) * 180/Math.PI;
    285.          
    286.           //Unteren Wert
    287.           wert = wert*-1;
    288.           double latUnten = lat + (wert/r) * 180/Math.PI;
    289.           double lonUnten = lon + (wert/(r*Math.cos(Math.PI*lat/180))) * 180/Math.PI;
    290.          
    291.          
    292.           //File downloaden
    293.           System.out.println("Ich sehe nach.");
    294.           File osmXmlFile = new File("md.osm.xml");
    295.           downloadSample(osmXmlFile, latOben, lonOben, latUnten, lonUnten, art);
    296.          
    297.           //Daten auswerten
    298.           datenHolen(osmXmlFile, geoobjekte, lat, lon, art);
    299.       } catch (Exception ex) {
    300.           Logger.getLogger(Geodaten.class.getName()).log(Level.SEVERE, null, ex);
    301.       }
    302.         }
    303.    
    304.     //Distanz zum Ausgangsort berechnen
    305.     private static double distanceInKm(double lat1, double lon1, double lat2, double lon2) {
    306.         //Erdumfang
    307.         int radius = 6371;
    308.         //Werte abziehen
    309.         double lat = Math.toRadians(lat2 - lat1);
    310.         double lon = Math.toRadians(lon2- lon1);
    311.        
    312.         //Berechnung
    313.         double ausgabe = Math.sin(lat / 2) * Math.sin(lat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(lon / 2) * Math.sin(lon / 2);
    314.         ausgabe = 2 * Math.atan2(Math.sqrt(ausgabe), Math.sqrt(1 - ausgabe));
    315.         ausgabe = radius * ausgabe;
    316.         ausgabe = Math.round(Math.abs(ausgabe)*100)/100.0;
    317.        
    318.         double distanceInKm = ausgabe;
    319.         return distanceInKm;
    320.     }
    321.    
    322.     //Daten herunterladen
    323.     private static void downloadSample(File file, double latOben, double lonOben, double latUnten, double lonUnten, String art) throws IOException {
    324.    
    325.        
    326.     String grundUrl = "http://www.overpass-api.de/api/xapi?node[bbox=";
    327.        
    328.     String lat02 = latOben+"";
    329.     String lon02 = lonOben+",";  
    330.     String lat01 = latUnten+",";
    331.     String lon01 = lonUnten+",";  
    332.    
    333.     String url = grundUrl+lon01+lat01+lon02+lat02+"][amenity="+art+"][@meta]";
    334.    
    335.     URL downloadUrl = new URL(url);    
    336.     InputStream in = downloadUrl.openStream();
    337.     OutputStream out = new FileOutputStream(file);
    338.     byte[] buffer = new byte[10000];
    339.     try {
    340.       int len = in.read(buffer);
    341.       while (len > 0) {
    342.         out.write(buffer, 0, len);
    343.         len = in.read(buffer);
    344.       }
    345.     } finally {
    346.       out.close();
    347.       in.close();
    348.     }
    349.   }
    350.    
    351.     void datenHolen(File osmXmlFile, ArrayList <GeodatenObjekte> geoobjekte, double lat, double lon, String art) throws ParserConfigurationException, SAXException, IOException, Exception{
    352.        
    353.         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    354.         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    355.         Document doc = dBuilder.parse(osmXmlFile);    
    356.         //Normalisieren
    357.         doc.getDocumentElement().normalize();
    358.         //Arten    
    359.         NodeList nList = doc.getElementsByTagName("node");
    360.        
    361.        
    362.        
    363.         //XML durchgehen
    364.         for (int temp = 0; temp < nList.getLength(); temp++) {
    365.             Node nNode = nList.item(temp);
    366.                 if (nNode.getNodeType() == Node.ELEMENT_NODE) {
    367.        
    368.                 Node item = nList.item(temp);
    369.                 NamedNodeMap attributes = item.getAttributes();    
    370.                  
    371.                 String name = art;
    372.                
    373.                 if (item.getNodeName().equals("node")) {
    374.                
    375.                 NodeList tagXMLNodes = item.getChildNodes();
    376.                 Map<String, String> tags = new HashMap<>();
    377.                 for (int j = 1; j < tagXMLNodes.getLength(); j++) {
    378.                     Node tagItem = tagXMLNodes.item(j);
    379.                     NamedNodeMap tagAttributes = tagItem.getAttributes();
    380.                     if (tagAttributes != null) {
    381.                         tags.put(tagAttributes.getNamedItem("k").getNodeValue(), tagAttributes.getNamedItem("v")
    382.                                 .getNodeValue());
    383.                                                 if (tagAttributes.getNamedItem("k").getNodeValue().equalsIgnoreCase("name")){
    384.                                                     name = (tagAttributes.getNamedItem("v").getNodeValue());
    385.                                                 }
    386.                     }
    387.                 }
    388.                 }                
    389.                
    390.                 if(name.equals(art)){
    391.                     String b = "" + art.charAt(0);
    392.                     b = b.toUpperCase();
    393.                     name = b + art.substring(1);
    394.                 }
    395.                
    396.                 String osmNr = attributes.getNamedItem("id").getNodeValue();
    397.                 double lat_x =  Double.parseDouble(attributes.getNamedItem("lat").getNodeValue());
    398.                 double lon_x =  Double.parseDouble(attributes.getNamedItem("lon").getNodeValue());
    399.                 double distanz = distanceInKm(lat_x, lon_x, lat, lon);
    400.                 String ortsangabe = ortBestimmen(lat_x, lon_x);
    401.                 geoobjekte.add(new GeodatenObjekte(osmNr, lat_x, lon_x,name,ortsangabe,distanz));
    402.                
    403.                
    404.             }
    405.         }
    406.        
    407.     }
    408.    
    409.     private static String ortBestimmen(double lat_x,double lon_x) throws Exception
    410.       {
    411.         int responseCode = 0;
    412.         String address = "Ort unbekannt";
    413.        
    414.         String api = "http://maps.googleapis.com/maps/api/geocode/xml?latlng="+lat_x+','+lon_x+"&sensor=true";
    415.                
    416.         URL url = new URL(api);
    417.         HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
    418.         httpConnection.connect();
    419.         responseCode = httpConnection.getResponseCode();
    420.         if(responseCode == 200)
    421.         {
    422.           DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();;
    423.           Document document = builder.parse(httpConnection.getInputStream());
    424.           XPathFactory xPathfactory = XPathFactory.newInstance();
    425.           XPath xpath = xPathfactory.newXPath();
    426.           XPathExpression expr = xpath.compile("/GeocodeResponse/status");
    427.           String status = (String)expr.evaluate(document, XPathConstants.STRING);
    428.           if(status.equals("OK"))
    429.           {
    430.              expr = xpath.compile("//formatted_address");            
    431.              address = (String)expr.evaluate(document, XPathConstants.STRING);
    432.              address = address.replace(", Germany", "");
    433.         }
    434.        
    435.       }
    436.         return address;
    437.     }
    438.    
    439.     private static final Comparator<GeodatenObjekte> Entfernung = new Comparator<GeodatenObjekte>() {
    440.             @Override
    441.             public int compare(GeodatenObjekte first, GeodatenObjekte second) {
    442.                 return doCompare(first.getDistanz(), second.getDistanz());
    443.             }
    444.    
    445.   };
    446.  
    447.     private static <T extends Comparable<? super T>> int doCompare(T t0, T t1)
    448.        {
    449.            if (t0 == null)
    450.            {
    451.                if (t1 == null)
    452.                {
    453.                    return 0;
    454.                }
    455.                return 1;
    456.            }
    457.            if (t1 == null)
    458.            {
    459.                return -1;
    460.            }
    461.            return t0.compareTo(t1);
    462.        }
    463.    
    464.    
    465.    
    466.   }
    Geändert von Marco13 (16.11.2016 um 14:39 Uhr)

  2. #2
    Global Moderator Viertel Gigabyte
    Registriert seit
    05.08.2008
    Fachbeiträge
    4.901
    Genannt
    307 Post(s)
    Das könnte hier untergehen. (Es ist mir auch gerade nicht ganz klar, wer du bist...)

    Spricht was dagegen, das in einen eigenen Thread zu verschieben?
    [wurde inzwischen verschoben]
    Geändert von SlaterB (16.11.2016 um 15:26 Uhr)

  3. #3
    Unregistered
    Gast/Guest
    Hallo Marco13, Nein dagegen spricht nichts.

  4. #4
    Unregistered
    Gast/Guest
    Ein Problem des Programms ist, dass die Sprache zwar auf Deutsch ist, die Abfragen allerdings auf Englisch sein müssen. Das ist unpraktisch. Eine eigene Datenbank zu erstellen wäre wohl ein wenig aufwendig. Mir kam die Idee das Ganze mittels glosbe.com zu lösen. Dort kann gibt es eine API zum übersetzen, allerdings ist diese für mich zu komplex. Ich bekomme sie nicht geparst. Hier ein Beispiel. Kann jemand helfen?

  5. #5
    Global Moderator Viertel Gigabyte Avatar von SlaterB
    Registriert seit
    06.08.2008
    Fachbeiträge
    2.695
    Genannt
    275 Post(s)
    mit dem OSM-Programm beschäftigst du dich doch anscheinend just auch schon mit Senden von HTML-Querys an eine API, was dir anscheinend bei glosbe auch schon gelingt,
    und Parsen des XML-Ergebnisses mit z.B. DocumentBuilder / XPath,

    da hast du bei glosbe doch genau dasselbe Problem, wieso Schwierigkeit?
    ist dir XML und die Suche darin nach Elementen usw. nicht klar? das ist ein Thema für sich, bestens dokumentiert, findet man doch überall

    und so kompliziert sieht das Ergebnis von glosbe nicht aus, meanings-Unterelemente, darunter liste mit Einträgen/ Beschreibungen

    ----------

    die Suche zeigt aber gut, wie wenig wahrscheinlich so eine Übersetzung zu nutzen ist,
    'bank' war freilich ein besonders mehrdeutiges Wort,
    aber die Ergebnisse über Sitzgelegenheit (Sport und anderes unterschieden), Finanzinstitut, 'A place where bodies or substances of the human body are preserved',
    Sandbank bis hin zu geologischen Schichten...

    wie willst du da im Programm sinnvolle Auswahl treffen falls mal mehrdeutig.., automatische Übersetzer sind ja mehr Star Trek, riesiges eigenes Problem,
    dürfte das vorhandene Programm, egal zu welchem Zweck, fast immer übersteigen

    wenn dein Programm nur begrenzten Wortschatz hat, dann lieber manuell gewählte Übersetzung gleich beifügen,
    wenn es für beliebige Eingaben ist, dann kannst du nicht Übersetzung anbieten, nicht wenn du nicht google bist mit 500 Mitarbeitern dafür..

    vielleicht noch Benutzer von mehreren Übersetungen auswählen lassen, Kontrolle und Verantwortung über letztliche englische Eingabe bieten,
    nur intern etwas vorübersetzen/ Vorschläge machen
    Geändert von SlaterB (16.11.2016 um 19:22 Uhr)
    Hansa wird Meister

+ Antworten Thema als "gelöst" markieren

Direkt antworten Direkt antworten

In welcher Stadt steht der Eiffelturm?

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. Exception zur Steuerung des Programms nutzen?
    Von Darse im Forum Java-Grundlagen
    Antworten: 23
    Letzter Beitrag: 28.01.2016, 19:07
  2. Klient-Nutzer eines Servlets abfragen/auslesen
    Von JSeann im Forum Java Enterprise Edition (Java EE)
    Antworten: 12
    Letzter Beitrag: 07.09.2015, 14:08
  3. Modellierung eines Programms in UML (Klassendiagramm)
    Von NikeAir22 im Forum Java-Grundlagen
    Antworten: 6
    Letzter Beitrag: 14.11.2013, 19:20
  4. OLE: aktive Instanz eines Programms übernehmen
    Von Vayu im Forum Allgemeine Themen
    Antworten: 0
    Letzter Beitrag: 09.08.2013, 11:17
  5. [Erledigt] Installation eines Programms unter Ubuntu
    Von L-ectron-X im Forum Software
    Antworten: 19
    Letzter Beitrag: 09.06.2007, 19:33

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •