我有一个数据库,其中包含在美国特定地理位置发生的数万个事件。数据包括每个事件的x,y坐标,使用NAD83参考系统编码。我想编写或使用算法来可靠地获取与每个NAD83 x,y坐标关联的美国邮政编码。
我还没有使用NAD83参考系统的邮政编码定义。我之前从未做过这种编程。但似乎直觉上很容易找出给定的x,y坐标是否位于使用相同NAD83参考系统定义的美国邮政编码的几何形状内。
任何人都可以帮助我解决以下问题:
1.)我在哪里可以获得NAD83参考系统格式的可靠美国邮政编码定义?
2.)在哪里可以找到算法的示例代码,以找到给定x,y坐标的邮政编码?
您可以发送到教学文章/教程,示例代码和NAD83邮政编码边界定义数据的任何链接都非常有用。我正在进行谷歌搜索,但我认为本网站上的人可能会给我更多专家指南。
我每天用Java编写代码。但是,如果您提供的代码不是用java编写的,我可以使用另一种语言编写的代码,并根据我的目的将其调整为java。我的计算机中没有安装数据库软件,因为我只使用csv或文本文件作为我的java应用程序的输入。如果您有一些建议我使用的数据库,我需要指向如何将数据转换为可以导入到编程语言(如java)中的格式的说明。
最后,我的数据集中的街道地址不包含邮政编码,并且街道地址是随意编写的,因此很难尝试清理地址数据以尝试从地址获取邮政编码。我可以将数据隔离到几个相邻的城市,可能是几百个邮政编码,但我认为NAD83 x,y坐标是我在获取我的数据集中每个事件发生的邮政编码的最佳镜头。我想通过邮政编码分析将我得到的邮政编码与我从美国人口普查等来源获得的每个邮政编码的其他数据进行链接。
提前感谢任何愿意提供帮助的人。
答案 0 :(得分:4)
您可以在java中使用GeoTools。这是一个在shapefile中搜索点的示例。
// projection/datum in SR-ORG:7169 (GCS NAD83)
File shapeFile = new File("zt08_d00.shp");
FileDataStore store = FileDataStoreFinder.getDataStore(shapeFile);
SimpleFeatureSource featureSource = store.getFeatureSource();
// Boulder, CO
Filter filter = CQL.toFilter("CONTAINS(the_geom, POINT(-105.292778 40.019444))");
SimpleFeatureCollection features = featureSource.getFeatures(filter);
for (SimpleFeature f : features) {
System.out.println(f.getAttribute('NAME'));
}
我从2000年人口普查中从美国人口普查局的5-Digit ZIP Code Tabulation Areas收集了一个shapefile。我只用了一个文件来表示科罗拉多州。您需要将这些合并为一个FeatureSource
。运行此输出80302为Boulder,CO。
如果需要,GeoTools还允许您convert between projections。幸运的是,这些shapefile已经在NAD83中了。
答案 1 :(得分:1)
我不知道从哪里获取邮政编码,但我认为你可以将其谷歌,the ZIP code of each state
。
和问题(2),首先你需要地理信息,即the boundary of each state
。然后你只需枚举所有点(x,y)并确定它所在的多边形。
以下是示例代码,它是为SGU124编写的。
#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 10005
using namespace std;
struct pnt{
int x,y;
};
struct seg{
pnt a,b;
} s[MAXN];
int n;
pnt p;
int h[MAXN<<1];
int k[MAXN<<1];
void work(){
int i,x,y,c = 0;
memset(h,0,sizeof(h));
memset(k,0,sizeof(k));
for (i=0;i<n;i++){
if (s[i].a.x<=p.x && p.x<=s[i].b.x && s[i].a.y<=p.y && p.y<=s[i].b.y){
printf("BORDER\n");
return;
}
if (s[i].a.x==s[i].b.x){
x = s[i].a.x;
y = p.y - p.x + x;
if (x<=p.x && s[i].a.y<=y && y<=s[i].b.y){
h[x+MAXN] = 1;
if (y==s[i].a.y) k[x+MAXN] |= 1;
else if (y==s[i].b.y) k[x+MAXN] |= 2;
}
}
else{
y = s[i].a.y;
x = p.x - p.y + y;
if (x<=p.x && s[i].a.x<=x && x<=s[i].b.x){
//printf("%d %d %d %d\n",s[i].a.x,s[i].a.y,s[i].b.x,s[i].b.y);
h[x+MAXN] = 1;
if (x==s[i].a.x) k[x+MAXN] |= 4;
else if (x==s[i].b.x) k[x+MAXN] |= 8;
}
}
}
for (i=p.x;i>=-10000;i--){
//if (h[i+MAXN]>0) printf("@ %d %d\n",i,k[i+MAXN]);
if (k[i+MAXN]!=9 && k[i+MAXN]!=6) c += h[i+MAXN];
}
//printf("p @ %d %d ",p.x,p.y);
if (c%2) printf("INSIDE\n");
else printf("OUTSIDE\n");
}
int main(){
freopen("sgu124.in","r",stdin);
int i;
while (~scanf("%d",&n)){
for (i=0;i<n;i++){
scanf("%d%d",&s[i].a.x,&s[i].a.y);
scanf("%d%d",&s[i].b.x,&s[i].b.y);
if (s[i].a.x>s[i].b.x || s[i].a.y>s[i].b.y) swap(s[i].a,s[i].b);
}
scanf("%d%d",&p.x,&p.y);
work();
//break;
}
return 0;
}
答案 2 :(得分:0)
您提到您拥有可以使用的地址。在这种情况下,地址验证服务将允许您根据地址和城市/州以编程方式查找邮政编码。即使格式不正确,地址数据也可能使您达到目标的90%或95%,剩下的就是清理并重新处理或尝试使用坐标来确定。
SmartyStreets将上传包含您数据的CSV文件并执行地址验证(更正并标准化地址),然后使用USPS中的数据验证地址。 SmartyStreets的一个独特功能是它们不会为坏地址收取任何费用。这将允许您格式化和处理每个地址的各种排列(以尝试计算随意数据),并且只有在解决了肯定匹配时才支付费用。
为了充分披露,我是SmartyStreets的创始人。我们提供街道地址验证。