C#将shapefile转换为geojson—代码拼接GeoJson字符串
之前项目有需要,GitHub上找到的资源。记录一下,以后需要好查找。
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using ESRI.ArcGIS.esriSystem; //using ESRI.ArcGIS.Server; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.SOESupport; namespace Zekiah.GeoJSON { /// <summary> /// GeoJson转换,网上找的方法,直接拼接整个geojson字符串 /// </summary> public static class GeoJsonExtensions { public static string ToGeoJsonOld(this IFeatureCursor rows) { try { string retval = "{ \"type\": \"FeatureCollection\", "; retval += "\"features\": ["; List<string> feats = new List<string>(); IFeature row = rows.NextFeature(); while (row != null) { feats.Add(row.ToGeoJson()); row = rows.NextFeature(); } var featarray = feats.ToArray(); var featjoin = string.Join(",", featarray); retval += featjoin; retval += "]}"; return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing row collection"); throw new Exception("Error processing row collection", ex); } } public static string ToGeoJson(this IFeatureCursor rows) { try { string retval = "{ \"type\": \"FeatureCollection\", "; retval += "\"features\": ["; List<string> feats = new List<string>(); IFeature row = rows.NextFeature(); while (row != null) { feats.Add(row.ToGeoJson()); row = rows.NextFeature(); } var featarray = feats.ToArray(); var featjoin = string.Join(",", featarray); retval += featjoin; retval += "],"; //坐标系 retval += "\"crs\":{\"properties\":{\"name\":\"EPSG:3857\"},\"type\":\"name\"}}"; return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing row collection"); throw new Exception("Error processing row collection", ex); } } public static string ToGeoJson(this IFeature row) { try { StringBuilder sb = new StringBuilder("{ \"type\": \"Feature\", "); var geom = row.Shape; //GeoJSONSOE.Helpers help = new GeoJSONSOE.Helpers(); //help.TransformShapeCS(row.Shape, (row.Class as IGeoDataset).SpatialReference, help.GetSpatialReference(102100)); sb.Append("\"geometry\": "); sb.Append(geom.ToGeoJson()); sb.Append(", "); sb.Append(processFields(row)); sb.Append("}"); return sb.ToString(); } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing row"); throw new Exception("Error processing row", ex); } } private static string processFields(IFeature row) { try { StringBuilder sb = new StringBuilder("\"properties\": {"); List<string> props = new List<string>(); string proptemplate = "\"{0}\": \"{1}\""; for (int fldnum = 0; fldnum < row.Fields.FieldCount; fldnum++) { proptemplate = "\"{0}\": \"{1}\""; string fldname = row.Fields.Field[fldnum].Name; IField fld = row.Fields.Field[fldnum]; string fldval = ""; if (row.Value[fldnum].Equals(null)) { fldval = "null"; } else { switch (fld.Type) { case esriFieldType.esriFieldTypeGeometry: fldval = "geometry"; break; case esriFieldType.esriFieldTypeBlob: fldval = "blob"; break; case esriFieldType.esriFieldTypeSmallInteger: case esriFieldType.esriFieldTypeInteger: case esriFieldType.esriFieldTypeSingle: case esriFieldType.esriFieldTypeDouble: proptemplate = "\"{0}\": {1}"; fldval = row.Value[fldnum].ToString(); break; case esriFieldType.esriFieldTypeString: case esriFieldType.esriFieldTypeOID: case esriFieldType.esriFieldTypeGUID: case esriFieldType.esriFieldTypeGlobalID: fldval = row.Value[fldnum].ToString(); break; case esriFieldType.esriFieldTypeDate: fldval = Convert.ToDateTime(row.Value[fldnum]).ToLongTimeString(); break; default: break; } } string propval = string.Format(proptemplate, fldname, fldval); props.Add(propval); } var proparray = props.ToArray(); string propsjoin = string.Join(",", proparray); sb.Append(propsjoin); sb.Append("}"); return sb.ToString(); } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing attributes"); throw new Exception("Error processing attributes", ex); } } public static string ToGeoJson(this IGeometry geometry) { try { string retval = ""; var shapeType = geometry.GeometryType; //note: "M" values are not really supported. Relevant geometries are handled to extract Z values, if present. switch (shapeType) { case esriGeometryType.esriGeometryMultipoint: IMultipoint mptbuff = (IMultipoint)geometry; retval = processMultiPointBuffer(mptbuff); break; case esriGeometryType.esriGeometryPoint: IPoint pt = (IPoint)geometry; retval = processPointBuffer(pt); break; case esriGeometryType.esriGeometryPolyline: IPolyline lbuff = (IPolyline)geometry; retval = processMultiPartBuffer((IGeometryCollection)lbuff, "MultiLineString"); break; case esriGeometryType.esriGeometryPolygon: IPolygon pbuff = (IPolygon)geometry; retval = processMultiPartBuffer((IGeometryCollection)pbuff, "Polygon"); break; } return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing geometry"); throw new Exception("Error processing geometry", ex); } } private static string processPointBuffer(IPoint buffer) { try { StringBuilder retval = new StringBuilder("{\"type\":\"Point\", \"coordinates\": "); bool hasZ = false; string coord = hasZ ? getCoordinate(buffer.X, buffer.Y, buffer.Z) : getCoordinate(buffer.X, buffer.Y); retval.Append(coord); retval.Append("}"); return retval.ToString(); } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing point buffer"); throw new Exception("Error processing point buffer", ex); } } private static string processMultiPointBuffer(IMultipoint buffer) { try { StringBuilder retval = new StringBuilder("{\"type\":\"MultiPoint\", \"coordinates\": ["); bool hasZ = false; IPointCollection points = (IPointCollection)buffer; List<string> coords = new List<string>(); for (int i = 0; i < points.PointCount; i++) { string coord = hasZ ? getCoordinate(points.Point[i].X, points.Point[i].Y, points.Point[i].Z) : getCoordinate(points.Point[i].X, points.Point[i].Y); coords.Add(coord); } string[] coordArray = coords.ToArray(); string coordList = string.Join(",", coordArray); retval.Append(coordList); retval.Append("]}"); return retval.ToString(); } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing multipoint buffer"); throw new Exception("Error processing multipoint buffer", ex); } } private static string processMultiPartBuffer(IGeometryCollection buffer, string geoJsonType) { try { List<string> delims = getMultipartDelimiter(geoJsonType); bool hasZ = false; StringBuilder retval = new StringBuilder("{\"type\":\"" + geoJsonType + "\", \"coordinates\": ["); int numPts = 0; int numParts = buffer.GeometryCount; List<string> coords = new List<string>(); List<string> polys = new List<string>(); for (int i = 0; i < numParts; i++) { if (coords.Count > 0) { string[] coordArray = coords.ToArray(); string coordList = string.Join(",", coordArray); polys.Add(delims[0] + coordList + delims[1]); } coords = new List<string>(); IGeometry part = buffer.Geometry[i]; IPointCollection pcoll = (IPointCollection)part; numPts = pcoll.PointCount; for (int j = 0; j < numPts; j++) { IPoint pt = pcoll.Point[j]; string coord = hasZ ? getCoordinate(pt.X, pt.Y, pt.Z) : getCoordinate(pt.X, pt.Y); coords.Add(coord); } //if (geoJsonType == "MultiPolygon") //{ // IPoint pt = pcoll.Point[0]; // string coord = hasZ ? getCoordinate(pt.X, pt.Y, pt.Z) : getCoordinate(pt.X, pt.Y); // coords.Add(coord); //} } if (coords.Count > 0) { string[] coordArray = coords.ToArray(); string coordList = string.Join(",", coordArray); polys.Add(delims[0] + coordList + delims[1]); } string[] polyArray = polys.ToArray(); string polyList = string.Join(",", polyArray); retval.Append(polyList); retval.Append("]}"); return retval.ToString(); } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error processing multipart buffer"); throw new Exception("Error processing multipart buffer", ex); } } private static List<string> getMultipartDelimiter(string geoJsonType) { try { List<string> retval = new List<string>(); switch (geoJsonType.ToLower()) { case "multipoint": retval.Add(""); retval.Add(""); break; case "multilinestring": retval.Add("["); retval.Add("]"); break; case "polygon": retval.Add("["); retval.Add("]"); break; } return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error generating delimiter"); throw new Exception("Error generating delimiter", ex); } } private static string getCoordinate(double x, double y) { try { string retval = string.Format(CultureInfo.InvariantCulture, "[{0}, {1}]", x, y); return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error generating coordinate"); throw new Exception("Error generating coordinate", ex); } } private static string getCoordinate(double x, double y, double z) { try { string retval = string.Format(CultureInfo.InvariantCulture, "[{0}, {1}, {2}]", x, y, z); return retval; } catch (Exception ex) { LogManager.Write(ex); LogManager.Write("Error generating coordinate"); throw new Exception("Error generating coordinate", ex); } } } }