第02章 - 快速入门与环境配置

2.1 环境要求

2.1.1 .NET版本

OGU4Net基于 .NET Standard 2.0 构建,兼容以下目标框架:

目标框架 最低版本 推荐版本
.NET 5.0 8.0+
.NET Core 2.0 3.1+
.NET Framework 4.6.1 4.8

检查.NET SDK版本:

dotnet --version

期望输出:

8.0.x

2.1.2 操作系统支持

OGU4Net通过 MaxRev.Gdal.Universal 实现跨平台支持:

操作系统 支持状态 说明
Windows x64 ✅ 完全支持 推荐Windows 10/11
Linux x64 ✅ 完全支持 Ubuntu 18.04+, CentOS 7+
macOS x64 ✅ 完全支持 macOS 10.15+
macOS ARM64 ✅ 完全支持 Apple Silicon (M1/M2/M3)

2.1.3 开发工具

推荐使用以下开发工具:

  • Visual Studio 2022(Windows推荐)
  • Visual Studio Code + C# 扩展(跨平台推荐)
  • JetBrains Rider(跨平台IDE)
  • .NET CLI(命令行开发)

2.2 NuGet包安装

2.2.1 使用.NET CLI安装

# 创建新项目
dotnet new console -n MyGisApp
cd MyGisApp

# 安装OGU4Net
dotnet add package OpenGIS.Utils

# 恢复依赖
dotnet restore

2.2.2 使用Package Manager Console安装

在Visual Studio的包管理器控制台中执行:

Install-Package OpenGIS.Utils

2.2.3 编辑.csproj文件安装

直接编辑项目文件添加包引用:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenGIS.Utils" Version="1.0.0" />
  </ItemGroup>
</Project>

2.2.4 依赖项说明

安装 OpenGIS.Utils 后,以下依赖将自动安装:

依赖包 版本 用途
MaxRev.Gdal.Core 3.13.3.557 GDAL核心绑定
MaxRev.Gdal.Universal 3.13.3.557 跨平台GDAL运行时
System.Text.Json 10.0.11 JSON处理
System.Text.Encoding.CodePages 10.0.11 编码支持
SharpZipLib 1.4.2 ZIP压缩
Microsoft.Extensions.Logging.Abstractions 10.0.11 日志抽象(OguLogging 门面)
System.Memory 4.6.3 内存与性能
System.Buffers 4.6.1 缓冲区支持

2.3 IDE配置

2.3.1 Visual Studio 2022配置

创建新项目:

  1. 文件 → 新建 → 项目
  2. 选择”控制台应用”模板
  3. 项目名称:OguNetDemo
  4. 框架选择:.NET 8.0

安装NuGet包:

  1. 右键项目 → 管理NuGet程序包
  2. 搜索 OpenGIS.Utils
  3. 点击安装

配置生成选项:

  1. 右键项目 → 属性
  2. 生成 → 平台目标:x64
  3. 生成 → 允许不安全代码:是(可选)

2.3.2 Visual Studio Code配置

安装扩展:

  1. 安装 C# Dev Kit 扩展
  2. 安装 .NET Install Tool 扩展

创建项目:

# 创建项目目录
mkdir OguNetDemo && cd OguNetDemo

# 初始化项目
dotnet new console

# 安装OGU4Net
dotnet add package OpenGIS.Utils

# 打开VS Code
code .

配置launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (console)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/net8.0/OguNetDemo.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "console": "internalConsole",
            "stopAtEntry": false
        }
    ]
}

2.3.3 JetBrains Rider配置

  1. 文件 → 新建解决方案
  2. 选择 .NET / .NET Core → Console Application
  3. 框架选择:net8.0
  4. 右键项目 → 管理NuGet包
  5. 搜索并安装 OpenGIS.Utils

2.4 第一个程序

2.4.1 Hello OGU4Net

创建一个简单的程序来验证环境配置:

using OpenGIS.Utils.Configuration;
using OpenGIS.Utils.Geometry;

// 验证GDAL配置
Console.WriteLine("OpenGIS Utils for .NET Demo");
Console.WriteLine("===========================");

// 获取GDAL版本
var gdalVersion = GdalConfiguration.GetGdalVersion();
Console.WriteLine($"GDAL Version: {gdalVersion}");

// 获取支持的驱动
var drivers = GdalConfiguration.GetSupportedDrivers();
Console.WriteLine($"Supported Drivers: {drivers.Count}");

// 列出部分驱动
Console.WriteLine("\nSome supported drivers:");
foreach (var driver in drivers.Take(10))
{
    Console.WriteLine($"  - {driver}");
}

// 测试几何操作
Console.WriteLine("\nGeometry Test:");
var wkt = "POINT (116.404 39.915)";
Console.WriteLine($"  WKT: {wkt}");

