概要
小工具(TypeScript+Vue3),可生成指定数量的网格状GeoJson格式矢量面(Polygon)数据,属性包括name、color、rotation、opacity等(随机值)。
核心代码
<script setup lang="ts">
import { onMounted, ref } from "vue"
// GeoJson对象
let geo = ref({
type: "FeatureCollection",
features: []
})
const startPoint = [100, 40] // 网格起点(左上角)
const areaSize = 10 // 网格宽度(度)
const cellSize = 0.1 // 格子宽度(度)
// 入口
function start() {
// 网格数据
const grid = generateGrid(startPoint, areaSize);
// format网格
grid.forEach(creatGeo)
// 下载数据
downloadFile(geo.value)
}
// 创建网格
function generateGrid(startPoint: number[], areaSize: number) {
const grid: number[][][] = [];
const startX = startPoint[0];
const startY = startPoint[1];
// 计算网格的行数和列数
const rows = Math.ceil(areaSize / cellSize);
const columns = Math.ceil(areaSize / cellSize);
// 生成每个格子的顶点坐标
for (let row = 0; row < rows; row++) {
for (let col = 0; col < columns; col++) {
const x1: number = startX + col * cellSize;
const y1: number = startY - row * cellSize;
const x2: number = x1 + cellSize;
const y2: number = y1 - cellSize;
grid.push([
[x1, y1],
[x1, y2],
[x2, y2],
[x2, y1],
[x1, y1]
]);
}
}
return grid;
}
// 数据处理
function creatGeo(coordinates: number[][]) {
// 旋转,精确到 2 位小数
const rotation = parseFloat((Math.random()).toFixed(2))
// 透明度,精确到 1 位小数
const opacity = parseFloat(Math.random().toFixed(1))
// 随机名称
function generateRandomName() {
const adjectives = ["Big", "Small", "Crazy", "Brave", "Wild", "Gentle", "Silly", "Happy", "Lucky", "Wise"];
const nouns = ["Elephant", "Tiger", "Lion", "Monkey", "Dolphin", "Kangaroo", "Giraffe", "Penguin", "Owl", "Turtle"];
const randomAdjective = adjectives[Math.floor(Math.random() * adjectives.length)];
const randomNoun = nouns[Math.floor(Math.random() * nouns.length)];
return randomAdjective + " " + randomNoun;
}
const name = generateRandomName();
// 随机颜色
function getRandomColor() {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
const color = getRandomColor()
let obj = {
"type": "Feature",
"properties": {
"rotation": rotation,
"name": name,
"opacity": opacity,
"color": color
},
"geometry": {
"coordinates": [coordinates],
"type": "Polygon"
}
}
geo.value.features.push(obj)
}
// 下载数据
function downloadFile(json: any) {
let jsonString = JSON.stringify(json)
// 创建Blob 对象
var blob = new Blob([jsonString], { type: "application/json" });
// 创建下载链接
var downloadLink = document.createElement("a");
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = "geoJson.json";
// 链接下载
document.body.appendChild(downloadLink);
downloadLink.click();
// 清理链接
document.body.removeChild(downloadLink);
}
onMounted(() => {
start()
})
</script>
数据样例:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"rotation": 0.47,
"name": "Wild Owl",
"opacity": 0.3,
"color": "#BC75AF"
},
"geometry": {
"coordinates": [
[
[100, 40],
[100,39.9],
[100.1,39.9],
[100.1,40],
[100,40]
]
],
"type": "Polygon"
}
}
]
}
加载效果:
下载地址(包含1W、25W网格状矢量面的GeoJson文件):
https://download.csdn.net/download/qq_40236953/88632379
写在最后:
在使用平面投影坐标系(如Web墨卡托投影)时,经纬度坐标被映射到平面上,这个过程会引起形变。在高纬度地区,尤其是在极地附近,经线(纵向)会收缩,导致小格子形变为长方形。而在低纬度地区,经线比较接近平行,在平面投影中形变相对较小,小格子基本保持正方形。