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

第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.12.0 GDAL核心绑定
MaxRev.Gdal.Universal 3.12.0 跨平台GDAL运行时
System.Text.Json 10.0.0 JSON处理
System.Text.Encoding.CodePages 10.0.0 编码支持
SharpZipLib 1.4.2 ZIP压缩
Microsoft.Extensions.Logging.Abstractions 10.0.0 日志

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的核心功能了。

posted @ 2025-12-03 17:40  我才是银古  阅读(0)  评论(0)    收藏  举报