美国邮政编码散点图的绘制与交互实现
发布时间: 2025-08-17 00:25:37 阅读量: 1 订阅数: 3 

### 美国邮政编码散点图的绘制与交互实现
#### 1. 绘制邮政编码散点图
在解析数据后,需要考虑如何将数据映射到屏幕上。数据文件中的 x 和 y 坐标并不对应屏幕上的位置,因此使用 `map()` 函数将它们重新映射到有用的坐标空间。以下是具体的实现步骤:
1. **设置边界框坐标**:在 `setup()` 方法中设置地图绘制的边界框坐标。
```java
// Border of where the map should be drawn on screen
float mapX1, mapY1;
float mapX2, mapY2;
public void setup() {
size(720, 453, P3D);
mapX1 = 30;
mapX2 = width - mapX1;
mapY1 = 20;
mapY2 = height - mapY1;
readData();
}
```
2. **添加 `draw()` 方法**:在 `Place` 类中添加 `draw()` 方法来绘制单个位置。
```java
void draw() {
int xx = (int) TX(x);
int yy = (int) TY(y);
set(xx, yy, #000000);
}
```
3. **添加主 `draw()` 方法**:在主应用程序中添加 `draw()` 方法,调用每个位置的 `draw()` 方法,并使用 `TX()` 和 `TY()` 函数将点映射到屏幕上。
```java
public void draw() {
background(255);
for (int i = 0; i < placeCount; i++) {
places[i].draw();
}
}
float TX(float x) {
return map(x, minX, maxX, mapX1, mapX2);
}
float TY(float y) {
return map(y, minY, maxY, mapY2, mapY1);
}
```
运行这段代码可以绘制出数千个位置,实际上得到的是美国的人口密度图,因为人口较多的地区有更多的邮政编码。
#### 2. 输入数字时高亮显示点
为了让用户能够探索邮政编码与地理的关系,需要添加交互功能。用户输入一系列数字,随着输入每个数字,根据位置是否属于已输入的邮政编码,位置会变亮或变暗。
1. **选择颜色**:选择背景颜色、初始颜色、高亮颜色、非高亮颜色和无匹配时的文本颜色。
```java
color backgroundColor = #333333; // dark background color
color dormantColor = #999966; // initial color of the map
color highlightedColor = #CBCBCB; // color for selected points
color unhighlightedColor = #66664C; // color for points that are not selected
color badColor = #FFFF66; // text color when nothing found
```
2. **设置字体和文本位置**:在 `setup()` 方法中加载字体并设置文本位置。
```java
PFont font;
String typedString = "";
char typedChars[] = new char[5];
int typedCount;
int typedPartials[] = new int[6];
float messageX, messageY;
int foundCount;
public void setup() {
// ...
font = loadFont("ScalaSans-Regular-14.vlw");
textFont(font);
textMode(SCREEN);
messageX = 40;
messageY = height - 40;
// ...
}
```
3. **处理按键事件**:使用 `keyPressed()` 方法处理用户输入的数字和删除操作,并调用 `updateTyped()` 方法更新选择。
```java
void keyPressed() {
if ((key == BACKSPACE) || (key == DELETE)) {
if (typedCount > 0) {
typedCount--;
}
updateTyped();
} else if ((key >= '0') && (key <= '9')) {
if (typedCount != 5) { // Stop at 5 digits.
if (foundCount > 0) { // If nothing found, ignore further typing.
typedChars[typedCount++] = key;
}
}
}
updateTyped();
}
```
4. **更新选择**:在 `updateTyped()` 方法中更新 `typedString` 和 `typedPartials` 数组,并调用每个位置的 `check()` 方法。
```java
void updateTyped() {
typedString = new String(typedChars, 0, typedCount);
typedPartials[typedCount] = int(typedString);
for (int j = typedCount-1; j > 0; --j) {
typedPartials[j] = typedPartials[j + 1] / 10;
}
foundCount = 0;
for (int i = 0; i < placeCount; i++) {
places[i].check();
}
}
```
5. **`Place` 类的更新**:在 `Place` 类中添加 `check()` 方法来计算位置是否被选中,并更新 `draw()` 方法以根据匹配深度设置颜色。
```java
class Place {
int code;
String name;
float x;
float y;
int partial[];
int matchDepth;
public Place(int code, String name, float x, float y) {
this.code = code;
this.name = name;
this.x = x;
this.y = y;
partial = new int[6];
partial[5] = code;
partial[4] = partial[5] / 10;
partial[3] = partial[4] / 10;
partial[2] = partial[3] / 10;
partial[1] = partial[2] / 10;
}
void check() {
matchDepth = 0;
if (typedCount != 0) {
for (int j = typedCount; j > 0; --j) {
if (typedPartials[j] == partial[j]) {
matchDepth = j;
break;
}
}
}
if (matchDepth == typedCount) {
foundCount++;
}
}
void draw() {
int xx = (int) TX(x);
int yy = (int) TY(y);
color c = dormantColor;
if (typedCount != 0) {
if (matchDepth == typedCount) {
c = highlightedColor;
} else {
c = unhighlightedColor;
}
}
set(xx, yy, c);
}
}
```
#### 3. 显示当前选中的点
当输入五个数字时,选中的点应该以不同的方式显示,并显示该位置的名称。
1. **添加 `drawChosen()` 方法**:在 `Place` 类中添加 `drawChosen()` 方法来绘制选中的点和显示位置名称。
```java
void drawChosen() {
noStroke();
fill(highlightColor);
int size = 4;
rect(TX(x), TY(y), size, size);
float textX = TX(x);
float textY = TY(y) - size - 4;
if (textY < 20) {
textY = TY(y) + 20;
}
if (textY > height - 5) {
textY = TY(y) - 20;
}
String location = name + " " + nf(code, 5);
float wide = textWidth(location);
if (textX > width/3) {
textX -= wide + 8;
} else {
textX += 8;
}
textAlign(LEFT);
fill(highlightColor);
text(location, textX, textY);
}
```
2. **更新 `draw()` 方法**:在主 `draw()` 方法中添加绘制选中点的逻辑。
```java
public void draw() {
background(backgroundColor);
for (int i = 0; i < placeCount; i++) {
places[i].draw();
}
if (typedCount != 0) {
if (foundCount > 0) {
if (typedCount == 4) {
for (int i = 0; i < placeCount; i++) {
if (places[i].matchDepth == typedCount) {
places[i].draw();
}
}
}
if (chosen != null) {
chosen.drawChos
```
0
0
相关推荐










