通过Java中的邮政编码查找纬度和经度

时间:2012-03-07 10:41:25

标签: java geocoding

我无法从给定的邮政编码中检索纬度和经度值。我试图通过Servlet执行此操作,即将邮政编码值传递到Servlet,然后Java代码使用Google Geocode API检索纬度和经度值,最好是在字符串中。

我已经在网上漫游了一个简单的示例,但似乎有比J更多的Javascript和PHP方法。

有人可以粘贴一个如何以这种方式提取纬度/经度值的简单样本吗?

提前致谢!!

-Rei

2 个答案:

答案 0 :(得分:12)

好的答案。这是我成功使用的一些代码,用于查询Google Geocode API。它需要与GSon一起使用,但如果你不想使用GSon,你可以手动解码答案:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import org.slf4j.Logger;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;


public class GeoCoder {
    private Gson gson = new Gson();

    private volatile long lastRequest = 0L;

    public GeocodeResponse getLocation(String... addressElements) throws JsonSyntaxException, JsonIOException, MalformedURLException,
            IOException {
        StringBuilder sb = new StringBuilder();
        for (String string : addressElements) {
            if (sb.length() > 0) {
                sb.append('+');
            }
            sb.append(URLEncoder.encode(string.replace(' ', '+'), "UTF-8"));
        }
        String url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=" + sb.toString();
        // Google limits this web service to 2500/day and 10 requests/s
        synchronized (this) {
            try {
                long elapsed = System.currentTimeMillis() - lastRequest;
                if (elapsed < 100) {
                    try {
                        Thread.sleep(100 - elapsed);
                    } catch (InterruptedException e) {
                    }
                }
                return gson.fromJson(new BufferedReader(new InputStreamReader(new URL(url).openStream())), GeocodeResponse.class);
            } finally {
                lastRequest = System.currentTimeMillis();
            }
        }
    }
}

其他课程: GeocodeResponse:

import java.util.List;

public class GeocodeResponse {

    public enum Status {
        OK, ZERO_RESULTS, OVER_QUERY_LIMIT, REQUEST_DENIED, INVALID_REQUEST;
    }

    public static class Result {

        public static enum Type {
            street_address,
            route,
            intersection,
            political,
            country,
            administrative_area_level_1,
            administrative_area_level_2,
            administrative_area_level_3,
            colloquial_area,
            locality,
            sublocality,
            neighborhood,
            premise,
            subpremise,
            postal_code,
            natural_feature,
            airport,
            park,
            point_of_interest,
            post_box,
            street_number,
            floor,
            room;
        }

        public static class AddressComponent {

            private String long_name;
            private String short_name;
            private Type[] types;

            public String getLong_name() {
                return long_name;
            }

            public void setLong_name(String long_name) {
                this.long_name = long_name;
            }

            public String getShort_name() {
                return short_name;
            }

            public void setShort_name(String short_name) {
                this.short_name = short_name;
            }

            public Type[] getTypes() {
                return types;
            }

            public void setTypes(Type[] types) {
                this.types = types;
            }
        }

        private String formatted_address;
        private List<AddressComponent> address_components;
        private Geometry geometry;
        private Type[] types;

        public Type[] getTypes() {
            return types;
        }

        public void setTypes(Type[] types) {
            this.types = types;
        }

        public String getFormatted_address() {
            return formatted_address;
        }

        public void setFormatted_address(String formatted_address) {
            this.formatted_address = formatted_address;
        }

        public List<AddressComponent> getAddress_components() {
            return address_components;
        }

        public void setAddress_components(List<AddressComponent> address_components) {
            this.address_components = address_components;
        }

        public Geometry getGeometry() {
            return geometry;
        }

        public void setGeometry(Geometry geometry) {
            this.geometry = geometry;
        }

    }

    public static class Geometry {
        public static enum LocationType {
            ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER, APPROXIMATE;
        }

        public static class ViewPort {
            private Location northeast;
            private Location southwest;

            public Location getNortheast() {
                return northeast;
            }

            public void setNortheast(Location northeast) {
                this.northeast = northeast;
            }

            public Location getSouthwest() {
                return southwest;
            }

            public void setSouthwest(Location southwest) {
                this.southwest = southwest;
            }
        }

        private Location location;
        private LocationType location_type;
        private ViewPort viewport;

        public Location getLocation() {
            return location;
        }

        public void setLocation(Location location) {
            this.location = location;
        }

        public LocationType getLocation_type() {
            return location_type;
        }

        public void setLocation_type(LocationType location_type) {
            this.location_type = location_type;
        }

        public ViewPort getViewport() {
            return viewport;
        }

        public void setViewport(ViewPort viewport) {
            this.viewport = viewport;
        }

    }

    private Status status;
    private List<Result> results;

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public List<Result> getResults() {
        return results;
    }

    public void setResults(List<Result> results) {
        this.results = results;
    }

}

位置:

public class Location {
    private double lat;
    private double lng;

    public Location() {
    }

    public Location(double lat, double lng) {
        this.lat = lat;
        this.lng = lng;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double lng) {
        this.lng = lng;
    }
}

答案 1 :(得分:5)

这不如Guillaume Polet的答案那么优雅,但它不需要额外的库。

论证:

"1600 Amphitheatre Parkway, Mountain View, CA"

打印答案:

Latitude: 37.42207610
Longitude: -122.08451870

以下是代码:

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;


public class GoogleGeoCode 
{
    private static final String GEO_CODE_SERVER = "http://maps.googleapis.com/maps/api/geocode/json?";

    public static void main(String[] args)
    {
        String code = args[0];

        String response = getLocation(code);

        String[] result = parseLocation(response);

        System.out.println("Latitude: " + result[0]);
        System.out.println("Longitude: " + result[1]);
    }

    private static String getLocation(String code)
    {
        String address = buildUrl(code);

        String content = null;

        try
        {
            URL url = new URL(address);

            InputStream stream = url.openStream();

            try
            {
                int available = stream.available();

                byte[] bytes = new byte[available];

                stream.read(bytes);

                content = new String(bytes);
            }
            finally
            {
                stream.close();
            }

            return (String) content.toString();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    private static String buildUrl(String code)
    {
        StringBuilder builder = new StringBuilder();

        builder.append(GEO_CODE_SERVER);

        builder.append("address=");
        builder.append(code.replaceAll(" ", "+"));
        builder.append("&sensor=false");

        return builder.toString();
    }

    private static String[] parseLocation(String response)
    {
        // Look for location using brute force.
        // There are much nicer ways to do this, e.g. with Google's JSON library: Gson
        //     https://sites.google.com/site/gson/gson-user-guide

        String[] lines = response.split("\n");

        String lat = null;
        String lng = null;

        for (int i = 0; i < lines.length; i++)
        {
            if ("\"location\" : {".equals(lines[i].trim()))
            {
                lat = getOrdinate(lines[i+1]);
                lng = getOrdinate(lines[i+2]);
                break;
            }
        }

        return new String[] {lat, lng};
    }

    private static String getOrdinate(String s)
    {
        String[] split = s.trim().split(" ");

        if (split.length < 1)
        {
            return null;
        }

        String ord = split[split.length - 1];

        if (ord.endsWith(","))
        {
            ord = ord.substring(0, ord.length() - 1);
        }

        // Check that the result is a valid double
        Double.parseDouble(ord);

        return ord;
    }
}