You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP从SQL Server生成GeoJSON报错:geometry应为对象而非字符串

解决GeoJSON中geometry为字符串而非对象的问题

你遇到的核心问题是:直接把SQL返回的WKT字符串塞进了GeoJSON的geometry字段,但GeoJSON规范明确要求geometry必须是包含type和coordinates的对象,而非字符串。下面是具体的修复方案:

问题根源分析

你当前生成的结果里,geometry是类似这样的字符串:

"geometry":"\"MULTILINESTRING ((-77.083060324719384 42.15108721847372, ...))"

但标准GeoJSON要求的结构应该是:

"geometry": {
  "type": "MULTILINESTRING",
  "coordinates": [
    [[-77.08306, 42.15109], [-77.08745, 42.15177], ...]
  ]
}

手动解析修复代码示例

针对你用到的MULTILINESTRING类型,我们可以手动把WKT字符串解析成符合要求的geometry对象,代码如下:

<?php
// 假设你已建立数据库连接$conn
$sql = "SELECT name, pwl_id, wbcatgry, basin, fact_sheet, geom.STAsText() as geo FROM dbo.total";
$stmt = sqlsrv_query($conn, $sql);

$features = [];

while ($res = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
    $wkt = $res['geo'];
    
    // 用正则提取WKT的几何类型和坐标部分
    preg_match('/^(\w+)\s*\((.*)\)$/', $wkt, $matches);
    $geometryType = strtoupper($matches[1]);
    $coordsRaw = $matches[2];
    
    // 初始化geometry对象
    $geometry = ['type' => $geometryType];
    
    // 处理MULTILINESTRING的坐标转换
    if ($geometryType === 'MULTILINESTRING') {
        // 拆分每个线串的坐标组
        $lineGroups = explode('), (', trim($coordsRaw, '()'));
        $coordinates = [];
        
        foreach ($lineGroups as $line) {
            $points = explode(', ', $line);
            $lineCoords = [];
            
            foreach ($points as $point) {
                // 拆分经纬度并转为浮点型(注意GeoJSON是[经度, 纬度]顺序)
                list($lon, $lat) = explode(' ', trim($point));
                $lineCoords[] = [(float)$lon, (float)$lat];
            }
            
            $coordinates[] = $lineCoords;
        }
        
        $geometry['coordinates'] = $coordinates;
    }
    
    // 扩展提示:如果需要支持POINT、LINESTRING、POLYGON等类型,可添加对应的解析逻辑
    
    // 构建Feature对象
    $feature = [
        'type' => 'Feature',
        'properties' => [
            'name' => $res['name'],
            'pwl_id' => $res['pwl_id'],
            'wbcatgry' => $res['wbcatgry'],
            'basin' => $res['basin'],
            'fact_sheet' => $res['fact_sheet']
        ],
        'geometry' => $geometry
    ];
    
    $features[] = $feature;
}

// 组装成标准的GeoJSON FeatureCollection结构
$geoJson = [
    'type' => 'FeatureCollection',
    'features' => $features
];

// 输出GeoJSON
header('Content-Type: application/json');
echo json_encode($geoJson);

// 清理资源
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>

简化方案:使用geoPHP库

如果你的项目需要支持多种几何类型,手动解析会比较繁琐,可以借助geoPHP库自动处理WKT到GeoJSON的转换:

  1. 先通过Composer安装geoPHP:
composer require phayes/geophp
  1. 然后替换代码中的解析逻辑:
// 引入geoPHP
require 'vendor/autoload.php';

// 在循环内替换解析部分
$wkt = $res['geo'];
$geometryObj = geoPHP::load($wkt, 'wkt');
// 直接获取符合规范的geometry数组结构
$geometry = json_decode($geometryObj->out('json'), true);

这样不管是哪种几何类型,都能自动转换成符合GeoJSON规范的对象。

内容的提问来源于stack exchange,提问作者Bill Chappell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:51:46