var geojson = GeometryUtil.Wkt2Geojson(wkt);
Console.WriteLine($"  GeoJSON: {geojson}");

Console.WriteLine("\nEnvironment configured successfully!");

运行程序:

dotnet run

期望输出:

OpenGIS Utils for .NET Demo
===========================
GDAL Version: 3.12.0
Supported Drivers: 85

Some supported drivers:
  - ESRI Shapefile
  - MapInfo File
  - UK .NTF
  - LVBAG
  - OGR_SDTS
  - S57
  - DGN
  - OGR_VRT
  - Memory
  - CSV

Geometry Test:
  WKT: POINT (116.404 39.915)
  GeoJSON: { "type": "Point", "coordinates": [ 116.404, 39.915 ] }

Environment configured successfully!

2.4.2 创建简单图层

using OpenGIS.Utils.Engine.Enums;
using OpenGIS.Utils.Engine.Model.Layer;

Console.WriteLine("Creating a simple layer...");

// 创建图层
var layer = new OguLayer
{
    Name = "Cities",
    GeometryType = GeometryType.POINT,
    Wkid = 4326  // WGS84
};

// 添加字段
layer.AddField(new OguField
{
    Name = "ID",
    DataType = FieldDataType.INTEGER
});

layer.AddField(new OguField
{
    Name = "Name",
    DataType = FieldDataType.STRING,
    Length = 50
});

layer.AddField(new OguField
{
    Name = "Population",
    DataType = FieldDataType.LONG
});

// 添加要素
var beijing = new OguFeature
{
    Fid = 1,
    Wkt = "POINT (116.404 39.915)"
};
beijing.SetValue("ID", 1);
beijing.SetValue("Name", "北京");
beijing.SetValue("Population", 21540000L);
layer.AddFeature(beijing);

var shanghai = new OguFeature
{
    Fid = 2,
    Wkt = "POINT (121.473 31.230)"
};
shanghai.SetValue("ID", 2);
shanghai.SetValue("Name", "上海");
shanghai.SetValue("Population", 24870000L);
layer.AddFeature(shanghai);

// 验证图层
layer.Validate();

// 输出信息
Console.WriteLine($"Layer: {layer.Name}");
Console.WriteLine($"Geometry Type: {layer.GeometryType}");
Console.WriteLine($"Fields: {layer.Fields.Count}");
Console.WriteLine($"Features: {layer.GetFeatureCount()}");

Console.WriteLine("\nFeatures:");
foreach (var feature in layer.Features)
{
    var name = feature.GetValue("Name");
    var pop = feature.GetAttribute("Population")?.GetLongValue();
    Console.WriteLine($"  - {name}: Population {pop:N0}");
}

// 转换为JSON
Console.WriteLine("\nLayer JSON:");
Console.WriteLine(layer.ToJson());

2.4.3 读写Shapefile

准备测试数据后,测试数据读写:

using OpenGIS.Utils.DataSource;
using OpenGIS.Utils.Engine.Enums;

// 假设已有测试Shapefile
var inputPath = "data/test.shp";
var outputPath = "output/result.geojson";

// 确保输出目录存在
Directory.CreateDirectory("output");

// 读取Shapefile
Console.WriteLine($"Reading: {inputPath}");
var layer = OguLayerUtil.ReadLayer(DataFormatType.SHP, inputPath);

Console.WriteLine($"Layer Name: {layer.Name}");
Console.WriteLine($"Feature Count: {layer.GetFeatureCount()}");
Console.WriteLine($"Fields: {string.Join(", ", layer.Fields.Select(f => f.Name))}");

// 写入GeoJSON
Console.WriteLine($"\nWriting: {outputPath}");
OguLayerUtil.WriteLayer(DataFormatType.GEOJSON, layer, outputPath);

Console.WriteLine("Conversion completed!");

2.5 项目模板

2.5.1 控制台应用模板

// Program.cs
using OpenGIS.Utils.Configuration;
using OpenGIS.Utils.DataSource;
using OpenGIS.Utils.Engine.Enums;
using OpenGIS.Utils.Geometry;

namespace OguNetApp;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            // 确保GDAL已初始化
            GdalConfiguration.ConfigureGdal();
            
            Console.WriteLine($"GDAL Version: {GdalConfiguration.GetGdalVersion()}");
            
            // 你的业务逻辑
            ProcessGisData();
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"Error: {ex.Message}");
            Environment.Exit(1);
        }
    }
    
    static void ProcessGisData()
    {
        // 实现你的GIS数据处理逻辑
    }
}

2.5.2 ASP.NET Core Web API模板

// Program.cs
using OpenGIS.Utils.Configuration;

var builder = WebApplication.CreateBuilder(args);

