10 void SCR_GeoPointData(vector
position, vector inTangent =
"0 0 0", vector outTangent =
"0 0 0")
13 m_vInTangent = inTangent;
14 m_vOutTangent = outTangent;
18enum SCR_EGeoExportType
31 void SCR_GeoProperty(
string name,
string value)
40 protected string m_sOutput;
41 protected float m_fXShift;
42 protected float m_fYShift;
44 protected ref FileHandle
m_File;
46 static const string IS_CLOSED_PROPERTY =
"IsClosed";
47 static const string LINE_COLOR_PROPERTY =
"LineColor";
48 static const string ROAD_WIDTH_PROPERTY =
"RoadWidth";
52 void SCR_GeoExporter(
string path,
int xShift,
int yShift)
67 Print(
"Unable to open file to write " + m_sOutput,
LogLevel.ERROR);
90 protected void Export(
string line)
107 void FeatureExport(
string name, GeoShapeType shapeType, array<ref SCR_GeoPointData> points, array<ref SCR_GeoProperty> props);
114class SCR_GeoSVGExporter : SCR_GeoExporter
116 protected float m_fXMax = 20000;
117 protected float m_fYMax = 20000;
119 protected static const string SVG_HEADER =
"<svg version=\"1.1\" id=\"WE\""
120 +
" xmlns=\"http:/" +
"/www.w3.org/2000/svg\""
121 +
" xmlns:xlink=\"http:/" +
"/www.w3.org/1999/xlink\""
122 +
" x=\"0px\" y=\"0px\" width=\"%1\" height=\"%2\" viewBox=\"0 0 %1 %2\">";
125 override void BeginExport()
127 WorldEditor we = Workbench.GetModule(WorldEditor);
130 we.GetTerrainBounds(min, max);
134 Export(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>");
135 Export(
"<!-- Generator: Enfusion, SVG Export Plug-In -->");
137 Export(
string.Format(SVG_HEADER, (
int)m_fXMax, (
int)m_fYMax));
141 override void FeatureExport(
string name, GeoShapeType shapeType, array<ref SCR_GeoPointData> points, array<ref SCR_GeoProperty> props)
143 if (shapeType == GeoShapeType.POINT)
146 foreach (SCR_GeoPointData point : points)
148 pos = point.m_vPosition;
149 Export(
string.Format(
"<path d=\"M%1,%2\"/>", pos[0] + m_fXShift, pos[2] + m_fYShift));
152 else if (shapeType == GeoShapeType.POLYLINE)
156 string polyline =
"<polyline fill=\"none\" stroke=\"#000000\" stroke-width=\"" + width +
"\" stroke-miterlimit=\"10\" ";
157 string pointsAttr =
"points=\"";
160 foreach (
int i, SCR_GeoPointData point : points)
165 pos = point.m_vPosition;
166 pointsAttr +=
string.Format(
"%1,%2", pos[0] + m_fXShift, pos[2] + m_fYShift);
169 polyline += pointsAttr;
174 else if (shapeType == GeoShapeType.POLYGON)
176 string polygon =
"<polygon ";
177 string pointsAttr =
"points=\"";
180 foreach (
int i, SCR_GeoPointData point : points)
185 pos = point.m_vPosition;
186 pointsAttr +=
string.Format(
"%1,%2", pos[0] + m_fXShift, pos[2] + m_fYShift);
189 polygon += pointsAttr;
194 else if (shapeType == GeoShapeType.UNKNOWN)
197 foreach (SCR_GeoProperty geo : props)
199 if (geo.m_sName == ROAD_WIDTH_PROPERTY && name.ToType() && name.ToType().IsInherited(RoadGeneratorEntity))
201 width = geo.m_sValue.ToInt();
206 string spline =
"<path fill=\"none\" stroke=\"#000000\" stroke-width=\"" + width +
"\" ";
207 string dAttr =
"d=\"";
209 vector inTangent, outTangent;
212 int countMinus1 = points.Count() - 1;
213 foreach (
int i, SCR_GeoPointData point : points)
215 if (i == countMinus1)
218 SCR_GeoPointData nextPoint = points[i + 1];
222 pos = point.m_vPosition;
223 pos[0] = pos[0] + m_fXShift;
224 pos[2] = -pos[2] + m_fYMax + m_fYShift;
225 vector ot = point.m_vOutTangent;
229 outTangent = pos + ot / 3;
231 nextPos = nextPoint.m_vPosition;
232 nextPos[0] = nextPos[0] + m_fXShift;
233 nextPos[2] = -nextPos[2] + m_fYMax + m_fYShift;
234 vector it = nextPoint.m_vInTangent;
237 inTangent = nextPos - it / 3;
240 dAttr +=
string.Format(
"M %1 %2", pos[0], pos[2]);
242 dAttr +=
string.Format(
" C %1 %2, %3 %4, %5 %6", outTangent[0], outTangent[2], inTangent[0], inTangent[2], nextPos[0], nextPos[2]);
254 override void EndExport()
260class SCR_GeoJSONExporter : SCR_GeoExporter
265 override void BeginExport()
267 Export(
"{\"type\": \"FeatureCollection\", \"features\": [");
271 override void FeatureExport(
string name, GeoShapeType shapeType, array<ref SCR_GeoPointData> points, array<ref SCR_GeoProperty> props)
273 string type =
"Point";
275 if (shapeType == GeoShapeType.UNKNOWN)
276 shapeType = GeoShapeType.POLYLINE;
278 if (shapeType == GeoShapeType.POLYLINE)
281 if (shapeType == GeoShapeType.POLYGON)
287 Export(
"{\"type\": \"Feature\",\"properties\":{");
288 Export(
"\"name\": \"" + name +
"\"");
290 foreach (SCR_GeoProperty geo : props)
292 Export(
",\"" + geo.m_sName +
"\": \"" + geo.m_sValue +
"\"");
295 Export(
"},\"geometry\":{\"type\": \"" +
type +
"\",\"coordinates\":");
297 if (shapeType == GeoShapeType.POLYGON)
300 if (shapeType == GeoShapeType.POLYLINE)
303 int countMinus1 = points.Count() - 1;
304 foreach (
int i, SCR_GeoPointData point : points)
306 if (i != countMinus1)
307 Export(
string.Format(
"[%1,%2],", point.m_vPosition[0] + m_fXShift, point.m_vPosition[2] + m_fYShift));
309 Export(
string.Format(
"[%1,%2]", point.m_vPosition[0] + m_fXShift, point.m_vPosition[2] + m_fYShift));
312 if (shapeType == GeoShapeType.POLYGON)
314 if (shapeType == GeoShapeType.POLYLINE)
325 override void EndExport()
336 description:
"Export vector data as Geographical data",
338 wbModules: {
"WorldEditor" },
340 awesomeFontCode: 0xF56E)]
341class SCR_ExportGeoDataPlugin : WorldEditorPlugin
343 [
Attribute(
"$profile:export",
UIWidgets.FileNamePicker,
"Where to save exported file. Do not use file suffix, it will be created automatically.")]
344 protected string m_sExportPath;
347 protected SCR_EGeoExportType
m_eType;
350 protected float m_fXShift;
353 protected float m_fYShift;
355 protected static const string PLUGIN_NAME =
"Export Geographic Data";
360 WorldEditorAPI worldEditorAPI = SCR_WorldEditorToolHelper.GetWorldEditorAPI();
361 int selectedCount = worldEditorAPI.GetSelectedEntitiesCount();
362 if (selectedCount < 1)
368 if (Workbench.ScriptDialog(PLUGIN_NAME,
"",
this) == 0)
375 protected void Export()
377 if (m_sExportPath.IsEmpty())
383 string relativeFilePath;
384 SCR_GeoExporter exporter;
386 if (
m_eType == SCR_EGeoExportType.SVG)
388 relativeFilePath = m_sExportPath +
".svg";
389 exporter =
new SCR_GeoSVGExporter(relativeFilePath, m_fXShift, m_fYShift);
393 relativeFilePath = m_sExportPath +
".json";
394 exporter =
new SCR_GeoJSONExporter(relativeFilePath, m_fXShift, m_fYShift);
397 if (!exporter.Init())
403 Debug.BeginTimeMeasure();
405 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
407 WBProgressDialog progress =
new WBProgressDialog(
"Processing", worldEditor);
409 int selectedCount = worldEditorAPI.GetSelectedEntitiesCount();
410 Print(
"GeoExport: exporting " + selectedCount +
" entities...",
LogLevel.NORMAL);
411 exporter.BeginExport();
414 array<ref SCR_GeoProperty> properties;
416 ShapeEntity shapeEntity;
417 SplineShapeEntity splineEntity;
418 array<vector> positions;
419 array<ref SCR_GeoPointData> pointData;
422 float prevProgress, currProgress;
423 for (
int i; i < selectedCount; i++)
425 currProgress = i / selectedCount;
426 if (currProgress - prevProgress >= 0.01)
428 progress.SetProgress(currProgress);
429 prevProgress = currProgress;
432 entitySource = worldEditorAPI.GetSelectedEntity(i);
434 string classname = entitySource.GetClassName();
442 typeName = classname.ToType();
443 if (typeName && typeName.IsInherited(SCR_GeneratorBaseEntity) && !typeName.IsInherited(PrefabGeneratorEntity))
445 if (typeName.IsInherited(RoadGeneratorEntity))
448 entitySource.Get(SCR_GeoExporter.ROAD_WIDTH_PROPERTY, roadWidth);
449 properties.Insert(
new SCR_GeoProperty(SCR_GeoExporter.ROAD_WIDTH_PROPERTY, roadWidth.ToString()));
453 entitySource = entitySource.GetParent();
459 classname = entitySource.GetClassName();
461 if (entitySource && typeName == PolylineShapeEntity || typeName == SplineShapeEntity)
467 entitySource.Get(SCR_GeoExporter.IS_CLOSED_PROPERTY, isClosed);
469 GeoShapeType shapeType;
470 if (typeName == PolylineShapeEntity)
473 shapeType = GeoShapeType.POLYGON;
475 shapeType = GeoShapeType.POLYLINE;
479 shapeType = GeoShapeType.UNKNOWN;
482 entitySource.Get(SCR_GeoExporter.LINE_COLOR_PROPERTY, color);
483 string colorProperty =
string.Format(
"%1,%2,%3,%4",
Math.Round(color.R() * 255),
Math.Round(color.G() * 255),
Math.Round(color.B() * 255),
Math.Round(color.A() * 255));
484 properties.Insert(
new SCR_GeoProperty(SCR_GeoExporter.LINE_COLOR_PROPERTY, colorProperty));
487 shapeEntity = ShapeEntity.Cast(worldEditorAPI.SourceToEntity(entitySource));
488 splineEntity = SplineShapeEntity.Cast(shapeEntity);
491 shapeEntity.GetPointsPositions(positions);
502 splineEntity.GetTangents(j, inTangent, outTangent);
504 pointData.Insert(
new SCR_GeoPointData(pos, inTangent, outTangent));
507 if (isClosed && pointData.Count() > 2)
509 vector first = pointData[0].m_vPosition;
510 vector last = pointData[pointData.Count() - 1].m_vPosition;
512 pointData.Insert(
new SCR_GeoPointData(first));
515 exporter.FeatureExport(classname, shapeType, pointData, properties);
519 pointData = {
new SCR_GeoPointData(worldEditorAPI.SourceToEntity(entitySource).
GetOrigin()) };
521 exporter.FeatureExport(classname, GeoShapeType.POINT, pointData, properties);
525 exporter.EndExport();
528 Debug.EndTimeMeasure(
typename.EnumToString(SCR_EGeoExportType,
m_eType) +
" export");
535 protected int ButtonExport()
SCR_ECampaignBaseType m_eType
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
proto native void Close()
class WorkbenchDialog_AbortRetryIgnore ButtonAttribute("OK", true)
proto external vector GetOrigin()
static ParamEnumArray FromString(string input)
static void PrintDialog(string message, string caption="", LogLevel level=LogLevel.WARNING)
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
SCR_FieldOfViewSettings Attribute
FileMode
Mode for opening file. See FileSystem::Open.