// 初始化GDAL
GdalConfiguration.ConfigureGdal();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.MapControllers();
app.Run();
// Controllers/GeoController.cs
using Microsoft.AspNetCore.Mvc;
using OpenGIS.Utils.Geometry;
using OpenGIS.Utils.Engine.Util;

namespace OguNetApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class GeoController : ControllerBase
{
    [HttpPost("wkt2geojson")]
    public IActionResult Wkt2Geojson([FromBody] string wkt)
    {
        try
        {
            var geojson = GeometryUtil.Wkt2Geojson(wkt);
            return Ok(new { geojson });
        }
        catch (Exception ex)
        {
            return BadRequest(new { error = ex.Message });
        }
    }
    
    [HttpPost("buffer")]
    public IActionResult Buffer([FromBody] BufferRequest request)
    {
        try
        {
            var buffered = GeometryUtil.BufferWkt(request.Wkt, request.Distance);
            return Ok(new { wkt = buffered });
        }
        catch (Exception ex)
        {
            return BadRequest(new { error = ex.Message });
        }
    }
    
    [HttpPost("transform")]
    public IActionResult Transform([FromBody] TransformRequest request)
    {
        try
        {
            var result = CrsUtil.Transform(request.Wkt, request.SourceWkid, request.TargetWkid);
            return Ok(new { wkt = result });
        }
        catch (Exception ex)
        {
            return BadRequest(new { error = ex.Message });
        }
    }
}

public record BufferRequest(string Wkt, double Distance);
public record TransformRequest(string Wkt, int SourceWkid, int TargetWkid);

2.5.3 类库项目模板

<!-- MyGisLibrary.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>latest</LangVersion>
    <Nullable>enable</Nullable>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenGIS.Utils" Version="1.0.0" />
  </ItemGroup>
</Project>

2.6 常见问题

2.6.1 GDAL初始化失败

问题: 运行时提示找不到GDAL库或初始化失败。

解决方案:

  1. 确保安装了正确版本的 MaxRev.Gdal.Universal
  2. 检查目标平台是否为x64
  3. 清理并重新生成项目:
    dotnet clean
    dotnet restore
    dotnet build
    

2.6.2 中文乱码问题

问题: 读取Shapefile时中文属性显示乱码。

解决方案:

using OpenGIS.Utils.Utils;
using System.Text;

// 注册编码提供程序(通常在程序启动时执行一次)
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

// 检测文件编码
var encoding = EncodingUtil.GetFileEncoding("data.dbf");
Console.WriteLine($"Detected encoding: {encoding.WebName}");

// 使用ShpUtil读取(自动处理编码)
var layer = ShpUtil.ReadShapefile("data.shp");

2.6.3 Linux部署问题

问题: 在Linux上运行时提示缺少依赖库。

解决方案:

Ubuntu/Debian:

sudo apt-get update
sudo apt-get install -y libgdal-dev gdal-bin libproj-dev

CentOS/RHEL:

sudo yum install -y gdal gdal-devel proj proj-devel

2.6.4 内存占用过高

问题: 处理大数据时内存占用过高。

解决方案:

// 使用分批处理
foreach (var batch in layer.Features.Chunk(1000))
{
    ProcessBatch(batch);
    GC.Collect();  // 适当时机手动GC
}

// 及时释放大对象
layer = null;
GC.Collect();

2.6.5 FileGDB驱动不可用

问题: 尝试读取FileGDB时提示驱动不可用。

解决方案:

// 检查FileGDB驱动是否可用
if (GdalConfiguration.IsDriverAvailable("FileGDB"))
{
    Console.WriteLine("FileGDB driver is available");
}
else if (GdalConfiguration.IsDriverAvailable("OpenFileGDB"))
{
    Console.WriteLine("OpenFileGDB driver is available (read-only)");
}
else
{
    Console.WriteLine("No FileGDB driver available");
}

2.7 下一步

环境配置完成后,建议按以下顺序学习:

  1. 第03章 - 核心架构解析:深入理解OGU4Net的内部结构
  2. 第04章 - 统一图层模型详解:掌握OguLayer、OguFeature等核心类
  3. 第06章 - 数据格式转换实战:学习各种格式的读写操作

2.8 小结

本章介绍了OGU4Net的环境配置:

  1. 环境要求:.NET Standard 2.0兼容,支持Windows/Linux/macOS
  2. 包安装:通过NuGet安装OpenGIS.Utils
  3. IDE配置:Visual Studio、VS Code、Rider配置指南
  4. 第一个程序:验证环境配置,创建简单图层
  5. 项目模板:控制台应用、Web API、类库模板
  6. 常见问题:解决GDAL初始化、中文编码等问题

配置好开发环境后,就可以开始深入学习OGU4Net的核心功能了。


← 上一章 目录 下一章 →