Repository: SpaceGroupUCL/depthmapX Branch: master Commit: 02ceaec01545 Files: 592 Total size: 29.1 MB Directory structure: gitextract_8mx2ef4h/ ├── .gitignore ├── .mailmap ├── .travis.yml ├── CMakeLists.txt ├── GuiUnitTest/ │ ├── .gitignore │ ├── CMakeLists.txt │ ├── main.cpp │ ├── testsettings.cpp │ └── testviewhelpers.cpp ├── README.md ├── RegressionTest/ │ ├── BaselineBinaries/ │ │ ├── Darwin/ │ │ │ └── depthmapXcli │ │ └── Linux/ │ │ └── depthmapXcli │ ├── RegressionTestRunner.py │ ├── cmdlinewrapper.py │ ├── config.py │ ├── depthmaprunner.py │ ├── performance_regression.json │ ├── performanceregressionconfig.py │ ├── performancerunner.py │ ├── regressionconfig.json │ ├── regressionconfig_agents.json │ ├── runhelpers.py │ └── test/ │ ├── context.py │ ├── disposablefile.py │ ├── fail/ │ │ └── test_fail.py │ ├── pass/ │ │ └── test_pass.py │ ├── test_RegressionTestRunner.py │ ├── test_cmdlinewrapper.py │ ├── test_config.py │ ├── test_depthmaprunner.py │ ├── test_disposablefile.py │ ├── test_main.py │ ├── test_performanceregressionconfig.py │ ├── test_performancerunner.py │ ├── test_runhelpers.py │ └── test_test_main.py ├── ThirdParty/ │ ├── Catch/ │ │ └── catch.hpp │ └── FakeIt/ │ └── Catch/ │ └── fakeit.hpp ├── ci/ │ ├── .gitattributes │ └── build.sh ├── cliTest/ │ ├── CMakeLists.txt │ ├── argumentholder.h │ ├── main.cpp │ ├── selfcleaningfile.h │ ├── testagentparser.cpp │ ├── testargumentholder.cpp │ ├── testaxialparser.cpp │ ├── testcommandlineparser.cpp │ ├── testexportparser.cpp │ ├── testimportparser.cpp │ ├── testisovistparser.cpp │ ├── testlinkparser.cpp │ ├── testmapconvertparser.cpp │ ├── testparsingutils.cpp │ ├── testperformancewriter.cpp │ ├── testradiusconverter.cpp │ ├── testsegmentparser.cpp │ ├── testselfcleaningfile.cpp │ ├── testsimpletimer.cpp │ ├── teststepdepthparser.cpp │ ├── testvgaparser.cpp │ └── testvisprepparser.cpp ├── depthmapX/ │ ├── CMakeLists.txt │ ├── GraphDoc.cpp │ ├── GraphDoc.h │ ├── UI/ │ │ ├── AboutDlg.ui │ │ ├── AgentAnalysisDlg.ui │ │ ├── AttributeChooserDlg.ui │ │ ├── AttributeSummary.ui │ │ ├── AxialAnalysisOptionsDlg.ui │ │ ├── ColourScaleDlg.ui │ │ ├── ColourScaleDlg.ui.bak │ │ ├── ColumnPropertiesDlg.ui │ │ ├── ConvertShapesDlg.ui │ │ ├── DepthmapAlert.ui │ │ ├── DepthmapOptionsDlg.ui │ │ ├── EditConnectionsDlg.ui │ │ ├── FewestLineOptionsDlg.ui │ │ ├── FilePropertiesDlg.ui │ │ ├── FindLocDlg.ui │ │ ├── GridDialog.ui │ │ ├── InsertColumnDlg.ui │ │ ├── IsovistPathDlg.ui │ │ ├── LayerChooserDlg.ui │ │ ├── LicenceDialog.ui │ │ ├── MakeLayerDlg.ui │ │ ├── MakeOptionsDlg.ui │ │ ├── NewLayerDlg.ui │ │ ├── OptionsDlg.ui │ │ ├── PromptReplace.ui │ │ ├── PushDialog.ui │ │ ├── RenameObjectDlg.ui │ │ ├── SegmentAnalysisDlg.ui │ │ ├── TopoMetDlg.ui │ │ ├── doAll.sh │ │ └── licenseagreement.ui │ ├── compatibilitydefines.h │ ├── coreapplication.cpp │ ├── coreapplication.h │ ├── dialogs/ │ │ ├── AboutDlg.cpp │ │ ├── AboutDlg.h │ │ ├── AgentAnalysisDlg.cpp │ │ ├── AgentAnalysisDlg.h │ │ ├── AttributeChooserDlg.cpp │ │ ├── AttributeChooserDlg.h │ │ ├── AttributeSummary.cpp │ │ ├── AttributeSummary.h │ │ ├── AxialAnalysisOptionsDlg.cpp │ │ ├── AxialAnalysisOptionsDlg.h │ │ ├── CMakeLists.txt │ │ ├── ColourScaleDlg.cpp │ │ ├── ColourScaleDlg.h │ │ ├── ColumnPropertiesDlg.cpp │ │ ├── ColumnPropertiesDlg.h │ │ ├── ConvertShapesDlg.cpp │ │ ├── ConvertShapesDlg.h │ │ ├── EditConnectionsDlg.cpp │ │ ├── EditConnectionsDlg.h │ │ ├── FewestLineOptionsDlg.cpp │ │ ├── FewestLineOptionsDlg.h │ │ ├── FilePropertiesDlg.cpp │ │ ├── FilePropertiesDlg.h │ │ ├── FindLocDlg.cpp │ │ ├── FindLocDlg.h │ │ ├── GridDialog.cpp │ │ ├── GridDialog.h │ │ ├── InsertColumnDlg.cpp │ │ ├── InsertColumnDlg.h │ │ ├── IsovistPathDlg.cpp │ │ ├── IsovistPathDlg.h │ │ ├── LayerChooserDlg.cpp │ │ ├── LayerChooserDlg.h │ │ ├── LicenceDialog.cpp │ │ ├── LicenceDialog.h │ │ ├── MakeLayerDlg.cpp │ │ ├── MakeLayerDlg.h │ │ ├── MakeOptionsDlg.cpp │ │ ├── MakeOptionsDlg.h │ │ ├── NewLayerDlg.cpp │ │ ├── NewLayerDlg.h │ │ ├── OptionsDlg.cpp │ │ ├── OptionsDlg.h │ │ ├── PromptReplace.cpp │ │ ├── PromptReplace.h │ │ ├── PushDialog.cpp │ │ ├── PushDialog.h │ │ ├── RenameObjectDlg.cpp │ │ ├── RenameObjectDlg.h │ │ ├── SegmentAnalysisDlg.cpp │ │ ├── SegmentAnalysisDlg.h │ │ ├── TopoMetDlg.cpp │ │ ├── TopoMetDlg.h │ │ ├── licenseagreement.cpp │ │ ├── licenseagreement.h │ │ └── settings/ │ │ ├── generalpage.cpp │ │ ├── generalpage.h │ │ ├── interfacepage.cpp │ │ ├── interfacepage.h │ │ ├── settingsdialog.cpp │ │ ├── settingsdialog.h │ │ ├── settingsdialog.qrc │ │ └── settingspage.h │ ├── icons/ │ │ ├── depthmapX.icns │ │ └── graph.icns │ ├── icons.rc │ ├── imainwindowmodule.h │ ├── imainwindowmodulefactory.h │ ├── indexWidget.cpp │ ├── indexWidget.h │ ├── main.cpp │ ├── mainwindow.cpp │ ├── mainwindow.h │ ├── mainwindowfactory.cpp │ ├── mainwindowfactory.h │ ├── mainwindowhelpers.cpp │ ├── mainwindowhelpers.h │ ├── mainwindowmodulefactory.cpp │ ├── mainwindowmoduleregistry.cpp │ ├── mainwindowmoduleregistry.hpp │ ├── make_version_header.bat │ ├── make_version_header.sh │ ├── mdichild.cpp │ ├── mdichild.h │ ├── qrc_mdi.cpp │ ├── renderthread.cpp │ ├── resource.qrc │ ├── resources/ │ │ └── Info.plist │ ├── settings.h │ ├── settingsimpl.cpp │ ├── settingsimpl.h │ ├── treeWindow.cpp │ ├── treeWindow.h │ └── views/ │ ├── 3dview/ │ │ ├── 3dview.cpp │ │ ├── 3dview.h │ │ └── glureimpl.h │ ├── CMakeLists.txt │ ├── depthmapview/ │ │ ├── depthmapview.cpp │ │ └── depthmapview.h │ ├── glview/ │ │ ├── gldynamicline.cpp │ │ ├── gldynamicline.h │ │ ├── gldynamicrect.cpp │ │ ├── gldynamicrect.h │ │ ├── gllines.cpp │ │ ├── gllines.h │ │ ├── gllinesuniform.cpp │ │ ├── gllinesuniform.h │ │ ├── glpointmap.cpp │ │ ├── glpointmap.h │ │ ├── glpolygons.cpp │ │ ├── glpolygons.h │ │ ├── glrastertexture.cpp │ │ ├── glrastertexture.h │ │ ├── glregularpolygons.cpp │ │ ├── glregularpolygons.h │ │ ├── glshapegraph.cpp │ │ ├── glshapegraph.h │ │ ├── glshapemap.cpp │ │ ├── glshapemap.h │ │ ├── gltriangles.cpp │ │ ├── gltriangles.h │ │ ├── gltrianglesuniform.cpp │ │ ├── gltrianglesuniform.h │ │ ├── glutriangulator.cpp │ │ ├── glutriangulator.h │ │ ├── glview.cpp │ │ └── glview.h │ ├── mapview.cpp │ ├── mapview.h │ ├── plotview/ │ │ ├── plotview.cpp │ │ └── plotview.h │ ├── tableview/ │ │ ├── tableview.cpp │ │ └── tableview.h │ ├── viewhelpers.cpp │ └── viewhelpers.h ├── depthmapXTest/ │ ├── CMakeLists.txt │ ├── main.cpp │ ├── testgllines.cpp │ ├── testgllinesuniform.cpp │ └── testglrastertexture.cpp ├── depthmapXcli/ │ ├── CMakeLists.txt │ ├── agentparser.cpp │ ├── agentparser.h │ ├── axialparser.cpp │ ├── axialparser.h │ ├── commandlineparser.cpp │ ├── commandlineparser.h │ ├── exceptions.h │ ├── exportparser.cpp │ ├── exportparser.h │ ├── imodeparser.h │ ├── imodeparserfactory.h │ ├── importparser.cpp │ ├── importparser.h │ ├── isovistparser.cpp │ ├── isovistparser.h │ ├── linkparser.cpp │ ├── linkparser.h │ ├── main.cpp │ ├── mapconvertparser.cpp │ ├── mapconvertparser.h │ ├── modeparserregistry.cpp │ ├── modeparserregistry.h │ ├── parsingutils.cpp │ ├── parsingutils.h │ ├── performancesink.h │ ├── performancewriter.cpp │ ├── performancewriter.h │ ├── printcommunicator.cpp │ ├── printcommunicator.h │ ├── radiusconverter.cpp │ ├── radiusconverter.h │ ├── runmethods.cpp │ ├── runmethods.h │ ├── segmentparser.cpp │ ├── segmentparser.h │ ├── simpletimer.h │ ├── stepdepthparser.cpp │ ├── stepdepthparser.h │ ├── vgaparser.cpp │ ├── vgaparser.h │ ├── visprepparser.cpp │ └── visprepparser.h ├── docs/ │ ├── about.md │ ├── building.md │ ├── commandline.md │ ├── formatting.md │ ├── gui.md │ ├── howdoi.md │ └── index.md ├── genlib/ │ ├── CMakeLists.txt │ ├── bsptree.cpp │ ├── bsptree.h │ ├── comm.h │ ├── containerutils.h │ ├── exceptions.h │ ├── lgpl.txt │ ├── linreg.h │ ├── p2dpoly.cpp │ ├── p2dpoly.h │ ├── pafmath.cpp │ ├── pafmath.h │ ├── pflipper.h │ ├── readwritehelpers.h │ ├── simplematrix.h │ ├── stringutils.cpp │ ├── stringutils.h │ ├── xmlparse.cpp │ └── xmlparse.h ├── genlibTest/ │ ├── CMakeLists.txt │ ├── main.cpp │ ├── testbspnode.cpp │ ├── testcontainerutils.cpp │ ├── testreadwritehelpers.cpp │ ├── testsimplematrix.cpp │ └── teststringutils.cpp ├── mgraph440/ │ ├── CMakeLists.txt │ ├── attr.cpp │ ├── attr.h │ ├── attributes.cpp │ ├── attributes.h │ ├── axialmap.cpp │ ├── axialmap.h │ ├── bspnode.h │ ├── comm.h │ ├── connector.cpp │ ├── connector.h │ ├── containerutils.h │ ├── datalayer.cpp │ ├── datalayer.h │ ├── displayparams.h │ ├── exceptions.h │ ├── fileproperties.h │ ├── legacyconverters.h │ ├── mapinfodata.h │ ├── mgraph.cpp │ ├── mgraph.h │ ├── mgraph_consts.h │ ├── ngraph.cpp │ ├── ngraph.h │ ├── options.h │ ├── p2dpoly.cpp │ ├── p2dpoly.h │ ├── pafcolor.cpp │ ├── pafcolor.h │ ├── pafmath.cpp │ ├── pafmath.h │ ├── paftl.h │ ├── pixelbase.cpp │ ├── pixelbase.h │ ├── pixelref.h │ ├── point.cpp │ ├── point.h │ ├── pointmap.cpp │ ├── pointmap.h │ ├── salaprogram.cpp │ ├── salaprogram.h │ ├── shapemap.cpp │ ├── shapemap.h │ ├── spacepix.cpp │ ├── spacepix.h │ ├── stringutils.cpp │ └── stringutils.h ├── mgraph440Test/ │ ├── CMakeLists.txt │ ├── main.cpp │ ├── testcontainers.cpp │ └── testconverters.cpp ├── moduleTest/ │ ├── CMakeLists.txt │ └── main.cpp ├── modules/ │ ├── CMakeLists.txt │ └── segmentshortestpaths/ │ ├── CMakeLists.txt │ ├── RegressionTest/ │ │ └── regressionconfig.json │ ├── cli/ │ │ ├── CMakeLists.txt │ │ ├── segmentshortestpathparser.cpp │ │ └── segmentshortestpathparser.h │ ├── cliTest/ │ │ ├── CMakeLists.txt │ │ └── segmentshortestpathparsertest.cpp │ ├── core/ │ │ ├── CMakeLists.txt │ │ ├── segmmetricshortestpath.cpp │ │ ├── segmmetricshortestpath.h │ │ ├── segmtopologicalshortestpath.cpp │ │ ├── segmtopologicalshortestpath.h │ │ ├── segmtulipshortestpath.cpp │ │ └── segmtulipshortestpath.h │ ├── coreTest/ │ │ ├── CMakeLists.txt │ │ └── segmentpathscoretest.cpp │ └── gui/ │ ├── CMakeLists.txt │ ├── segmentpathsmainwindow.cpp │ ├── segmentpathsmainwindow.h │ └── uictrigger.cpp ├── releases/ │ ├── README.txt │ ├── gplv3.txt │ ├── lgplv3.txt │ └── licenses.txt ├── salaTest/ │ ├── CMakeLists.txt │ ├── main.cpp │ ├── testattributetable.cpp │ ├── testattributetablehelpers.cpp │ ├── testattributetableindex.cpp │ ├── testattributetableview.cpp │ ├── testdxfp.cpp │ ├── testentityparsing.cpp │ ├── testgeometrygenerators.cpp │ ├── testgridproperties.cpp │ ├── testisovist.cpp │ ├── testisovistdef.cpp │ ├── testlayermanager.cpp │ ├── testlinkutils.cpp │ ├── testmapconversion.cpp │ ├── testmapinfodata.cpp │ ├── testmgraph.cpp │ ├── testpointinpoly.cpp │ ├── testpointmap.cpp │ ├── testpushvalues.cpp │ ├── testsalaprogram.cpp │ ├── testshapegraphs.cpp │ ├── testshapemaps.cpp │ ├── testshaperemove.cpp │ ├── testsparksieve.cpp │ └── teststructsizes.cpp ├── salalib/ │ ├── CMakeLists.txt │ ├── agents/ │ │ ├── CMakeLists.txt │ │ ├── agent.cpp │ │ ├── agent.h │ │ ├── agentengine.cpp │ │ ├── agentengine.h │ │ ├── agentga.cpp │ │ ├── agentga.h │ │ ├── agenthelpers.h │ │ ├── agentprogram.cpp │ │ ├── agentprogram.h │ │ ├── agentset.cpp │ │ └── agentset.h │ ├── alllinemap.cpp │ ├── alllinemap.h │ ├── attributetable.cpp │ ├── attributetable.h │ ├── attributetablehelpers.h │ ├── attributetableindex.cpp │ ├── attributetableindex.h │ ├── attributetableview.cpp │ ├── attributetableview.h │ ├── axialmap.cpp │ ├── axialmap.h │ ├── axialminimiser.cpp │ ├── axialminimiser.h │ ├── axialmodules/ │ │ ├── CMakeLists.txt │ │ ├── axialintegration.cpp │ │ ├── axialintegration.h │ │ ├── axialstepdepth.cpp │ │ └── axialstepdepth.h │ ├── axialpolygons.cpp │ ├── axialpolygons.h │ ├── connector.cpp │ ├── connector.h │ ├── displayparams.h │ ├── entityparsing.cpp │ ├── entityparsing.h │ ├── fileproperties.h │ ├── geometrygenerators.cpp │ ├── geometrygenerators.h │ ├── gridproperties.cpp │ ├── gridproperties.h │ ├── ianalysis.h │ ├── iaxial.h │ ├── importtypedefs.h │ ├── importutils.cpp │ ├── importutils.h │ ├── isegment.h │ ├── isovist.cpp │ ├── isovist.h │ ├── isovistdef.h │ ├── ivga.h │ ├── layermanager.h │ ├── layermanagerimpl.cpp │ ├── layermanagerimpl.h │ ├── linkutils.cpp │ ├── linkutils.h │ ├── mapconverter.cpp │ ├── mapconverter.h │ ├── mgraph.cpp │ ├── mgraph.h │ ├── mgraph_consts.h │ ├── ngraph.cpp │ ├── ngraph.h │ ├── options.h │ ├── pafcolor.cpp │ ├── pafcolor.h │ ├── parsers/ │ │ ├── CMakeLists.txt │ │ ├── dxfp.cpp │ │ ├── dxfp.h │ │ ├── mapinfodata.cpp │ │ ├── mapinfodata.h │ │ ├── ntfp.cpp │ │ ├── ntfp.h │ │ ├── tigerp.cpp │ │ └── tigerp.h │ ├── pixelref.h │ ├── point.cpp │ ├── point.h │ ├── pointdata.cpp │ ├── pointdata.h │ ├── salaprogram.cpp │ ├── salaprogram.h │ ├── segmmodules/ │ │ ├── CMakeLists.txt │ │ ├── segmangular.cpp │ │ ├── segmangular.h │ │ ├── segmhelpers.h │ │ ├── segmmetric.cpp │ │ ├── segmmetric.h │ │ ├── segmmetricpd.cpp │ │ ├── segmmetricpd.h │ │ ├── segmtopological.cpp │ │ ├── segmtopological.h │ │ ├── segmtopologicalpd.cpp │ │ ├── segmtopologicalpd.h │ │ ├── segmtulip.cpp │ │ ├── segmtulip.h │ │ ├── segmtulipdepth.cpp │ │ └── segmtulipdepth.h │ ├── shapemap.cpp │ ├── shapemap.h │ ├── spacepix.cpp │ ├── spacepix.h │ ├── spacepixfile.cpp │ ├── spacepixfile.h │ ├── sparksieve2.cpp │ ├── sparksieve2.h │ ├── tidylines.cpp │ ├── tidylines.h │ ├── tolerances.h │ └── vgamodules/ │ ├── CMakeLists.txt │ ├── vgaangular.cpp │ ├── vgaangular.h │ ├── vgaangulardepth.cpp │ ├── vgaangulardepth.h │ ├── vgaisovist.cpp │ ├── vgaisovist.h │ ├── vgametric.cpp │ ├── vgametric.h │ ├── vgametricdepth.cpp │ ├── vgametricdepth.h │ ├── vgathroughvision.cpp │ ├── vgathroughvision.h │ ├── vgavisualglobal.cpp │ ├── vgavisualglobal.h │ ├── vgavisualglobaldepth.cpp │ ├── vgavisualglobaldepth.h │ ├── vgavisuallocal.cpp │ └── vgavisuallocal.h ├── testdata/ │ ├── all_line_noncont_keys.graph │ ├── axmap_noncont_keys.graph │ ├── barnsbury_axial.RT1 │ ├── barnsbury_axial.graph │ ├── barnsbury_drawing.graph │ ├── barnsbury_extended1.dxf │ ├── barnsbury_extended1_axial.csv │ ├── barnsbury_extended1_axial.graph │ ├── barnsbury_extended1_axial.tsv │ ├── barnsbury_extended1_segment.graph │ ├── barnsbury_extended2.dxf │ ├── barnsbury_extended2_axial.graph │ ├── barnsbury_extended2_drawing.graph │ ├── barnsbury_segment.graph │ ├── barnsbury_segment_lines.mid │ ├── barnsbury_segment_lines.mif │ ├── barnsbury_segment_pline.mid │ ├── barnsbury_segment_pline.mif │ ├── gallery.dxf │ ├── gallery_connected.graph │ ├── gallery_connected_merge_links.txt │ ├── gallery_connected_with_isovist.graph │ ├── gallery_empty.graph │ ├── gallery_graph_vga.txt │ ├── gallery_two_pointmaps.graph │ ├── isovists.csv │ ├── polygons_drawing.graph │ ├── polywall.graph │ ├── rect1x1.graph │ ├── rooms.dxf │ ├── simple_axial_lines.ntf │ ├── simple_axlines.graph │ ├── simple_axlines.mid │ ├── simple_axlines.mif │ ├── simple_axlines_pline.mid │ ├── simple_axlines_pline.mif │ ├── turns.dxf │ └── turns_connected.graph ├── tools/ │ ├── build_and_upload.sh │ ├── graph.grammar │ └── storePerformanceTest.php ├── version.h └── version_defs.h.in ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .idea .DS_Store depthmapX-build build build-* RegressionTest/rundir __pycache__ CMakeLists.txt.user *_BACKUP_* *_BASE_* *_LOCAL_* *_REMOTE_* ================================================ FILE: .mailmap ================================================ Petros Koutsolampros <2184600+pklampros@users.noreply.github.com> <2184600+orange-vertex@users.noreply.github.com> Petros Koutsolampros <2184600+pklampros@users.noreply.github.com> Petros Koutsolampros Petros Koutsolampros <2184600+pklampros@users.noreply.github.com> Petros ================================================ FILE: .travis.yml ================================================ sudo: required dist: xenial language: c++ services: - docker notifications: slack: depthmapx:B3CKNlNDLrNz1vSOU5yoQQqA webhooks: urls: - "https://scalar.vector.im/api/neb/services/hooks/dHJhdmlzLWNpLyU0MG9yYW5nZS12ZXJ0ZXglM0FtYXRyaXgub3JnLyUyMUVZQUZRaEVrV3lDZm1hcm9QaCUzQW1hdHJpeC5vcmc" on_success: always # always|never|change on_failure: always on_start: never script: - docker run --security-opt seccomp:unconfined --user $UID -v $PWD:/mnt/code blackseamonster/depthmapx-buildenv:0.3 bash -c ci/build.sh ================================================ FILE: CMakeLists.txt ================================================ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum macOS deployment version") project(depthmapX) cmake_minimum_required(VERSION 3.13.0) set(CMAKE_CXX_STANDARD 17) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(warnings "-Wall -Wextra") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(warnings "/W4 /EHsc") execute_process(COMMAND make_version_header.bat WORKING_DIRECTORY depthmapX) endif() # policy for target sources - we don't expect any old CMakes cmake_policy(SET CMP0076 NEW) include_directories(".") # Get the current working branch execute_process( COMMAND git rev-parse --abbrev-ref HEAD WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE APP_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE ) # Get the latest abbreviated commit hash of the working branch execute_process( COMMAND git log -1 --format=%h WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE APP_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE ) # generate version_defs.h include_directories(${CMAKE_BINARY_DIR}) configure_file("${CMAKE_SOURCE_DIR}/version_defs.h.in" "${CMAKE_BINARY_DIR}/version_defs.h" @ONLY) string(TIMESTAMP APP_DATE %Y-%m-%d) set(modules_core "" CACHE INTERNAL "modules_core" FORCE) set(MODULES_GUI FALSE) set(MODULES_CLI FALSE) set(MODULES_CLI_TEST FALSE) set(MODULES_CORE TRUE) set(MODULES_CORE_TEST FALSE) add_subdirectory(genlib) add_subdirectory(genlibTest) add_subdirectory(salalib) add_subdirectory(modules) # only the core modules are loaded here add_subdirectory(mgraph440) add_subdirectory(mgraph440Test) add_subdirectory(salaTest) add_subdirectory(depthmapXcli) add_subdirectory(cliTest) add_subdirectory(depthmapXTest) add_subdirectory(depthmapX) add_subdirectory(GuiUnitTest) add_subdirectory(moduleTest) ================================================ FILE: GuiUnitTest/.gitignore ================================================ # This file is used to ignore files which are generated # ---------------------------------------------------------------------------- *~ *.autosave *.a *.core *.moc *.o *.obj *.orig *.rej *.so *.so.* *_pch.h.cpp *_resource.rc *.qm .#* *.*# core !core/ tags .DS_Store .directory *.debug Makefile* *.prl *.app moc_*.cpp ui_*.h qrc_*.cpp Thumbs.db *.res *.rc /.qmake.cache /.qmake.stash # qtcreator generated files *.pro.user* # xemacs temporary files *.flc # Vim temporary files .*.swp # Visual Studio generated files *.ib_pdb_index *.idb *.ilk *.pdb *.sln *.suo *.vcproj *vcproj.*.*.user *.ncb *.sdf *.opensdf *.vcxproj *vcxproj.* # MinGW generated files *.Debug *.Release # Python byte code *.pyc # Binaries # -------- *.dll *.exe ================================================ FILE: GuiUnitTest/CMakeLists.txt ================================================ set(GuiUnitTest GuiUnitTest) set(CMAKE_INCLUDE_CURRENT_DIR ON) # Find the QtWidgets library find_package(Qt5 COMPONENTS Core Widgets Gui OpenGL REQUIRED) # Instruct CMake to run moc automatically when needed set(CMAKE_AUTOMOC ON) set(guiUnitTest_SRCS main.cpp testviewhelpers.cpp testsettings.cpp ../depthmapX/settingsimpl.cpp ../depthmapX/views/viewhelpers.cpp) include_directories("../ThirdParty/Catch" "../ThirdParty/FakeIt" "../depthmapX") set(LINK_LIBS salalib genlib mgraph440 Qt5::Core) add_executable(${GuiUnitTest} ${guiUnitTest_SRCS}) target_link_libraries(${GuiUnitTest} ${LINK_LIBS}) ================================================ FILE: GuiUnitTest/main.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: GuiUnitTest/testsettings.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include <../cliTest/selfcleaningfile.h> #include <../depthmapX/settingsimpl.h> class TestSettingsFactory : public QSettingsFactory { public: TestSettingsFactory(const QString &filename) : mFilename(filename) {} virtual std::unique_ptr getSettings() const { return std::unique_ptr(new QSettings(mFilename, QSettings::IniFormat)); } private: QString mFilename; }; TEST_CASE("Test simple settings") { SelfCleaningFile scf("./test.ini"); SettingsImpl settings(new TestSettingsFactory(scf.Filename().c_str())); REQUIRE(settings.readSetting("test1", "bar").toString().toStdString() == "bar"); settings.writeSetting("test1", "foo"); REQUIRE(settings.readSetting("test1", "bar").toString().toStdString() == "foo"); } TEST_CASE("Test settings transaction") { SelfCleaningFile scf("./test.ini"); SettingsImpl settings(new TestSettingsFactory(scf.Filename().c_str())); REQUIRE(settings.readSetting("test1", "bar").toString() == "bar"); { auto transaction = settings.getTransaction(); transaction->writeSetting("test1", "foo"); } REQUIRE(settings.readSetting("test1", "bar").toString() == "foo"); } ================================================ FILE: GuiUnitTest/testviewhelpers.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "depthmapX/views/viewhelpers.h" #include "catch.hpp" #include #include #include TEST_CASE("Calculating the new center", "[calculateCenter]"){ auto point = QPoint(100, 100); auto oldCenter = QPoint(200,200); auto newCenter = Point2f(150,150); REQUIRE(ViewHelpers::calculateCenter(point, oldCenter, 0.5) == newCenter); newCenter.x = 300; newCenter.y = 300; REQUIRE(ViewHelpers::calculateCenter(point, oldCenter, 2.0) == newCenter); } TEST_CASE("Date string format", "[getCurrentDate]"){ auto now = time(NULL); const tm* ltime = localtime(&now); std::stringstream sstream; sstream << ltime->tm_year + 1900 << "/" << std::setfill('0') << std::setw(2) << ltime->tm_mon + 1 << "/" << std::setfill('0') << std::setw(2) << ltime->tm_mday << std::flush; REQUIRE(ViewHelpers::getCurrentDate() == sstream.str().c_str()); } ================================================ FILE: README.md ================================================ ## depthmapX - multi-platform spatial network analyses software This is the home for the development of depthmapX. Latest releases can be found at the [releases page](https://github.com/SpaceGroupUCL/depthmapX/releases) For any issues/bugs/crashes please create [a new issue](https://github.com/SpaceGroupUCL/depthmapX/issues/new) For more information please check the [documentation](./docs/index.md) and the [wiki](https://github.com/SpaceGroupUCL/depthmapX/wiki) [About depthmapX](./docs/about.md) ## depthmapX is licensed under the [GPLv3](http://www.gnu.org/licenses/gpl-3.0.html) licence. depthmapX uses [Qt5](http://www.qt.io) as UI toolkit and build system, [Catch](https://github.com/philsquared/catch) as unit testing framework and [FakeIt](https://github.com/eranpeer/FakeIt) for test mocks. Please join the depthmapX mail distribution list at www.jiscmail.ac.uk/lists/DEPTHMAP.html for updates. The developers and users of depthmapX can also be found on matrix for more direct and extended discussions in the following channels: - [depthmapX-users](https://matrix.to/#/#depthmapX-users:matrix.org) - for general discussion, and questions about using depthmapX - [depthmapX-devel](https://matrix.to/#/#depthmapX-devel:matrix.org) - for development discussion ================================================ FILE: RegressionTest/RegressionTestRunner.py ================================================ import runhelpers import config import depthmaprunner import performancerunner import os import sys defaultConfigFile = "regressionconfig.json" class RegressionTestRunner(): def __init__(self, configfile, runfunc): self.config = config.RegressionConfig(configfile) self.testBinary = runhelpers.getTestExecutable(self.config.testbinlocation) print("Binary under test is " + self.testBinary) self.baseBinary = runhelpers.getExecutable(self.config.basebinlocation) print("Baseline binary is " + self.baseBinary) self.runfunc = runfunc def run(self): if not os.path.exists(self.config.rundir): os.makedirs(self.config.rundir) if self.config.performanceRegression.enabled: print("Performance regression runs enabled") runner = performancerunner.PerformanceRunner(self.runfunc, self.baseBinary, self.testBinary, self.config.rundir,self.config.performanceRegression ) else: print("Default regression runs - no performance") runner = depthmaprunner.DepthmapRegressionRunner( self.runfunc, self.baseBinary, self.testBinary, self.config.rundir ) good = True for name, case in self.config.testcases.items(): print("Running test case " + name) success, output = runner.runTestCase(name, case) if not success: good = False print ("Failed:\n" + output) else: print("ok") return good if __name__ == "__main__": print("Starting up RegressionTestRunner") configFile = defaultConfigFile if len(sys.argv) == 2: configFile = sys.argv[1] print("Config file in use is: " + configFile) r = RegressionTestRunner(configFile, runhelpers.runExecutable) print("Setup complete, starting run") if not r.run(): exit(-1) ================================================ FILE: RegressionTest/cmdlinewrapper.py ================================================ class CommandLineError(Exception): def __init__(self, message): self.message = message class DepthmapCmd(): def __init__(self): self.infile = None self.outfile = None self.simpleMode = False self.mode = None self.extraArgs = {} self.timingFile = None def toCmdArray(self): if self.infile == None: raise CommandLineError("infile must be defined") if self.outfile == None: raise CommandLineError("outfile must be defined") if self.mode == None: raise CommandLineError("mode must be defined") args = ["-f", self.infile, "-o", self.outfile, "-m", self.mode] if self.simpleMode: args.append("-s") if self.timingFile: args.extend(["-t", self.timingFile]) for key, value in self.extraArgs.items(): if isinstance(value, list): for v in value: args.append(key) args.append(v) else: args.append(key) if value: args.append(value) return args ================================================ FILE: RegressionTest/config.py ================================================ import json import os.path import cmdlinewrapper from performanceregressionconfig import PerformanceRegressionConfig class ConfigError(Exception): def __init__(self, message): self.message = message def buildCmd(testcaseSet): cmds = []; for testcase in testcaseSet: cmd = cmdlinewrapper.DepthmapCmd() cmd.infile = testcase["infile"] cmd.outfile = testcase["outfile"] cmd.mode = testcase["mode"] if "simple" in testcase and not testcase["simple"] == "false": cmd.simpleMode = True cmd.extraArgs = testcase.get("extraArgs", {}) cmds.append(cmd) return cmds class RegressionConfig(): def __init__(self, filename): with open(filename, "r") as f: config = json.load(f) configdir = os.path.dirname(filename) self.rundir = config["rundir"] self.basebinlocation = config["basebinlocation"] self.testbinlocation = config["testbinlocation"] self.performanceRegression = PerformanceRegressionConfig(config.get("performance", None)) self.testcases = {} for (name, tc) in config["testcases"].items(): self.testcases[name] = buildCmd(tc) ================================================ FILE: RegressionTest/depthmaprunner.py ================================================ import os.path import cmdlinewrapper import difflib import pprint import runhelpers class DepthmapRunner(): def __init__(self, runFunc, binary ): self.__runFunc = runFunc self.__binary = binary def runDepthmap(self, cmdWrapper, runDir): args = [self.__binary] args.extend(cmdWrapper.toCmdArray()) return self.__runFunc(runDir, args) def diffBinaryFiles(file1, file2): with open(file1, "rb") as f: content1 = f.read() with open(file2, "rb") as f: content2 = f.read() gen = difflib.diff_bytes(difflib.unified_diff, [content1], [content2]) return not(list(gen)) class DepthmapRegressionRunner(): def __init__(self, runFunc, baseBinary, testBinary, workingDir): self.__baseRunner = DepthmapRunner(runFunc, baseBinary) self.__testRunner = DepthmapRunner(runFunc, testBinary) self.__workingDir = workingDir def makeBaseDir(self, name): return os.path.join(self.__workingDir, name + "_base") def makeTestDir(self, name): return os.path.join(self.__workingDir, name + "_test") def runTestCase(self, name, cmds): runhelpers.prepareDirectory(self.makeBaseDir(name)) runhelpers.prepareDirectory(self.makeTestDir(name)) return self.runTestCaseImpl(name, cmds) def runTestCaseImpl(self, name, cmds): baseDir = self.makeBaseDir(name) for step,cmd in enumerate(cmds): (baseSuccess, baseOut) = self.__baseRunner.runDepthmap(cmd, baseDir) if not baseSuccess: print("Baseline run failed at step " + str(step) + " with arguments " + pprint.pformat(cmd.toCmdArray())) print(baseOut) return (False, "Baseline run failed at step: " + str(step)) testDir = self.makeTestDir(name) for step,cmd in enumerate(cmds): (testSuccess, testOut) = self.__testRunner.runDepthmap(cmd, testDir) if not testSuccess: print("Test run failed at step " + str(step) + " with arguments " + pprint.pformat(cmd.toCmdArray())) print(testOut) return (False, "Test run failed at step: " + str(step)) baseFile = os.path.join(baseDir, cmds[-1].outfile) testFile = os.path.join(testDir, cmds[-1].outfile) if not os.path.exists(baseFile): message = "Baseline output {0} does not exist".format(baseFile) print (message) return (False, message) if not os.path.exists(testFile): message = "Test output {0} does not exist".format(testFile) print(message) return (False, message) if not diffBinaryFiles(baseFile, testFile): message = "Test outputs differ" print (message) return (False, message) return (True, "") ================================================ FILE: RegressionTest/performance_regression.json ================================================ { "rundir": "rundir", "basebinlocation": "../../BaselineBinaries", "testbinlocation": "../../../build", "performance":{}, "testcases": { "vis_prep_dense_pointmap":[{ "infile": "../../../testdata/rect1x1.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.02", "-pp": "0.5,0.5" } }], "visibility_local": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vl": "" } }], "vga_isovist": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "isovist" } }], "vga_angular": [{ "infile": "../../../testdata/turns_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "angular" } }], "vga_metric": [{ "infile": "../../../testdata/turns_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "metric", "-vr": "n" } }], "vga_thru_vision": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "thruvision" } }], "isovist_args": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "ISOVIST", "extraArgs": { "-ii": ["1.77,6.6,90,30", "3.1,5.6,270,90" ] } }], "visibility_global_n": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "1", "-vr": "n" } }], "axial_makelines": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs":{ "-xl": "3,5", "-xf": "" } }], "axial_rn": [{ "infile": "../../../testdata/barnsbury_extended2_axial.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n" } }], "axial_rn_choice": [{ "infile": "../../../testdata/barnsbury_extended2_axial.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xac": "" } }], "axial_rn_local": [{ "infile": "../../../testdata/barnsbury_extended2_axial.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xal": "" } }], "segment_tulip_1024_rn_steps": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps" } }], "segment_tulip_1024_rn_steps_choice": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps", "-sic": "" } }], "segment_tulip_1024_rn_steps_weighted": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps", "-swa": "Segment Length" } }], "segment_topological_rn": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "topological", "-sr": "n" } }], "segment_metric_rn": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "metric", "-sr": "n" } }], "convert_drawing_axial":[{ "infile": "../../../testdata/barnsbury_extended2_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Axial Map Test" } }], "convert_axial_segment":[{ "infile": "../../../testdata/barnsbury_extended2_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test" } }] } } ================================================ FILE: RegressionTest/performanceregressionconfig.py ================================================ class PerformanceRegressionConfig: """ Encapsulate performance regression config This takes an optional performance regression config. All Elements in the performance regression config are optional. If it is None completly, performance regresssion will be disabled "peformanceRegression": { enabled = 1, <- enabling performance regression - only required if nothing else is set, the existence of a non null config will turn on performance regression runsPerInstance = 3, <- how many runs of each run def to run and average over relativeThresholdInPercent = 1.5, <- how many percent can the new version be slower without failing absoluteThresholdInSeconds = 2.3, <- how many seconds the new version can be slower without failing of the two above, breaching the lower one will lead to failure. } """ def __init__(self, perfConfig): if None == perfConfig or ("enabled" in perfConfig and perfConfig["enabled"] not in ["True", "true", "1", "yes"]): self.enabled = False return self.enabled = True; self.runsPerInstance = int(perfConfig.get("runsPerInstance", 3)) self.relativeThresholdInPercent = float(perfConfig.get("relativeThresholdInPercent", 1)) self.absoluteThresholdInSeconds = float(perfConfig.get("absoluteThresholdInSeconds",1)) ================================================ FILE: RegressionTest/performancerunner.py ================================================ from statistics import mean from collections import OrderedDict import depthmaprunner import os import csv import runhelpers from performanceregressionconfig import PerformanceRegressionConfig def checkPerformance(baseFile, testFile, relativeThreshold, absoluteThreshold): """ Check the performance of 2 depthmap runs against each other This function expects the timing from a base and test run and parses them as CSV. For now, it expects the entries to be the same. It will return an error message if * one or both of the files are missing * the number of lines or the labels don't match * the test run is more than 5 seconds or 5% slower than the baseline (whatever is greater) """ if not os.path.exists(baseFile): return "Base performance timing file {0} is missing".format(baseFile) if not os.path.exists(testFile): return "Test performance timing file {0} is missing".format(testFile) with open(baseFile) as baseHandle, open(testFile) as testHandle: baseReader = csv.DictReader(baseHandle) testReader = csv.DictReader(testHandle) baseDone = False testDone = False while True: try: baseLine = next(baseReader) except StopIteration: baseDone = True try: testLine = next(testReader) except StopIteration: testDone = True if baseDone and testDone: return "" if baseDone and not testDone: return "baseline performance file {0} has fewer lines than the test one {1}".format(baseFile, testFile) if testDone and not baseDone: return "baseline performance file {0} has more lines than the test one {1}".format(baseFile, testFile) if not baseLine["action"] == testLine["action"]: return "performance line mismatch: base '{0}', test '{1}'".format(baseLine["action"], testLine["action"]) baseTime = float(baseLine["average"]) testTime = float(testLine["average"]) allowance = max(absoluteThreshold, baseTime * relativeThreshold / 100 ) if testTime > baseTime + allowance: return "Performance regression: {0} took {1}s instead of {2}s".format(baseLine["action"], testLine["average"], baseLine["average"]) def aggregatePerformanceStats(dir, numRuns, numCmds, filenameTemplate ): data = OrderedDict() totalValues = [] for i in range(numRuns): for j in range(numCmds): with open(os.path.join(dir, filenameTemplate.format(i, j)), "r") as f: reader = csv.DictReader(f) total = 0 for line in reader: if not line["action"] in data: data[line["action"]] = [] data[line["action"]].append(float(line["duration"])) total = total + float(line["duration"]) totalValues.append(total) data["total"] = totalValues outputFile =os.path.join(dir, filenameTemplate.format("", "all")) with open(outputFile, "w+") as f: writer = csv.DictWriter(f, ["action", "min", "max", "average"]) writer.writeheader() for key, val in data.items(): rowDict = {"action": key, "min": min(val), "max": max(val), "average": mean(val)} writer.writerow(rowDict) return outputFile class PerformanceRunner(depthmaprunner.DepthmapRegressionRunner): def __init__(self, runFunc, baseBinary, testBinary, workingDir, perfConfig): depthmaprunner.DepthmapRegressionRunner.__init__(self,runFunc,baseBinary,testBinary,workingDir) self.perfConfig = perfConfig def runTestCase(self, name, cmds): runhelpers.prepareDirectory(self.makeBaseDir(name)) runhelpers.prepareDirectory(self.makeTestDir(name)) nameTemplate = "timings_{0}_{1}.csv" for i in range(self.perfConfig.runsPerInstance): print ("Running test case {0}, run {1} of {2}".format(name, i, self.perfConfig.runsPerInstance)) for j in range(len(cmds)): cmds[j].timingFile = nameTemplate.format(i,j) result, message = self.runTestCaseImpl(name, cmds) if not result: return (False, "Run {0} failed with message: {1}".format(i, message)) testFile = aggregatePerformanceStats(self.makeTestDir(name),self.perfConfig.runsPerInstance, len(cmds), nameTemplate) baseFile = aggregatePerformanceStats(self.makeBaseDir(name),self.perfConfig.runsPerInstance, len(cmds), nameTemplate) message = checkPerformance(testFile, baseFile, self.perfConfig.relativeThresholdInPercent, self.perfConfig.absoluteThresholdInSeconds) if message: return (False, message) return (True, "") ================================================ FILE: RegressionTest/regressionconfig.json ================================================ { "rundir": "rundir", "basebinlocation": "../../BaselineBinaries", "testbinlocation": "../../../build", "testcases": { "links_pointmap_manual": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lnk": ["1.32,7.24,4.88,5.24","1.16,5.28,3.28,7.12"] } }], "links_pointmap_file": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lf": "../../../testdata/gallery_connected_merge_links.txt" } }], "unlinks_shapegraph_coords": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lmt": "shapegraphs", "-lm": "unlink", "-lt": "coords", "-lnk": "530797,184255" } }], "unlinks_shapegraph_refs": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lmt": "shapegraphs", "-lm": "unlink", "-lt": "refs", "-lnk": "18,24" } }], "links_shapegraph_coords": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lmt": "shapegraphs", "-lm": "link", "-lt": "coords", "-lnk": "530684,184098,531388,184353" } }], "links_shapegraph_refs": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lmt": "shapegraphs", "-lm": "link", "-lt": "refs", "-lnk": "1,41" } }], "links_shapegraph_refs_non_cont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lmt": "shapegraphs", "-lm": "link", "-lt": "refs", "-lnk": "17,11" } }], "visibility_local": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vl": "" } }], "visibility_local_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vl": "" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "visibility_global_with_multiple_pointmaps": [{ "infile": "../../../testdata/gallery_two_pointmaps.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "3" } }], "visibility_global_3": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "3" } }], "visibility_global_3_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "3" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "pointmap_export_links": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-links-csv" } }], "axial_export_map_csv": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "shapegraph-map-csv" } }], "axial_export_map_mif_given_mif": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.mif", "mode": "EXPORT", "extraArgs": { "-em": "shapegraph-map-mif" } }], "axial_export_map_mif_given_mid": [{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.mid", "mode": "EXPORT", "extraArgs": { "-em": "shapegraph-map-mif" } }], "visibility_global_n": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "n" } }], "visibility_global_n_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "n" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "vga_isovist": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "isovist" } }], "vga_isovist_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "isovist" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "vga_angular": [{ "infile": "../../../testdata/turns_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "angular" } }], "vga_angular_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "angular" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "vga_metric": [{ "infile": "../../../testdata/turns_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "metric", "-vr": "n" } }], "vga_metric_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "metric", "-vr": "n" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "vga_thru_vision": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "thruvision" } }], "vga_thru_vision_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "VGA", "extraArgs": { "-vm": "thruvision" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "pointmap-data-csv" } }], "vga_visual_step_depth": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "STEPDEPTH", "extraArgs":{ "-sdp": "3,5", "-sdt": "visual" } }], "vga_metric_step_depth": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "STEPDEPTH", "extraArgs":{ "-sdp": "3,5", "-sdt": "metric" } }], "vga_angular_step_depth": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "STEPDEPTH", "extraArgs":{ "-sdp": "3,5", "-sdt": "angular" } }], "isovist_args": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "ISOVIST", "extraArgs": { "-ii": ["1.77,6.6,90,30", "3.1,5.6,270,90" ] } }], "isovist_file": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "ISOVIST", "extraArgs": { "-if": "../../../testdata/isovists.csv" } }], "axial_makelines": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs":{ "-xl": "3,5", "-xf": "" } }], "axial_makelines_polywall": [{ "infile": "../../../testdata/polywall.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs":{ "-xl": "4300,1500" } }], "axial_makelines_rooms": [{ "infile": "../../../testdata/rooms.dxf", "outfile": "out.graph", "mode": "IMPORT", "extraArgs":{} },{ "infile": "out.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs":{ "-xl": "7.5,7.5", "-xf": "" } }], "axial_rn": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n" } }], "axial_r3": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "3" } }], "axial_rn_length_weighted": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xaw": "Line Length" } }], "axial_rn_rra": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xar": "" } }], "axial_rn_choice": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xac": "" } }], "axial_rn_local": [{ "infile": "../../../testdata/simple_axlines.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xal": "" } }], "axial_rn_noncont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n" } }], "axial_r3_noncont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "3" } }], "axial_rn_rra_noncont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xar": "" } }], "axial_rn_choice_noncont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xac": "" } }], "axial_rn_local_noncont_keys": [{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "AXIAL", "extraArgs": { "-xa": "n", "-xal": "" } }], "segment_tulip_1024_rn_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps" } }], "segment_tulip_1024_rn_steps_choice": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps", "-sic": "" } }], "segment_tulip_1024_rn_steps_weighted": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "n", "-srt": "steps", "-swa": "Segment Length" } }], "segment_tulip_512_rn_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "512", "-sr": "n", "-srt": "steps" } }], "segment_tulip_123_rn_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "123", "-sr": "n", "-srt": "steps" } }], "segment_tulip_4_rn_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "4", "-sr": "n", "-srt": "steps" } }], "segment_tulip_1024_r5_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "5", "-srt": "steps" } }], "segment_tulip_1024_rn_r5_steps": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "5,n", "-srt": "steps" } }], "segment_tulip_1024_r500_metric": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "500", "-srt": "metric" } }], "segment_tulip_1024_r180_angular": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "tulip", "-stb": "1024", "-sr": "500", "-srt": "metric" } }], "segment_angular_rn": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "angular", "-sr": "n" } }], "segment_topological_rn": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "topological", "-sr": "n" } }], "segment_metric_rn": [{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "SEGMENT", "extraArgs": { "-st": "metric", "-sr": "n" } }], "import_dxf_to_drawing":[{ "infile": "../../../testdata/barnsbury_extended1.dxf", "outfile": "out.graph", "mode": "IMPORT", "extraArgs": {} }], "import_csv_to_drawing":[{ "infile": "../../../testdata/barnsbury_extended1_axial.csv", "outfile": "out.graph", "mode": "IMPORT", "extraArgs": {} }], "import_tsv_to_data":[{ "infile": "../../../testdata/barnsbury_extended1_axial.tsv", "outfile": "out.graph", "mode": "IMPORT", "extraArgs": { "-it": "data" } }], "convert_drawing_axial":[{ "infile": "../../../testdata/barnsbury_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Axial Map Test" } }], "convert_drawing_segment":[{ "infile": "../../../testdata/barnsbury_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test" } }], "convert_drawing_segment_only_map":[{ "infile": "../../../testdata/barnsbury_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test" } },{ "infile": "out.graph", "outfile": "out.csv", "mode": "EXPORT", "extraArgs": { "-em": "shapegraph-map-csv" } }], "convert_drawing_convex":[{ "infile": "../../../testdata/polygons_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "convex", "-con": "Convex Map Test" } }], "convert_drawing_data_convex":[{ "infile": "../../../testdata/polygons_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "convex", "-con": "Convex Map Test" } }], "convert_drawing_data_drawing_polygons":[{ "infile": "../../../testdata/polygons_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "drawing", "-con": "Drawing Map Test" } }], "convert_drawing_data_drawing_lines":[{ "infile": "../../../testdata/barnsbury_drawing.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "drawing", "-con": "Drawing Map Test" } }], "convert_axial_data":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } }], "convert_axial_data_copy_attributes":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test", "-coc":"" } }], "convert_axial_drawing":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "drawing", "-con": "Drawing Map Test" } }], "convert_axial_segment":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test" } }], "convert_axial_segment_remove_input":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test", "-cir":"" } }], "convert_axial_segment_trim_lines":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test", "-crsl":"40" } }], "convert_axial_segment_copy_attributes":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test", "-coc": "" } }], "convert_axial_segment_copy_attributes_non_cont_keys":[{ "infile": "../../../testdata/axmap_noncont_keys.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "segment", "-con": "Segment Map Test", "-coc": "" } }], "convert_axial_data_axial":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Axial Map Test" } }], "convert_axial_data_axial_copy_attributes":[{ "infile": "../../../testdata/barnsbury_axial.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test", "-coc": "" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Axial Map Test", "-coc": "" } }], "convert_segment_data":[{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } }], "convert_segment_data_segment":[{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Segment Map Test" } }], "convert_segment_data_segment_copy_attributes":[{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "data", "-con": "Data Map Test", "-coc": "" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "axial", "-con": "Segment Map Test", "-coc": "" } }], "convert_segment_drawing":[{ "infile": "../../../testdata/barnsbury_segment.graph", "outfile": "out.graph", "mode": "MAPCONVERT", "extraArgs": { "-co": "drawing", "-con": "Drawing Map Test" } }], "pointmap_create_fill_make_one_operation": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.04", "-pp": "1.32,7.24,4.88,5.24", "-pm": "" } }], "dense_pointmap_create_fill_make":[{ "infile": "../../../testdata/rect1x1.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.02", "-pp": "0.5,0.5" } }], "pointmap_create_fill_make_unmake": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.04" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pp": "1.32,7.24,4.88,5.24" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pm": "" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pu": "" } }], "pointmap_create_fill_make_link_unmake": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.04", "-pp": "1.32,7.24,4.88,5.24", "-pm": "" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lnk": ["1.32,7.24,4.88,5.24","1.16,5.28,3.28,7.12"] } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pu": "" } }], "pointmap_create_fill_make_link_unmake_unlink": [{ "infile": "../../../testdata/gallery_empty.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pg": "0.04", "-pp": "1.32,7.24,4.88,5.24", "-pm": "" } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "LINK", "extraArgs": { "-lnk": ["1.32,7.24,4.88,5.24","1.16,5.28,3.28,7.12"] } },{ "infile": "out.graph", "outfile": "out.graph", "mode": "VISPREP", "extraArgs": { "-pu": "", "-pl": "" } }] } } ================================================ FILE: RegressionTest/regressionconfig_agents.json ================================================ { "rundir": "rundir", "basebinlocation": "../../BaselineBinaries", "testbinlocation": "../../../build", "testcases": { "agents_defaults": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "standard", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_line_of_sight_length_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "los-length", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_line_of_sight_length_look_only_map": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.tsv", "mode": "AGENTS", "extraArgs": { "-am": "los-length", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0", "-ot": "gatecounts" } }], "agents_occluded_length_look": [{ "infile": "../../../testdata/gallery_connected_with_isovist.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "occ-length", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_any_occlusion_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "occ-any", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_occlusion_group_bins_45_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "occ-group-45", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_occlusion_group_bins_60_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "occ-group-60", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_furthest_occlusion_per_bin_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "occ-furthest", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_per_bin_far_distance_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "bin-far-dist", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_per_bin_angle_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "bin-angle", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_per_bin_far_distance_and_angle_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "bin-far-dist-angle", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_per_bin_memory_look": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.graph", "mode": "AGENTS", "extraArgs": { "-am": "bin-memory", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0" } }], "agents_gatecounts": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.tsv", "mode": "AGENTS", "extraArgs": { "-am": "standard", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "5", "-ot": "gatecounts" } }], "agents_trails_all": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.cat", "mode": "AGENTS", "extraArgs": { "-am": "standard", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0", "-atrails": "0", "-ot": "trails" } }], "agents_trails_1": [{ "infile": "../../../testdata/gallery_connected.graph", "outfile": "out.cat", "mode": "AGENTS", "extraArgs": { "-am": "standard", "-ats": "5000", "-arr": "0.1", "-afov": "15", "-asteps": "3", "-alife": "1000", "-alocseed": "0", "-atrails": "1", "-ot": "trails" } }] } } ================================================ FILE: RegressionTest/runhelpers.py ================================================ import os import shutil import subprocess import platform def runTest(): pass class cd: """Context manager for changing the current working directory""" def __init__(self, newPath): self.newPath = os.path.expanduser(newPath) def __enter__(self): self.savedPath = os.getcwd() os.chdir(self.newPath) def __exit__(self, etype, value, traceback): os.chdir(self.savedPath) def prepareDirectory(dirname): if os.path.exists( dirname ): shutil.rmtree(dirname) os.makedirs(dirname) def runExecutable( workingDir, arguments ): """ Prepares a clean run directoy and runs the process in this """ with cd(workingDir): with open("out.txt", "w") as outfile: result = subprocess.run(arguments, stdout = outfile, stderr = subprocess.STDOUT ) output = "" if os.path.exists( "out.txt"): with open( "out.txt", "r" ) as f: output = f.read() if os.path.exists( "err.txt" ): with open( "err.txt", "r") as f: error = f.read(); return (result.returncode == 0, output) def getExecutable(basedir): sys = platform.system() if sys == "Windows": return os.path.join(basedir, sys, "depthmapXcli.exe") else: return os.path.join(basedir, sys, "depthmapXcli") def getTestExecutable(basedir): sys = platform.system() if sys == "Windows": return os.path.join(basedir, "depthmapXcli", "release", "depthmapXcli.exe") else: return os.path.join(basedir, "depthmapXcli", "depthmapXcli") ================================================ FILE: RegressionTest/test/context.py ================================================ import os import sys sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) import cmdlinewrapper import config import depthmaprunner import RegressionTestRunner import runhelpers import performanceregressionconfig import performancerunner ================================================ FILE: RegressionTest/test/disposablefile.py ================================================ import os import shutil class DisposableFile: def __init__( self, filename ): self.__filename = filename def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): if os.path.exists(self.filename()): os.remove(self.filename()) def filename(self): return self.__filename class DisposableDirectoryError(Exception): def __init__(self, message): self.message = message class DisposableDirectory: def __init__(self, directoryName, create = False): if directoryName == ".": raise DisposableDirectoryError("The disposable directory cannot be the current directory") if os.path.exists(directoryName): raise DisposableDirectoryError("You can't make an existing directory disposable") self.__directoryName = directoryName if create: os.makedirs(directoryName) def __enter__(self): return self def __exit__(self, exc_type, exc_value, backtrace): if os.path.exists(self.__directoryName): shutil.rmtree(self.__directoryName) def name(self): return self.__directoryName ================================================ FILE: RegressionTest/test/fail/test_fail.py ================================================ import unittest class TestFailure(unittest.TestCase): """ Test case that always fails to test that we capture failures correctly """ def test_fail_this(self): print("This will always fail and should only be used in tests of the unittest framework") self.assertTrue(False) if __name__=="__main__": unittest.main() ================================================ FILE: RegressionTest/test/pass/test_pass.py ================================================ import unittest class TestFailure(unittest.TestCase): """ Test case that always passes to test that we capture failures correctly """ def test_fail_this(self): print("This will always pass and should only be used in tests of the unittest framework") self.assertTrue(True) if __name__=="__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_RegressionTestRunner.py ================================================ import unittest from test_config import writeConfig from RegressionTestRunner import RegressionTestRunner from disposablefile import DisposableFile, DisposableDirectory import os class TestRegressionTestRunner(unittest.TestCase): def runfunc(self, workingdir, args): if self.counter >= 0: self.counter = self.counter - 1 if self.counter == 0: return (False, "Failed") if not os.path.exists(workingdir): os.makedirs(workingdir) with open(os.path.join(workingdir, "outfile.graph"), "w") as f: f.write("123") with open(os.path.join(workingdir, "runtimes.csv"), "w") as f: f.write("action,duration\n") return (True, "") def test_RegressionTestRunnerAllGoesWell(self): with DisposableFile("testconfig.json") as f, DisposableDirectory("testrundir") as d: writeConfig(f.filename(), d.name()) runner = RegressionTestRunner(f.filename(), lambda w, a: self.runfunc(w, a)) self.counter = -1 self.assertTrue(runner.run()) def test_RegressionTestRunnerOneRunFails(self): with DisposableFile("testconfig.json") as f, DisposableDirectory("testrundir") as d: writeConfig(f.filename(), d.name()) runner = RegressionTestRunner(f.filename(), lambda w, a: self.runfunc(w, a)) self.counter = 2 self.assertFalse(runner.run()) if __name__ == "__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_cmdlinewrapper.py ================================================ import unittest import collections from context import cmdlinewrapper class TestDepthmapCmd(unittest.TestCase): def test_correctBehaviour(self): cmd = cmdlinewrapper.DepthmapCmd() cmd.infile = "foo" cmd.outfile = "bar" cmd.mode = "visibility" self.assertEqual(cmd.toCmdArray(), ["-f", "foo", "-o", "bar", "-m", "visibility" ]) cmd.simpleMode = True self.assertEqual(cmd.toCmdArray(), ["-f", "foo", "-o", "bar", "-m", "visibility", "-s" ]) def test_exceptions(self): cmd = cmdlinewrapper.DepthmapCmd() with self.assertRaises(cmdlinewrapper.CommandLineError) as cm: cmd.toCmdArray() self.assertEqual(cm.exception.message, "infile must be defined") cmd.infile = "foo" with self.assertRaises(cmdlinewrapper.CommandLineError) as cm: cmd.toCmdArray() self.assertEqual(cm.exception.message, "outfile must be defined") cmd.outfile = "bar" with self.assertRaises(cmdlinewrapper.CommandLineError) as cm: cmd.toCmdArray() self.assertEqual(cm.exception.message, "mode must be defined") def test_extraArgs(self): cmd = cmdlinewrapper.DepthmapCmd() cmd.infile = "foo" cmd.outfile = "bar" cmd.mode = "visibility" # use ordered dict here for testability cmd.extraArgs = collections.OrderedDict([("-lnk", ["foo", "bar"]), ("-vm", "metric"), ("-vg", "" )]) self.assertEqual(cmd.toCmdArray(), ["-f", "foo", "-o", "bar", "-m", "visibility", "-lnk", "foo", "-lnk", "bar", "-vm", "metric", "-vg" ]) if __name__ == "__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_config.py ================================================ import unittest from context import config from disposablefile import DisposableFile import RegressionTestRunner import os def writeConfig(filename, rundir): with open(filename, "w") as f: f.write('{ "rundir": "'+ rundir +'",\n') f.write(' "basebinlocation": "../baselineBinaries",\n') f.write(' "testbinlocation": "../..",\n') f.write(' "testcases": {\n') f.write(' "test1": [{\n') f.write(' "infile": "infile.graph",\n') f.write(' "outfile": "outfile.graph",\n') f.write(' "mode": "VGA",\n') f.write(' "extraArgs": {\n') f.write(' "-vm": "metric",\n') f.write(' "-vr": "7"}}]}}') class TestMethods(unittest.TestCase): def test_buildCmd(self): data = [{ "infile": "foo.graph", "outfile": "bar.graph", "mode": "VGA", "extraArgs": { "-vm": "visibility", "-vg": "", "-vr": "5"}}] cmds = config.buildCmd( data ) self.assertEqual(cmds[0].infile, "foo.graph") self.assertEqual(cmds[0].outfile, "bar.graph") self.assertEqual(cmds[0].mode, "VGA") self.assertEqual(len(cmds[0].extraArgs),3) def test_configClass(self): with DisposableFile("test.config") as testfile: writeConfig(testfile.filename(), "../foo/bar") conf = config.RegressionConfig(testfile.filename()) self.assertEqual(len(conf.testcases), 1) self.assertEqual(conf.rundir, "../foo/bar") self.assertTrue("test1" in conf.testcases) class TestRealConfig(unittest.TestCase): def test_realConfig(self): configFile = os.path.join("..", RegressionTestRunner.defaultConfigFile) self.assertNotEqual( configFile, "" ) conf = config.RegressionConfig(configFile) self.assertFalse(conf.performanceRegression.enabled) if __name__ == "__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_depthmaprunner.py ================================================ from context import depthmaprunner import cmdlinewrapper from cmdlinewrapper import DepthmapCmd import unittest from disposablefile import DisposableFile, DisposableDirectory import os.path class BinaryDiffTest(unittest.TestCase): def test_binaryDiff(self): with DisposableFile( "testfile1.bin" ) as f1, DisposableFile( "testfile2.bin") as f2: with open( f1.filename(), "wb" ) as f: f.write( bytes.fromhex( "2000 0839") ) with open( f2.filename(), "wb" ) as f: f.write( bytes.fromhex( "2000 0838" )) self.assertTrue(depthmaprunner.diffBinaryFiles(f1.filename(), f1.filename())) self.assertFalse(depthmaprunner.diffBinaryFiles(f1.filename(), f2.filename())) class DepthmapRunnerTest(unittest.TestCase): def runfunc(self, rundir, args): self.assertEqual(rundir, self.__rundir) self.assertEqual(args, self.__args) def testDepthmapRunner(self): dcmd = DepthmapCmd() dcmd.infile = "foo" dcmd.outfile = "bar" dcmd.mode = "mode" dcmd.modeLines = [] runner = depthmaprunner.DepthmapRunner(lambda d, a: self.runfunc(d, a), "bin") self.__args = ["bin", "-f", "foo", "-o", "bar", "-m", "mode"] self.__rundir = "dir" runner.runDepthmap(dcmd, "dir") class DepthmapRegressioRunnerTest(unittest.TestCase): def getOutfile(self, args): outputfile = None for i in range(0, len(args)): if args[i] == "-o" and i < len(args): outputfile = args[i+1] break self.assertFalse( outputfile == None ) return outputfile def getTimingsFile(self,args): timingsFile = None for i in range(0, len(args)): if args[i] == "-t" and i < len(args): timingsFile = args[i+1] break return timingsFile def runfuncSucceedAlwaysSame(self, rundir, args): outpath = os.path.join(rundir, self.getOutfile(args)) with open (outpath, "w") as f: f.write("123") timingsFile = self.getTimingsFile(args) if timingsFile: with open (os.path.join(rundir, timingsFile), "w") as f: f.write('"action","duration"\n') return (True, "") def runfuncDifferentResults(self, rundir, args): outpath = os.path.join(rundir, self.getOutfile(args)) with open (outpath, "w") as f: f.write(self.__outContent) self.__outContent = self.__outContent + "x" return (True, "") def runfuncWriteNoFile(self, rundir, args, dontWriteFor): if not args[0] == dontWriteFor: outpath = os.path.join(rundir, self.getOutfile(args)) with open (outpath, "w") as f: f.write("123") return (True, "") def runfuncFail(self, rundir, args, failFor, shouldOtherRun): if args[0] == failFor: return (False, "Boom!") if shouldOtherRun: outpath = os.path.join(rundir, self.getOutfile(args)) with open (outpath, "w") as f: f.write("123") return (True, "") else: self.assertFail("Should not have been called for " + args[0]) def makeCommand(self, infile, outfile, mode): cmd = cmdlinewrapper.DepthmapCmd() cmd.infile = infile cmd.outfile = outfile cmd.mode = mode return [cmd] def testSuccessfullRun(self): with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncSucceedAlwaysSame(d,a), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertTrue(result) def testRunWithDiff(self): self.__outContent = "abc" with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncDifferentResults(d,a), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertFalse(result) self.assertEqual(message, "Test outputs differ") def testBaseRunOutputMissing(self): with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncWriteNoFile(d,a, "basebin"), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertFalse(result) self.assertEqual(message, "Baseline output {0} does not exist".format(os.path.join(dir.name(), "testname" + "_base", "outfile.graph"))) def testTestRunOutputMissing(self): with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncWriteNoFile(d,a, "testbin"), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertFalse(result) self.assertEqual(message, "Test output {0} does not exist".format(os.path.join(dir.name(), "testname" + "_test", "outfile.graph"))) def testBaseRunFail(self): with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncFail(d,a, "basebin", False), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertFalse(result) self.assertEqual(message, "Baseline run failed at step: 0") def testTestRunFail(self): with DisposableDirectory("testdir", True) as dir: runner = depthmaprunner.DepthmapRegressionRunner(lambda d, a: self.runfuncFail(d,a, "testbin", True), "basebin", "testbin", dir.name()) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph", "visibility")) self.assertFalse(result) self.assertEqual(message, "Test run failed at step: 0") if __name__=="__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_disposablefile.py ================================================ import disposablefile import unittest import os.path class TestDisposableFile(unittest.TestCase): def testFileDeletion(self): with disposablefile.DisposableFile("testfile.xyz") as f: self.assertEqual(f.filename(), "testfile.xyz") with open( f.filename(), "w") as tf: tf.write("foo") self.assertTrue( os.path.exists(f.filename())) self.assertFalse( os.path.exists("testfile.xyz")) class TestDisposableDirectory(unittest.TestCase): def testLifetime(self): with disposablefile.DisposableDirectory("testdir1", True) as d: self.assertEqual("testdir1", d.name()) self.assertTrue(os.path.exists(d.name())) self.assertTrue(os.path.isdir(d.name())) with open ( os.path.join(d.name(), "testfile.txt"), "w") as f: f.write("123") self.assertTrue(os.path.exists(os.path.join(d.name(), "testfile.txt"))) self.assertFalse(os.path.exists(d.name())) def testNotAutomaticallyCreated(self): with disposablefile.DisposableDirectory("testdir1", False) as d: self.assertEqual("testdir1", d.name()) self.assertFalse(os.path.exists(d.name())) os.makedirs(d.name()) self.assertTrue(os.path.exists(d.name())) self.assertTrue(os.path.isdir(d.name())) with open ( os.path.join(d.name(), "testfile.txt"), "w") as f: f.write("123") self.assertTrue(os.path.exists(os.path.join(d.name(), "testfile.txt"))) self.assertFalse(os.path.exists(d.name())) def testNeverCreated(self): with disposablefile.DisposableDirectory("testdir1", False) as d: self.assertEqual("testdir1", d.name()) self.assertFalse(os.path.exists(d.name())) self.assertFalse(os.path.exists(d.name())) def testExceptions(self): with self.assertRaises(disposablefile.DisposableDirectoryError) as cm: disposablefile.DisposableDirectory(".") self.assertEqual(cm.exception.message,"The disposable directory cannot be the current directory" ) with disposablefile.DisposableDirectory("testdir1", True) as d: with self.assertRaises(disposablefile.DisposableDirectoryError) as cm: disposablefile.DisposableDirectory(d.name()) self.assertEqual( cm.exception.message, "You can't make an existing directory disposable" ) if __name__=="__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_main.py ================================================ import argparse import unittest if __name__ == "__main__": parser = argparse.ArgumentParser("Find and run all unittest in a folder") parser.add_argument('--folder', '-f', dest='folder', help='Optional folder to search, defaults to .') args = parser.parse_args() if args.folder: folder = args.folder else: folder = '.' loader = unittest.TestLoader() suite = loader.discover(folder) runner = unittest.TextTestRunner() result = runner.run(suite) if not result.wasSuccessful(): exit(-1) ================================================ FILE: RegressionTest/test/test_performanceregressionconfig.py ================================================ import unittest from context import performanceregressionconfig import disposablefile class TestDisabledConfig(unittest.TestCase): def test_missingConfig(self): p = performanceregressionconfig.PerformanceRegressionConfig(None) self.assertFalse(p.enabled) def test_disabledConfig(self): p = performanceregressionconfig.PerformanceRegressionConfig({"enabled": "0"}) self.assertFalse(p.enabled) p = performanceregressionconfig.PerformanceRegressionConfig({"enabled": "False"}) self.assertFalse(p.enabled) p = performanceregressionconfig.PerformanceRegressionConfig({"enabled": "True"}) self.assertTrue(p.enabled) class TestSuccessfulConfig(unittest.TestCase): def test_defaultValues(self): p = performanceregressionconfig.PerformanceRegressionConfig({}) self.assertTrue(p.enabled) self.assertEqual(p.runsPerInstance, 3) self.assertEqual(p.relativeThresholdInPercent, 1) self.assertEqual(p.absoluteThresholdInSeconds, 1) def test_overrideValues(self): p = performanceregressionconfig.PerformanceRegressionConfig( { "runsPerInstance": "5", "relativeThresholdInPercent": 1.5, "absoluteThresholdInSeconds": "4.1" }) self.assertTrue(p.enabled) self.assertEqual(p.runsPerInstance, 5) self.assertEqual(p.relativeThresholdInPercent, 1.5) self.assertEqual(p.absoluteThresholdInSeconds, 4.1) if __name__ == "__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_performancerunner.py ================================================ import csv import os import unittest from disposablefile import DisposableFile, DisposableDirectory from context import performancerunner from context import performanceregressionconfig import test_depthmaprunner class PerformanceCheckTest(unittest.TestCase): def test_filesMissing(self): message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "Base performance timing file f1.csv is missing") with DisposableFile("f1.csv") as f1: with open(f1.filename(), "w") as f: f.write("action,average\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv",1 ,2) self.assertEqual(message, "Test performance timing file f2.csv is missing") with DisposableFile("f2.csv") as f2: with open(f2.filename(), "w") as f: f.write("action,average\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "Base performance timing file f1.csv is missing") def test_fileLineNumberMismatch(self): with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\nfoo,10\n") with open(f2.filename(), "w") as f: f.write("action,average\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "baseline performance file f1.csv has more lines than the test one f2.csv") with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\nfoo,10\n") with open(f2.filename(), "w") as f: f.write("action,average\nfoo,10\nbar,20\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1 , 2) self.assertEqual(message, "baseline performance file f1.csv has fewer lines than the test one f2.csv") def test_fileLabelMismatch(self): with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\nfoo,10\n") with open(f2.filename(), "w") as f: f.write("action,average\nbar,10\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "performance line mismatch: base 'foo', test 'bar'") def test_successfulRunEmptyFile(self): with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\n") with open(f2.filename(), "w") as f: f.write("action,average\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "") def test_successfulRun(self): with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\nfoo,10\nbar,21\nbaz,1000\nblub,10\n") with open(f2.filename(), "w") as f: f.write("action,average\nfoo,10.9\nbar,10\nbaz,1010\nblub,10\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "") def test_performanceRegression(self): with DisposableFile("f1.csv") as f1, DisposableFile("f2.csv") as f2: with open(f1.filename(), "w") as f: f.write("action,average\nfoo,10\n") with open(f2.filename(), "w") as f: f.write("action,average\nfoo,18\n") message = performancerunner.checkPerformance("f1.csv", "f2.csv", 1, 2) self.assertEqual(message, "Performance regression: foo took 18s instead of 10s") class test_PerformanceAggregation(unittest.TestCase): def test_aggregation(self): with DisposableDirectory("testdir") as d: os.makedirs(d.name()) nameTemplate = "test{0}{1}.csv" with open(os.path.join(d.name(), nameTemplate.format(0,0)), "w") as f: f.write("action,duration\nt1,3\nt2,2\n") with open(os.path.join(d.name(), nameTemplate.format(1,0)), "w") as f: f.write("action,duration\nt1,1.5\nt2,2.5\n") with open(os.path.join(d.name(), nameTemplate.format(2,0)), "w") as f: f.write("action,duration\nt1,2\nt2,1.5\n") resFile = performancerunner.aggregatePerformanceStats(d.name(), 3, 1, nameTemplate) with open(resFile, "r") as f: reader = csv.DictReader(f) line = next(reader) self.assertEqual(line["action"], "t1") self.assertEqual(float(line["max"]), 3 ) self.assertEqual(float(line["min"]), 1.5) self.assertEqual(float(line["average"]), 6.5/3) line = next(reader) self.assertEqual(line["action"], "t2") self.assertEqual(float(line["max"]), 2.5 ) self.assertEqual(float(line["min"]), 1.5) self.assertEqual(float(line["average"]), 2) line = next(reader) self.assertEqual(line["action"], "total") self.assertEqual(float(line["max"]), 5 ) self.assertEqual(float(line["min"]), 3.5) self.assertEqual(float(line["average"]), 12.5/3) class test_PerformanceRunner(test_depthmaprunner.DepthmapRegressioRunnerTest): def testSuccessfullRun(self): with DisposableDirectory("testdir", True) as testDir, DisposableDirectory("basedir") as baseDir: conf = performanceregressionconfig.PerformanceRegressionConfig({}) runner = performancerunner.PerformanceRunner(lambda d, a: self.runfuncSucceedAlwaysSame(d,a), "basebin", "testbin", testDir.name(), conf) (result, message) = runner.runTestCase("testname", self.makeCommand("infile.graph", "outfile.graph","visibility")) self.assertTrue(result) ================================================ FILE: RegressionTest/test/test_runhelpers.py ================================================ import unittest from context import runhelpers from disposablefile import DisposableDirectory import os import platform import sys class TestRunHelpers(unittest.TestCase): def test_prepareDirectory(self): with DisposableDirectory("testdir", True) as d: self.assertTrue(os.path.isdir(d.name())) testfile = os.path.join(d.name(), "testfile.txt") with open(testfile, "w") as f: f.write("123") self.assertTrue(os.path.exists(testfile)) runhelpers.prepareDirectory(d.name()) self.assertTrue(os.path.isdir(d.name())) self.assertFalse(os.path.exists(testfile)) def test_cd(self): currentpath = os.getcwd() with DisposableDirectory("testdir", True) as d: with runhelpers.cd("testdir"): self.assertEqual(os.getcwd(), os.path.join(currentpath, d.name())) self.assertEqual(os.getcwd(), currentpath, d.name()) def test_getBinary(self): result = runhelpers.getExecutable("foo") sys = platform.system() if sys == "Windows": self.assertEqual( result, "foo\\Windows\\depthmapXcli.exe") else: self.assertEqual( result, "foo/" + sys + "/depthmapXcli" ) def test_getTestBinary(self): result = runhelpers.getTestExecutable("foo") sys = platform.system() if sys == "Windows": self.assertEqual( result, "foo\\depthmapXcli\\release\\depthmapXcli.exe") else: self.assertEqual( result, "foo/depthmapXcli/depthmapXcli" ) def test_runExecutable(self): with DisposableDirectory("testdir", True) as d: retcode, output = runhelpers.runExecutable( d.name(), [sys.executable, "-c", "print('foo')"]) self.assertTrue(retcode) self.assertEqual(output, "foo\n") def test_runExecutableFail(self): with DisposableDirectory("testdir") as d: runhelpers.prepareDirectory(d.name()) retcode, output = runhelpers.runExecutable( d.name(), [sys.executable, "-c", "exit(-1)"]) self.assertFalse(retcode) self.assertEqual(output, "") def test_runExecutableException(self): with DisposableDirectory("testdir") as d: runhelpers.prepareDirectory(d.name()) retcode, output = runhelpers.runExecutable( d.name(), [sys.executable, "-c", "raise Exception()"]) self.assertFalse(retcode) self.assertEqual(output, 'Traceback (most recent call last):\n File "", line 1, in \nException\n') if __name__=="__main__": unittest.main() ================================================ FILE: RegressionTest/test/test_test_main.py ================================================ import unittest from disposablefile import DisposableDirectory from context import runhelpers import sys class TestUnitTestMain(unittest.TestCase): def test_capture_pass(self): with DisposableDirectory("testdir_pass", True) as d: retcode, output = runhelpers.runExecutable( d.name(), [sys.executable, "../test_main.py", "-f", "../pass"]) if not retcode: print("printing the underlying test output to help diagnose the issue:") print(output) self.assertTrue(retcode) def test_capture_fail(self): with DisposableDirectory("testdir_fail", True) as d: retcode, output = runhelpers.runExecutable( d.name(), [sys.executable, "../test_main.py", "-f", "../fail"]) if retcode: print("printing the underlying test output to help diagnose the issue:") print(output) self.assertFalse(retcode) if __name__=="__main__": unittest.main() ================================================ FILE: ThirdParty/Catch/catch.hpp ================================================ /* * Catch v1.6.1 * Generated: 2017-01-20 12:33:53.497767 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_CATCH_HPP_INCLUDED #ifdef __clang__ # pragma clang system_header #elif defined __GNUC__ # pragma GCC system_header #endif // #included from: internal/catch_suppress_warnings.h #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC # pragma clang diagnostic ignored "-Wglobal-constructors" # pragma clang diagnostic ignored "-Wvariadic-macros" # pragma clang diagnostic ignored "-Wc99-extensions" # pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" # pragma clang diagnostic ignored "-Wc++98-compat" # pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ # pragma GCC diagnostic ignored "-Wvariadic-macros" # pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wpadded" #endif #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL #endif #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED # define CLARA_CONFIG_MAIN # endif #endif // #included from: internal/catch_notimplemented_exception.h #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED // #included from: catch_common.h #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED // #included from: catch_compiler_capabilities.h #define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? // CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? // CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported // CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? // CATCH_CONFIG_CPP11_OVERRIDE : is override supported? // CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form // (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 #ifdef __cplusplus # if __cplusplus >= 201103L # define CATCH_CPP11_OR_GREATER # endif # if __cplusplus >= 201402L # define CATCH_CPP14_OR_GREATER # endif #endif #ifdef __clang__ # if __has_feature(cxx_nullptr) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # if __has_feature(cxx_noexcept) # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # if defined(CATCH_CPP11_OR_GREATER) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) # endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // Borland #ifdef __BORLANDC__ #endif // __BORLANDC__ //////////////////////////////////////////////////////////////////////////////// // EDG #ifdef __EDG_VERSION__ #endif // __EDG_VERSION__ //////////////////////////////////////////////////////////////////////////////// // Digital Mars #ifdef __DMC__ #endif // __DMC__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ # if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) && defined(CATCH_CPP11_OR_GREATER) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS _Pragma( "GCC diagnostic ignored \"-Wparentheses\"" ) # endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #if (_MSC_VER >= 1600) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // Use variadic macros if the compiler supports them #if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ ( defined __GNUC__ && __GNUC__ >= 3 ) || \ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) #define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS #endif // Use __COUNTER__ if the compiler supports it #if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ ( defined __GNUC__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 ) || \ ( defined __clang__ && __clang_major__ >= 3 ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(CATCH_CPP11_OR_GREATER) # if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) # define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # endif # ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE # define CATCH_INTERNAL_CONFIG_CPP11_TUPLE # endif # ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) # define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) # define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) # define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR # endif # if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) # define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE # endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NULLPTR #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_NOEXCEPT #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_IS_ENUM #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_TUPLE #endif #if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) # define CATCH_CONFIG_VARIADIC_MACROS #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_LONG_LONG #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_OVERRIDE #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_UNIQUE_PTR #endif // Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for // analytics) because, at time of writing, __COUNTER__ is not properly handled by it. // This does not affect compilation #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__) # define CATCH_CONFIG_COUNTER #endif #if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) # define CATCH_CONFIG_CPP11_SHUFFLE #endif #if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) # define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS #endif // noexcept support: #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) # define CATCH_NOEXCEPT noexcept # define CATCH_NOEXCEPT_IS(x) noexcept(x) #else # define CATCH_NOEXCEPT throw() # define CATCH_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CATCH_CONFIG_CPP11_NULLPTR # define CATCH_NULL nullptr #else # define CATCH_NULL NULL #endif // override support #ifdef CATCH_CONFIG_CPP11_OVERRIDE # define CATCH_OVERRIDE override #else # define CATCH_OVERRIDE #endif // unique_ptr support #ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR # define CATCH_AUTO_PTR( T ) std::unique_ptr #else # define CATCH_AUTO_PTR( T ) std::auto_ptr #endif #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) #else # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #include #include #include namespace Catch { struct IConfig; struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { #ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; #else NonCopyable( NonCopyable const& info ); NonCopyable& operator = ( NonCopyable const& ); #endif protected: NonCopyable() {} virtual ~NonCopyable(); }; class SafeBool { public: typedef void (SafeBool::*type)() const; static type makeSafe( bool value ) { return value ? &SafeBool::trueValue : 0; } private: void trueValue() const {} }; template inline void deleteAll( ContainerT& container ) { typename ContainerT::const_iterator it = container.begin(); typename ContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete *it; } template inline void deleteAllValues( AssociativeContainerT& container ) { typename AssociativeContainerT::const_iterator it = container.begin(); typename AssociativeContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete it->second; } bool startsWith( std::string const& s, std::string const& prefix ); bool endsWith( std::string const& s, std::string const& suffix ); bool contains( std::string const& s, std::string const& infix ); void toLowerInPlace( std::string& s ); std::string toLower( std::string const& s ); std::string trim( std::string const& str ); bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); struct pluralise { pluralise( std::size_t count, std::string const& label ); friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); std::size_t m_count; std::string m_label; }; struct SourceLineInfo { SourceLineInfo(); SourceLineInfo( char const* _file, std::size_t _line ); SourceLineInfo( SourceLineInfo const& other ); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SourceLineInfo( SourceLineInfo && ) = default; SourceLineInfo& operator = ( SourceLineInfo const& ) = default; SourceLineInfo& operator = ( SourceLineInfo && ) = default; # endif bool empty() const; bool operator == ( SourceLineInfo const& other ) const; bool operator < ( SourceLineInfo const& other ) const; std::string file; std::size_t line; }; std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool alwaysTrue( std::size_t = 0 ) { return true; } inline bool alwaysFalse( std::size_t = 0 ) { return false; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); void seedRng( IConfig const& config ); unsigned int rngSeed(); // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { std::string operator+() { return std::string(); } }; template T const& operator + ( T const& value, StreamEndStop ) { return value; } } #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); #include namespace Catch { class NotImplementedException : public std::exception { public: NotImplementedException( SourceLineInfo const& lineInfo ); NotImplementedException( NotImplementedException const& ) {} virtual ~NotImplementedException() CATCH_NOEXCEPT {} virtual const char* what() const CATCH_NOEXCEPT; private: std::string m_what; SourceLineInfo m_lineInfo; }; } // end namespace Catch /////////////////////////////////////////////////////////////////////////////// #define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) // #included from: internal/catch_context.h #define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED // #included from: catch_interfaces_generators.h #define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED #include namespace Catch { struct IGeneratorInfo { virtual ~IGeneratorInfo(); virtual bool moveNext() = 0; virtual std::size_t getCurrentIndex() const = 0; }; struct IGeneratorsForTest { virtual ~IGeneratorsForTest(); virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; virtual bool moveNext() = 0; }; IGeneratorsForTest* createGeneratorsForTest(); } // end namespace Catch // #included from: catch_ptr.hpp #define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { // An intrusive reference counting smart pointer. // T must implement addRef() and release() methods // typically implementing the IShared interface template class Ptr { public: Ptr() : m_p( CATCH_NULL ){} Ptr( T* p ) : m_p( p ){ if( m_p ) m_p->addRef(); } Ptr( Ptr const& other ) : m_p( other.m_p ){ if( m_p ) m_p->addRef(); } ~Ptr(){ if( m_p ) m_p->release(); } void reset() { if( m_p ) m_p->release(); m_p = CATCH_NULL; } Ptr& operator = ( T* p ){ Ptr temp( p ); swap( temp ); return *this; } Ptr& operator = ( Ptr const& other ){ Ptr temp( other ); swap( temp ); return *this; } void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } T* get() const{ return m_p; } T& operator*() const { return *m_p; } T* operator->() const { return m_p; } bool operator !() const { return m_p == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } private: T* m_p; }; struct IShared : NonCopyable { virtual ~IShared(); virtual void addRef() const = 0; virtual void release() const = 0; }; template struct SharedImpl : T { SharedImpl() : m_rc( 0 ){} virtual void addRef() const { ++m_rc; } virtual void release() const { if( --m_rc == 0 ) delete this; } mutable unsigned int m_rc; }; } // end namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif #include #include #include namespace Catch { class TestCase; class Stream; struct IResultCapture; struct IRunner; struct IGeneratorsForTest; struct IConfig; struct IContext { virtual ~IContext(); virtual IResultCapture* getResultCapture() = 0; virtual IRunner* getRunner() = 0; virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; virtual bool advanceGeneratorsForCurrentTest() = 0; virtual Ptr getConfig() const = 0; }; struct IMutableContext : IContext { virtual ~IMutableContext(); virtual void setResultCapture( IResultCapture* resultCapture ) = 0; virtual void setRunner( IRunner* runner ) = 0; virtual void setConfig( Ptr const& config ) = 0; }; IContext& getCurrentContext(); IMutableContext& getCurrentMutableContext(); void cleanUpContext(); Stream createStream( std::string const& streamName ); } // #included from: internal/catch_test_registry.hpp #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED // #included from: catch_interfaces_testcase.h #define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED #include namespace Catch { class TestSpec; struct ITestCase : IShared { virtual void invoke () const = 0; protected: virtual ~ITestCase(); }; class TestCase; struct IConfig; struct ITestCaseRegistry { virtual ~ITestCaseRegistry(); virtual std::vector const& getAllTests() const = 0; virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); std::vector const& getAllTestCasesSorted( IConfig const& config ); } namespace Catch { template class MethodTestCase : public SharedImpl { public: MethodTestCase( void (C::*method)() ) : m_method( method ) {} virtual void invoke() const { C obj; (obj.*m_method)(); } private: virtual ~MethodTestCase() {} void (C::*m_method)(); }; typedef void(*TestFunction)(); struct NameAndDesc { NameAndDesc( const char* _name = "", const char* _description= "" ) : name( _name ), description( _description ) {} const char* name; const char* description; }; void registerTestCase ( ITestCase* testCase, char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ); struct AutoReg { AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); template AutoReg ( void (C::*method)(), char const* className, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { registerTestCase ( new MethodTestCase( method ), className, nameAndDesc, lineInfo ); } ~AutoReg(); private: AutoReg( AutoReg const& ); void operator= ( AutoReg const& ); }; void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ); } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ static void TestName(); \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ static void TestName() #define INTERNAL_CATCH_TESTCASE( ... ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ namespace{ \ struct TestName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestName::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ } \ void TestName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); #else /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TESTCASE2( TestName, Name, Desc ) \ static void TestName(); \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &TestName, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ static void TestName() #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), Name, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestCaseName, ClassName, TestName, Desc )\ namespace{ \ struct TestCaseName : ClassName{ \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &TestCaseName::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ } \ void TestCaseName::test() #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, TestName, Desc ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, Name, Desc ) \ Catch::AutoReg( Function, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); #endif // #included from: internal/catch_capture.hpp #define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED // #included from: catch_result_builder.h #define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED // #included from: catch_result_type.h #define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED namespace Catch { // ResultWas::OfType enum struct ResultWas { enum OfType { Unknown = -1, Ok = 0, Info = 1, Warning = 2, FailureBit = 0x10, ExpressionFailed = FailureBit | 1, ExplicitFailure = FailureBit | 2, Exception = 0x100 | FailureBit, ThrewException = Exception | 1, DidntThrowException = Exception | 2, FatalErrorCondition = 0x200 | FailureBit }; }; inline bool isOk( ResultWas::OfType resultType ) { return ( resultType & ResultWas::FailureBit ) == 0; } inline bool isJustInfo( int flags ) { return flags == ResultWas::Info; } // ResultDisposition::Flags enum struct ResultDisposition { enum Flags { Normal = 0x01, ContinueOnFailure = 0x02, // Failures fail test, but execution continues FalseTest = 0x04, // Prefix expression with ! SuppressFail = 0x08 // Failures are reported but do not fail the test }; }; inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { return static_cast( static_cast( lhs ) | static_cast( rhs ) ); } inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } } // end namespace Catch // #included from: catch_assertionresult.h #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED #include namespace Catch { struct AssertionInfo { AssertionInfo() {} AssertionInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, std::string const& _capturedExpression, ResultDisposition::Flags _resultDisposition ); std::string macroName; SourceLineInfo lineInfo; std::string capturedExpression; ResultDisposition::Flags resultDisposition; }; struct AssertionResultData { AssertionResultData() : resultType( ResultWas::Unknown ) {} std::string reconstructedExpression; std::string message; ResultWas::OfType resultType; }; class AssertionResult { public: AssertionResult(); AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); ~AssertionResult(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionResult( AssertionResult const& ) = default; AssertionResult( AssertionResult && ) = default; AssertionResult& operator = ( AssertionResult const& ) = default; AssertionResult& operator = ( AssertionResult && ) = default; # endif bool isOk() const; bool succeeded() const; ResultWas::OfType getResultType() const; bool hasExpression() const; bool hasMessage() const; std::string getExpression() const; std::string getExpressionInMacro() const; bool hasExpandedExpression() const; std::string getExpandedExpression() const; std::string getMessage() const; SourceLineInfo getSourceInfo() const; std::string getTestMacroName() const; protected: AssertionInfo m_info; AssertionResultData m_resultData; }; } // end namespace Catch // #included from: catch_matchers.hpp #define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED namespace Catch { namespace Matchers { namespace Impl { namespace Generic { template class AllOf; template class AnyOf; template class Not; } template struct Matcher : SharedImpl { typedef ExpressionT ExpressionType; virtual ~Matcher() {} virtual Ptr clone() const = 0; virtual bool match( ExpressionT const& expr ) const = 0; virtual std::string toString() const = 0; Generic::AllOf operator && ( Matcher const& other ) const; Generic::AnyOf operator || ( Matcher const& other ) const; Generic::Not operator ! () const; }; template struct MatcherImpl : Matcher { virtual Ptr > clone() const { return Ptr >( new DerivedT( static_cast( *this ) ) ); } }; namespace Generic { template class Not : public MatcherImpl, ExpressionT> { public: explicit Not( Matcher const& matcher ) : m_matcher(matcher.clone()) {} Not( Not const& other ) : m_matcher( other.m_matcher ) {} virtual bool match( ExpressionT const& expr ) const CATCH_OVERRIDE { return !m_matcher->match( expr ); } virtual std::string toString() const CATCH_OVERRIDE { return "not " + m_matcher->toString(); } private: Ptr< Matcher > m_matcher; }; template class AllOf : public MatcherImpl, ExpressionT> { public: AllOf() {} AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {} AllOf& add( Matcher const& matcher ) { m_matchers.push_back( matcher.clone() ); return *this; } virtual bool match( ExpressionT const& expr ) const { for( std::size_t i = 0; i < m_matchers.size(); ++i ) if( !m_matchers[i]->match( expr ) ) return false; return true; } virtual std::string toString() const { std::ostringstream oss; oss << "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) oss << " and "; oss << m_matchers[i]->toString(); } oss << " )"; return oss.str(); } AllOf operator && ( Matcher const& other ) const { AllOf allOfExpr( *this ); allOfExpr.add( other ); return allOfExpr; } private: std::vector > > m_matchers; }; template class AnyOf : public MatcherImpl, ExpressionT> { public: AnyOf() {} AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {} AnyOf& add( Matcher const& matcher ) { m_matchers.push_back( matcher.clone() ); return *this; } virtual bool match( ExpressionT const& expr ) const { for( std::size_t i = 0; i < m_matchers.size(); ++i ) if( m_matchers[i]->match( expr ) ) return true; return false; } virtual std::string toString() const { std::ostringstream oss; oss << "( "; for( std::size_t i = 0; i < m_matchers.size(); ++i ) { if( i != 0 ) oss << " or "; oss << m_matchers[i]->toString(); } oss << " )"; return oss.str(); } AnyOf operator || ( Matcher const& other ) const { AnyOf anyOfExpr( *this ); anyOfExpr.add( other ); return anyOfExpr; } private: std::vector > > m_matchers; }; } // namespace Generic template Generic::AllOf Matcher::operator && ( Matcher const& other ) const { Generic::AllOf allOfExpr; allOfExpr.add( *this ); allOfExpr.add( other ); return allOfExpr; } template Generic::AnyOf Matcher::operator || ( Matcher const& other ) const { Generic::AnyOf anyOfExpr; anyOfExpr.add( *this ); anyOfExpr.add( other ); return anyOfExpr; } template Generic::Not Matcher::operator ! () const { return Generic::Not( *this ); } namespace StdString { inline std::string makeString( std::string const& str ) { return str; } inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); } struct CasedString { CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_str( adjustString( str ) ) {} std::string adjustString( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } std::string toStringSuffix() const { return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : ""; } CaseSensitive::Choice m_caseSensitivity; std::string m_str; }; struct Equals : MatcherImpl { Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) : m_data( str, caseSensitivity ) {} Equals( Equals const& other ) : m_data( other.m_data ){} virtual ~Equals(); virtual bool match( std::string const& expr ) const { return m_data.m_str == m_data.adjustString( expr );; } virtual std::string toString() const { return "equals: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); } CasedString m_data; }; struct Contains : MatcherImpl { Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) : m_data( substr, caseSensitivity ){} Contains( Contains const& other ) : m_data( other.m_data ){} virtual ~Contains(); virtual bool match( std::string const& expr ) const { return m_data.adjustString( expr ).find( m_data.m_str ) != std::string::npos; } virtual std::string toString() const { return "contains: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); } CasedString m_data; }; struct StartsWith : MatcherImpl { StartsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) : m_data( substr, caseSensitivity ){} StartsWith( StartsWith const& other ) : m_data( other.m_data ){} virtual ~StartsWith(); virtual bool match( std::string const& expr ) const { return startsWith( m_data.adjustString( expr ), m_data.m_str ); } virtual std::string toString() const { return "starts with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); } CasedString m_data; }; struct EndsWith : MatcherImpl { EndsWith( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) : m_data( substr, caseSensitivity ){} EndsWith( EndsWith const& other ) : m_data( other.m_data ){} virtual ~EndsWith(); virtual bool match( std::string const& expr ) const { return endsWith( m_data.adjustString( expr ), m_data.m_str ); } virtual std::string toString() const { return "ends with: \"" + m_data.m_str + "\"" + m_data.toStringSuffix(); } CasedString m_data; }; } // namespace StdString } // namespace Impl // The following functions create the actual matcher objects. // This allows the types to be inferred template inline Impl::Generic::Not Not( Impl::Matcher const& m ) { return Impl::Generic::Not( m ); } template inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, Impl::Matcher const& m2 ) { return Impl::Generic::AllOf().add( m1 ).add( m2 ); } template inline Impl::Generic::AllOf AllOf( Impl::Matcher const& m1, Impl::Matcher const& m2, Impl::Matcher const& m3 ) { return Impl::Generic::AllOf().add( m1 ).add( m2 ).add( m3 ); } template inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, Impl::Matcher const& m2 ) { return Impl::Generic::AnyOf().add( m1 ).add( m2 ); } template inline Impl::Generic::AnyOf AnyOf( Impl::Matcher const& m1, Impl::Matcher const& m2, Impl::Matcher const& m3 ) { return Impl::Generic::AnyOf().add( m1 ).add( m2 ).add( m3 ); } inline Impl::StdString::Equals Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { return Impl::StdString::Equals( str, caseSensitivity ); } inline Impl::StdString::Equals Equals( const char* str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { return Impl::StdString::Equals( Impl::StdString::makeString( str ), caseSensitivity ); } inline Impl::StdString::Contains Contains( std::string const& substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { return Impl::StdString::Contains( substr, caseSensitivity ); } inline Impl::StdString::Contains Contains( const char* substr, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes ) { return Impl::StdString::Contains( Impl::StdString::makeString( substr ), caseSensitivity ); } inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) { return Impl::StdString::StartsWith( substr ); } inline Impl::StdString::StartsWith StartsWith( const char* substr ) { return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) ); } inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) { return Impl::StdString::EndsWith( substr ); } inline Impl::StdString::EndsWith EndsWith( const char* substr ) { return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) ); } } // namespace Matchers using namespace Matchers; } // namespace Catch namespace Catch { struct TestFailureException{}; template class ExpressionLhs; struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; struct CopyableStream { CopyableStream() {} CopyableStream( CopyableStream const& other ) { oss << other.oss.str(); } CopyableStream& operator=( CopyableStream const& other ) { oss.str(""); oss << other.oss.str(); return *this; } std::ostringstream oss; }; class ResultBuilder { public: ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg = "" ); template ExpressionLhs operator <= ( T const& operand ); ExpressionLhs operator <= ( bool value ); template ResultBuilder& operator << ( T const& value ) { m_stream.oss << value; return *this; } template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); ResultBuilder& setResultType( ResultWas::OfType result ); ResultBuilder& setResultType( bool result ); ResultBuilder& setLhs( std::string const& lhs ); ResultBuilder& setRhs( std::string const& rhs ); ResultBuilder& setOp( std::string const& op ); void endExpression(); std::string reconstructExpression() const; AssertionResult build() const; void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); void captureResult( ResultWas::OfType resultType ); void captureExpression(); void captureExpectedException( std::string const& expectedMessage ); void captureExpectedException( Matchers::Impl::Matcher const& matcher ); void handleResult( AssertionResult const& result ); void react(); bool shouldDebugBreak() const; bool allowThrows() const; private: AssertionInfo m_assertionInfo; AssertionResultData m_data; struct ExprComponents { ExprComponents() : testFalse( false ) {} bool testFalse; std::string lhs, rhs, op; } m_exprComponents; CopyableStream m_stream; bool m_shouldDebugBreak; bool m_shouldThrow; }; } // namespace Catch // Include after due to circular dependency: // #included from: catch_expression_lhs.hpp #define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED // #included from: catch_evaluate.hpp #define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4389) // '==' : signed/unsigned mismatch #endif #include namespace Catch { namespace Internal { enum Operator { IsEqualTo, IsNotEqualTo, IsLessThan, IsGreaterThan, IsLessThanOrEqualTo, IsGreaterThanOrEqualTo }; template struct OperatorTraits { static const char* getName(){ return "*error*"; } }; template<> struct OperatorTraits { static const char* getName(){ return "=="; } }; template<> struct OperatorTraits { static const char* getName(){ return "!="; } }; template<> struct OperatorTraits { static const char* getName(){ return "<"; } }; template<> struct OperatorTraits { static const char* getName(){ return ">"; } }; template<> struct OperatorTraits { static const char* getName(){ return "<="; } }; template<> struct OperatorTraits{ static const char* getName(){ return ">="; } }; template inline T& opCast(T const& t) { return const_cast(t); } // nullptr_t support based on pull request #154 from Konstantin Baumann #ifdef CATCH_CONFIG_CPP11_NULLPTR inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } #endif // CATCH_CONFIG_CPP11_NULLPTR // So the compare overloads can be operator agnostic we convey the operator as a template // enum, which is used to specialise an Evaluator for doing the comparison. template class Evaluator{}; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs) { return bool( opCast( lhs ) == opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) != opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) < opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) > opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) >= opCast( rhs ) ); } }; template struct Evaluator { static bool evaluate( T1 const& lhs, T2 const& rhs ) { return bool( opCast( lhs ) <= opCast( rhs ) ); } }; template bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // This level of indirection allows us to specialise for integer types // to avoid signed/ unsigned warnings // "base" overload template bool compare( T1 const& lhs, T2 const& rhs ) { return Evaluator::evaluate( lhs, rhs ); } // unsigned X to int template bool compare( unsigned int lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, int rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // unsigned X to long template bool compare( unsigned int lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned long lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } template bool compare( unsigned char lhs, long rhs ) { return applyEvaluator( lhs, static_cast( rhs ) ); } // int to unsigned X template bool compare( int lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( int lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // long to unsigned X template bool compare( long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long (when comparing against NULL) template bool compare( long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } // pointer to int (when comparing against NULL) template bool compare( int lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, int rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG // long long to unsigned X template bool compare( long long lhs, unsigned int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( long long lhs, unsigned char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // unsigned long long to X template bool compare( unsigned long long lhs, int rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, long long rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } template bool compare( unsigned long long lhs, char rhs ) { return applyEvaluator( static_cast( lhs ), rhs ); } // pointer to long long (when comparing against NULL) template bool compare( long long lhs, T* rhs ) { return Evaluator::evaluate( reinterpret_cast( lhs ), rhs ); } template bool compare( T* lhs, long long rhs ) { return Evaluator::evaluate( lhs, reinterpret_cast( rhs ) ); } #endif // CATCH_CONFIG_CPP11_LONG_LONG #ifdef CATCH_CONFIG_CPP11_NULLPTR // pointer to nullptr_t (when comparing against nullptr) template bool compare( std::nullptr_t, T* rhs ) { return Evaluator::evaluate( nullptr, rhs ); } template bool compare( T* lhs, std::nullptr_t ) { return Evaluator::evaluate( lhs, nullptr ); } #endif // CATCH_CONFIG_CPP11_NULLPTR } // end of namespace Internal } // end of namespace Catch #ifdef _MSC_VER #pragma warning(pop) #endif // #included from: catch_tostring.h #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED #include #include #include #include #include #ifdef __OBJC__ // #included from: catch_objc_arc.hpp #define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED #import #ifdef __has_feature #define CATCH_ARC_ENABLED __has_feature(objc_arc) #else #define CATCH_ARC_ENABLED 0 #endif void arcSafeRelease( NSObject* obj ); id performOptionalSelector( id obj, SEL sel ); #if !CATCH_ARC_ENABLED inline void arcSafeRelease( NSObject* obj ) { [obj release]; } inline id performOptionalSelector( id obj, SEL sel ) { if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; return nil; } #define CATCH_UNSAFE_UNRETAINED #define CATCH_ARC_STRONG #else inline void arcSafeRelease( NSObject* ){} inline id performOptionalSelector( id obj, SEL sel ) { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" #endif if( [obj respondsToSelector: sel] ) return [obj performSelector: sel]; #ifdef __clang__ #pragma clang diagnostic pop #endif return nil; } #define CATCH_UNSAFE_UNRETAINED __unsafe_unretained #define CATCH_ARC_STRONG __strong #endif #endif #ifdef CATCH_CONFIG_CPP11_TUPLE #include #endif #ifdef CATCH_CONFIG_CPP11_IS_ENUM #include #endif namespace Catch { // Why we're here. template std::string toString( T const& value ); // Built in overloads std::string toString( std::string const& value ); std::string toString( std::wstring const& value ); std::string toString( const char* const value ); std::string toString( char* const value ); std::string toString( const wchar_t* const value ); std::string toString( wchar_t* const value ); std::string toString( int value ); std::string toString( unsigned long value ); std::string toString( unsigned int value ); std::string toString( const double value ); std::string toString( const float value ); std::string toString( bool value ); std::string toString( char value ); std::string toString( signed char value ); std::string toString( unsigned char value ); #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ); std::string toString( unsigned long long value ); #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ); #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ); std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); std::string toString( NSObject* const& nsObject ); #endif namespace Detail { extern const std::string unprintableString; struct BorgType { template BorgType( T const& ); }; struct TrueType { char sizer[1]; }; struct FalseType { char sizer[2]; }; TrueType& testStreamable( std::ostream& ); FalseType testStreamable( FalseType ); FalseType operator<<( std::ostream const&, BorgType const& ); template struct IsStreamInsertable { static std::ostream &s; static T const&t; enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; }; #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template::value > struct EnumStringMaker { static std::string convert( T const& ) { return unprintableString; } }; template struct EnumStringMaker { static std::string convert( T const& v ) { return ::Catch::toString( static_cast::type>(v) ); } }; #endif template struct StringMakerBase { #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template static std::string convert( T const& v ) { return EnumStringMaker::convert( v ); } #else template static std::string convert( T const& ) { return unprintableString; } #endif }; template<> struct StringMakerBase { template static std::string convert( T const& _value ) { std::ostringstream oss; oss << _value; return oss.str(); } }; std::string rawMemoryToString( const void *object, std::size_t size ); template inline std::string rawMemoryToString( const T& object ) { return rawMemoryToString( &object, sizeof(object) ); } } // end namespace Detail template struct StringMaker : Detail::StringMakerBase::value> {}; template struct StringMaker { template static std::string convert( U* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; template struct StringMaker { static std::string convert( R C::* p ) { if( !p ) return "NULL"; else return Detail::rawMemoryToString( p ); } }; namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ); } //template //struct StringMaker > { // static std::string convert( std::vector const& v ) { // return Detail::rangeToString( v.begin(), v.end() ); // } //}; template std::string toString( std::vector const& v ) { return Detail::rangeToString( v.begin(), v.end() ); } #ifdef CATCH_CONFIG_CPP11_TUPLE // toString for tuples namespace TupleDetail { template< typename Tuple, std::size_t N = 0, bool = (N < std::tuple_size::value) > struct ElementPrinter { static void print( const Tuple& tuple, std::ostream& os ) { os << ( N ? ", " : " " ) << Catch::toString(std::get(tuple)); ElementPrinter::print(tuple,os); } }; template< typename Tuple, std::size_t N > struct ElementPrinter { static void print( const Tuple&, std::ostream& ) {} }; } template struct StringMaker> { static std::string convert( const std::tuple& tuple ) { std::ostringstream os; os << '{'; TupleDetail::ElementPrinter>::print( tuple, os ); os << " }"; return os.str(); } }; #endif // CATCH_CONFIG_CPP11_TUPLE namespace Detail { template std::string makeString( T const& value ) { return StringMaker::convert( value ); } } // end namespace Detail /// \brief converts any type to a string /// /// The default template forwards on to ostringstream - except when an /// ostringstream overload does not exist - in which case it attempts to detect /// that and writes {?}. /// Overload (not specialise) this template for custom typs that you don't want /// to provide an ostream overload for. template std::string toString( T const& value ) { return StringMaker::convert( value ); } namespace Detail { template std::string rangeToString( InputIterator first, InputIterator last ) { std::ostringstream oss; oss << "{ "; if( first != last ) { oss << Catch::toString( *first ); for( ++first ; first != last ; ++first ) oss << ", " << Catch::toString( *first ); } oss << " }"; return oss.str(); } } } // end namespace Catch namespace Catch { // Wraps the LHS of an expression and captures the operator and RHS (if any) - // wrapping them all in a ResultBuilder object template class ExpressionLhs { ExpressionLhs& operator = ( ExpressionLhs const& ); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS ExpressionLhs& operator = ( ExpressionLhs && ) = delete; # endif public: ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS ExpressionLhs( ExpressionLhs const& ) = default; ExpressionLhs( ExpressionLhs && ) = default; # endif template ResultBuilder& operator == ( RhsT const& rhs ) { return captureExpression( rhs ); } template ResultBuilder& operator != ( RhsT const& rhs ) { return captureExpression( rhs ); } template ResultBuilder& operator < ( RhsT const& rhs ) { return captureExpression( rhs ); } template ResultBuilder& operator > ( RhsT const& rhs ) { return captureExpression( rhs ); } template ResultBuilder& operator <= ( RhsT const& rhs ) { return captureExpression( rhs ); } template ResultBuilder& operator >= ( RhsT const& rhs ) { return captureExpression( rhs ); } ResultBuilder& operator == ( bool rhs ) { return captureExpression( rhs ); } ResultBuilder& operator != ( bool rhs ) { return captureExpression( rhs ); } void endExpression() { bool value = m_lhs ? true : false; m_rb .setLhs( Catch::toString( value ) ) .setResultType( value ) .endExpression(); } // Only simple binary expressions are allowed on the LHS. // If more complex compositions are required then place the sub expression in parentheses template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); template STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); private: template ResultBuilder& captureExpression( RhsT const& rhs ) { return m_rb .setResultType( Internal::compare( m_lhs, rhs ) ) .setLhs( Catch::toString( m_lhs ) ) .setRhs( Catch::toString( rhs ) ) .setOp( Internal::OperatorTraits::getName() ); } private: ResultBuilder& m_rb; T m_lhs; }; } // end namespace Catch namespace Catch { template inline ExpressionLhs ResultBuilder::operator <= ( T const& operand ) { return ExpressionLhs( *this, operand ); } inline ExpressionLhs ResultBuilder::operator <= ( bool value ) { return ExpressionLhs( *this, value ); } } // namespace Catch // #included from: catch_message.h #define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED #include namespace Catch { struct MessageInfo { MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ); std::string macroName; SourceLineInfo lineInfo; ResultWas::OfType type; std::string message; unsigned int sequence; bool operator == ( MessageInfo const& other ) const { return sequence == other.sequence; } bool operator < ( MessageInfo const& other ) const { return sequence < other.sequence; } private: static unsigned int globalCount; }; struct MessageBuilder { MessageBuilder( std::string const& macroName, SourceLineInfo const& lineInfo, ResultWas::OfType type ) : m_info( macroName, lineInfo, type ) {} template MessageBuilder& operator << ( T const& value ) { m_stream << value; return *this; } MessageInfo m_info; std::ostringstream m_stream; }; class ScopedMessage { public: ScopedMessage( MessageBuilder const& builder ); ScopedMessage( ScopedMessage const& other ); ~ScopedMessage(); MessageInfo m_info; }; } // end namespace Catch // #included from: catch_interfaces_capture.h #define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED #include namespace Catch { class TestCase; class AssertionResult; struct AssertionInfo; struct SectionInfo; struct SectionEndInfo; struct MessageInfo; class ScopedMessageBuilder; struct Counts; struct IResultCapture { virtual ~IResultCapture(); virtual void assertionEnded( AssertionResult const& result ) = 0; virtual bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) = 0; virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0; virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0; virtual void pushScopedMessage( MessageInfo const& message ) = 0; virtual void popScopedMessage( MessageInfo const& message ) = 0; virtual std::string getCurrentTestName() const = 0; virtual const AssertionResult* getLastResult() const = 0; virtual void handleFatalErrorCondition( std::string const& message ) = 0; }; IResultCapture& getResultCapture(); } // #included from: catch_debugger.h #define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED // #included from: catch_platform.h #define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_MAC #elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) # define CATCH_PLATFORM_IPHONE #elif defined(linux) || defined(__linux) || defined(__linux__) # define CATCH_PLATFORM_LINUX #elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) # define CATCH_PLATFORM_WINDOWS # if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) # define CATCH_DEFINES_NOMINMAX # endif # if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) # define CATCH_DEFINES_WIN32_LEAN_AND_MEAN # endif #endif #include namespace Catch{ bool isDebuggerActive(); void writeToDebugConsole( std::string const& text ); } #ifdef CATCH_PLATFORM_MAC // The following code snippet based on: // http://cocoawithlove.com/2008/03/break-into-debugger.html #ifdef DEBUG #if defined(__ppc64__) || defined(__ppc__) #define CATCH_TRAP() \ __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ : : : "memory","r0","r3","r4" ) #else #define CATCH_TRAP() _asm__("int $3\n" : : ) #endif #endif #elif defined(CATCH_PLATFORM_LINUX) // If we can use inline assembler, do it because this allows us to break // directly at the location of the failing check instead of breaking inside // raise() called from it, i.e. one stack frame below. #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) #define CATCH_TRAP() asm volatile ("int $3") #else // Fall back to the generic way. #include #define CATCH_TRAP() raise(SIGTRAP) #endif #elif defined(_MSC_VER) #define CATCH_TRAP() __debugbreak() #elif defined(__MINGW32__) extern "C" __declspec(dllimport) void __stdcall DebugBreak(); #define CATCH_TRAP() DebugBreak() #endif #ifdef CATCH_TRAP #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } #else #define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); #endif // #included from: catch_interfaces_runner.h #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED namespace Catch { class TestCase; struct IRunner { virtual ~IRunner(); virtual bool aborting() const = 0; }; } /////////////////////////////////////////////////////////////////////////////// // In the event of a failure works out if the debugger needs to be invoked // and/or an exception thrown and takes appropriate action. // This needs to be done as a macro so the debugger will stop in the user // source code rather than in Catch library code #define INTERNAL_CATCH_REACT( resultBuilder ) \ if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ resultBuilder.react(); /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ try { \ CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ ( __catchResult <= expr ).endExpression(); \ } \ catch( ... ) { \ __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse( sizeof(expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ if( Catch::getResultCapture().getLastResult()->succeeded() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ if( !Catch::getResultCapture().getLastResult()->succeeded() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ try { \ expr; \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS( expr, resultDisposition, matcher, macroName ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition, #matcher ); \ if( __catchResult.allowThrows() ) \ try { \ expr; \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( ... ) { \ __catchResult.captureExpectedException( matcher ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ if( __catchResult.allowThrows() ) \ try { \ expr; \ __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ } \ catch( exceptionType ) { \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ } \ catch( ... ) { \ __catchResult.useActiveException( resultDisposition ); \ } \ else \ __catchResult.captureResult( Catch::ResultWas::Ok ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) /////////////////////////////////////////////////////////////////////////////// #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #else #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ __catchResult << log + ::Catch::StreamEndStop(); \ __catchResult.captureResult( messageType ); \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) #endif /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_INFO( log, macroName ) \ Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ do { \ Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg ", " #matcher, resultDisposition ); \ try { \ std::string matcherAsString = (matcher).toString(); \ __catchResult \ .setLhs( Catch::toString( arg ) ) \ .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ .setOp( "matches" ) \ .setResultType( (matcher).match( arg ) ); \ __catchResult.captureExpression(); \ } catch( ... ) { \ __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ } \ INTERNAL_CATCH_REACT( __catchResult ) \ } while( Catch::alwaysFalse() ) // #included from: internal/catch_section.h #define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED // #included from: catch_section_info.h #define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED // #included from: catch_totals.hpp #define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED #include namespace Catch { struct Counts { Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} Counts operator - ( Counts const& other ) const { Counts diff; diff.passed = passed - other.passed; diff.failed = failed - other.failed; diff.failedButOk = failedButOk - other.failedButOk; return diff; } Counts& operator += ( Counts const& other ) { passed += other.passed; failed += other.failed; failedButOk += other.failedButOk; return *this; } std::size_t total() const { return passed + failed + failedButOk; } bool allPassed() const { return failed == 0 && failedButOk == 0; } bool allOk() const { return failed == 0; } std::size_t passed; std::size_t failed; std::size_t failedButOk; }; struct Totals { Totals operator - ( Totals const& other ) const { Totals diff; diff.assertions = assertions - other.assertions; diff.testCases = testCases - other.testCases; return diff; } Totals delta( Totals const& prevTotals ) const { Totals diff = *this - prevTotals; if( diff.assertions.failed > 0 ) ++diff.testCases.failed; else if( diff.assertions.failedButOk > 0 ) ++diff.testCases.failedButOk; else ++diff.testCases.passed; return diff; } Totals& operator += ( Totals const& other ) { assertions += other.assertions; testCases += other.testCases; return *this; } Counts assertions; Counts testCases; }; } namespace Catch { struct SectionInfo { SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description = std::string() ); std::string name; std::string description; SourceLineInfo lineInfo; }; struct SectionEndInfo { SectionEndInfo( SectionInfo const& _sectionInfo, Counts const& _prevAssertions, double _durationInSeconds ) : sectionInfo( _sectionInfo ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) {} SectionInfo sectionInfo; Counts prevAssertions; double durationInSeconds; }; } // end namespace Catch // #included from: catch_timer.h #define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED #ifdef CATCH_PLATFORM_WINDOWS typedef unsigned long long uint64_t; #else #include #endif namespace Catch { class Timer { public: Timer() : m_ticks( 0 ) {} void start(); unsigned int getElapsedMicroseconds() const; unsigned int getElapsedMilliseconds() const; double getElapsedSeconds() const; private: uint64_t m_ticks; }; } // namespace Catch #include namespace Catch { class Section : NonCopyable { public: Section( SectionInfo const& info ); ~Section(); // This indicates whether the section should be executed or not operator bool() const; private: SectionInfo m_info; std::string m_name; Counts m_assertions; bool m_sectionIncluded; Timer m_timer; }; } // end namespace Catch #ifdef CATCH_CONFIG_VARIADIC_MACROS #define INTERNAL_CATCH_SECTION( ... ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) #else #define INTERNAL_CATCH_SECTION( name, desc ) \ if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) #endif // #included from: internal/catch_generators.hpp #define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED #include #include #include #include namespace Catch { template struct IGenerator { virtual ~IGenerator() {} virtual T getValue( std::size_t index ) const = 0; virtual std::size_t size () const = 0; }; template class BetweenGenerator : public IGenerator { public: BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} virtual T getValue( std::size_t index ) const { return m_from+static_cast( index ); } virtual std::size_t size() const { return static_cast( 1+m_to-m_from ); } private: T m_from; T m_to; }; template class ValuesGenerator : public IGenerator { public: ValuesGenerator(){} void add( T value ) { m_values.push_back( value ); } virtual T getValue( std::size_t index ) const { return m_values[index]; } virtual std::size_t size() const { return m_values.size(); } private: std::vector m_values; }; template class CompositeGenerator { public: CompositeGenerator() : m_totalSize( 0 ) {} // *** Move semantics, similar to auto_ptr *** CompositeGenerator( CompositeGenerator& other ) : m_fileInfo( other.m_fileInfo ), m_totalSize( 0 ) { move( other ); } CompositeGenerator& setFileInfo( const char* fileInfo ) { m_fileInfo = fileInfo; return *this; } ~CompositeGenerator() { deleteAll( m_composed ); } operator T () const { size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); typename std::vector*>::const_iterator it = m_composed.begin(); typename std::vector*>::const_iterator itEnd = m_composed.end(); for( size_t index = 0; it != itEnd; ++it ) { const IGenerator* generator = *it; if( overallIndex >= index && overallIndex < index + generator->size() ) { return generator->getValue( overallIndex-index ); } index += generator->size(); } CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so } void add( const IGenerator* generator ) { m_totalSize += generator->size(); m_composed.push_back( generator ); } CompositeGenerator& then( CompositeGenerator& other ) { move( other ); return *this; } CompositeGenerator& then( T value ) { ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( value ); add( valuesGen ); return *this; } private: void move( CompositeGenerator& other ) { std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); m_totalSize += other.m_totalSize; other.m_composed.clear(); } std::vector*> m_composed; std::string m_fileInfo; size_t m_totalSize; }; namespace Generators { template CompositeGenerator between( T from, T to ) { CompositeGenerator generators; generators.add( new BetweenGenerator( from, to ) ); return generators; } template CompositeGenerator values( T val1, T val2 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3 ){ CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); generators.add( valuesGen ); return generators; } template CompositeGenerator values( T val1, T val2, T val3, T val4 ) { CompositeGenerator generators; ValuesGenerator* valuesGen = new ValuesGenerator(); valuesGen->add( val1 ); valuesGen->add( val2 ); valuesGen->add( val3 ); valuesGen->add( val4 ); generators.add( valuesGen ); return generators; } } // end namespace Generators using namespace Generators; } // end namespace Catch #define INTERNAL_CATCH_LINESTR2( line ) #line #define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) #define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) // #included from: internal/catch_interfaces_exception.h #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED #include #include // #included from: catch_interfaces_registry_hub.h #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED #include namespace Catch { class TestCase; struct ITestCaseRegistry; struct IExceptionTranslatorRegistry; struct IExceptionTranslator; struct IReporterRegistry; struct IReporterFactory; struct IRegistryHub { virtual ~IRegistryHub(); virtual IReporterRegistry const& getReporterRegistry() const = 0; virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; }; struct IMutableRegistryHub { virtual ~IMutableRegistryHub(); virtual void registerReporter( std::string const& name, Ptr const& factory ) = 0; virtual void registerListener( Ptr const& factory ) = 0; virtual void registerTest( TestCase const& testInfo ) = 0; virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; }; IRegistryHub& getRegistryHub(); IMutableRegistryHub& getMutableRegistryHub(); void cleanUp(); std::string translateActiveException(); } namespace Catch { typedef std::string(*exceptionTranslateFunction)(); struct IExceptionTranslator; typedef std::vector ExceptionTranslators; struct IExceptionTranslator { virtual ~IExceptionTranslator(); virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; }; struct IExceptionTranslatorRegistry { virtual ~IExceptionTranslatorRegistry(); virtual std::string translateActiveException() const = 0; }; class ExceptionTranslatorRegistrar { template class ExceptionTranslator : public IExceptionTranslator { public: ExceptionTranslator( std::string(*translateFunction)( T& ) ) : m_translateFunction( translateFunction ) {} virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE { try { if( it == itEnd ) throw; else return (*it)->translate( it+1, itEnd ); } catch( T& ex ) { return m_translateFunction( ex ); } } protected: std::string(*m_translateFunction)( T& ); }; public: template ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { getMutableRegistryHub().registerTranslator ( new ExceptionTranslator( translateFunction ) ); } }; } /////////////////////////////////////////////////////////////////////////////// #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ static std::string translatorName( signature ); \ namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\ static std::string translatorName( signature ) #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) // #included from: internal/catch_approx.hpp #define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED #include #include namespace Catch { namespace Detail { class Approx { public: explicit Approx ( double value ) : m_epsilon( std::numeric_limits::epsilon()*100 ), m_scale( 1.0 ), m_value( value ) {} Approx( Approx const& other ) : m_epsilon( other.m_epsilon ), m_scale( other.m_scale ), m_value( other.m_value ) {} static Approx custom() { return Approx( 0 ); } Approx operator()( double value ) { Approx approx( value ); approx.epsilon( m_epsilon ); approx.scale( m_scale ); return approx; } friend bool operator == ( double lhs, Approx const& rhs ) { // Thanks to Richard Harris for his help refining this formula return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); } friend bool operator == ( Approx const& lhs, double rhs ) { return operator==( rhs, lhs ); } friend bool operator != ( double lhs, Approx const& rhs ) { return !operator==( lhs, rhs ); } friend bool operator != ( Approx const& lhs, double rhs ) { return !operator==( rhs, lhs ); } friend bool operator <= ( double lhs, Approx const& rhs ) { return lhs < rhs.m_value || lhs == rhs; } friend bool operator <= ( Approx const& lhs, double rhs ) { return lhs.m_value < rhs || lhs == rhs; } friend bool operator >= ( double lhs, Approx const& rhs ) { return lhs > rhs.m_value || lhs == rhs; } friend bool operator >= ( Approx const& lhs, double rhs ) { return lhs.m_value > rhs || lhs == rhs; } Approx& epsilon( double newEpsilon ) { m_epsilon = newEpsilon; return *this; } Approx& scale( double newScale ) { m_scale = newScale; return *this; } std::string toString() const { std::ostringstream oss; oss << "Approx( " << Catch::toString( m_value ) << " )"; return oss.str(); } private: double m_epsilon; double m_scale; double m_value; }; } template<> inline std::string toString( Detail::Approx const& value ) { return value.toString(); } } // end namespace Catch // #included from: internal/catch_interfaces_tag_alias_registry.h #define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED // #included from: catch_tag_alias.h #define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED #include namespace Catch { struct TagAlias { TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} std::string tag; SourceLineInfo lineInfo; }; struct RegistrarForTagAliases { RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch #define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } // #included from: catch_option.hpp #define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED namespace Catch { // An optional type template class Option { public: Option() : nullableValue( CATCH_NULL ) {} Option( T const& _value ) : nullableValue( new( storage ) T( _value ) ) {} Option( Option const& _other ) : nullableValue( _other ? new( storage ) T( *_other ) : CATCH_NULL ) {} ~Option() { reset(); } Option& operator= ( Option const& _other ) { if( &_other != this ) { reset(); if( _other ) nullableValue = new( storage ) T( *_other ); } return *this; } Option& operator = ( T const& _value ) { reset(); nullableValue = new( storage ) T( _value ); return *this; } void reset() { if( nullableValue ) nullableValue->~T(); nullableValue = CATCH_NULL; } T& operator*() { return *nullableValue; } T const& operator*() const { return *nullableValue; } T* operator->() { return nullableValue; } const T* operator->() const { return nullableValue; } T valueOr( T const& defaultValue ) const { return nullableValue ? *nullableValue : defaultValue; } bool some() const { return nullableValue != CATCH_NULL; } bool none() const { return nullableValue == CATCH_NULL; } bool operator !() const { return nullableValue == CATCH_NULL; } operator SafeBool::type() const { return SafeBool::makeSafe( some() ); } private: T* nullableValue; char storage[sizeof(T)]; }; } // end namespace Catch namespace Catch { struct ITagAliasRegistry { virtual ~ITagAliasRegistry(); virtual Option find( std::string const& alias ) const = 0; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; static ITagAliasRegistry const& get(); }; } // end namespace Catch // These files are included here so the single_include script doesn't put them // in the conditionally compiled sections // #included from: internal/catch_test_case_info.h #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED #include #include #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif namespace Catch { struct ITestCase; struct TestCaseInfo { enum SpecialProperties{ None = 0, IsHidden = 1 << 1, ShouldFail = 1 << 2, MayFail = 1 << 3, Throws = 1 << 4 }; TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ); TestCaseInfo( TestCaseInfo const& other ); friend void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ); bool isHidden() const; bool throws() const; bool okToFail() const; bool expectedToFail() const; std::string name; std::string className; std::string description; std::set tags; std::set lcaseTags; std::string tagsAsString; SourceLineInfo lineInfo; SpecialProperties properties; }; class TestCase : public TestCaseInfo { public: TestCase( ITestCase* testCase, TestCaseInfo const& info ); TestCase( TestCase const& other ); TestCase withName( std::string const& _newName ) const; void invoke() const; TestCaseInfo const& getTestCaseInfo() const; void swap( TestCase& other ); bool operator == ( TestCase const& other ) const; bool operator < ( TestCase const& other ) const; TestCase& operator = ( TestCase const& other ); private: Ptr test; }; TestCase makeTestCase( ITestCase* testCase, std::string const& className, std::string const& name, std::string const& description, SourceLineInfo const& lineInfo ); } #ifdef __clang__ #pragma clang diagnostic pop #endif #ifdef __OBJC__ // #included from: internal/catch_objc.hpp #define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED #import #include // NB. Any general catch headers included here must be included // in catch.hpp first to make sure they are included by the single // header for non obj-usage /////////////////////////////////////////////////////////////////////////////// // This protocol is really only here for (self) documenting purposes, since // all its methods are optional. @protocol OcFixture @optional -(void) setUp; -(void) tearDown; @end namespace Catch { class OcMethod : public SharedImpl { public: OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} virtual void invoke() const { id obj = [[m_cls alloc] init]; performOptionalSelector( obj, @selector(setUp) ); performOptionalSelector( obj, m_sel ); performOptionalSelector( obj, @selector(tearDown) ); arcSafeRelease( obj ); } private: virtual ~OcMethod() {} Class m_cls; SEL m_sel; }; namespace Detail{ inline std::string getAnnotation( Class cls, std::string const& annotationName, std::string const& testCaseName ) { NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; SEL sel = NSSelectorFromString( selStr ); arcSafeRelease( selStr ); id value = performOptionalSelector( cls, sel ); if( value ) return [(NSString*)value UTF8String]; return ""; } } inline size_t registerTestMethods() { size_t noTestMethods = 0; int noClasses = objc_getClassList( CATCH_NULL, 0 ); Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); objc_getClassList( classes, noClasses ); for( int c = 0; c < noClasses; c++ ) { Class cls = classes[c]; { u_int count; Method* methods = class_copyMethodList( cls, &count ); for( u_int m = 0; m < count ; m++ ) { SEL selector = method_getName(methods[m]); std::string methodName = sel_getName(selector); if( startsWith( methodName, "Catch_TestCase_" ) ) { std::string testCaseName = methodName.substr( 15 ); std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); const char* className = class_getName( cls ); getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); noTestMethods++; } } free(methods); } } return noTestMethods; } namespace Matchers { namespace Impl { namespace NSStringMatchers { template struct StringHolder : MatcherImpl{ StringHolder( NSString* substr ) : m_substr( [substr copy] ){} StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} StringHolder() { arcSafeRelease( m_substr ); } NSString* m_substr; }; struct Equals : StringHolder { Equals( NSString* substr ) : StringHolder( substr ){} virtual bool match( ExpressionType const& str ) const { return (str != nil || m_substr == nil ) && [str isEqualToString:m_substr]; } virtual std::string toString() const { return "equals string: " + Catch::toString( m_substr ); } }; struct Contains : StringHolder { Contains( NSString* substr ) : StringHolder( substr ){} virtual bool match( ExpressionType const& str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location != NSNotFound; } virtual std::string toString() const { return "contains string: " + Catch::toString( m_substr ); } }; struct StartsWith : StringHolder { StartsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( ExpressionType const& str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == 0; } virtual std::string toString() const { return "starts with: " + Catch::toString( m_substr ); } }; struct EndsWith : StringHolder { EndsWith( NSString* substr ) : StringHolder( substr ){} virtual bool match( ExpressionType const& str ) const { return (str != nil || m_substr == nil ) && [str rangeOfString:m_substr].location == [str length] - [m_substr length]; } virtual std::string toString() const { return "ends with: " + Catch::toString( m_substr ); } }; } // namespace NSStringMatchers } // namespace Impl inline Impl::NSStringMatchers::Equals Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } inline Impl::NSStringMatchers::Contains Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } inline Impl::NSStringMatchers::StartsWith StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } inline Impl::NSStringMatchers::EndsWith EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } } // namespace Matchers using namespace Matchers; } // namespace Catch /////////////////////////////////////////////////////////////////////////////// #define OC_TEST_CASE( name, desc )\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ {\ return @ name; \ }\ +(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ { \ return @ desc; \ } \ -(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) #endif #ifdef CATCH_IMPL // #included from: internal/catch_impl.hpp #define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED // Collect all the implementation files together here // These are the equivalent of what would usually be cpp files #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wweak-vtables" #endif // #included from: ../catch_session.hpp #define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED // #included from: internal/catch_commandline.hpp #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED // #included from: catch_config.hpp #define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED // #included from: catch_test_spec_parser.hpp #define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif // #included from: catch_test_spec.hpp #define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wpadded" #endif // #included from: catch_wildcard_pattern.hpp #define TWOBLUECUBES_CATCH_WILDCARD_PATTERN_HPP_INCLUDED namespace Catch { class WildcardPattern { enum WildcardPosition { NoWildcard = 0, WildcardAtStart = 1, WildcardAtEnd = 2, WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd }; public: WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity ) : m_caseSensitivity( caseSensitivity ), m_wildcard( NoWildcard ), m_pattern( adjustCase( pattern ) ) { if( startsWith( m_pattern, "*" ) ) { m_pattern = m_pattern.substr( 1 ); m_wildcard = WildcardAtStart; } if( endsWith( m_pattern, "*" ) ) { m_pattern = m_pattern.substr( 0, m_pattern.size()-1 ); m_wildcard = static_cast( m_wildcard | WildcardAtEnd ); } } virtual ~WildcardPattern(); virtual bool matches( std::string const& str ) const { switch( m_wildcard ) { case NoWildcard: return m_pattern == adjustCase( str ); case WildcardAtStart: return endsWith( adjustCase( str ), m_pattern ); case WildcardAtEnd: return startsWith( adjustCase( str ), m_pattern ); case WildcardAtBothEnds: return contains( adjustCase( str ), m_pattern ); } #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunreachable-code" #endif throw std::logic_error( "Unknown enum" ); #ifdef __clang__ #pragma clang diagnostic pop #endif } private: std::string adjustCase( std::string const& str ) const { return m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str; } CaseSensitive::Choice m_caseSensitivity; WildcardPosition m_wildcard; std::string m_pattern; }; } #include #include namespace Catch { class TestSpec { struct Pattern : SharedImpl<> { virtual ~Pattern(); virtual bool matches( TestCaseInfo const& testCase ) const = 0; }; class NamePattern : public Pattern { public: NamePattern( std::string const& name ) : m_wildcardPattern( toLower( name ), CaseSensitive::No ) {} virtual ~NamePattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return m_wildcardPattern.matches( toLower( testCase.name ) ); } private: WildcardPattern m_wildcardPattern; }; class TagPattern : public Pattern { public: TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} virtual ~TagPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); } private: std::string m_tag; }; class ExcludedPattern : public Pattern { public: ExcludedPattern( Ptr const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} virtual ~ExcludedPattern(); virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } private: Ptr m_underlyingPattern; }; struct Filter { std::vector > m_patterns; bool matches( TestCaseInfo const& testCase ) const { // All patterns in a filter must match for the filter to be a match for( std::vector >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) { if( !(*it)->matches( testCase ) ) return false; } return true; } }; public: bool hasFilters() const { return !m_filters.empty(); } bool matches( TestCaseInfo const& testCase ) const { // A TestSpec matches if any filter matches for( std::vector::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) if( it->matches( testCase ) ) return true; return false; } private: std::vector m_filters; friend class TestSpecParser; }; } #ifdef __clang__ #pragma clang diagnostic pop #endif namespace Catch { class TestSpecParser { enum Mode{ None, Name, QuotedName, Tag, EscapedName }; Mode m_mode; bool m_exclusion; std::size_t m_start, m_pos; std::string m_arg; std::vector m_escapeChars; TestSpec::Filter m_currentFilter; TestSpec m_testSpec; ITagAliasRegistry const* m_tagAliases; public: TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} TestSpecParser& parse( std::string const& arg ) { m_mode = None; m_exclusion = false; m_start = std::string::npos; m_arg = m_tagAliases->expandAliases( arg ); m_escapeChars.clear(); for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) visitChar( m_arg[m_pos] ); if( m_mode == Name ) addPattern(); return *this; } TestSpec testSpec() { addFilter(); return m_testSpec; } private: void visitChar( char c ) { if( m_mode == None ) { switch( c ) { case ' ': return; case '~': m_exclusion = true; return; case '[': return startNewMode( Tag, ++m_pos ); case '"': return startNewMode( QuotedName, ++m_pos ); case '\\': return escape(); default: startNewMode( Name, m_pos ); break; } } if( m_mode == Name ) { if( c == ',' ) { addPattern(); addFilter(); } else if( c == '[' ) { if( subString() == "exclude:" ) m_exclusion = true; else addPattern(); startNewMode( Tag, ++m_pos ); } else if( c == '\\' ) escape(); } else if( m_mode == EscapedName ) m_mode = Name; else if( m_mode == QuotedName && c == '"' ) addPattern(); else if( m_mode == Tag && c == ']' ) addPattern(); } void startNewMode( Mode mode, std::size_t start ) { m_mode = mode; m_start = start; } void escape() { m_mode = EscapedName; m_escapeChars.push_back( m_pos ); } std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } template void addPattern() { std::string token = subString(); for( size_t i = 0; i < m_escapeChars.size(); ++i ) token = token.substr( 0, m_escapeChars[i] ) + token.substr( m_escapeChars[i]+1 ); m_escapeChars.clear(); if( startsWith( token, "exclude:" ) ) { m_exclusion = true; token = token.substr( 8 ); } if( !token.empty() ) { Ptr pattern = new T( token ); if( m_exclusion ) pattern = new TestSpec::ExcludedPattern( pattern ); m_currentFilter.m_patterns.push_back( pattern ); } m_exclusion = false; m_mode = None; } void addFilter() { if( !m_currentFilter.m_patterns.empty() ) { m_testSpec.m_filters.push_back( m_currentFilter ); m_currentFilter = TestSpec::Filter(); } } }; inline TestSpec parseTestSpec( std::string const& arg ) { return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif // #included from: catch_interfaces_config.h #define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED #include #include #include namespace Catch { struct Verbosity { enum Level { NoOutput = 0, Quiet, Normal }; }; struct WarnAbout { enum What { Nothing = 0x00, NoAssertions = 0x01 }; }; struct ShowDurations { enum OrNot { DefaultForReporter, Always, Never }; }; struct RunTests { enum InWhatOrder { InDeclarationOrder, InLexicographicalOrder, InRandomOrder }; }; struct UseColour { enum YesOrNo { Auto, Yes, No }; }; class TestSpec; struct IConfig : IShared { virtual ~IConfig(); virtual bool allowThrows() const = 0; virtual std::ostream& stream() const = 0; virtual std::string name() const = 0; virtual bool includeSuccessfulResults() const = 0; virtual bool shouldDebugBreak() const = 0; virtual bool warnAboutMissingAssertions() const = 0; virtual int abortAfter() const = 0; virtual bool showInvisibles() const = 0; virtual ShowDurations::OrNot showDurations() const = 0; virtual TestSpec const& testSpec() const = 0; virtual RunTests::InWhatOrder runOrder() const = 0; virtual unsigned int rngSeed() const = 0; virtual UseColour::YesOrNo useColour() const = 0; }; } // #included from: catch_stream.h #define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED // #included from: catch_streambuf.h #define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED #include namespace Catch { class StreamBufBase : public std::streambuf { public: virtual ~StreamBufBase() CATCH_NOEXCEPT; }; } #include #include #include #include namespace Catch { std::ostream& cout(); std::ostream& cerr(); struct IStream { virtual ~IStream() CATCH_NOEXCEPT; virtual std::ostream& stream() const = 0; }; class FileStream : public IStream { mutable std::ofstream m_ofs; public: FileStream( std::string const& filename ); virtual ~FileStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class CoutStream : public IStream { mutable std::ostream m_os; public: CoutStream(); virtual ~CoutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; class DebugOutStream : public IStream { CATCH_AUTO_PTR( StreamBufBase ) m_streamBuf; mutable std::ostream m_os; public: DebugOutStream(); virtual ~DebugOutStream() CATCH_NOEXCEPT; public: // IStream virtual std::ostream& stream() const CATCH_OVERRIDE; }; } #include #include #include #include #include #ifndef CATCH_CONFIG_CONSOLE_WIDTH #define CATCH_CONFIG_CONSOLE_WIDTH 80 #endif namespace Catch { struct ConfigData { ConfigData() : listTests( false ), listTags( false ), listReporters( false ), listTestNamesOnly( false ), showSuccessfulTests( false ), shouldDebugBreak( false ), noThrow( false ), showHelp( false ), showInvisibles( false ), filenamesAsTags( false ), abortAfter( -1 ), rngSeed( 0 ), verbosity( Verbosity::Normal ), warnings( WarnAbout::Nothing ), showDurations( ShowDurations::DefaultForReporter ), runOrder( RunTests::InDeclarationOrder ), useColour( UseColour::Auto ) {} bool listTests; bool listTags; bool listReporters; bool listTestNamesOnly; bool showSuccessfulTests; bool shouldDebugBreak; bool noThrow; bool showHelp; bool showInvisibles; bool filenamesAsTags; int abortAfter; unsigned int rngSeed; Verbosity::Level verbosity; WarnAbout::What warnings; ShowDurations::OrNot showDurations; RunTests::InWhatOrder runOrder; UseColour::YesOrNo useColour; std::string outputFilename; std::string name; std::string processName; std::vector reporterNames; std::vector testsOrTags; }; class Config : public SharedImpl { private: Config( Config const& other ); Config& operator = ( Config const& other ); virtual void dummy(); public: Config() {} Config( ConfigData const& data ) : m_data( data ), m_stream( openStream() ) { if( !data.testsOrTags.empty() ) { TestSpecParser parser( ITagAliasRegistry::get() ); for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) parser.parse( data.testsOrTags[i] ); m_testSpec = parser.testSpec(); } } virtual ~Config() { } std::string const& getFilename() const { return m_data.outputFilename ; } bool listTests() const { return m_data.listTests; } bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } bool listTags() const { return m_data.listTags; } bool listReporters() const { return m_data.listReporters; } std::string getProcessName() const { return m_data.processName; } bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } std::vector getReporterNames() const { return m_data.reporterNames; } int abortAfter() const { return m_data.abortAfter; } TestSpec const& testSpec() const { return m_testSpec; } bool showHelp() const { return m_data.showHelp; } bool showInvisibles() const { return m_data.showInvisibles; } // IConfig interface virtual bool allowThrows() const { return !m_data.noThrow; } virtual std::ostream& stream() const { return m_stream->stream(); } virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } virtual unsigned int rngSeed() const { return m_data.rngSeed; } virtual UseColour::YesOrNo useColour() const { return m_data.useColour; } private: IStream const* openStream() { if( m_data.outputFilename.empty() ) return new CoutStream(); else if( m_data.outputFilename[0] == '%' ) { if( m_data.outputFilename == "%debug" ) return new DebugOutStream(); else throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename ); } else return new FileStream( m_data.outputFilename ); } ConfigData m_data; CATCH_AUTO_PTR( IStream const ) m_stream; TestSpec m_testSpec; }; } // end namespace Catch // #included from: catch_clara.h #define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED // Use Catch's value for console width (store Clara's off to the side, if present) #ifdef CLARA_CONFIG_CONSOLE_WIDTH #define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH #undef CLARA_CONFIG_CONSOLE_WIDTH #endif #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH // Declare Clara inside the Catch namespace #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { // #included from: ../external/clara.h // Version 0.0.2.4 // Only use header guard if we are not using an outer namespace #if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) #ifndef STITCH_CLARA_OPEN_NAMESPACE #define TWOBLUECUBES_CLARA_H_INCLUDED #define STITCH_CLARA_OPEN_NAMESPACE #define STITCH_CLARA_CLOSE_NAMESPACE #else #define STITCH_CLARA_CLOSE_NAMESPACE } #endif #define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE // ----------- #included from tbc_text_format.h ----------- // Only use header guard if we are not using an outer namespace #if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) #ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE #define TBC_TEXT_FORMAT_H_INCLUDED #endif #include #include #include #include // Use optional outer namespace #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ), tabChar( '\t' ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap char tabChar; // If this char is seen the indent is changed to current pos }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { std::string wrappableChars = " [({.,/|\\-"; std::size_t indent = _attr.initialIndent != std::string::npos ? _attr.initialIndent : _attr.indent; std::string remainder = _str; while( !remainder.empty() ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::size_t tabPos = std::string::npos; std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); std::size_t pos = remainder.find_first_of( '\n' ); if( pos <= width ) { width = pos; } pos = remainder.find_last_of( _attr.tabChar, width ); if( pos != std::string::npos ) { tabPos = pos; if( remainder[width] == '\n' ) width--; remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); } if( width == remainder.size() ) { spliceLine( indent, remainder, width ); } else if( remainder[width] == '\n' ) { spliceLine( indent, remainder, width ); if( width <= 1 || remainder.size() != 1 ) remainder = remainder.substr( 1 ); indent = _attr.indent; } else { pos = remainder.find_last_of( wrappableChars, width ); if( pos != std::string::npos && pos > 0 ) { spliceLine( indent, remainder, pos ); if( remainder[0] == ' ' ) remainder = remainder.substr( 1 ); } else { spliceLine( indent, remainder, width-1 ); lines.back() += "-"; } if( lines.size() == 1 ) indent = _attr.indent; if( tabPos != std::string::npos ) indent += tabPos; } } } void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); _remainder = _remainder.substr( _pos ); } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TBC_TEXT_FORMAT_H_INCLUDED // ----------- end of #include from tbc_text_format.h ----------- // ........... back in clara.h #undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE // ----------- #included from clara_compilers.h ----------- #ifndef TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED #define TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // Detect a number of compiler features - mostly C++11/14 conformance - by compiler // The following features are defined: // // CLARA_CONFIG_CPP11_NULLPTR : is nullptr supported? // CLARA_CONFIG_CPP11_NOEXCEPT : is noexcept supported? // CLARA_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods // CLARA_CONFIG_CPP11_OVERRIDE : is override supported? // CLARA_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) // CLARA_CONFIG_CPP11_OR_GREATER : Is C++11 supported? // CLARA_CONFIG_VARIADIC_MACROS : are variadic macros supported? // In general each macro has a _NO_ form // (e.g. CLARA_CONFIG_CPP11_NO_NULLPTR) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. // All the C++11 features can be disabled with CLARA_CONFIG_NO_CPP11 #ifdef __clang__ #if __has_feature(cxx_nullptr) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #if __has_feature(cxx_noexcept) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// // GCC #ifdef __GNUC__ #if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif // - otherwise more recent versions define __cplusplus >= 201103L // and will get picked up below #endif // __GNUC__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ #ifdef _MSC_VER #if (_MSC_VER >= 1600) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// // C++ language feature support // catch all support for C++11 #if defined(__cplusplus) && __cplusplus >= 201103L #define CLARA_CPP11_OR_GREATER #if !defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) #define CLARA_INTERNAL_CONFIG_CPP11_NULLPTR #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #define CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT #endif #ifndef CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #define CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) #define CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE #endif #if !defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) #define CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR #endif #endif // __cplusplus >= 201103L // Now set the actual defines based on the above + anything the user has configured #if defined(CLARA_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NO_NULLPTR) && !defined(CLARA_CONFIG_CPP11_NULLPTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NULLPTR #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_NOEXCEPT #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CLARA_CONFIG_CPP11_GENERATED_METHODS) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_GENERATED_METHODS #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_OVERRIDE) && !defined(CLARA_CONFIG_CPP11_OVERRIDE) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_OVERRIDE #endif #if defined(CLARA_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_UNIQUE_PTR) && !defined(CLARA_CONFIG_CPP11_UNIQUE_PTR) && !defined(CLARA_CONFIG_NO_CPP11) #define CLARA_CONFIG_CPP11_UNIQUE_PTR #endif // noexcept support: #if defined(CLARA_CONFIG_CPP11_NOEXCEPT) && !defined(CLARA_NOEXCEPT) #define CLARA_NOEXCEPT noexcept # define CLARA_NOEXCEPT_IS(x) noexcept(x) #else #define CLARA_NOEXCEPT throw() # define CLARA_NOEXCEPT_IS(x) #endif // nullptr support #ifdef CLARA_CONFIG_CPP11_NULLPTR #define CLARA_NULL nullptr #else #define CLARA_NULL NULL #endif // override support #ifdef CLARA_CONFIG_CPP11_OVERRIDE #define CLARA_OVERRIDE override #else #define CLARA_OVERRIDE #endif // unique_ptr support #ifdef CLARA_CONFIG_CPP11_UNIQUE_PTR # define CLARA_AUTO_PTR( T ) std::unique_ptr #else # define CLARA_AUTO_PTR( T ) std::auto_ptr #endif #endif // TWOBLUECUBES_CLARA_COMPILERS_H_INCLUDED // ----------- end of #include from clara_compilers.h ----------- // ........... back in clara.h #include #include #include #if defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) #define CLARA_PLATFORM_WINDOWS #endif // Use optional outer namespace #ifdef STITCH_CLARA_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE #endif namespace Clara { struct UnpositionalTag {}; extern UnpositionalTag _; #ifdef CLARA_CONFIG_MAIN UnpositionalTag _; #endif namespace Detail { #ifdef CLARA_CONSOLE_WIDTH const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif using namespace Tbc; inline bool startsWith( std::string const& str, std::string const& prefix ) { return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; } template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct RemoveConstRef{ typedef T type; }; template struct IsBool { static const bool value = false; }; template<> struct IsBool { static const bool value = true; }; template void convertInto( std::string const& _source, T& _dest ) { std::stringstream ss; ss << _source; ss >> _dest; if( ss.fail() ) throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); } inline void convertInto( std::string const& _source, std::string& _dest ) { _dest = _source; } char toLowerCh(char c) { return static_cast( ::tolower( c ) ); } inline void convertInto( std::string const& _source, bool& _dest ) { std::string sourceLC = _source; std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), toLowerCh ); if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) _dest = true; else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) _dest = false; else throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); } template struct IArgFunction { virtual ~IArgFunction() {} #ifdef CLARA_CONFIG_CPP11_GENERATED_METHODS IArgFunction() = default; IArgFunction( IArgFunction const& ) = default; #endif virtual void set( ConfigT& config, std::string const& value ) const = 0; virtual bool takesArg() const = 0; virtual IArgFunction* clone() const = 0; }; template class BoundArgFunction { public: BoundArgFunction() : functionObj( CLARA_NULL ) {} BoundArgFunction( IArgFunction* _functionObj ) : functionObj( _functionObj ) {} BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : CLARA_NULL ) {} BoundArgFunction& operator = ( BoundArgFunction const& other ) { IArgFunction* newFunctionObj = other.functionObj ? other.functionObj->clone() : CLARA_NULL; delete functionObj; functionObj = newFunctionObj; return *this; } ~BoundArgFunction() { delete functionObj; } void set( ConfigT& config, std::string const& value ) const { functionObj->set( config, value ); } bool takesArg() const { return functionObj->takesArg(); } bool isSet() const { return functionObj != CLARA_NULL; } private: IArgFunction* functionObj; }; template struct NullBinder : IArgFunction{ virtual void set( C&, std::string const& ) const {} virtual bool takesArg() const { return true; } virtual IArgFunction* clone() const { return new NullBinder( *this ); } }; template struct BoundDataMember : IArgFunction{ BoundDataMember( M C::* _member ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { convertInto( stringValue, p.*member ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundDataMember( *this ); } M C::* member; }; template struct BoundUnaryMethod : IArgFunction{ BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); (p.*member)( value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundUnaryMethod( *this ); } void (C::*member)( M ); }; template struct BoundNullaryMethod : IArgFunction{ BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} virtual void set( C& p, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) (p.*member)(); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundNullaryMethod( *this ); } void (C::*member)(); }; template struct BoundUnaryFunction : IArgFunction{ BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { bool value; convertInto( stringValue, value ); if( value ) function( obj ); } virtual bool takesArg() const { return false; } virtual IArgFunction* clone() const { return new BoundUnaryFunction( *this ); } void (*function)( C& ); }; template struct BoundBinaryFunction : IArgFunction{ BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} virtual void set( C& obj, std::string const& stringValue ) const { typename RemoveConstRef::type value; convertInto( stringValue, value ); function( obj, value ); } virtual bool takesArg() const { return !IsBool::value; } virtual IArgFunction* clone() const { return new BoundBinaryFunction( *this ); } void (*function)( C&, T ); }; } // namespace Detail inline std::vector argsToVector( int argc, char const* const* const argv ) { std::vector args( static_cast( argc ) ); for( std::size_t i = 0; i < static_cast( argc ); ++i ) args[i] = argv[i]; return args; } class Parser { enum Mode { None, MaybeShortOpt, SlashOpt, ShortOpt, LongOpt, Positional }; Mode mode; std::size_t from; bool inQuotes; public: struct Token { enum Type { Positional, ShortOpt, LongOpt }; Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} Type type; std::string data; }; Parser() : mode( None ), from( 0 ), inQuotes( false ){} void parseIntoTokens( std::vector const& args, std::vector& tokens ) { const std::string doubleDash = "--"; for( std::size_t i = 1; i < args.size() && args[i] != doubleDash; ++i ) parseIntoTokens( args[i], tokens); } void parseIntoTokens( std::string const& arg, std::vector& tokens ) { for( std::size_t i = 0; i <= arg.size(); ++i ) { char c = arg[i]; if( c == '"' ) inQuotes = !inQuotes; mode = handleMode( i, c, arg, tokens ); } } Mode handleMode( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { switch( mode ) { case None: return handleNone( i, c ); case MaybeShortOpt: return handleMaybeShortOpt( i, c ); case ShortOpt: case LongOpt: case SlashOpt: return handleOpt( i, c, arg, tokens ); case Positional: return handlePositional( i, c, arg, tokens ); default: throw std::logic_error( "Unknown mode" ); } } Mode handleNone( std::size_t i, char c ) { if( inQuotes ) { from = i; return Positional; } switch( c ) { case '-': return MaybeShortOpt; #ifdef CLARA_PLATFORM_WINDOWS case '/': from = i+1; return SlashOpt; #endif default: from = i; return Positional; } } Mode handleMaybeShortOpt( std::size_t i, char c ) { switch( c ) { case '-': from = i+1; return LongOpt; default: from = i; return ShortOpt; } } Mode handleOpt( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( std::string( ":=\0", 3 ).find( c ) == std::string::npos ) return mode; std::string optName = arg.substr( from, i-from ); if( mode == ShortOpt ) for( std::size_t j = 0; j < optName.size(); ++j ) tokens.push_back( Token( Token::ShortOpt, optName.substr( j, 1 ) ) ); else if( mode == SlashOpt && optName.size() == 1 ) tokens.push_back( Token( Token::ShortOpt, optName ) ); else tokens.push_back( Token( Token::LongOpt, optName ) ); return None; } Mode handlePositional( std::size_t i, char c, std::string const& arg, std::vector& tokens ) { if( inQuotes || std::string( "\0", 1 ).find( c ) == std::string::npos ) return mode; std::string data = arg.substr( from, i-from ); tokens.push_back( Token( Token::Positional, data ) ); return None; } }; template struct CommonArgProperties { CommonArgProperties() {} CommonArgProperties( Detail::BoundArgFunction const& _boundField ) : boundField( _boundField ) {} Detail::BoundArgFunction boundField; std::string description; std::string detail; std::string placeholder; // Only value if boundField takes an arg bool takesArg() const { return !placeholder.empty(); } void validate() const { if( !boundField.isSet() ) throw std::logic_error( "option not bound" ); } }; struct OptionArgProperties { std::vector shortNames; std::string longName; bool hasShortName( std::string const& shortName ) const { return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); } bool hasLongName( std::string const& _longName ) const { return _longName == longName; } }; struct PositionalArgProperties { PositionalArgProperties() : position( -1 ) {} int position; // -1 means non-positional (floating) bool isFixedPositional() const { return position != -1; } }; template class CommandLine { struct Arg : CommonArgProperties, OptionArgProperties, PositionalArgProperties { Arg() {} Arg( Detail::BoundArgFunction const& _boundField ) : CommonArgProperties( _boundField ) {} using CommonArgProperties::placeholder; // !TBD std::string dbgName() const { if( !longName.empty() ) return "--" + longName; if( !shortNames.empty() ) return "-" + shortNames[0]; return "positional args"; } std::string commands() const { std::ostringstream oss; bool first = true; std::vector::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); for(; it != itEnd; ++it ) { if( first ) first = false; else oss << ", "; oss << "-" << *it; } if( !longName.empty() ) { if( !first ) oss << ", "; oss << "--" << longName; } if( !placeholder.empty() ) oss << " <" << placeholder << ">"; return oss.str(); } }; typedef CLARA_AUTO_PTR( Arg ) ArgAutoPtr; friend void addOptName( Arg& arg, std::string const& optName ) { if( optName.empty() ) return; if( Detail::startsWith( optName, "--" ) ) { if( !arg.longName.empty() ) throw std::logic_error( "Only one long opt may be specified. '" + arg.longName + "' already specified, now attempting to add '" + optName + "'" ); arg.longName = optName.substr( 2 ); } else if( Detail::startsWith( optName, "-" ) ) arg.shortNames.push_back( optName.substr( 1 ) ); else throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); } friend void setPositionalArg( Arg& arg, int position ) { arg.position = position; } class ArgBuilder { public: ArgBuilder( Arg* arg ) : m_arg( arg ) {} // Bind a non-boolean data member (requires placeholder string) template void bind( M C::* field, std::string const& placeholder ) { m_arg->boundField = new Detail::BoundDataMember( field ); m_arg->placeholder = placeholder; } // Bind a boolean data member (no placeholder required) template void bind( bool C::* field ) { m_arg->boundField = new Detail::BoundDataMember( field ); } // Bind a method taking a single, non-boolean argument (requires a placeholder string) template void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); m_arg->placeholder = placeholder; } // Bind a method taking a single, boolean argument (no placeholder string required) template void bind( void (C::* unaryMethod)( bool ) ) { m_arg->boundField = new Detail::BoundUnaryMethod( unaryMethod ); } // Bind a method that takes no arguments (will be called if opt is present) template void bind( void (C::* nullaryMethod)() ) { m_arg->boundField = new Detail::BoundNullaryMethod( nullaryMethod ); } // Bind a free function taking a single argument - the object to operate on (no placeholder string required) template void bind( void (* unaryFunction)( C& ) ) { m_arg->boundField = new Detail::BoundUnaryFunction( unaryFunction ); } // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) template void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { m_arg->boundField = new Detail::BoundBinaryFunction( binaryFunction ); m_arg->placeholder = placeholder; } ArgBuilder& describe( std::string const& description ) { m_arg->description = description; return *this; } ArgBuilder& detail( std::string const& detail ) { m_arg->detail = detail; return *this; } protected: Arg* m_arg; }; class OptBuilder : public ArgBuilder { public: OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} OptBuilder& operator[]( std::string const& optName ) { addOptName( *ArgBuilder::m_arg, optName ); return *this; } }; public: CommandLine() : m_boundProcessName( new Detail::NullBinder() ), m_highestSpecifiedArgPosition( 0 ), m_throwOnUnrecognisedTokens( false ) {} CommandLine( CommandLine const& other ) : m_boundProcessName( other.m_boundProcessName ), m_options ( other.m_options ), m_positionalArgs( other.m_positionalArgs ), m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) { if( other.m_floatingArg.get() ) m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); } CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { m_throwOnUnrecognisedTokens = shouldThrow; return *this; } OptBuilder operator[]( std::string const& optName ) { m_options.push_back( Arg() ); addOptName( m_options.back(), optName ); OptBuilder builder( &m_options.back() ); return builder; } ArgBuilder operator[]( int position ) { m_positionalArgs.insert( std::make_pair( position, Arg() ) ); if( position > m_highestSpecifiedArgPosition ) m_highestSpecifiedArgPosition = position; setPositionalArg( m_positionalArgs[position], position ); ArgBuilder builder( &m_positionalArgs[position] ); return builder; } // Invoke this with the _ instance ArgBuilder operator[]( UnpositionalTag ) { if( m_floatingArg.get() ) throw std::logic_error( "Only one unpositional argument can be added" ); m_floatingArg.reset( new Arg() ); ArgBuilder builder( m_floatingArg.get() ); return builder; } template void bindProcessName( M C::* field ) { m_boundProcessName = new Detail::BoundDataMember( field ); } template void bindProcessName( void (C::*_unaryMethod)( M ) ) { m_boundProcessName = new Detail::BoundUnaryMethod( _unaryMethod ); } void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { typename std::vector::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; std::size_t maxWidth = 0; for( it = itBegin; it != itEnd; ++it ) maxWidth = (std::max)( maxWidth, it->commands().size() ); for( it = itBegin; it != itEnd; ++it ) { Detail::Text usage( it->commands(), Detail::TextAttributes() .setWidth( maxWidth+indent ) .setIndent( indent ) ); Detail::Text desc( it->description, Detail::TextAttributes() .setWidth( width - maxWidth - 3 ) ); for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { std::string usageCol = i < usage.size() ? usage[i] : ""; os << usageCol; if( i < desc.size() && !desc[i].empty() ) os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) << desc[i]; os << "\n"; } } } std::string optUsage() const { std::ostringstream oss; optUsage( oss ); return oss.str(); } void argSynopsis( std::ostream& os ) const { for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { if( i > 1 ) os << " "; typename std::map::const_iterator it = m_positionalArgs.find( i ); if( it != m_positionalArgs.end() ) os << "<" << it->second.placeholder << ">"; else if( m_floatingArg.get() ) os << "<" << m_floatingArg->placeholder << ">"; else throw std::logic_error( "non consecutive positional arguments with no floating args" ); } // !TBD No indication of mandatory args if( m_floatingArg.get() ) { if( m_highestSpecifiedArgPosition > 1 ) os << " "; os << "[<" << m_floatingArg->placeholder << "> ...]"; } } std::string argSynopsis() const { std::ostringstream oss; argSynopsis( oss ); return oss.str(); } void usage( std::ostream& os, std::string const& procName ) const { validate(); os << "usage:\n " << procName << " "; argSynopsis( os ); if( !m_options.empty() ) { os << " [options]\n\nwhere options are: \n"; optUsage( os, 2 ); } os << "\n"; } std::string usage( std::string const& procName ) const { std::ostringstream oss; usage( oss, procName ); return oss.str(); } ConfigT parse( std::vector const& args ) const { ConfigT config; parseInto( args, config ); return config; } std::vector parseInto( std::vector const& args, ConfigT& config ) const { std::string processName = args[0]; std::size_t lastSlash = processName.find_last_of( "/\\" ); if( lastSlash != std::string::npos ) processName = processName.substr( lastSlash+1 ); m_boundProcessName.set( config, processName ); std::vector tokens; Parser parser; parser.parseIntoTokens( args, tokens ); return populate( tokens, config ); } std::vector populate( std::vector const& tokens, ConfigT& config ) const { validate(); std::vector unusedTokens = populateOptions( tokens, config ); unusedTokens = populateFixedArgs( unusedTokens, config ); unusedTokens = populateFloatingArgs( unusedTokens, config ); return unusedTokens; } std::vector populateOptions( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; std::vector errors; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); for(; it != itEnd; ++it ) { Arg const& arg = *it; try { if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { if( arg.takesArg() ) { if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) errors.push_back( "Expected argument to option: " + token.data ); else arg.boundField.set( config, tokens[++i].data ); } else { arg.boundField.set( config, "true" ); } break; } } catch( std::exception& ex ) { errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); } } if( it == itEnd ) { if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) unusedTokens.push_back( token ); else if( errors.empty() && m_throwOnUnrecognisedTokens ) errors.push_back( "unrecognised option: " + token.data ); } } if( !errors.empty() ) { std::ostringstream oss; for( std::vector::const_iterator it = errors.begin(), itEnd = errors.end(); it != itEnd; ++it ) { if( it != errors.begin() ) oss << "\n"; oss << *it; } throw std::runtime_error( oss.str() ); } return unusedTokens; } std::vector populateFixedArgs( std::vector const& tokens, ConfigT& config ) const { std::vector unusedTokens; int position = 1; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; typename std::map::const_iterator it = m_positionalArgs.find( position ); if( it != m_positionalArgs.end() ) it->second.boundField.set( config, token.data ); else unusedTokens.push_back( token ); if( token.type == Parser::Token::Positional ) position++; } return unusedTokens; } std::vector populateFloatingArgs( std::vector const& tokens, ConfigT& config ) const { if( !m_floatingArg.get() ) return tokens; std::vector unusedTokens; for( std::size_t i = 0; i < tokens.size(); ++i ) { Parser::Token const& token = tokens[i]; if( token.type == Parser::Token::Positional ) m_floatingArg->boundField.set( config, token.data ); else unusedTokens.push_back( token ); } return unusedTokens; } void validate() const { if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) throw std::logic_error( "No options or arguments specified" ); for( typename std::vector::const_iterator it = m_options.begin(), itEnd = m_options.end(); it != itEnd; ++it ) it->validate(); } private: Detail::BoundArgFunction m_boundProcessName; std::vector m_options; std::map m_positionalArgs; ArgAutoPtr m_floatingArg; int m_highestSpecifiedArgPosition; bool m_throwOnUnrecognisedTokens; }; } // end namespace Clara STITCH_CLARA_CLOSE_NAMESPACE #undef STITCH_CLARA_OPEN_NAMESPACE #undef STITCH_CLARA_CLOSE_NAMESPACE #endif // TWOBLUECUBES_CLARA_H_INCLUDED #undef STITCH_CLARA_OPEN_NAMESPACE // Restore Clara's value for console width, if present #ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH #endif #include namespace Catch { inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } inline void abortAfterX( ConfigData& config, int x ) { if( x < 1 ) throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); config.abortAfter = x; } inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); } inline void addWarning( ConfigData& config, std::string const& _warning ) { if( _warning == "NoAssertions" ) config.warnings = static_cast( config.warnings | WarnAbout::NoAssertions ); else throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" ); } inline void setOrder( ConfigData& config, std::string const& order ) { if( startsWith( "declared", order ) ) config.runOrder = RunTests::InDeclarationOrder; else if( startsWith( "lexical", order ) ) config.runOrder = RunTests::InLexicographicalOrder; else if( startsWith( "random", order ) ) config.runOrder = RunTests::InRandomOrder; else throw std::runtime_error( "Unrecognised ordering: '" + order + "'" ); } inline void setRngSeed( ConfigData& config, std::string const& seed ) { if( seed == "time" ) { config.rngSeed = static_cast( std::time(0) ); } else { std::stringstream ss; ss << seed; ss >> config.rngSeed; if( ss.fail() ) throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" ); } } inline void setVerbosity( ConfigData& config, int level ) { // !TBD: accept strings? config.verbosity = static_cast( level ); } inline void setShowDurations( ConfigData& config, bool _showDurations ) { config.showDurations = _showDurations ? ShowDurations::Always : ShowDurations::Never; } inline void setUseColour( ConfigData& config, std::string const& value ) { std::string mode = toLower( value ); if( mode == "yes" ) config.useColour = UseColour::Yes; else if( mode == "no" ) config.useColour = UseColour::No; else if( mode == "auto" ) config.useColour = UseColour::Auto; else throw std::runtime_error( "colour mode must be one of: auto, yes or no" ); } inline void forceColour( ConfigData& config ) { config.useColour = UseColour::Yes; } inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { std::ifstream f( _filename.c_str() ); if( !f.is_open() ) throw std::domain_error( "Unable to load input file: " + _filename ); std::string line; while( std::getline( f, line ) ) { line = trim(line); if( !line.empty() && !startsWith( line, "#" ) ) { if( !startsWith( line, "\"" ) ) line = "\"" + line + "\""; addTestOrTags( config, line + "," ); } } } inline Clara::CommandLine makeCommandLineParser() { using namespace Clara; CommandLine cli; cli.bindProcessName( &ConfigData::processName ); cli["-?"]["-h"]["--help"] .describe( "display usage information" ) .bind( &ConfigData::showHelp ); cli["-l"]["--list-tests"] .describe( "list all/matching test cases" ) .bind( &ConfigData::listTests ); cli["-t"]["--list-tags"] .describe( "list all/matching tags" ) .bind( &ConfigData::listTags ); cli["-s"]["--success"] .describe( "include successful tests in output" ) .bind( &ConfigData::showSuccessfulTests ); cli["-b"]["--break"] .describe( "break into debugger on failure" ) .bind( &ConfigData::shouldDebugBreak ); cli["-e"]["--nothrow"] .describe( "skip exception tests" ) .bind( &ConfigData::noThrow ); cli["-i"]["--invisibles"] .describe( "show invisibles (tabs, newlines)" ) .bind( &ConfigData::showInvisibles ); cli["-o"]["--out"] .describe( "output filename" ) .bind( &ConfigData::outputFilename, "filename" ); cli["-r"]["--reporter"] // .placeholder( "name[:filename]" ) .describe( "reporter to use (defaults to console)" ) .bind( &addReporterName, "name" ); cli["-n"]["--name"] .describe( "suite name" ) .bind( &ConfigData::name, "name" ); cli["-a"]["--abort"] .describe( "abort at first failure" ) .bind( &abortAfterFirst ); cli["-x"]["--abortx"] .describe( "abort after x failures" ) .bind( &abortAfterX, "no. failures" ); cli["-w"]["--warn"] .describe( "enable warnings" ) .bind( &addWarning, "warning name" ); // - needs updating if reinstated // cli.into( &setVerbosity ) // .describe( "level of verbosity (0=no output)" ) // .shortOpt( "v") // .longOpt( "verbosity" ) // .placeholder( "level" ); cli[_] .describe( "which test or tests to use" ) .bind( &addTestOrTags, "test name, pattern or tags" ); cli["-d"]["--durations"] .describe( "show test durations" ) .bind( &setShowDurations, "yes|no" ); cli["-f"]["--input-file"] .describe( "load test names to run from a file" ) .bind( &loadTestNamesFromFile, "filename" ); cli["-#"]["--filenames-as-tags"] .describe( "adds a tag for the filename" ) .bind( &ConfigData::filenamesAsTags ); // Less common commands which don't have a short form cli["--list-test-names-only"] .describe( "list all/matching test cases names only" ) .bind( &ConfigData::listTestNamesOnly ); cli["--list-reporters"] .describe( "list all reporters" ) .bind( &ConfigData::listReporters ); cli["--order"] .describe( "test case order (defaults to decl)" ) .bind( &setOrder, "decl|lex|rand" ); cli["--rng-seed"] .describe( "set a specific seed for random numbers" ) .bind( &setRngSeed, "'time'|number" ); cli["--force-colour"] .describe( "force colourised output (deprecated)" ) .bind( &forceColour ); cli["--use-colour"] .describe( "should output be colourised" ) .bind( &setUseColour, "yes|no" ); return cli; } } // end namespace Catch // #included from: internal/catch_list.hpp #define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED // #included from: catch_text.h #define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED #define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH #define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch // #included from: ../external/tbc_text_format.h // Only use header guard if we are not using an outer namespace #ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE # ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED # endif # else # define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED # endif #endif #ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED #include #include #include // Use optional outer namespace #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { #endif namespace Tbc { #ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; #else const unsigned int consoleWidth = 80; #endif struct TextAttributes { TextAttributes() : initialIndent( std::string::npos ), indent( 0 ), width( consoleWidth-1 ), tabChar( '\t' ) {} TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } std::size_t initialIndent; // indent of first line, or npos std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos std::size_t width; // maximum width of text, including indent. Longer text will wrap char tabChar; // If this char is seen the indent is changed to current pos }; class Text { public: Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) : attr( _attr ) { std::string wrappableChars = " [({.,/|\\-"; std::size_t indent = _attr.initialIndent != std::string::npos ? _attr.initialIndent : _attr.indent; std::string remainder = _str; while( !remainder.empty() ) { if( lines.size() >= 1000 ) { lines.push_back( "... message truncated due to excessive size" ); return; } std::size_t tabPos = std::string::npos; std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); std::size_t pos = remainder.find_first_of( '\n' ); if( pos <= width ) { width = pos; } pos = remainder.find_last_of( _attr.tabChar, width ); if( pos != std::string::npos ) { tabPos = pos; if( remainder[width] == '\n' ) width--; remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); } if( width == remainder.size() ) { spliceLine( indent, remainder, width ); } else if( remainder[width] == '\n' ) { spliceLine( indent, remainder, width ); if( width <= 1 || remainder.size() != 1 ) remainder = remainder.substr( 1 ); indent = _attr.indent; } else { pos = remainder.find_last_of( wrappableChars, width ); if( pos != std::string::npos && pos > 0 ) { spliceLine( indent, remainder, pos ); if( remainder[0] == ' ' ) remainder = remainder.substr( 1 ); } else { spliceLine( indent, remainder, width-1 ); lines.back() += "-"; } if( lines.size() == 1 ) indent = _attr.indent; if( tabPos != std::string::npos ) indent += tabPos; } } } void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); _remainder = _remainder.substr( _pos ); } typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return lines.begin(); } const_iterator end() const { return lines.end(); } std::string const& last() const { return lines.back(); } std::size_t size() const { return lines.size(); } std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } std::string toString() const { std::ostringstream oss; oss << *this; return oss.str(); } inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); it != itEnd; ++it ) { if( it != _text.begin() ) _stream << "\n"; _stream << *it; } return _stream; } private: std::string str; TextAttributes attr; std::vector lines; }; } // end namespace Tbc #ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE } // end outer namespace #endif #endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED #undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE namespace Catch { using Tbc::Text; using Tbc::TextAttributes; } // #included from: catch_console_colour.hpp #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED namespace Catch { struct Colour { enum Code { None = 0, White, Red, Green, Blue, Cyan, Yellow, Grey, Bright = 0x10, BrightRed = Bright | Red, BrightGreen = Bright | Green, LightGrey = Bright | Grey, BrightWhite = Bright | White, // By intention FileName = LightGrey, Warning = Yellow, ResultError = BrightRed, ResultSuccess = BrightGreen, ResultExpectedFailure = Warning, Error = BrightRed, Success = Green, OriginalExpression = Cyan, ReconstructedExpression = Yellow, SecondaryText = LightGrey, Headers = White }; // Use constructed object for RAII guard Colour( Code _colourCode ); Colour( Colour const& other ); ~Colour(); // Use static method for one-shot changes static void use( Code _colourCode ); private: bool m_moved; }; inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } } // end namespace Catch // #included from: catch_interfaces_reporter.h #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED #include #include #include #include namespace Catch { struct ReporterConfig { explicit ReporterConfig( Ptr const& _fullConfig ) : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} ReporterConfig( Ptr const& _fullConfig, std::ostream& _stream ) : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} std::ostream& stream() const { return *m_stream; } Ptr fullConfig() const { return m_fullConfig; } private: std::ostream* m_stream; Ptr m_fullConfig; }; struct ReporterPreferences { ReporterPreferences() : shouldRedirectStdOut( false ) {} bool shouldRedirectStdOut; }; template struct LazyStat : Option { LazyStat() : used( false ) {} LazyStat& operator=( T const& _value ) { Option::operator=( _value ); used = false; return *this; } void reset() { Option::reset(); used = false; } bool used; }; struct TestRunInfo { TestRunInfo( std::string const& _name ) : name( _name ) {} std::string name; }; struct GroupInfo { GroupInfo( std::string const& _name, std::size_t _groupIndex, std::size_t _groupsCount ) : name( _name ), groupIndex( _groupIndex ), groupsCounts( _groupsCount ) {} std::string name; std::size_t groupIndex; std::size_t groupsCounts; }; struct AssertionStats { AssertionStats( AssertionResult const& _assertionResult, std::vector const& _infoMessages, Totals const& _totals ) : assertionResult( _assertionResult ), infoMessages( _infoMessages ), totals( _totals ) { if( assertionResult.hasMessage() ) { // Copy message into messages list. // !TBD This should have been done earlier, somewhere MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); builder << assertionResult.getMessage(); builder.m_info.message = builder.m_stream.str(); infoMessages.push_back( builder.m_info ); } } virtual ~AssertionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS AssertionStats( AssertionStats const& ) = default; AssertionStats( AssertionStats && ) = default; AssertionStats& operator = ( AssertionStats const& ) = default; AssertionStats& operator = ( AssertionStats && ) = default; # endif AssertionResult assertionResult; std::vector infoMessages; Totals totals; }; struct SectionStats { SectionStats( SectionInfo const& _sectionInfo, Counts const& _assertions, double _durationInSeconds, bool _missingAssertions ) : sectionInfo( _sectionInfo ), assertions( _assertions ), durationInSeconds( _durationInSeconds ), missingAssertions( _missingAssertions ) {} virtual ~SectionStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS SectionStats( SectionStats const& ) = default; SectionStats( SectionStats && ) = default; SectionStats& operator = ( SectionStats const& ) = default; SectionStats& operator = ( SectionStats && ) = default; # endif SectionInfo sectionInfo; Counts assertions; double durationInSeconds; bool missingAssertions; }; struct TestCaseStats { TestCaseStats( TestCaseInfo const& _testInfo, Totals const& _totals, std::string const& _stdOut, std::string const& _stdErr, bool _aborting ) : testInfo( _testInfo ), totals( _totals ), stdOut( _stdOut ), stdErr( _stdErr ), aborting( _aborting ) {} virtual ~TestCaseStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestCaseStats( TestCaseStats const& ) = default; TestCaseStats( TestCaseStats && ) = default; TestCaseStats& operator = ( TestCaseStats const& ) = default; TestCaseStats& operator = ( TestCaseStats && ) = default; # endif TestCaseInfo testInfo; Totals totals; std::string stdOut; std::string stdErr; bool aborting; }; struct TestGroupStats { TestGroupStats( GroupInfo const& _groupInfo, Totals const& _totals, bool _aborting ) : groupInfo( _groupInfo ), totals( _totals ), aborting( _aborting ) {} TestGroupStats( GroupInfo const& _groupInfo ) : groupInfo( _groupInfo ), aborting( false ) {} virtual ~TestGroupStats(); # ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS TestGroupStats( TestGroupStats const& ) = default; TestGroupStats( TestGroupStats && ) = default; TestGroupStats& operator = ( TestGroupStats const& ) = default; TestGroupStats& operator = ( TestGroupStats && ) = default; # endif GroupInfo groupInfo; Totals totals; bool aborting; }; struct TestRunStats { TestRunStats( TestRunInfo const& _runInfo, Totals const& _totals, bool _aborting ) : runInfo( _runInfo ), totals( _totals ), aborting( _aborting ) {} virtual ~TestRunStats(); # ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS TestRunStats( TestRunStats const& _other ) : runInfo( _other.runInfo ), totals( _other.totals ), aborting( _other.aborting ) {} # else TestRunStats( TestRunStats const& ) = default; TestRunStats( TestRunStats && ) = default; TestRunStats& operator = ( TestRunStats const& ) = default; TestRunStats& operator = ( TestRunStats && ) = default; # endif TestRunInfo runInfo; Totals totals; bool aborting; }; class MultipleReporters; struct IStreamingReporter : IShared { virtual ~IStreamingReporter(); // Implementing class must also provide the following static method: // static std::string getDescription(); virtual ReporterPreferences getPreferences() const = 0; virtual void noMatchingTestCases( std::string const& spec ) = 0; virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; virtual void sectionEnded( SectionStats const& sectionStats ) = 0; virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; virtual void skipTest( TestCaseInfo const& testInfo ) = 0; virtual MultipleReporters* tryAsMulti() { return CATCH_NULL; } }; struct IReporterFactory : IShared { virtual ~IReporterFactory(); virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; virtual std::string getDescription() const = 0; }; struct IReporterRegistry { typedef std::map > FactoryMap; typedef std::vector > Listeners; virtual ~IReporterRegistry(); virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const = 0; virtual FactoryMap const& getFactories() const = 0; virtual Listeners const& getListeners() const = 0; }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ); } #include #include namespace Catch { inline std::size_t listTests( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Matching test cases:\n"; else { Catch::cout() << "All available test cases:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::size_t matchedTests = 0; TextAttributes nameAttr, tagsAttr; nameAttr.setInitialIndent( 2 ).setIndent( 4 ); tagsAttr.setIndent( 6 ); std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None; Colour colourGuard( colour ); Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; if( !testCaseInfo.tags.empty() ) Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; } if( !config.testSpec().hasFilters() ) Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl; else Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl; return matchedTests; } inline std::size_t listTestsNamesOnly( Config const& config ) { TestSpec testSpec = config.testSpec(); if( !config.testSpec().hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); std::size_t matchedTests = 0; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { matchedTests++; TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); if( startsWith( testCaseInfo.name, "#" ) ) Catch::cout() << "\"" << testCaseInfo.name << "\"" << std::endl; else Catch::cout() << testCaseInfo.name << std::endl; } return matchedTests; } struct TagInfo { TagInfo() : count ( 0 ) {} void add( std::string const& spelling ) { ++count; spellings.insert( spelling ); } std::string all() const { std::string out; for( std::set::const_iterator it = spellings.begin(), itEnd = spellings.end(); it != itEnd; ++it ) out += "[" + *it + "]"; return out; } std::set spellings; std::size_t count; }; inline std::size_t listTags( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Tags for matching test cases:\n"; else { Catch::cout() << "All available tags:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::map tagCounts; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( std::vector::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); it != itEnd; ++it ) { for( std::set::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), tagItEnd = it->getTestCaseInfo().tags.end(); tagIt != tagItEnd; ++tagIt ) { std::string tagName = *tagIt; std::string lcaseTagName = toLower( tagName ); std::map::iterator countIt = tagCounts.find( lcaseTagName ); if( countIt == tagCounts.end() ) countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; countIt->second.add( tagName ); } } for( std::map::const_iterator countIt = tagCounts.begin(), countItEnd = tagCounts.end(); countIt != countItEnd; ++countIt ) { std::ostringstream oss; oss << " " << std::setw(2) << countIt->second.count << " "; Text wrapper( countIt->second.all(), TextAttributes() .setInitialIndent( 0 ) .setIndent( oss.str().size() ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); Catch::cout() << oss.str() << wrapper << "\n"; } Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl; return tagCounts.size(); } inline std::size_t listReporters( Config const& /*config*/ ) { Catch::cout() << "Available reporters:\n"; IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; std::size_t maxNameLen = 0; for(it = itBegin; it != itEnd; ++it ) maxNameLen = (std::max)( maxNameLen, it->first.size() ); for(it = itBegin; it != itEnd; ++it ) { Text wrapper( it->second->getDescription(), TextAttributes() .setInitialIndent( 0 ) .setIndent( 7+maxNameLen ) .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); Catch::cout() << " " << it->first << ":" << std::string( maxNameLen - it->first.size() + 2, ' ' ) << wrapper << "\n"; } Catch::cout() << std::endl; return factories.size(); } inline Option list( Config const& config ) { Option listedCount; if( config.listTests() ) listedCount = listedCount.valueOr(0) + listTests( config ); if( config.listTestNamesOnly() ) listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); if( config.listTags() ) listedCount = listedCount.valueOr(0) + listTags( config ); if( config.listReporters() ) listedCount = listedCount.valueOr(0) + listReporters( config ); return listedCount; } } // end namespace Catch // #included from: internal/catch_run_context.hpp #define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED // #included from: catch_test_case_tracker.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED #include #include #include #include namespace Catch { namespace TestCaseTracking { struct ITracker : SharedImpl<> { virtual ~ITracker(); // static queries virtual std::string name() const = 0; // dynamic queries virtual bool isComplete() const = 0; // Successfully completed or failed virtual bool isSuccessfullyCompleted() const = 0; virtual bool isOpen() const = 0; // Started but not complete virtual bool hasChildren() const = 0; virtual ITracker& parent() = 0; // actions virtual void close() = 0; // Successfully complete virtual void fail() = 0; virtual void markAsNeedingAnotherRun() = 0; virtual void addChild( Ptr const& child ) = 0; virtual ITracker* findChild( std::string const& name ) = 0; virtual void openChild() = 0; // Debug/ checking virtual bool isSectionTracker() const = 0; virtual bool isIndexTracker() const = 0; }; class TrackerContext { enum RunState { NotStarted, Executing, CompletedCycle }; Ptr m_rootTracker; ITracker* m_currentTracker; RunState m_runState; public: static TrackerContext& instance() { static TrackerContext s_instance; return s_instance; } TrackerContext() : m_currentTracker( CATCH_NULL ), m_runState( NotStarted ) {} ITracker& startRun(); void endRun() { m_rootTracker.reset(); m_currentTracker = CATCH_NULL; m_runState = NotStarted; } void startCycle() { m_currentTracker = m_rootTracker.get(); m_runState = Executing; } void completeCycle() { m_runState = CompletedCycle; } bool completedCycle() const { return m_runState == CompletedCycle; } ITracker& currentTracker() { return *m_currentTracker; } void setCurrentTracker( ITracker* tracker ) { m_currentTracker = tracker; } }; class TrackerBase : public ITracker { protected: enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed }; class TrackerHasName { std::string m_name; public: TrackerHasName( std::string const& name ) : m_name( name ) {} bool operator ()( Ptr const& tracker ) { return tracker->name() == m_name; } }; typedef std::vector > Children; std::string m_name; TrackerContext& m_ctx; ITracker* m_parent; Children m_children; CycleState m_runState; public: TrackerBase( std::string const& name, TrackerContext& ctx, ITracker* parent ) : m_name( name ), m_ctx( ctx ), m_parent( parent ), m_runState( NotStarted ) {} virtual ~TrackerBase(); virtual std::string name() const CATCH_OVERRIDE { return m_name; } virtual bool isComplete() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully || m_runState == Failed; } virtual bool isSuccessfullyCompleted() const CATCH_OVERRIDE { return m_runState == CompletedSuccessfully; } virtual bool isOpen() const CATCH_OVERRIDE { return m_runState != NotStarted && !isComplete(); } virtual bool hasChildren() const CATCH_OVERRIDE { return !m_children.empty(); } virtual void addChild( Ptr const& child ) CATCH_OVERRIDE { m_children.push_back( child ); } virtual ITracker* findChild( std::string const& name ) CATCH_OVERRIDE { Children::const_iterator it = std::find_if( m_children.begin(), m_children.end(), TrackerHasName( name ) ); return( it != m_children.end() ) ? it->get() : CATCH_NULL; } virtual ITracker& parent() CATCH_OVERRIDE { assert( m_parent ); // Should always be non-null except for root return *m_parent; } virtual void openChild() CATCH_OVERRIDE { if( m_runState != ExecutingChildren ) { m_runState = ExecutingChildren; if( m_parent ) m_parent->openChild(); } } virtual bool isSectionTracker() const CATCH_OVERRIDE { return false; } virtual bool isIndexTracker() const CATCH_OVERRIDE { return false; } void open() { m_runState = Executing; moveToThis(); if( m_parent ) m_parent->openChild(); } virtual void close() CATCH_OVERRIDE { // Close any still open children (e.g. generators) while( &m_ctx.currentTracker() != this ) m_ctx.currentTracker().close(); switch( m_runState ) { case NotStarted: case CompletedSuccessfully: case Failed: throw std::logic_error( "Illogical state" ); case NeedsAnotherRun: break;; case Executing: m_runState = CompletedSuccessfully; break; case ExecutingChildren: if( m_children.empty() || m_children.back()->isComplete() ) m_runState = CompletedSuccessfully; break; default: throw std::logic_error( "Unexpected state" ); } moveToParent(); m_ctx.completeCycle(); } virtual void fail() CATCH_OVERRIDE { m_runState = Failed; if( m_parent ) m_parent->markAsNeedingAnotherRun(); moveToParent(); m_ctx.completeCycle(); } virtual void markAsNeedingAnotherRun() CATCH_OVERRIDE { m_runState = NeedsAnotherRun; } private: void moveToParent() { assert( m_parent ); m_ctx.setCurrentTracker( m_parent ); } void moveToThis() { m_ctx.setCurrentTracker( this ); } }; class SectionTracker : public TrackerBase { public: SectionTracker( std::string const& name, TrackerContext& ctx, ITracker* parent ) : TrackerBase( name, ctx, parent ) {} virtual ~SectionTracker(); virtual bool isSectionTracker() const CATCH_OVERRIDE { return true; } static SectionTracker& acquire( TrackerContext& ctx, std::string const& name ) { SectionTracker* section = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( name ) ) { assert( childTracker ); assert( childTracker->isSectionTracker() ); section = static_cast( childTracker ); } else { section = new SectionTracker( name, ctx, ¤tTracker ); currentTracker.addChild( section ); } if( !ctx.completedCycle() && !section->isComplete() ) { section->open(); } return *section; } }; class IndexTracker : public TrackerBase { int m_size; int m_index; public: IndexTracker( std::string const& name, TrackerContext& ctx, ITracker* parent, int size ) : TrackerBase( name, ctx, parent ), m_size( size ), m_index( -1 ) {} virtual ~IndexTracker(); virtual bool isIndexTracker() const CATCH_OVERRIDE { return true; } static IndexTracker& acquire( TrackerContext& ctx, std::string const& name, int size ) { IndexTracker* tracker = CATCH_NULL; ITracker& currentTracker = ctx.currentTracker(); if( ITracker* childTracker = currentTracker.findChild( name ) ) { assert( childTracker ); assert( childTracker->isIndexTracker() ); tracker = static_cast( childTracker ); } else { tracker = new IndexTracker( name, ctx, ¤tTracker, size ); currentTracker.addChild( tracker ); } if( !ctx.completedCycle() && !tracker->isComplete() ) { if( tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun ) tracker->moveNext(); tracker->open(); } return *tracker; } int index() const { return m_index; } void moveNext() { m_index++; m_children.clear(); } virtual void close() CATCH_OVERRIDE { TrackerBase::close(); if( m_runState == CompletedSuccessfully && m_index < m_size-1 ) m_runState = Executing; } }; inline ITracker& TrackerContext::startRun() { m_rootTracker = new SectionTracker( "{root}", *this, CATCH_NULL ); m_currentTracker = CATCH_NULL; m_runState = Executing; return *m_rootTracker; } } // namespace TestCaseTracking using TestCaseTracking::ITracker; using TestCaseTracking::TrackerContext; using TestCaseTracking::SectionTracker; using TestCaseTracking::IndexTracker; } // namespace Catch // #included from: catch_fatal_condition.hpp #define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED namespace Catch { // Report the error condition then exit the process inline void fatal( std::string const& message, int exitCode ) { IContext& context = Catch::getCurrentContext(); IResultCapture* resultCapture = context.getResultCapture(); resultCapture->handleFatalErrorCondition( message ); if( Catch::alwaysTrue() ) // avoids "no return" warnings exit( exitCode ); } } // namespace Catch #if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// namespace Catch { struct FatalConditionHandler { void reset() {} }; } // namespace Catch #else // Not Windows - assumed to be POSIX compatible ////////////////////////// #include namespace Catch { struct SignalDefs { int id; const char* name; }; extern SignalDefs signalDefs[]; SignalDefs signalDefs[] = { { SIGINT, "SIGINT - Terminal interrupt signal" }, { SIGILL, "SIGILL - Illegal instruction signal" }, { SIGFPE, "SIGFPE - Floating point error signal" }, { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, { SIGTERM, "SIGTERM - Termination request signal" }, { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } }; struct FatalConditionHandler { static void handleSignal( int sig ) { for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) if( sig == signalDefs[i].id ) fatal( signalDefs[i].name, -sig ); fatal( "", -sig ); } FatalConditionHandler() : m_isSet( true ) { for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) signal( signalDefs[i].id, handleSignal ); } ~FatalConditionHandler() { reset(); } void reset() { if( m_isSet ) { for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) signal( signalDefs[i].id, SIG_DFL ); m_isSet = false; } } bool m_isSet; }; } // namespace Catch #endif // not Windows #include #include namespace Catch { class StreamRedirect { public: StreamRedirect( std::ostream& stream, std::string& targetString ) : m_stream( stream ), m_prevBuf( stream.rdbuf() ), m_targetString( targetString ) { stream.rdbuf( m_oss.rdbuf() ); } ~StreamRedirect() { m_targetString += m_oss.str(); m_stream.rdbuf( m_prevBuf ); } private: std::ostream& m_stream; std::streambuf* m_prevBuf; std::ostringstream m_oss; std::string& m_targetString; }; /////////////////////////////////////////////////////////////////////////// class RunContext : public IResultCapture, public IRunner { RunContext( RunContext const& ); void operator =( RunContext const& ); public: explicit RunContext( Ptr const& _config, Ptr const& reporter ) : m_runInfo( _config->name() ), m_context( getCurrentMutableContext() ), m_activeTestCase( CATCH_NULL ), m_config( _config ), m_reporter( reporter ) { m_context.setRunner( this ); m_context.setConfig( m_config ); m_context.setResultCapture( this ); m_reporter->testRunStarting( m_runInfo ); } virtual ~RunContext() { m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); } void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); } void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); } Totals runTest( TestCase const& testCase ) { Totals prevTotals = m_totals; std::string redirectedCout; std::string redirectedCerr; TestCaseInfo testInfo = testCase.getTestCaseInfo(); m_reporter->testCaseStarting( testInfo ); m_activeTestCase = &testCase; do { m_trackerContext.startRun(); do { m_trackerContext.startCycle(); m_testCaseTracker = &SectionTracker::acquire( m_trackerContext, testInfo.name ); runCurrentTest( redirectedCout, redirectedCerr ); } while( !m_testCaseTracker->isSuccessfullyCompleted() && !aborting() ); } // !TBD: deprecated - this will be replaced by indexed trackers while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); Totals deltaTotals = m_totals.delta( prevTotals ); if( testInfo.expectedToFail() && deltaTotals.testCases.passed > 0 ) { deltaTotals.assertions.failed++; deltaTotals.testCases.passed--; deltaTotals.testCases.failed++; } m_totals.testCases += deltaTotals.testCases; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting() ) ); m_activeTestCase = CATCH_NULL; m_testCaseTracker = CATCH_NULL; return deltaTotals; } Ptr config() const { return m_config; } private: // IResultCapture virtual void assertionEnded( AssertionResult const& result ) { if( result.getResultType() == ResultWas::Ok ) { m_totals.assertions.passed++; } else if( !result.isOk() ) { m_totals.assertions.failed++; } if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) m_messages.clear(); // Reset working state m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); m_lastResult = result; } virtual bool sectionStarted ( SectionInfo const& sectionInfo, Counts& assertions ) { std::ostringstream oss; oss << sectionInfo.name << "@" << sectionInfo.lineInfo; ITracker& sectionTracker = SectionTracker::acquire( m_trackerContext, oss.str() ); if( !sectionTracker.isOpen() ) return false; m_activeSections.push_back( §ionTracker ); m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; m_reporter->sectionStarting( sectionInfo ); assertions = m_totals.assertions; return true; } bool testForMissingAssertions( Counts& assertions ) { if( assertions.total() != 0 ) return false; if( !m_config->warnAboutMissingAssertions() ) return false; if( m_trackerContext.currentTracker().hasChildren() ) return false; m_totals.assertions.failed++; assertions.failed++; return true; } virtual void sectionEnded( SectionEndInfo const& endInfo ) { Counts assertions = m_totals.assertions - endInfo.prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); if( !m_activeSections.empty() ) { m_activeSections.back()->close(); m_activeSections.pop_back(); } m_reporter->sectionEnded( SectionStats( endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions ) ); m_messages.clear(); } virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) { if( m_unfinishedSections.empty() ) m_activeSections.back()->fail(); else m_activeSections.back()->close(); m_activeSections.pop_back(); m_unfinishedSections.push_back( endInfo ); } virtual void pushScopedMessage( MessageInfo const& message ) { m_messages.push_back( message ); } virtual void popScopedMessage( MessageInfo const& message ) { m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); } virtual std::string getCurrentTestName() const { return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : ""; } virtual const AssertionResult* getLastResult() const { return &m_lastResult; } virtual void handleFatalErrorCondition( std::string const& message ) { ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); resultBuilder.setResultType( ResultWas::FatalErrorCondition ); resultBuilder << message; resultBuilder.captureExpression(); handleUnfinishedSections(); // Recreate section for test case (as we will lose the one that was in scope) TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); Counts assertions; assertions.failed = 1; SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); m_reporter->sectionEnded( testCaseSectionStats ); TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); Totals deltaTotals; deltaTotals.testCases.failed = 1; m_reporter->testCaseEnded( TestCaseStats( testInfo, deltaTotals, "", "", false ) ); m_totals.testCases.failed++; testGroupEnded( "", m_totals, 1, 1 ); m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); } public: // !TBD We need to do this another way! bool aborting() const { return m_totals.assertions.failed == static_cast( m_config->abortAfter() ); } private: void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); m_reporter->sectionStarting( testCaseSection ); Counts prevAssertions = m_totals.assertions; double duration = 0; try { m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); seedRng( *m_config ); Timer timer; timer.start(); if( m_reporter->getPreferences().shouldRedirectStdOut ) { StreamRedirect coutRedir( Catch::cout(), redirectedCout ); StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); invokeActiveTestCase(); } else { invokeActiveTestCase(); } duration = timer.getElapsedSeconds(); } catch( TestFailureException& ) { // This just means the test was aborted due to failure } catch(...) { makeUnexpectedResultBuilder().useActiveException(); } m_testCaseTracker->close(); handleUnfinishedSections(); m_messages.clear(); Counts assertions = m_totals.assertions - prevAssertions; bool missingAssertions = testForMissingAssertions( assertions ); if( testCaseInfo.okToFail() ) { std::swap( assertions.failedButOk, assertions.failed ); m_totals.assertions.failed -= assertions.failedButOk; m_totals.assertions.failedButOk += assertions.failedButOk; } SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); m_reporter->sectionEnded( testCaseSectionStats ); } void invokeActiveTestCase() { FatalConditionHandler fatalConditionHandler; // Handle signals m_activeTestCase->invoke(); fatalConditionHandler.reset(); } private: ResultBuilder makeUnexpectedResultBuilder() const { return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), m_lastAssertionInfo.lineInfo, m_lastAssertionInfo.capturedExpression.c_str(), m_lastAssertionInfo.resultDisposition ); } void handleUnfinishedSections() { // If sections ended prematurely due to an exception we stored their // infos here so we can tear them down outside the unwind process. for( std::vector::const_reverse_iterator it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it ) sectionEnded( *it ); m_unfinishedSections.clear(); } TestRunInfo m_runInfo; IMutableContext& m_context; TestCase const* m_activeTestCase; ITracker* m_testCaseTracker; ITracker* m_currentSectionTracker; AssertionResult m_lastResult; Ptr m_config; Totals m_totals; Ptr m_reporter; std::vector m_messages; AssertionInfo m_lastAssertionInfo; std::vector m_unfinishedSections; std::vector m_activeSections; TrackerContext m_trackerContext; }; IResultCapture& getResultCapture() { if( IResultCapture* capture = getCurrentContext().getResultCapture() ) return *capture; else throw std::logic_error( "No result capture instance" ); } } // end namespace Catch // #included from: internal/catch_version.h #define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED namespace Catch { // Versioning information struct Version { Version( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, std::string const& _branchName, unsigned int _buildNumber ); unsigned int const majorVersion; unsigned int const minorVersion; unsigned int const patchNumber; // buildNumber is only used if branchName is not null std::string const branchName; unsigned int const buildNumber; friend std::ostream& operator << ( std::ostream& os, Version const& version ); private: void operator=( Version const& ); }; extern Version libraryVersion; } #include #include #include namespace Catch { Ptr createReporter( std::string const& reporterName, Ptr const& config ) { Ptr reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() ); if( !reporter ) { std::ostringstream oss; oss << "No reporter registered with name: '" << reporterName << "'"; throw std::domain_error( oss.str() ); } return reporter; } Ptr makeReporter( Ptr const& config ) { std::vector reporters = config->getReporterNames(); if( reporters.empty() ) reporters.push_back( "console" ); Ptr reporter; for( std::vector::const_iterator it = reporters.begin(), itEnd = reporters.end(); it != itEnd; ++it ) reporter = addReporter( reporter, createReporter( *it, config ) ); return reporter; } Ptr addListeners( Ptr const& config, Ptr reporters ) { IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners(); for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end(); it != itEnd; ++it ) reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) ); return reporters; } Totals runTests( Ptr const& config ) { Ptr iconfig = config.get(); Ptr reporter = makeReporter( config ); reporter = addListeners( iconfig, reporter ); RunContext context( iconfig, reporter ); Totals totals; context.testGroupStarting( config->name(), 1, 1 ); TestSpec testSpec = config->testSpec(); if( !testSpec.hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests std::vector const& allTestCases = getAllTestCasesSorted( *iconfig ); for( std::vector::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end(); it != itEnd; ++it ) { if( !context.aborting() && matchTest( *it, testSpec, *iconfig ) ) totals += context.runTest( *it ); else reporter->skipTest( *it ); } context.testGroupEnded( iconfig->name(), totals, 1, 1 ); return totals; } void applyFilenamesAsTags( IConfig const& config ) { std::vector const& tests = getAllTestCasesSorted( config ); for(std::size_t i = 0; i < tests.size(); ++i ) { TestCase& test = const_cast( tests[i] ); std::set tags = test.tags; std::string filename = test.lineInfo.file; std::string::size_type lastSlash = filename.find_last_of( "\\/" ); if( lastSlash != std::string::npos ) filename = filename.substr( lastSlash+1 ); std::string::size_type lastDot = filename.find_last_of( "." ); if( lastDot != std::string::npos ) filename = filename.substr( 0, lastDot ); tags.insert( "#" + filename ); setTags( test, tags ); } } class Session : NonCopyable { static bool alreadyInstantiated; public: struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; Session() : m_cli( makeCommandLineParser() ) { if( alreadyInstantiated ) { std::string msg = "Only one instance of Catch::Session can ever be used"; Catch::cerr() << msg << std::endl; throw std::logic_error( msg ); } alreadyInstantiated = true; } ~Session() { Catch::cleanUp(); } void showHelp( std::string const& processName ) { Catch::cout() << "\nCatch v" << libraryVersion << "\n"; m_cli.usage( Catch::cout(), processName ); Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; } int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { try { m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); if( m_configData.showHelp ) showHelp( m_configData.processName ); m_config.reset(); } catch( std::exception& ex ) { { Colour colourGuard( Colour::Red ); Catch::cerr() << "\nError(s) in input:\n" << Text( ex.what(), TextAttributes().setIndent(2) ) << "\n\n"; } m_cli.usage( Catch::cout(), m_configData.processName ); return (std::numeric_limits::max)(); } return 0; } void useConfigData( ConfigData const& _configData ) { m_configData = _configData; m_config.reset(); } int run( int argc, char const* const* const argv ) { int returnCode = applyCommandLine( argc, argv ); if( returnCode == 0 ) returnCode = run(); return returnCode; } int run() { if( m_configData.showHelp ) return 0; try { config(); // Force config to be constructed seedRng( *m_config ); if( m_configData.filenamesAsTags ) applyFilenamesAsTags( *m_config ); // Handle list request if( Option listed = list( config() ) ) return static_cast( *listed ); return static_cast( runTests( m_config ).assertions.failed ); } catch( std::exception& ex ) { Catch::cerr() << ex.what() << std::endl; return (std::numeric_limits::max)(); } } Clara::CommandLine const& cli() const { return m_cli; } std::vector const& unusedTokens() const { return m_unusedTokens; } ConfigData& configData() { return m_configData; } Config& config() { if( !m_config ) m_config = new Config( m_configData ); return *m_config; } private: Clara::CommandLine m_cli; std::vector m_unusedTokens; ConfigData m_configData; Ptr m_config; }; bool Session::alreadyInstantiated = false; } // end namespace Catch // #included from: catch_registry_hub.hpp #define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED // #included from: catch_test_case_registry_impl.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #include #include #include #include #include namespace Catch { struct RandomNumberGenerator { typedef std::ptrdiff_t result_type; result_type operator()( result_type n ) const { return std::rand() % n; } #ifdef CATCH_CONFIG_CPP11_SHUFFLE static constexpr result_type min() { return 0; } static constexpr result_type max() { return 1000000; } result_type operator()() const { return std::rand() % max(); } #endif template static void shuffle( V& vector ) { RandomNumberGenerator rng; #ifdef CATCH_CONFIG_CPP11_SHUFFLE std::shuffle( vector.begin(), vector.end(), rng ); #else std::random_shuffle( vector.begin(), vector.end(), rng ); #endif } }; inline std::vector sortTests( IConfig const& config, std::vector const& unsortedTestCases ) { std::vector sorted = unsortedTestCases; switch( config.runOrder() ) { case RunTests::InLexicographicalOrder: std::sort( sorted.begin(), sorted.end() ); break; case RunTests::InRandomOrder: { seedRng( config ); RandomNumberGenerator::shuffle( sorted ); } break; case RunTests::InDeclarationOrder: // already in declaration order break; } return sorted; } bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) { return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() ); } void enforceNoDuplicateTestCases( std::vector const& functions ) { std::set seenFunctions; for( std::vector::const_iterator it = functions.begin(), itEnd = functions.end(); it != itEnd; ++it ) { std::pair::const_iterator, bool> prev = seenFunctions.insert( *it ); if( !prev.second ) { std::ostringstream ss; ss << Colour( Colour::Red ) << "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n" << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n" << "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl; throw std::runtime_error(ss.str()); } } } std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ) { std::vector filtered; filtered.reserve( testCases.size() ); for( std::vector::const_iterator it = testCases.begin(), itEnd = testCases.end(); it != itEnd; ++it ) if( matchTest( *it, testSpec, config ) ) filtered.push_back( *it ); return filtered; } std::vector const& getAllTestCasesSorted( IConfig const& config ) { return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config ); } class TestRegistry : public ITestCaseRegistry { public: TestRegistry() : m_currentSortOrder( RunTests::InDeclarationOrder ), m_unnamedCount( 0 ) {} virtual ~TestRegistry(); virtual void registerTest( TestCase const& testCase ) { std::string name = testCase.getTestCaseInfo().name; if( name == "" ) { std::ostringstream oss; oss << "Anonymous test case " << ++m_unnamedCount; return registerTest( testCase.withName( oss.str() ) ); } m_functions.push_back( testCase ); } virtual std::vector const& getAllTests() const { return m_functions; } virtual std::vector const& getAllTestsSorted( IConfig const& config ) const { if( m_sortedFunctions.empty() ) enforceNoDuplicateTestCases( m_functions ); if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) { m_sortedFunctions = sortTests( config, m_functions ); m_currentSortOrder = config.runOrder(); } return m_sortedFunctions; } private: std::vector m_functions; mutable RunTests::InWhatOrder m_currentSortOrder; mutable std::vector m_sortedFunctions; size_t m_unnamedCount; std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised }; /////////////////////////////////////////////////////////////////////////// class FreeFunctionTestCase : public SharedImpl { public: FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} virtual void invoke() const { m_fun(); } private: virtual ~FreeFunctionTestCase(); TestFunction m_fun; }; inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { std::string className = classOrQualifiedMethodName; if( startsWith( className, "&" ) ) { std::size_t lastColons = className.rfind( "::" ); std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); if( penultimateColons == std::string::npos ) penultimateColons = 1; className = className.substr( penultimateColons, lastColons-penultimateColons ); } return className; } void registerTestCase ( ITestCase* testCase, char const* classOrQualifiedMethodName, NameAndDesc const& nameAndDesc, SourceLineInfo const& lineInfo ) { getMutableRegistryHub().registerTest ( makeTestCase ( testCase, extractClassName( classOrQualifiedMethodName ), nameAndDesc.name, nameAndDesc.description, lineInfo ) ); } void registerTestCaseFunction ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); } /////////////////////////////////////////////////////////////////////////// AutoReg::AutoReg ( TestFunction function, SourceLineInfo const& lineInfo, NameAndDesc const& nameAndDesc ) { registerTestCaseFunction( function, lineInfo, nameAndDesc ); } AutoReg::~AutoReg() {} } // end namespace Catch // #included from: catch_reporter_registry.hpp #define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED #include namespace Catch { class ReporterRegistry : public IReporterRegistry { public: virtual ~ReporterRegistry() CATCH_OVERRIDE {} virtual IStreamingReporter* create( std::string const& name, Ptr const& config ) const CATCH_OVERRIDE { FactoryMap::const_iterator it = m_factories.find( name ); if( it == m_factories.end() ) return CATCH_NULL; return it->second->create( ReporterConfig( config ) ); } void registerReporter( std::string const& name, Ptr const& factory ) { m_factories.insert( std::make_pair( name, factory ) ); } void registerListener( Ptr const& factory ) { m_listeners.push_back( factory ); } virtual FactoryMap const& getFactories() const CATCH_OVERRIDE { return m_factories; } virtual Listeners const& getListeners() const CATCH_OVERRIDE { return m_listeners; } private: FactoryMap m_factories; Listeners m_listeners; }; } // #included from: catch_exception_translator_registry.hpp #define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED #ifdef __OBJC__ #import "Foundation/Foundation.h" #endif namespace Catch { class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { public: ~ExceptionTranslatorRegistry() { deleteAll( m_translators ); } virtual void registerTranslator( const IExceptionTranslator* translator ) { m_translators.push_back( translator ); } virtual std::string translateActiveException() const { try { #ifdef __OBJC__ // In Objective-C try objective-c exceptions first @try { return tryTranslators(); } @catch (NSException *exception) { return Catch::toString( [exception description] ); } #else return tryTranslators(); #endif } catch( TestFailureException& ) { throw; } catch( std::exception& ex ) { return ex.what(); } catch( std::string& msg ) { return msg; } catch( const char* msg ) { return msg; } catch(...) { return "Unknown exception"; } } std::string tryTranslators() const { if( m_translators.empty() ) throw; else return m_translators[0]->translate( m_translators.begin()+1, m_translators.end() ); } private: std::vector m_translators; }; } namespace Catch { namespace { class RegistryHub : public IRegistryHub, public IMutableRegistryHub { RegistryHub( RegistryHub const& ); void operator=( RegistryHub const& ); public: // IRegistryHub RegistryHub() { } virtual IReporterRegistry const& getReporterRegistry() const CATCH_OVERRIDE { return m_reporterRegistry; } virtual ITestCaseRegistry const& getTestCaseRegistry() const CATCH_OVERRIDE { return m_testCaseRegistry; } virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() CATCH_OVERRIDE { return m_exceptionTranslatorRegistry; } public: // IMutableRegistryHub virtual void registerReporter( std::string const& name, Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerReporter( name, factory ); } virtual void registerListener( Ptr const& factory ) CATCH_OVERRIDE { m_reporterRegistry.registerListener( factory ); } virtual void registerTest( TestCase const& testInfo ) CATCH_OVERRIDE { m_testCaseRegistry.registerTest( testInfo ); } virtual void registerTranslator( const IExceptionTranslator* translator ) CATCH_OVERRIDE { m_exceptionTranslatorRegistry.registerTranslator( translator ); } private: TestRegistry m_testCaseRegistry; ReporterRegistry m_reporterRegistry; ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; }; // Single, global, instance inline RegistryHub*& getTheRegistryHub() { static RegistryHub* theRegistryHub = CATCH_NULL; if( !theRegistryHub ) theRegistryHub = new RegistryHub(); return theRegistryHub; } } IRegistryHub& getRegistryHub() { return *getTheRegistryHub(); } IMutableRegistryHub& getMutableRegistryHub() { return *getTheRegistryHub(); } void cleanUp() { delete getTheRegistryHub(); getTheRegistryHub() = CATCH_NULL; cleanUpContext(); } std::string translateActiveException() { return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); } } // end namespace Catch // #included from: catch_notimplemented_exception.hpp #define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED #include namespace Catch { NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) : m_lineInfo( lineInfo ) { std::ostringstream oss; oss << lineInfo << ": function "; oss << "not implemented"; m_what = oss.str(); } const char* NotImplementedException::what() const CATCH_NOEXCEPT { return m_what.c_str(); } } // end namespace Catch // #included from: catch_context_impl.hpp #define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED // #included from: catch_stream.hpp #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED #include #include #include namespace Catch { template class StreamBufImpl : public StreamBufBase { char data[bufferSize]; WriterF m_writer; public: StreamBufImpl() { setp( data, data + sizeof(data) ); } ~StreamBufImpl() CATCH_NOEXCEPT { sync(); } private: int overflow( int c ) { sync(); if( c != EOF ) { if( pbase() == epptr() ) m_writer( std::string( 1, static_cast( c ) ) ); else sputc( static_cast( c ) ); } return 0; } int sync() { if( pbase() != pptr() ) { m_writer( std::string( pbase(), static_cast( pptr() - pbase() ) ) ); setp( pbase(), epptr() ); } return 0; } }; /////////////////////////////////////////////////////////////////////////// FileStream::FileStream( std::string const& filename ) { m_ofs.open( filename.c_str() ); if( m_ofs.fail() ) { std::ostringstream oss; oss << "Unable to open file: '" << filename << "'"; throw std::domain_error( oss.str() ); } } std::ostream& FileStream::stream() const { return m_ofs; } struct OutputDebugWriter { void operator()( std::string const&str ) { writeToDebugConsole( str ); } }; DebugOutStream::DebugOutStream() : m_streamBuf( new StreamBufImpl() ), m_os( m_streamBuf.get() ) {} std::ostream& DebugOutStream::stream() const { return m_os; } // Store the streambuf from cout up-front because // cout may get redirected when running tests CoutStream::CoutStream() : m_os( Catch::cout().rdbuf() ) {} std::ostream& CoutStream::stream() const { return m_os; } #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions std::ostream& cout() { return std::cout; } std::ostream& cerr() { return std::cerr; } #endif } namespace Catch { class Context : public IMutableContext { Context() : m_config( CATCH_NULL ), m_runner( CATCH_NULL ), m_resultCapture( CATCH_NULL ) {} Context( Context const& ); void operator=( Context const& ); public: virtual ~Context() { deleteAllValues( m_generatorsByTestName ); } public: // IContext virtual IResultCapture* getResultCapture() { return m_resultCapture; } virtual IRunner* getRunner() { return m_runner; } virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { return getGeneratorsForCurrentTest() .getGeneratorInfo( fileInfo, totalSize ) .getCurrentIndex(); } virtual bool advanceGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); return generators && generators->moveNext(); } virtual Ptr getConfig() const { return m_config; } public: // IMutableContext virtual void setResultCapture( IResultCapture* resultCapture ) { m_resultCapture = resultCapture; } virtual void setRunner( IRunner* runner ) { m_runner = runner; } virtual void setConfig( Ptr const& config ) { m_config = config; } friend IMutableContext& getCurrentMutableContext(); private: IGeneratorsForTest* findGeneratorsForCurrentTest() { std::string testName = getResultCapture()->getCurrentTestName(); std::map::const_iterator it = m_generatorsByTestName.find( testName ); return it != m_generatorsByTestName.end() ? it->second : CATCH_NULL; } IGeneratorsForTest& getGeneratorsForCurrentTest() { IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); if( !generators ) { std::string testName = getResultCapture()->getCurrentTestName(); generators = createGeneratorsForTest(); m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); } return *generators; } private: Ptr m_config; IRunner* m_runner; IResultCapture* m_resultCapture; std::map m_generatorsByTestName; }; namespace { Context* currentContext = CATCH_NULL; } IMutableContext& getCurrentMutableContext() { if( !currentContext ) currentContext = new Context(); return *currentContext; } IContext& getCurrentContext() { return getCurrentMutableContext(); } void cleanUpContext() { delete currentContext; currentContext = CATCH_NULL; } } // #included from: catch_console_colour_impl.hpp #define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED namespace Catch { namespace { struct IColourImpl { virtual ~IColourImpl() {} virtual void use( Colour::Code _colourCode ) = 0; }; struct NoColourImpl : IColourImpl { void use( Colour::Code ) {} static IColourImpl* instance() { static NoColourImpl s_instance; return &s_instance; } }; } // anon namespace } // namespace Catch #if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) # ifdef CATCH_PLATFORM_WINDOWS # define CATCH_CONFIG_COLOUR_WINDOWS # else # define CATCH_CONFIG_COLOUR_ANSI # endif #endif #if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// // #included from: catch_windows_h_proxy.h #define TWOBLUECUBES_CATCH_WINDOWS_H_PROXY_H_INCLUDED #ifdef CATCH_DEFINES_NOMINMAX # define NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #ifdef __AFXDLL #include #else #include #endif #ifdef CATCH_DEFINES_NOMINMAX # undef NOMINMAX #endif #ifdef CATCH_DEFINES_WIN32_LEAN_AND_MEAN # undef WIN32_LEAN_AND_MEAN #endif namespace Catch { namespace { class Win32ColourImpl : public IColourImpl { public: Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) { CONSOLE_SCREEN_BUFFER_INFO csbiInfo; GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY ); originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY ); } virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: return setTextAttribute( originalForegroundAttributes ); case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Red: return setTextAttribute( FOREGROUND_RED ); case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); case Colour::Grey: return setTextAttribute( 0 ); case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } private: void setTextAttribute( WORD _textAttribute ) { SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes ); } HANDLE stdoutHandle; WORD originalForegroundAttributes; WORD originalBackgroundAttributes; }; IColourImpl* platformColourInstance() { static Win32ColourImpl s_instance; Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = !isDebuggerActive() ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// #include namespace Catch { namespace { // use POSIX/ ANSI console terminal codes // Thanks to Adam Strzelecki for original contribution // (http://github.com/nanoant) // https://github.com/philsquared/Catch/pull/131 class PosixColourImpl : public IColourImpl { public: virtual void use( Colour::Code _colourCode ) { switch( _colourCode ) { case Colour::None: case Colour::White: return setColour( "[0m" ); case Colour::Red: return setColour( "[0;31m" ); case Colour::Green: return setColour( "[0;32m" ); case Colour::Blue: return setColour( "[0;34m" ); case Colour::Cyan: return setColour( "[0;36m" ); case Colour::Yellow: return setColour( "[0;33m" ); case Colour::Grey: return setColour( "[1;30m" ); case Colour::LightGrey: return setColour( "[0;37m" ); case Colour::BrightRed: return setColour( "[1;31m" ); case Colour::BrightGreen: return setColour( "[1;32m" ); case Colour::BrightWhite: return setColour( "[1;37m" ); case Colour::Bright: throw std::logic_error( "not a colour" ); } } static IColourImpl* instance() { static PosixColourImpl s_instance; return &s_instance; } private: void setColour( const char* _escapeCode ) { Catch::cout() << '\033' << _escapeCode; } }; IColourImpl* platformColourInstance() { Ptr config = getCurrentContext().getConfig(); UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; if( colourMode == UseColour::Auto ) colourMode = (!isDebuggerActive() && isatty(STDOUT_FILENO) ) ? UseColour::Yes : UseColour::No; return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance(); } } // end anon namespace } // end namespace Catch #else // not Windows or ANSI /////////////////////////////////////////////// namespace Catch { static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } } // end namespace Catch #endif // Windows/ ANSI/ None namespace Catch { Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast( _other ).m_moved = true; } Colour::~Colour(){ if( !m_moved ) use( None ); } void Colour::use( Code _colourCode ) { static IColourImpl* impl = platformColourInstance(); impl->use( _colourCode ); } } // end namespace Catch // #included from: catch_generators_impl.hpp #define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED #include #include #include namespace Catch { struct GeneratorInfo : IGeneratorInfo { GeneratorInfo( std::size_t size ) : m_size( size ), m_currentIndex( 0 ) {} bool moveNext() { if( ++m_currentIndex == m_size ) { m_currentIndex = 0; return false; } return true; } std::size_t getCurrentIndex() const { return m_currentIndex; } std::size_t m_size; std::size_t m_currentIndex; }; /////////////////////////////////////////////////////////////////////////// class GeneratorsForTest : public IGeneratorsForTest { public: ~GeneratorsForTest() { deleteAll( m_generatorsInOrder ); } IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { std::map::const_iterator it = m_generatorsByName.find( fileInfo ); if( it == m_generatorsByName.end() ) { IGeneratorInfo* info = new GeneratorInfo( size ); m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); m_generatorsInOrder.push_back( info ); return *info; } return *it->second; } bool moveNext() { std::vector::const_iterator it = m_generatorsInOrder.begin(); std::vector::const_iterator itEnd = m_generatorsInOrder.end(); for(; it != itEnd; ++it ) { if( (*it)->moveNext() ) return true; } return false; } private: std::map m_generatorsByName; std::vector m_generatorsInOrder; }; IGeneratorsForTest* createGeneratorsForTest() { return new GeneratorsForTest(); } } // end namespace Catch // #included from: catch_assertionresult.hpp #define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED namespace Catch { AssertionInfo::AssertionInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, std::string const& _capturedExpression, ResultDisposition::Flags _resultDisposition ) : macroName( _macroName ), lineInfo( _lineInfo ), capturedExpression( _capturedExpression ), resultDisposition( _resultDisposition ) {} AssertionResult::AssertionResult() {} AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) : m_info( info ), m_resultData( data ) {} AssertionResult::~AssertionResult() {} // Result was a success bool AssertionResult::succeeded() const { return Catch::isOk( m_resultData.resultType ); } // Result was a success, or failure is suppressed bool AssertionResult::isOk() const { return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); } ResultWas::OfType AssertionResult::getResultType() const { return m_resultData.resultType; } bool AssertionResult::hasExpression() const { return !m_info.capturedExpression.empty(); } bool AssertionResult::hasMessage() const { return !m_resultData.message.empty(); } std::string AssertionResult::getExpression() const { if( isFalseTest( m_info.resultDisposition ) ) return "!" + m_info.capturedExpression; else return m_info.capturedExpression; } std::string AssertionResult::getExpressionInMacro() const { if( m_info.macroName.empty() ) return m_info.capturedExpression; else return m_info.macroName + "( " + m_info.capturedExpression + " )"; } bool AssertionResult::hasExpandedExpression() const { return hasExpression() && getExpandedExpression() != getExpression(); } std::string AssertionResult::getExpandedExpression() const { return m_resultData.reconstructedExpression; } std::string AssertionResult::getMessage() const { return m_resultData.message; } SourceLineInfo AssertionResult::getSourceInfo() const { return m_info.lineInfo; } std::string AssertionResult::getTestMacroName() const { return m_info.macroName; } } // end namespace Catch // #included from: catch_test_case_info.hpp #define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED namespace Catch { inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { if( startsWith( tag, "." ) || tag == "hide" || tag == "!hide" ) return TestCaseInfo::IsHidden; else if( tag == "!throws" ) return TestCaseInfo::Throws; else if( tag == "!shouldfail" ) return TestCaseInfo::ShouldFail; else if( tag == "!mayfail" ) return TestCaseInfo::MayFail; else return TestCaseInfo::None; } inline bool isReservedTag( std::string const& tag ) { return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] ); } inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { if( isReservedTag( tag ) ) { { Colour colourGuard( Colour::Red ); Catch::cerr() << "Tag name [" << tag << "] not allowed.\n" << "Tag names starting with non alpha-numeric characters are reserved\n"; } { Colour colourGuard( Colour::FileName ); Catch::cerr() << _lineInfo << std::endl; } exit(1); } } TestCase makeTestCase( ITestCase* _testCase, std::string const& _className, std::string const& _name, std::string const& _descOrTags, SourceLineInfo const& _lineInfo ) { bool isHidden( startsWith( _name, "./" ) ); // Legacy support // Parse out tags std::set tags; std::string desc, tag; bool inTag = false; for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { char c = _descOrTags[i]; if( !inTag ) { if( c == '[' ) inTag = true; else desc += c; } else { if( c == ']' ) { TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); if( prop == TestCaseInfo::IsHidden ) isHidden = true; else if( prop == TestCaseInfo::None ) enforceNotReservedTag( tag, _lineInfo ); tags.insert( tag ); tag.clear(); inTag = false; } else tag += c; } } if( isHidden ) { tags.insert( "hide" ); tags.insert( "." ); } TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); return TestCase( _testCase, info ); } void setTags( TestCaseInfo& testCaseInfo, std::set const& tags ) { testCaseInfo.tags = tags; testCaseInfo.lcaseTags.clear(); std::ostringstream oss; for( std::set::const_iterator it = tags.begin(), itEnd = tags.end(); it != itEnd; ++it ) { oss << "[" << *it << "]"; std::string lcaseTag = toLower( *it ); testCaseInfo.properties = static_cast( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); testCaseInfo.lcaseTags.insert( lcaseTag ); } testCaseInfo.tagsAsString = oss.str(); } TestCaseInfo::TestCaseInfo( std::string const& _name, std::string const& _className, std::string const& _description, std::set const& _tags, SourceLineInfo const& _lineInfo ) : name( _name ), className( _className ), description( _description ), lineInfo( _lineInfo ), properties( None ) { setTags( *this, _tags ); } TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) : name( other.name ), className( other.className ), description( other.description ), tags( other.tags ), lcaseTags( other.lcaseTags ), tagsAsString( other.tagsAsString ), lineInfo( other.lineInfo ), properties( other.properties ) {} bool TestCaseInfo::isHidden() const { return ( properties & IsHidden ) != 0; } bool TestCaseInfo::throws() const { return ( properties & Throws ) != 0; } bool TestCaseInfo::okToFail() const { return ( properties & (ShouldFail | MayFail ) ) != 0; } bool TestCaseInfo::expectedToFail() const { return ( properties & (ShouldFail ) ) != 0; } TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} TestCase::TestCase( TestCase const& other ) : TestCaseInfo( other ), test( other.test ) {} TestCase TestCase::withName( std::string const& _newName ) const { TestCase other( *this ); other.name = _newName; return other; } void TestCase::swap( TestCase& other ) { test.swap( other.test ); name.swap( other.name ); className.swap( other.className ); description.swap( other.description ); tags.swap( other.tags ); lcaseTags.swap( other.lcaseTags ); tagsAsString.swap( other.tagsAsString ); std::swap( TestCaseInfo::properties, static_cast( other ).properties ); std::swap( lineInfo, other.lineInfo ); } void TestCase::invoke() const { test->invoke(); } bool TestCase::operator == ( TestCase const& other ) const { return test.get() == other.test.get() && name == other.name && className == other.className; } bool TestCase::operator < ( TestCase const& other ) const { return name < other.name; } TestCase& TestCase::operator = ( TestCase const& other ) { TestCase temp( other ); swap( temp ); return *this; } TestCaseInfo const& TestCase::getTestCaseInfo() const { return *this; } } // end namespace Catch // #included from: catch_version.hpp #define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED namespace Catch { Version::Version ( unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, std::string const& _branchName, unsigned int _buildNumber ) : majorVersion( _majorVersion ), minorVersion( _minorVersion ), patchNumber( _patchNumber ), branchName( _branchName ), buildNumber( _buildNumber ) {} std::ostream& operator << ( std::ostream& os, Version const& version ) { os << version.majorVersion << "." << version.minorVersion << "." << version.patchNumber; if( !version.branchName.empty() ) { os << "-" << version.branchName << "." << version.buildNumber; } return os; } Version libraryVersion( 1, 6, 1, "", 0 ); } // #included from: catch_message.hpp #define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED namespace Catch { MessageInfo::MessageInfo( std::string const& _macroName, SourceLineInfo const& _lineInfo, ResultWas::OfType _type ) : macroName( _macroName ), lineInfo( _lineInfo ), type( _type ), sequence( ++globalCount ) {} // This may need protecting if threading support is added unsigned int MessageInfo::globalCount = 0; //////////////////////////////////////////////////////////////////////////// ScopedMessage::ScopedMessage( MessageBuilder const& builder ) : m_info( builder.m_info ) { m_info.message = builder.m_stream.str(); getResultCapture().pushScopedMessage( m_info ); } ScopedMessage::ScopedMessage( ScopedMessage const& other ) : m_info( other.m_info ) {} ScopedMessage::~ScopedMessage() { getResultCapture().popScopedMessage( m_info ); } } // end namespace Catch // #included from: catch_legacy_reporter_adapter.hpp #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED // #included from: catch_legacy_reporter_adapter.h #define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED namespace Catch { // Deprecated struct IReporter : IShared { virtual ~IReporter(); virtual bool shouldRedirectStdout() const = 0; virtual void StartTesting() = 0; virtual void EndTesting( Totals const& totals ) = 0; virtual void StartGroup( std::string const& groupName ) = 0; virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; virtual void Aborted() = 0; virtual void Result( AssertionResult const& result ) = 0; }; class LegacyReporterAdapter : public SharedImpl { public: LegacyReporterAdapter( Ptr const& legacyReporter ); virtual ~LegacyReporterAdapter(); virtual ReporterPreferences getPreferences() const; virtual void noMatchingTestCases( std::string const& ); virtual void testRunStarting( TestRunInfo const& ); virtual void testGroupStarting( GroupInfo const& groupInfo ); virtual void testCaseStarting( TestCaseInfo const& testInfo ); virtual void sectionStarting( SectionInfo const& sectionInfo ); virtual void assertionStarting( AssertionInfo const& ); virtual bool assertionEnded( AssertionStats const& assertionStats ); virtual void sectionEnded( SectionStats const& sectionStats ); virtual void testCaseEnded( TestCaseStats const& testCaseStats ); virtual void testGroupEnded( TestGroupStats const& testGroupStats ); virtual void testRunEnded( TestRunStats const& testRunStats ); virtual void skipTest( TestCaseInfo const& ); private: Ptr m_legacyReporter; }; } namespace Catch { LegacyReporterAdapter::LegacyReporterAdapter( Ptr const& legacyReporter ) : m_legacyReporter( legacyReporter ) {} LegacyReporterAdapter::~LegacyReporterAdapter() {} ReporterPreferences LegacyReporterAdapter::getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); return prefs; } void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { m_legacyReporter->StartTesting(); } void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { m_legacyReporter->StartGroup( groupInfo.name ); } void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { m_legacyReporter->StartTestCase( testInfo ); } void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); } void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { // Not on legacy interface } bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info ) { ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); rb << it->message; rb.setResultType( ResultWas::Info ); AssertionResult result = rb.build(); m_legacyReporter->Result( result ); } } } m_legacyReporter->Result( assertionStats.assertionResult ); return true; } void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { if( sectionStats.missingAssertions ) m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); } void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { m_legacyReporter->EndTestCase ( testCaseStats.testInfo, testCaseStats.totals, testCaseStats.stdOut, testCaseStats.stdErr ); } void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { if( testGroupStats.aborting ) m_legacyReporter->Aborted(); m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); } void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { m_legacyReporter->EndTesting( testRunStats.totals ); } void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { } } // #included from: catch_timer.hpp #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wc++11-long-long" #endif #ifdef CATCH_PLATFORM_WINDOWS #else #include #endif namespace Catch { namespace { #ifdef CATCH_PLATFORM_WINDOWS uint64_t getCurrentTicks() { static uint64_t hz=0, hzo=0; if (!hz) { QueryPerformanceFrequency( reinterpret_cast( &hz ) ); QueryPerformanceCounter( reinterpret_cast( &hzo ) ); } uint64_t t; QueryPerformanceCounter( reinterpret_cast( &t ) ); return ((t-hzo)*1000000)/hz; } #else uint64_t getCurrentTicks() { timeval t; gettimeofday(&t,CATCH_NULL); return static_cast( t.tv_sec ) * 1000000ull + static_cast( t.tv_usec ); } #endif } void Timer::start() { m_ticks = getCurrentTicks(); } unsigned int Timer::getElapsedMicroseconds() const { return static_cast(getCurrentTicks() - m_ticks); } unsigned int Timer::getElapsedMilliseconds() const { return static_cast(getElapsedMicroseconds()/1000); } double Timer::getElapsedSeconds() const { return getElapsedMicroseconds()/1000000.0; } } // namespace Catch #ifdef __clang__ #pragma clang diagnostic pop #endif // #included from: catch_common.hpp #define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED namespace Catch { bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; } bool endsWith( std::string const& s, std::string const& suffix ) { return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; } bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } char toLowerCh(char c) { return static_cast( ::tolower( c ) ); } void toLowerInPlace( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), toLowerCh ); } std::string toLower( std::string const& s ) { std::string lc = s; toLowerInPlace( lc ); return lc; } std::string trim( std::string const& str ) { static char const* whitespaceChars = "\n\r\t "; std::string::size_type start = str.find_first_not_of( whitespaceChars ); std::string::size_type end = str.find_last_not_of( whitespaceChars ); return start != std::string::npos ? str.substr( start, 1+end-start ) : ""; } bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { bool replaced = false; std::size_t i = str.find( replaceThis ); while( i != std::string::npos ) { replaced = true; str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); if( i < str.size()-withThis.size() ) i = str.find( replaceThis, i+withThis.size() ); else i = std::string::npos; } return replaced; } pluralise::pluralise( std::size_t count, std::string const& label ) : m_count( count ), m_label( label ) {} std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { os << pluraliser.m_count << " " << pluraliser.m_label; if( pluraliser.m_count != 1 ) os << "s"; return os; } SourceLineInfo::SourceLineInfo() : line( 0 ){} SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) : file( _file ), line( _line ) {} SourceLineInfo::SourceLineInfo( SourceLineInfo const& other ) : file( other.file ), line( other.line ) {} bool SourceLineInfo::empty() const { return file.empty(); } bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { return line == other.line && file == other.file; } bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { return line < other.line || ( line == other.line && file < other.file ); } void seedRng( IConfig const& config ) { if( config.rngSeed() != 0 ) std::srand( config.rngSeed() ); } unsigned int rngSeed() { return getCurrentContext().getConfig()->rngSeed(); } std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { #ifndef __GNUG__ os << info.file << "(" << info.line << ")"; #else os << info.file << ":" << info.line; #endif return os; } void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { std::ostringstream oss; oss << locationInfo << ": Internal Catch error: '" << message << "'"; if( alwaysTrue() ) throw std::logic_error( oss.str() ); } } // #included from: catch_section.hpp #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED namespace Catch { SectionInfo::SectionInfo ( SourceLineInfo const& _lineInfo, std::string const& _name, std::string const& _description ) : name( _name ), description( _description ), lineInfo( _lineInfo ) {} Section::Section( SectionInfo const& info ) : m_info( info ), m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) { m_timer.start(); } Section::~Section() { if( m_sectionIncluded ) { SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() ); if( std::uncaught_exception() ) getResultCapture().sectionEndedEarly( endInfo ); else getResultCapture().sectionEnded( endInfo ); } } // This indicates whether the section should be executed or not Section::operator bool() const { return m_sectionIncluded; } } // end namespace Catch // #included from: catch_debugger.hpp #define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED #include #ifdef CATCH_PLATFORM_MAC #include #include #include #include #include namespace Catch{ // The following function is taken directly from the following technical note: // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html // Returns true if the current process is being debugged (either // running under the debugger or has a debugger attached post facto). bool isDebuggerActive(){ int mib[4]; struct kinfo_proc info; size_t size; // Initialize the flags so that, if sysctl fails for some bizarre // reason, we get a predictable result. info.kp_proc.p_flag = 0; // Initialize mib, which tells sysctl the info we want, in this case // we're looking for information about a specific process ID. mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID; mib[3] = getpid(); // Call sysctl. size = sizeof(info); if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, CATCH_NULL, 0) != 0 ) { Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; return false; } // We're being debugged if the P_TRACED flag is set. return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); } } // namespace Catch #elif defined(CATCH_PLATFORM_LINUX) #include #include namespace Catch{ // The standard POSIX way of detecting a debugger is to attempt to // ptrace() the process, but this needs to be done from a child and not // this process itself to still allow attaching to this process later // if wanted, so is rather heavy. Under Linux we have the PID of the // "debugger" (which doesn't need to be gdb, of course, it could also // be strace, for example) in /proc/$PID/status, so just get it from // there instead. bool isDebuggerActive(){ std::ifstream in("/proc/self/status"); for( std::string line; std::getline(in, line); ) { static const int PREFIX_LEN = 11; if( line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0 ) { // We're traced if the PID is not 0 and no other PID starts // with 0 digit, so it's enough to check for just a single // character. return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; } } return false; } } // namespace Catch #elif defined(_MSC_VER) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #elif defined(__MINGW32__) extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace Catch { bool isDebuggerActive() { return IsDebuggerPresent() != 0; } } #else namespace Catch { inline bool isDebuggerActive() { return false; } } #endif // Platform #ifdef CATCH_PLATFORM_WINDOWS extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); namespace Catch { void writeToDebugConsole( std::string const& text ) { ::OutputDebugStringA( text.c_str() ); } } #else namespace Catch { void writeToDebugConsole( std::string const& text ) { // !TBD: Need a version for Mac/ XCode and other IDEs Catch::cout() << text; } } #endif // Platform // #included from: catch_tostring.hpp #define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED namespace Catch { namespace Detail { const std::string unprintableString = "{?}"; namespace { const int hexThreshold = 255; struct Endianness { enum Arch { Big, Little }; static Arch which() { union _{ int asInt; char asChar[sizeof (int)]; } u; u.asInt = 1; return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; } }; } std::string rawMemoryToString( const void *object, std::size_t size ) { // Reverse order for little endian architectures int i = 0, end = static_cast( size ), inc = 1; if( Endianness::which() == Endianness::Little ) { i = end-1; end = inc = -1; } unsigned char const *bytes = static_cast(object); std::ostringstream os; os << "0x" << std::setfill('0') << std::hex; for( ; i != end; i += inc ) os << std::setw(2) << static_cast(bytes[i]); return os.str(); } } std::string toString( std::string const& value ) { std::string s = value; if( getCurrentContext().getConfig()->showInvisibles() ) { for(size_t i = 0; i < s.size(); ++i ) { std::string subs; switch( s[i] ) { case '\n': subs = "\\n"; break; case '\t': subs = "\\t"; break; default: break; } if( !subs.empty() ) { s = s.substr( 0, i ) + subs + s.substr( i+1 ); ++i; } } } return "\"" + s + "\""; } std::string toString( std::wstring const& value ) { std::string s; s.reserve( value.size() ); for(size_t i = 0; i < value.size(); ++i ) s += value[i] <= 0xff ? static_cast( value[i] ) : '?'; return Catch::toString( s ); } std::string toString( const char* const value ) { return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); } std::string toString( char* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( const wchar_t* const value ) { return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); } std::string toString( wchar_t* const value ) { return Catch::toString( static_cast( value ) ); } std::string toString( int value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ")"; return oss.str(); } std::string toString( unsigned long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ")"; return oss.str(); } std::string toString( unsigned int value ) { return Catch::toString( static_cast( value ) ); } template std::string fpToString( T value, int precision ) { std::ostringstream oss; oss << std::setprecision( precision ) << std::fixed << value; std::string d = oss.str(); std::size_t i = d.find_last_not_of( '0' ); if( i != std::string::npos && i != d.size()-1 ) { if( d[i] == '.' ) i++; d = d.substr( 0, i+1 ); } return d; } std::string toString( const double value ) { return fpToString( value, 10 ); } std::string toString( const float value ) { return fpToString( value, 5 ) + "f"; } std::string toString( bool value ) { return value ? "true" : "false"; } std::string toString( char value ) { return value < ' ' ? toString( static_cast( value ) ) : Detail::makeString( value ); } std::string toString( signed char value ) { return toString( static_cast( value ) ); } std::string toString( unsigned char value ) { return toString( static_cast( value ) ); } #ifdef CATCH_CONFIG_CPP11_LONG_LONG std::string toString( long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ")"; return oss.str(); } std::string toString( unsigned long long value ) { std::ostringstream oss; oss << value; if( value > Detail::hexThreshold ) oss << " (0x" << std::hex << value << ")"; return oss.str(); } #endif #ifdef CATCH_CONFIG_CPP11_NULLPTR std::string toString( std::nullptr_t ) { return "nullptr"; } #endif #ifdef __OBJC__ std::string toString( NSString const * const& nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { if( !nsstring ) return "nil"; return "@" + toString([nsstring UTF8String]); } std::string toString( NSObject* const& nsObject ) { return toString( [nsObject description] ); } #endif } // end namespace Catch // #included from: catch_result_builder.hpp #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED namespace Catch { std::string capturedExpressionWithSecondArgument( std::string const& capturedExpression, std::string const& secondArg ) { return secondArg.empty() || secondArg == "\"\"" ? capturedExpression : capturedExpression + ", " + secondArg; } ResultBuilder::ResultBuilder( char const* macroName, SourceLineInfo const& lineInfo, char const* capturedExpression, ResultDisposition::Flags resultDisposition, char const* secondArg ) : m_assertionInfo( macroName, lineInfo, capturedExpressionWithSecondArgument( capturedExpression, secondArg ), resultDisposition ), m_shouldDebugBreak( false ), m_shouldThrow( false ) {} ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { m_data.resultType = result; return *this; } ResultBuilder& ResultBuilder::setResultType( bool result ) { m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; return *this; } ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { m_exprComponents.lhs = lhs; return *this; } ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { m_exprComponents.rhs = rhs; return *this; } ResultBuilder& ResultBuilder::setOp( std::string const& op ) { m_exprComponents.op = op; return *this; } void ResultBuilder::endExpression() { m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); captureExpression(); } void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { m_assertionInfo.resultDisposition = resultDisposition; m_stream.oss << Catch::translateActiveException(); captureResult( ResultWas::ThrewException ); } void ResultBuilder::captureResult( ResultWas::OfType resultType ) { setResultType( resultType ); captureExpression(); } void ResultBuilder::captureExpectedException( std::string const& expectedMessage ) { if( expectedMessage.empty() ) captureExpectedException( Matchers::Impl::Generic::AllOf() ); else captureExpectedException( Matchers::Equals( expectedMessage ) ); } void ResultBuilder::captureExpectedException( Matchers::Impl::Matcher const& matcher ) { assert( m_exprComponents.testFalse == false ); AssertionResultData data = m_data; data.resultType = ResultWas::Ok; data.reconstructedExpression = m_assertionInfo.capturedExpression; std::string actualMessage = Catch::translateActiveException(); if( !matcher.match( actualMessage ) ) { data.resultType = ResultWas::ExpressionFailed; data.reconstructedExpression = actualMessage; } AssertionResult result( m_assertionInfo, data ); handleResult( result ); } void ResultBuilder::captureExpression() { AssertionResult result = build(); handleResult( result ); } void ResultBuilder::handleResult( AssertionResult const& result ) { getResultCapture().assertionEnded( result ); if( !result.isOk() ) { if( getCurrentContext().getConfig()->shouldDebugBreak() ) m_shouldDebugBreak = true; if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) m_shouldThrow = true; } } void ResultBuilder::react() { if( m_shouldThrow ) throw Catch::TestFailureException(); } bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } AssertionResult ResultBuilder::build() const { assert( m_data.resultType != ResultWas::Unknown ); AssertionResultData data = m_data; // Flip bool results if testFalse is set if( m_exprComponents.testFalse ) { if( data.resultType == ResultWas::Ok ) data.resultType = ResultWas::ExpressionFailed; else if( data.resultType == ResultWas::ExpressionFailed ) data.resultType = ResultWas::Ok; } data.message = m_stream.oss.str(); data.reconstructedExpression = reconstructExpression(); if( m_exprComponents.testFalse ) { if( m_exprComponents.op == "" ) data.reconstructedExpression = "!" + data.reconstructedExpression; else data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; } return AssertionResult( m_assertionInfo, data ); } std::string ResultBuilder::reconstructExpression() const { if( m_exprComponents.op == "" ) return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.lhs; else if( m_exprComponents.op == "matches" ) return m_exprComponents.lhs + " " + m_exprComponents.rhs; else if( m_exprComponents.op != "!" ) { if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && m_exprComponents.lhs.find("\n") == std::string::npos && m_exprComponents.rhs.find("\n") == std::string::npos ) return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; else return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; } else return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; } } // end namespace Catch // #included from: catch_tag_alias_registry.hpp #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED // #included from: catch_tag_alias_registry.h #define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED #include namespace Catch { class TagAliasRegistry : public ITagAliasRegistry { public: virtual ~TagAliasRegistry(); virtual Option find( std::string const& alias ) const; virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); static TagAliasRegistry& get(); private: std::map m_registry; }; } // end namespace Catch #include #include namespace Catch { TagAliasRegistry::~TagAliasRegistry() {} Option TagAliasRegistry::find( std::string const& alias ) const { std::map::const_iterator it = m_registry.find( alias ); if( it != m_registry.end() ) return it->second; else return Option(); } std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { std::string expandedTestSpec = unexpandedTestSpec; for( std::map::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); it != itEnd; ++it ) { std::size_t pos = expandedTestSpec.find( it->first ); if( pos != std::string::npos ) { expandedTestSpec = expandedTestSpec.substr( 0, pos ) + it->second.tag + expandedTestSpec.substr( pos + it->first.size() ); } } return expandedTestSpec; } void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) { std::ostringstream oss; oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; throw std::domain_error( oss.str().c_str() ); } if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { std::ostringstream oss; oss << "error: tag alias, \"" << alias << "\" already registered.\n" << "\tFirst seen at " << find(alias)->lineInfo << "\n" << "\tRedefined at " << lineInfo; throw std::domain_error( oss.str().c_str() ); } } TagAliasRegistry& TagAliasRegistry::get() { static TagAliasRegistry instance; return instance; } ITagAliasRegistry::~ITagAliasRegistry() {} ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { try { TagAliasRegistry::get().add( alias, tag, lineInfo ); } catch( std::exception& ex ) { Colour colourGuard( Colour::Red ); Catch::cerr() << ex.what() << std::endl; exit(1); } } } // end namespace Catch // #included from: ../reporters/catch_reporter_multi.hpp #define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED namespace Catch { class MultipleReporters : public SharedImpl { typedef std::vector > Reporters; Reporters m_reporters; public: void add( Ptr const& reporter ) { m_reporters.push_back( reporter ); } public: // IStreamingReporter virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporters[0]->getPreferences(); } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->noMatchingTestCases( spec ); } virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunStarting( testRunInfo ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupStarting( groupInfo ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseStarting( testInfo ); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionStarting( sectionInfo ); } virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->assertionStarting( assertionInfo ); } // The return value indicates if the messages buffer should be cleared: virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { bool clearBuffer = false; for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) clearBuffer |= (*it)->assertionEnded( assertionStats ); return clearBuffer; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->sectionEnded( sectionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testGroupEnded( testGroupStats ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->testRunEnded( testRunStats ); } virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end(); it != itEnd; ++it ) (*it)->skipTest( testInfo ); } virtual MultipleReporters* tryAsMulti() CATCH_OVERRIDE { return this; } }; Ptr addReporter( Ptr const& existingReporter, Ptr const& additionalReporter ) { Ptr resultingReporter; if( existingReporter ) { MultipleReporters* multi = existingReporter->tryAsMulti(); if( !multi ) { multi = new MultipleReporters; resultingReporter = Ptr( multi ); if( existingReporter ) multi->add( existingReporter ); } else resultingReporter = existingReporter; multi->add( additionalReporter ); } else resultingReporter = additionalReporter; return resultingReporter; } } // end namespace Catch // #included from: ../reporters/catch_reporter_xml.hpp #define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED // #included from: catch_reporter_bases.hpp #define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED #include namespace Catch { struct StreamingReporterBase : SharedImpl { StreamingReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual ~StreamingReporterBase() CATCH_OVERRIDE; virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE { currentTestRunInfo = _testRunInfo; } virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE { currentGroupInfo = _groupInfo; } virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE { currentTestCaseInfo = _testInfo; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_sectionStack.push_back( _sectionInfo ); } virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE { m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); } virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE { currentGroupInfo.reset(); } virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE { currentTestCaseInfo.reset(); currentGroupInfo.reset(); currentTestRunInfo.reset(); } virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE { // Don't do anything with this by default. // It can optionally be overridden in the derived class. } Ptr m_config; std::ostream& stream; LazyStat currentTestRunInfo; LazyStat currentGroupInfo; LazyStat currentTestCaseInfo; std::vector m_sectionStack; ReporterPreferences m_reporterPrefs; }; struct CumulativeReporterBase : SharedImpl { template struct Node : SharedImpl<> { explicit Node( T const& _value ) : value( _value ) {} virtual ~Node() {} typedef std::vector > ChildNodes; T value; ChildNodes children; }; struct SectionNode : SharedImpl<> { explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} virtual ~SectionNode(); bool operator == ( SectionNode const& other ) const { return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; } bool operator == ( Ptr const& other ) const { return operator==( *other ); } SectionStats stats; typedef std::vector > ChildSections; typedef std::vector Assertions; ChildSections childSections; Assertions assertions; std::string stdOut; std::string stdErr; }; struct BySectionInfo { BySectionInfo( SectionInfo const& other ) : m_other( other ) {} BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} bool operator() ( Ptr const& node ) const { return node->stats.sectionInfo.lineInfo == m_other.lineInfo; } private: void operator=( BySectionInfo const& ); SectionInfo const& m_other; }; typedef Node TestCaseNode; typedef Node TestGroupNode; typedef Node TestRunNode; CumulativeReporterBase( ReporterConfig const& _config ) : m_config( _config.fullConfig() ), stream( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = false; } ~CumulativeReporterBase(); virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE { return m_reporterPrefs; } virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {} virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {} virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {} virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); Ptr node; if( m_sectionStack.empty() ) { if( !m_rootSection ) m_rootSection = new SectionNode( incompleteStats ); node = m_rootSection; } else { SectionNode& parentNode = *m_sectionStack.back(); SectionNode::ChildSections::const_iterator it = std::find_if( parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo( sectionInfo ) ); if( it == parentNode.childSections.end() ) { node = new SectionNode( incompleteStats ); parentNode.childSections.push_back( node ); } else node = *it; } m_sectionStack.push_back( node ); m_deepestSection = node; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& sectionNode = *m_sectionStack.back(); sectionNode.assertions.push_back( assertionStats ); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { assert( !m_sectionStack.empty() ); SectionNode& node = *m_sectionStack.back(); node.stats = sectionStats; m_sectionStack.pop_back(); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { Ptr node = new TestCaseNode( testCaseStats ); assert( m_sectionStack.size() == 0 ); node->children.push_back( m_rootSection ); m_testCases.push_back( node ); m_rootSection.reset(); assert( m_deepestSection ); m_deepestSection->stdOut = testCaseStats.stdOut; m_deepestSection->stdErr = testCaseStats.stdErr; } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { Ptr node = new TestGroupNode( testGroupStats ); node->children.swap( m_testCases ); m_testGroups.push_back( node ); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { Ptr node = new TestRunNode( testRunStats ); node->children.swap( m_testGroups ); m_testRuns.push_back( node ); testRunEndedCumulative(); } virtual void testRunEndedCumulative() = 0; virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {} Ptr m_config; std::ostream& stream; std::vector m_assertions; std::vector > > m_sections; std::vector > m_testCases; std::vector > m_testGroups; std::vector > m_testRuns; Ptr m_rootSection; Ptr m_deepestSection; std::vector > m_sectionStack; ReporterPreferences m_reporterPrefs; }; template char const* getLineOfChars() { static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; if( !*line ) { memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; } return line; } struct TestEventListenerBase : StreamingReporterBase { TestEventListenerBase( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {} virtual bool assertionEnded( AssertionStats const& ) CATCH_OVERRIDE { return false; } }; } // end namespace Catch // #included from: ../internal/catch_reporter_registrars.hpp #define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED namespace Catch { template class LegacyReporterRegistrar { class ReporterFactory : public IReporterFactory { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new LegacyReporterAdapter( new T( config ) ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: LegacyReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ReporterRegistrar { class ReporterFactory : public SharedImpl { // *** Please Note ***: // - If you end up here looking at a compiler error because it's trying to register // your custom reporter class be aware that the native reporter interface has changed // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. // However please consider updating to the new interface as the old one is now // deprecated and will probably be removed quite soon! // Please contact me via github if you have any questions at all about this. // In fact, ideally, please contact me anyway to let me know you've hit this - as I have // no idea who is actually using custom reporters at all (possibly no-one!). // The new interface is designed to minimise exposure to interface changes in the future. virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return T::getDescription(); } }; public: ReporterRegistrar( std::string const& name ) { getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); } }; template class ListenerRegistrar { class ListenerFactory : public SharedImpl { virtual IStreamingReporter* create( ReporterConfig const& config ) const { return new T( config ); } virtual std::string getDescription() const { return ""; } }; public: ListenerRegistrar() { getMutableRegistryHub().registerListener( new ListenerFactory() ); } }; } #define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ namespace{ Catch::LegacyReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } #define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ namespace{ Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType( name ); } #define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \ namespace{ Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; } // #included from: ../internal/catch_xmlwriter.hpp #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED #include #include #include #include namespace Catch { class XmlEncode { public: enum ForWhat { ForTextNodes, ForAttributes }; XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ) : m_str( str ), m_forWhat( forWhat ) {} void encodeTo( std::ostream& os ) const { // Apostrophe escaping not necessary if we always use " to write attributes // (see: http://www.w3.org/TR/xml/#syntax) for( std::size_t i = 0; i < m_str.size(); ++ i ) { char c = m_str[i]; switch( c ) { case '<': os << "<"; break; case '&': os << "&"; break; case '>': // See: http://www.w3.org/TR/xml/#syntax if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' ) os << ">"; else os << c; break; case '\"': if( m_forWhat == ForAttributes ) os << """; else os << c; break; default: // Escape control chars - based on contribution by @espenalb in PR #465 and // by @mrpi PR #588 if ( ( c >= 0 && c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' ) os << "&#x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast( c ) << ';'; else os << c; } } } friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { xmlEncode.encodeTo( os ); return os; } private: std::string m_str; ForWhat m_forWhat; }; class XmlWriter { public: class ScopedElement { public: ScopedElement( XmlWriter* writer ) : m_writer( writer ) {} ScopedElement( ScopedElement const& other ) : m_writer( other.m_writer ){ other.m_writer = CATCH_NULL; } ~ScopedElement() { if( m_writer ) m_writer->endElement(); } ScopedElement& writeText( std::string const& text, bool indent = true ) { m_writer->writeText( text, indent ); return *this; } template ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { m_writer->writeAttribute( name, attribute ); return *this; } private: mutable XmlWriter* m_writer; }; XmlWriter() : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &Catch::cout() ) { // We encode control characters, which requires // XML 1.1 // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 *m_os << "\n"; } XmlWriter( std::ostream& os ) : m_tagIsOpen( false ), m_needsNewline( false ), m_os( &os ) { *m_os << "\n"; } ~XmlWriter() { while( !m_tags.empty() ) endElement(); } XmlWriter& startElement( std::string const& name ) { ensureTagClosed(); newlineIfNecessary(); stream() << m_indent << "<" << name; m_tags.push_back( name ); m_indent += " "; m_tagIsOpen = true; return *this; } ScopedElement scopedElement( std::string const& name ) { ScopedElement scoped( this ); startElement( name ); return scoped; } XmlWriter& endElement() { newlineIfNecessary(); m_indent = m_indent.substr( 0, m_indent.size()-2 ); if( m_tagIsOpen ) { stream() << "/>\n"; m_tagIsOpen = false; } else { stream() << m_indent << "\n"; } m_tags.pop_back(); return *this; } XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { if( !name.empty() && !attribute.empty() ) stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\""; return *this; } XmlWriter& writeAttribute( std::string const& name, bool attribute ) { stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\""; return *this; } template XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { std::ostringstream oss; oss << attribute; return writeAttribute( name, oss.str() ); } XmlWriter& writeText( std::string const& text, bool indent = true ) { if( !text.empty() ){ bool tagWasOpen = m_tagIsOpen; ensureTagClosed(); if( tagWasOpen && indent ) stream() << m_indent; stream() << XmlEncode( text ); m_needsNewline = true; } return *this; } XmlWriter& writeComment( std::string const& text ) { ensureTagClosed(); stream() << m_indent << ""; m_needsNewline = true; return *this; } XmlWriter& writeBlankLine() { ensureTagClosed(); stream() << "\n"; return *this; } void setStream( std::ostream& os ) { m_os = &os; } private: XmlWriter( XmlWriter const& ); void operator=( XmlWriter const& ); std::ostream& stream() { return *m_os; } void ensureTagClosed() { if( m_tagIsOpen ) { stream() << ">\n"; m_tagIsOpen = false; } } void newlineIfNecessary() { if( m_needsNewline ) { stream() << "\n"; m_needsNewline = false; } } bool m_tagIsOpen; bool m_needsNewline; std::vector m_tags; std::string m_indent; std::ostream* m_os; }; } // #included from: catch_reenable_warnings.h #define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(pop) # else # pragma clang diagnostic pop # endif #elif defined __GNUC__ # pragma GCC diagnostic pop #endif namespace Catch { class XmlReporter : public StreamingReporterBase { public: XmlReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_xml(_config.stream()), m_sectionDepth( 0 ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~XmlReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as an XML document"; } public: // StreamingReporterBase virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE { StreamingReporterBase::noMatchingTestCases( s ); } virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testRunStarting( testInfo ); m_xml.startElement( "Catch" ); if( !m_config->name().empty() ) m_xml.writeAttribute( "name", m_config->name() ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { StreamingReporterBase::testGroupStarting( groupInfo ); m_xml.startElement( "Group" ) .writeAttribute( "name", groupInfo.name ); } virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE { StreamingReporterBase::testCaseStarting(testInfo); m_xml.startElement( "TestCase" ).writeAttribute( "name", testInfo.name ); if ( m_config->showDurations() == ShowDurations::Always ) m_testCaseTimer.start(); } virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE { StreamingReporterBase::sectionStarting( sectionInfo ); if( m_sectionDepth++ > 0 ) { m_xml.startElement( "Section" ) .writeAttribute( "name", trim( sectionInfo.name ) ) .writeAttribute( "description", sectionInfo.description ); } } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { const AssertionResult& assertionResult = assertionStats.assertionResult; // Print any info messages in tags. if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { for( std::vector::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); it != itEnd; ++it ) { if( it->type == ResultWas::Info ) { m_xml.scopedElement( "Info" ) .writeText( it->message ); } else if ( it->type == ResultWas::Warning ) { m_xml.scopedElement( "Warning" ) .writeText( it->message ); } } } // Drop out if result was successful but we're not printing them. if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) ) return true; // Print the expression if there is one. if( assertionResult.hasExpression() ) { m_xml.startElement( "Expression" ) .writeAttribute( "success", assertionResult.succeeded() ) .writeAttribute( "type", assertionResult.getTestMacroName() ) .writeAttribute( "filename", assertionResult.getSourceInfo().file ) .writeAttribute( "line", assertionResult.getSourceInfo().line ); m_xml.scopedElement( "Original" ) .writeText( assertionResult.getExpression() ); m_xml.scopedElement( "Expanded" ) .writeText( assertionResult.getExpandedExpression() ); } // And... Print a result applicable to each result type. switch( assertionResult.getResultType() ) { case ResultWas::ThrewException: m_xml.scopedElement( "Exception" ) .writeAttribute( "filename", assertionResult.getSourceInfo().file ) .writeAttribute( "line", assertionResult.getSourceInfo().line ) .writeText( assertionResult.getMessage() ); break; case ResultWas::FatalErrorCondition: m_xml.scopedElement( "FatalErrorCondition" ) .writeAttribute( "filename", assertionResult.getSourceInfo().file ) .writeAttribute( "line", assertionResult.getSourceInfo().line ) .writeText( assertionResult.getMessage() ); break; case ResultWas::Info: m_xml.scopedElement( "Info" ) .writeText( assertionResult.getMessage() ); break; case ResultWas::Warning: // Warning will already have been written break; case ResultWas::ExplicitFailure: m_xml.scopedElement( "Failure" ) .writeText( assertionResult.getMessage() ); break; default: break; } if( assertionResult.hasExpression() ) m_xml.endElement(); return true; } virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE { StreamingReporterBase::sectionEnded( sectionStats ); if( --m_sectionDepth > 0 ) { XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); e.writeAttribute( "successes", sectionStats.assertions.passed ); e.writeAttribute( "failures", sectionStats.assertions.failed ); e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); m_xml.endElement(); } } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( testCaseStats ); XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); if ( m_config->showDurations() == ShowDurations::Always ) e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); m_xml.endElement(); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { StreamingReporterBase::testGroupEnded( testGroupStats ); // TODO: Check testGroupStats.aborting and act accordingly. m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); m_xml.endElement(); } virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE { StreamingReporterBase::testRunEnded( testRunStats ); m_xml.scopedElement( "OverallResults" ) .writeAttribute( "successes", testRunStats.totals.assertions.passed ) .writeAttribute( "failures", testRunStats.totals.assertions.failed ) .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); m_xml.endElement(); } private: Timer m_testCaseTimer; XmlWriter m_xml; int m_sectionDepth; }; INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_junit.hpp #define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED #include namespace Catch { namespace { std::string getCurrentTimestamp() { // Beware, this is not reentrant because of backward compatibility issues // Also, UTC only, again because of backward compatibility (%z is C++11) time_t rawtime; std::time(&rawtime); const size_t timeStampSize = sizeof("2017-01-16T17:06:45Z"); #ifdef CATCH_PLATFORM_WINDOWS std::tm timeInfo = {}; gmtime_s(&timeInfo, &rawtime); #else std::tm* timeInfo; timeInfo = std::gmtime(&rawtime); #endif char timeStamp[timeStampSize]; const char * const fmt = "%Y-%m-%dT%H:%M:%SZ"; #ifdef CATCH_PLATFORM_WINDOWS std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); #else std::strftime(timeStamp, timeStampSize, fmt, timeInfo); #endif return std::string(timeStamp); } } class JunitReporter : public CumulativeReporterBase { public: JunitReporter( ReporterConfig const& _config ) : CumulativeReporterBase( _config ), xml( _config.stream() ) { m_reporterPrefs.shouldRedirectStdOut = true; } virtual ~JunitReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results in an XML format that looks like Ant's junitreport target"; } virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {} virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE { CumulativeReporterBase::testRunStarting( runInfo ); xml.startElement( "testsuites" ); } virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE { suiteTimer.start(); stdOutForSuite.str(""); stdErrForSuite.str(""); unexpectedExceptions = 0; CumulativeReporterBase::testGroupStarting( groupInfo ); } virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE { if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) unexpectedExceptions++; return CumulativeReporterBase::assertionEnded( assertionStats ); } virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE { stdOutForSuite << testCaseStats.stdOut; stdErrForSuite << testCaseStats.stdErr; CumulativeReporterBase::testCaseEnded( testCaseStats ); } virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE { double suiteTime = suiteTimer.getElapsedSeconds(); CumulativeReporterBase::testGroupEnded( testGroupStats ); writeGroup( *m_testGroups.back(), suiteTime ); } virtual void testRunEndedCumulative() CATCH_OVERRIDE { xml.endElement(); } void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); TestGroupStats const& stats = groupNode.value; xml.writeAttribute( "name", stats.groupInfo.name ); xml.writeAttribute( "errors", unexpectedExceptions ); xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); xml.writeAttribute( "tests", stats.totals.assertions.total() ); xml.writeAttribute( "hostname", "tbd" ); // !TBD if( m_config->showDurations() == ShowDurations::Never ) xml.writeAttribute( "time", "" ); else xml.writeAttribute( "time", suiteTime ); xml.writeAttribute( "timestamp", getCurrentTimestamp() ); // Write test cases for( TestGroupNode::ChildNodes::const_iterator it = groupNode.children.begin(), itEnd = groupNode.children.end(); it != itEnd; ++it ) writeTestCase( **it ); xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); } void writeTestCase( TestCaseNode const& testCaseNode ) { TestCaseStats const& stats = testCaseNode.value; // All test cases have exactly one section - which represents the // test case itself. That section may have 0-n nested sections assert( testCaseNode.children.size() == 1 ); SectionNode const& rootSection = *testCaseNode.children.front(); std::string className = stats.testInfo.className; if( className.empty() ) { if( rootSection.childSections.empty() ) className = "global"; } writeSection( className, "", rootSection ); } void writeSection( std::string const& className, std::string const& rootName, SectionNode const& sectionNode ) { std::string name = trim( sectionNode.stats.sectionInfo.name ); if( !rootName.empty() ) name = rootName + "/" + name; if( !sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty() ) { XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); if( className.empty() ) { xml.writeAttribute( "classname", name ); xml.writeAttribute( "name", "root" ); } else { xml.writeAttribute( "classname", className ); xml.writeAttribute( "name", name ); } xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); writeAssertions( sectionNode ); if( !sectionNode.stdOut.empty() ) xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); if( !sectionNode.stdErr.empty() ) xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); } for( SectionNode::ChildSections::const_iterator it = sectionNode.childSections.begin(), itEnd = sectionNode.childSections.end(); it != itEnd; ++it ) if( className.empty() ) writeSection( name, "", **it ); else writeSection( className, name, **it ); } void writeAssertions( SectionNode const& sectionNode ) { for( SectionNode::Assertions::const_iterator it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); it != itEnd; ++it ) writeAssertion( *it ); } void writeAssertion( AssertionStats const& stats ) { AssertionResult const& result = stats.assertionResult; if( !result.isOk() ) { std::string elementName; switch( result.getResultType() ) { case ResultWas::ThrewException: case ResultWas::FatalErrorCondition: elementName = "error"; break; case ResultWas::ExplicitFailure: elementName = "failure"; break; case ResultWas::ExpressionFailed: elementName = "failure"; break; case ResultWas::DidntThrowException: elementName = "failure"; break; // We should never see these here: case ResultWas::Info: case ResultWas::Warning: case ResultWas::Ok: case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: elementName = "internalError"; break; } XmlWriter::ScopedElement e = xml.scopedElement( elementName ); xml.writeAttribute( "message", result.getExpandedExpression() ); xml.writeAttribute( "type", result.getTestMacroName() ); std::ostringstream oss; if( !result.getMessage().empty() ) oss << result.getMessage() << "\n"; for( std::vector::const_iterator it = stats.infoMessages.begin(), itEnd = stats.infoMessages.end(); it != itEnd; ++it ) if( it->type == ResultWas::Info ) oss << it->message << "\n"; oss << "at " << result.getSourceInfo(); xml.writeText( oss.str(), false ); } } XmlWriter xml; Timer suiteTimer; std::ostringstream stdOutForSuite; std::ostringstream stdErrForSuite; unsigned int unexpectedExceptions; }; INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_console.hpp #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED namespace Catch { struct ConsoleReporter : StreamingReporterBase { ConsoleReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ), m_headerPrinted( false ) {} virtual ~ConsoleReporter() CATCH_OVERRIDE; static std::string getDescription() { return "Reports test results as plain lines of text"; } virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE { stream << "No test cases matched '" << spec << "'" << std::endl; } virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { } virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE { AssertionResult const& result = _assertionStats.assertionResult; bool printInfoMessages = true; // Drop out if result was successful and we're not printing those if( !m_config->includeSuccessfulResults() && result.isOk() ) { if( result.getResultType() != ResultWas::Warning ) return false; printInfoMessages = false; } lazyPrint(); AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); printer.print(); stream << std::endl; return true; } virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE { m_headerPrinted = false; StreamingReporterBase::sectionStarting( _sectionInfo ); } virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE { if( _sectionStats.missingAssertions ) { lazyPrint(); Colour colour( Colour::ResultError ); if( m_sectionStack.size() > 1 ) stream << "\nNo assertions in section"; else stream << "\nNo assertions in test case"; stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; } if( m_headerPrinted ) { if( m_config->showDurations() == ShowDurations::Always ) stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl; m_headerPrinted = false; } else { if( m_config->showDurations() == ShowDurations::Always ) stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl; } StreamingReporterBase::sectionEnded( _sectionStats ); } virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE { StreamingReporterBase::testCaseEnded( _testCaseStats ); m_headerPrinted = false; } virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE { if( currentGroupInfo.used ) { printSummaryDivider(); stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; printTotals( _testGroupStats.totals ); stream << "\n" << std::endl; } StreamingReporterBase::testGroupEnded( _testGroupStats ); } virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE { printTotalsDivider( _testRunStats.totals ); printTotals( _testRunStats.totals ); stream << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ), stats( _stats ), result( _stats.assertionResult ), colour( Colour::None ), message( result.getMessage() ), messages( _stats.infoMessages ), printInfoMessages( _printInfoMessages ) { switch( result.getResultType() ) { case ResultWas::Ok: colour = Colour::Success; passOrFail = "PASSED"; //if( result.hasMessage() ) if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ExpressionFailed: if( result.isOk() ) { colour = Colour::Success; passOrFail = "FAILED - but was ok"; } else { colour = Colour::Error; passOrFail = "FAILED"; } if( _stats.infoMessages.size() == 1 ) messageLabel = "with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "with messages"; break; case ResultWas::ThrewException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to unexpected exception with message"; break; case ResultWas::FatalErrorCondition: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "due to a fatal error condition"; break; case ResultWas::DidntThrowException: colour = Colour::Error; passOrFail = "FAILED"; messageLabel = "because no exception was thrown where one was expected"; break; case ResultWas::Info: messageLabel = "info"; break; case ResultWas::Warning: messageLabel = "warning"; break; case ResultWas::ExplicitFailure: passOrFail = "FAILED"; colour = Colour::Error; if( _stats.infoMessages.size() == 1 ) messageLabel = "explicitly with message"; if( _stats.infoMessages.size() > 1 ) messageLabel = "explicitly with messages"; break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: passOrFail = "** internal error **"; colour = Colour::Error; break; } } void print() const { printSourceInfo(); if( stats.totals.assertions.total() > 0 ) { if( result.isOk() ) stream << "\n"; printResultType(); printOriginalExpression(); printReconstructedExpression(); } else { stream << "\n"; } printMessage(); } private: void printResultType() const { if( !passOrFail.empty() ) { Colour colourGuard( colour ); stream << passOrFail << ":\n"; } } void printOriginalExpression() const { if( result.hasExpression() ) { Colour colourGuard( Colour::OriginalExpression ); stream << " "; stream << result.getExpressionInMacro(); stream << "\n"; } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { stream << "with expansion:\n"; Colour colourGuard( Colour::ReconstructedExpression ); stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n"; } } void printMessage() const { if( !messageLabel.empty() ) stream << messageLabel << ":" << "\n"; for( std::vector::const_iterator it = messages.begin(), itEnd = messages.end(); it != itEnd; ++it ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || it->type != ResultWas::Info ) stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n"; } } void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ": "; } std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; Colour::Code colour; std::string passOrFail; std::string messageLabel; std::string message; std::vector messages; bool printInfoMessages; }; void lazyPrint() { if( !currentTestRunInfo.used ) lazyPrintRunInfo(); if( !currentGroupInfo.used ) lazyPrintGroupInfo(); if( !m_headerPrinted ) { printTestCaseAndSectionHeader(); m_headerPrinted = true; } } void lazyPrintRunInfo() { stream << "\n" << getLineOfChars<'~'>() << "\n"; Colour colour( Colour::SecondaryText ); stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion << " host application.\n" << "Run with -? for options\n\n"; if( m_config->rngSeed() != 0 ) stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; currentTestRunInfo.used = true; } void lazyPrintGroupInfo() { if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { printClosedHeader( "Group: " + currentGroupInfo->name ); currentGroupInfo.used = true; } } void printTestCaseAndSectionHeader() { assert( !m_sectionStack.empty() ); printOpenHeader( currentTestCaseInfo->name ); if( m_sectionStack.size() > 1 ) { Colour colourGuard( Colour::Headers ); std::vector::const_iterator it = m_sectionStack.begin()+1, // Skip first section (test case) itEnd = m_sectionStack.end(); for( ; it != itEnd; ++it ) printHeaderString( it->name, 2 ); } SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; if( !lineInfo.empty() ){ stream << getLineOfChars<'-'>() << "\n"; Colour colourGuard( Colour::FileName ); stream << lineInfo << "\n"; } stream << getLineOfChars<'.'>() << "\n" << std::endl; } void printClosedHeader( std::string const& _name ) { printOpenHeader( _name ); stream << getLineOfChars<'.'>() << "\n"; } void printOpenHeader( std::string const& _name ) { stream << getLineOfChars<'-'>() << "\n"; { Colour colourGuard( Colour::Headers ); printHeaderString( _name ); } } // if string has a : in first line will set indent to follow it on // subsequent lines void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { std::size_t i = _string.find( ": " ); if( i != std::string::npos ) i+=2; else i = 0; stream << Text( _string, TextAttributes() .setIndent( indent+i) .setInitialIndent( indent ) ) << "\n"; } struct SummaryColumn { SummaryColumn( std::string const& _label, Colour::Code _colour ) : label( _label ), colour( _colour ) {} SummaryColumn addRow( std::size_t count ) { std::ostringstream oss; oss << count; std::string row = oss.str(); for( std::vector::iterator it = rows.begin(); it != rows.end(); ++it ) { while( it->size() < row.size() ) *it = " " + *it; while( it->size() > row.size() ) row = " " + row; } rows.push_back( row ); return *this; } std::string label; Colour::Code colour; std::vector rows; }; void printTotals( Totals const& totals ) { if( totals.testCases.total() == 0 ) { stream << Colour( Colour::Warning ) << "No tests ran\n"; } else if( totals.assertions.total() > 0 && totals.testCases.allPassed() ) { stream << Colour( Colour::ResultSuccess ) << "All tests passed"; stream << " (" << pluralise( totals.assertions.passed, "assertion" ) << " in " << pluralise( totals.testCases.passed, "test case" ) << ")" << "\n"; } else { std::vector columns; columns.push_back( SummaryColumn( "", Colour::None ) .addRow( totals.testCases.total() ) .addRow( totals.assertions.total() ) ); columns.push_back( SummaryColumn( "passed", Colour::Success ) .addRow( totals.testCases.passed ) .addRow( totals.assertions.passed ) ); columns.push_back( SummaryColumn( "failed", Colour::ResultError ) .addRow( totals.testCases.failed ) .addRow( totals.assertions.failed ) ); columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) .addRow( totals.testCases.failedButOk ) .addRow( totals.assertions.failedButOk ) ); printSummaryRow( "test cases", columns, 0 ); printSummaryRow( "assertions", columns, 1 ); } } void printSummaryRow( std::string const& label, std::vector const& cols, std::size_t row ) { for( std::vector::const_iterator it = cols.begin(); it != cols.end(); ++it ) { std::string value = it->rows[row]; if( it->label.empty() ) { stream << label << ": "; if( value != "0" ) stream << value; else stream << Colour( Colour::Warning ) << "- none -"; } else if( value != "0" ) { stream << Colour( Colour::LightGrey ) << " | "; stream << Colour( it->colour ) << value << " " << it->label; } } stream << "\n"; } static std::size_t makeRatio( std::size_t number, std::size_t total ) { std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; return ( ratio == 0 && number > 0 ) ? 1 : ratio; } static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { if( i > j && i > k ) return i; else if( j > k ) return j; else return k; } void printTotalsDivider( Totals const& totals ) { if( totals.testCases.total() > 0 ) { std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )++; while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) findMax( failedRatio, failedButOkRatio, passedRatio )--; stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); if( totals.testCases.allPassed() ) stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); else stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); } else { stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); } stream << "\n"; } void printSummaryDivider() { stream << getLineOfChars<'-'>() << "\n"; } private: bool m_headerPrinted; }; INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) } // end namespace Catch // #included from: ../reporters/catch_reporter_compact.hpp #define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED namespace Catch { struct CompactReporter : StreamingReporterBase { CompactReporter( ReporterConfig const& _config ) : StreamingReporterBase( _config ) {} virtual ~CompactReporter(); static std::string getDescription() { return "Reports test results on a single line, suitable for IDEs"; } virtual ReporterPreferences getPreferences() const { ReporterPreferences prefs; prefs.shouldRedirectStdOut = false; return prefs; } virtual void noMatchingTestCases( std::string const& spec ) { stream << "No test cases matched '" << spec << "'" << std::endl; } virtual void assertionStarting( AssertionInfo const& ) { } virtual bool assertionEnded( AssertionStats const& _assertionStats ) { AssertionResult const& result = _assertionStats.assertionResult; bool printInfoMessages = true; // Drop out if result was successful and we're not printing those if( !m_config->includeSuccessfulResults() && result.isOk() ) { if( result.getResultType() != ResultWas::Warning ) return false; printInfoMessages = false; } AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); printer.print(); stream << std::endl; return true; } virtual void testRunEnded( TestRunStats const& _testRunStats ) { printTotals( _testRunStats.totals ); stream << "\n" << std::endl; StreamingReporterBase::testRunEnded( _testRunStats ); } private: class AssertionPrinter { void operator= ( AssertionPrinter const& ); public: AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) : stream( _stream ) , stats( _stats ) , result( _stats.assertionResult ) , messages( _stats.infoMessages ) , itMessage( _stats.infoMessages.begin() ) , printInfoMessages( _printInfoMessages ) {} void print() { printSourceInfo(); itMessage = messages.begin(); switch( result.getResultType() ) { case ResultWas::Ok: printResultType( Colour::ResultSuccess, passedString() ); printOriginalExpression(); printReconstructedExpression(); if ( ! result.hasExpression() ) printRemainingMessages( Colour::None ); else printRemainingMessages(); break; case ResultWas::ExpressionFailed: if( result.isOk() ) printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); else printResultType( Colour::Error, failedString() ); printOriginalExpression(); printReconstructedExpression(); printRemainingMessages(); break; case ResultWas::ThrewException: printResultType( Colour::Error, failedString() ); printIssue( "unexpected exception with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::FatalErrorCondition: printResultType( Colour::Error, failedString() ); printIssue( "fatal error condition with message:" ); printMessage(); printExpressionWas(); printRemainingMessages(); break; case ResultWas::DidntThrowException: printResultType( Colour::Error, failedString() ); printIssue( "expected exception, got none" ); printExpressionWas(); printRemainingMessages(); break; case ResultWas::Info: printResultType( Colour::None, "info" ); printMessage(); printRemainingMessages(); break; case ResultWas::Warning: printResultType( Colour::None, "warning" ); printMessage(); printRemainingMessages(); break; case ResultWas::ExplicitFailure: printResultType( Colour::Error, failedString() ); printIssue( "explicitly" ); printRemainingMessages( Colour::None ); break; // These cases are here to prevent compiler warnings case ResultWas::Unknown: case ResultWas::FailureBit: case ResultWas::Exception: printResultType( Colour::Error, "** internal error **" ); break; } } private: // Colour::LightGrey static Colour::Code dimColour() { return Colour::FileName; } #ifdef CATCH_PLATFORM_MAC static const char* failedString() { return "FAILED"; } static const char* passedString() { return "PASSED"; } #else static const char* failedString() { return "failed"; } static const char* passedString() { return "passed"; } #endif void printSourceInfo() const { Colour colourGuard( Colour::FileName ); stream << result.getSourceInfo() << ":"; } void printResultType( Colour::Code colour, std::string passOrFail ) const { if( !passOrFail.empty() ) { { Colour colourGuard( colour ); stream << " " << passOrFail; } stream << ":"; } } void printIssue( std::string issue ) const { stream << " " << issue; } void printExpressionWas() { if( result.hasExpression() ) { stream << ";"; { Colour colour( dimColour() ); stream << " expression was:"; } printOriginalExpression(); } } void printOriginalExpression() const { if( result.hasExpression() ) { stream << " " << result.getExpression(); } } void printReconstructedExpression() const { if( result.hasExpandedExpression() ) { { Colour colour( dimColour() ); stream << " for: "; } stream << result.getExpandedExpression(); } } void printMessage() { if ( itMessage != messages.end() ) { stream << " '" << itMessage->message << "'"; ++itMessage; } } void printRemainingMessages( Colour::Code colour = dimColour() ) { if ( itMessage == messages.end() ) return; // using messages.end() directly yields compilation error: std::vector::const_iterator itEnd = messages.end(); const std::size_t N = static_cast( std::distance( itMessage, itEnd ) ); { Colour colourGuard( colour ); stream << " with " << pluralise( N, "message" ) << ":"; } for(; itMessage != itEnd; ) { // If this assertion is a warning ignore any INFO messages if( printInfoMessages || itMessage->type != ResultWas::Info ) { stream << " '" << itMessage->message << "'"; if ( ++itMessage != itEnd ) { Colour colourGuard( dimColour() ); stream << " and"; } } } } private: std::ostream& stream; AssertionStats const& stats; AssertionResult const& result; std::vector messages; std::vector::const_iterator itMessage; bool printInfoMessages; }; // Colour, message variants: // - white: No tests ran. // - red: Failed [both/all] N test cases, failed [both/all] M assertions. // - white: Passed [both/all] N test cases (no assertions). // - red: Failed N tests cases, failed M assertions. // - green: Passed [both/all] N tests cases with M assertions. std::string bothOrAll( std::size_t count ) const { return count == 1 ? "" : count == 2 ? "both " : "all " ; } void printTotals( const Totals& totals ) const { if( totals.testCases.total() == 0 ) { stream << "No tests ran."; } else if( totals.testCases.failed == totals.testCases.total() ) { Colour colour( Colour::ResultError ); const std::string qualify_assertions_failed = totals.assertions.failed == totals.assertions.total() ? bothOrAll( totals.assertions.failed ) : ""; stream << "Failed " << bothOrAll( totals.testCases.failed ) << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << qualify_assertions_failed << pluralise( totals.assertions.failed, "assertion" ) << "."; } else if( totals.assertions.total() == 0 ) { stream << "Passed " << bothOrAll( totals.testCases.total() ) << pluralise( totals.testCases.total(), "test case" ) << " (no assertions)."; } else if( totals.assertions.failed ) { Colour colour( Colour::ResultError ); stream << "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " "failed " << pluralise( totals.assertions.failed, "assertion" ) << "."; } else { Colour colour( Colour::ResultSuccess ); stream << "Passed " << bothOrAll( totals.testCases.passed ) << pluralise( totals.testCases.passed, "test case" ) << " with " << pluralise( totals.assertions.passed, "assertion" ) << "."; } } }; INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) } // end namespace Catch namespace Catch { // These are all here to avoid warnings about not having any out of line // virtual methods NonCopyable::~NonCopyable() {} IShared::~IShared() {} IStream::~IStream() CATCH_NOEXCEPT {} FileStream::~FileStream() CATCH_NOEXCEPT {} CoutStream::~CoutStream() CATCH_NOEXCEPT {} DebugOutStream::~DebugOutStream() CATCH_NOEXCEPT {} StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} IContext::~IContext() {} IResultCapture::~IResultCapture() {} ITestCase::~ITestCase() {} ITestCaseRegistry::~ITestCaseRegistry() {} IRegistryHub::~IRegistryHub() {} IMutableRegistryHub::~IMutableRegistryHub() {} IExceptionTranslator::~IExceptionTranslator() {} IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} IReporter::~IReporter() {} IReporterFactory::~IReporterFactory() {} IReporterRegistry::~IReporterRegistry() {} IStreamingReporter::~IStreamingReporter() {} AssertionStats::~AssertionStats() {} SectionStats::~SectionStats() {} TestCaseStats::~TestCaseStats() {} TestGroupStats::~TestGroupStats() {} TestRunStats::~TestRunStats() {} CumulativeReporterBase::SectionNode::~SectionNode() {} CumulativeReporterBase::~CumulativeReporterBase() {} StreamingReporterBase::~StreamingReporterBase() {} ConsoleReporter::~ConsoleReporter() {} CompactReporter::~CompactReporter() {} IRunner::~IRunner() {} IMutableContext::~IMutableContext() {} IConfig::~IConfig() {} XmlReporter::~XmlReporter() {} JunitReporter::~JunitReporter() {} TestRegistry::~TestRegistry() {} FreeFunctionTestCase::~FreeFunctionTestCase() {} IGeneratorInfo::~IGeneratorInfo() {} IGeneratorsForTest::~IGeneratorsForTest() {} WildcardPattern::~WildcardPattern() {} TestSpec::Pattern::~Pattern() {} TestSpec::NamePattern::~NamePattern() {} TestSpec::TagPattern::~TagPattern() {} TestSpec::ExcludedPattern::~ExcludedPattern() {} Matchers::Impl::StdString::Equals::~Equals() {} Matchers::Impl::StdString::Contains::~Contains() {} Matchers::Impl::StdString::StartsWith::~StartsWith() {} Matchers::Impl::StdString::EndsWith::~EndsWith() {} void Config::dummy() {} namespace TestCaseTracking { ITracker::~ITracker() {} TrackerBase::~TrackerBase() {} SectionTracker::~SectionTracker() {} IndexTracker::~IndexTracker() {} } } #ifdef __clang__ #pragma clang diagnostic pop #endif #endif #ifdef CATCH_CONFIG_MAIN // #included from: internal/catch_default_main.hpp #define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED #ifndef __OBJC__ // Standard C/C++ main entry point int main (int argc, char * argv[]) { return Catch::Session().run( argc, argv ); } #else // __OBJC__ // Objective-C entry point int main (int argc, char * const argv[]) { #if !CATCH_ARC_ENABLED NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; #endif Catch::registerTestMethods(); int result = Catch::Session().run( argc, (char* const*)argv ); #if !CATCH_ARC_ENABLED [pool drain]; #endif return result; } #endif // __OBJC__ #endif #ifdef CLARA_CONFIG_MAIN_NOT_DEFINED # undef CLARA_CONFIG_MAIN #endif ////// // If this config identifier is defined then all CATCH macros are prefixed with CATCH_ #ifdef CATCH_CONFIG_PREFIX_ALL #define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) #define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) #define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "CATCH_REQUIRE_THROWS" ) #define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) #define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "CATCH_REQUIRE_THROWS_WITH" ) #define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) #define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) #define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) #define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) #define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) #define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) #define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CATCH_CHECK_THROWS" ) #define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) #define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CATCH_CHECK_THROWS_WITH" ) #define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) #define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) #define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) #define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) #define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) #define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) #define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) #define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) #else #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define CATCH_REGISTER_TEST_CASE( function, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( function, name, description ) #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) #endif #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) #define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" ) #define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" ) #define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) #define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" ) #define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" ) // If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required #else #define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) #define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) #define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "", "REQUIRE_THROWS" ) #define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) #define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, matcher, "REQUIRE_THROWS_WITH" ) #define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) #define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) #define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) #define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) #define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) #define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) #define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "", "CHECK_THROWS" ) #define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) #define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, matcher, "CHECK_THROWS_WITH" ) #define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) #define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) #define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) #define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) #define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) #define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) #define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) #define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) #ifdef CATCH_CONFIG_VARIADIC_MACROS #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) #define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ ) #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) #else #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) #define REGISTER_TEST_CASE( method, name, description ) INTERNAL_CATCH_REGISTER_TESTCASE( method, name, description ) #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) #endif #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) #define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) #define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) #define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) #endif #define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) // "BDD-style" convenience wrappers #ifdef CATCH_CONFIG_VARIADIC_MACROS #define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) #define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) #else #define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) #define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) #endif #define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" ) #define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" ) #define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" ) #define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" ) #define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" ) using Catch::Detail::Approx; #endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED ================================================ FILE: ThirdParty/FakeIt/Catch/fakeit.hpp ================================================ #pragma once /* * FakeIt - A Simplified C++ Mocking Framework * Copyright (c) Eran Pe'er 2013 * Generated: 2017-05-07 09:27:02.651812 * Distributed under the MIT License. Please refer to the LICENSE file at: * https://github.com/eranpeer/FakeIt */ #ifndef fakeit_h__ #define fakeit_h__ #include #include #include #include #include #if defined (__GNUG__) || _MSC_VER >= 1900 #define THROWS noexcept(false) #define NO_THROWS noexcept(true) #elif defined (_MSC_VER) #define THROWS throw(...) #define NO_THROWS #endif #include #include #include #include #include #include #include namespace fakeit { template struct naked_type { typedef typename std::remove_cv::type>::type type; }; template< class T > struct tuple_arg { typedef T type; }; template< class T > struct tuple_arg < T& > { typedef T& type; }; template< class T > struct tuple_arg < T&& > { typedef T&& type; }; template using ArgumentsTuple = std::tuple < arglist... > ; template< class T > struct test_arg { typedef T& type; }; template< class T > struct test_arg< T& > { typedef T& type; }; template< class T > struct test_arg< T&& > { typedef T& type; }; template< class T > struct production_arg { typedef T& type; }; template< class T > struct production_arg< T& > { typedef T& type; }; template< class T > struct production_arg< T&& > { typedef T&& type; }; template class is_ostreamable { struct no {}; #if defined(_MSC_VER) && _MSC_VER < 1900 template static decltype(operator<<(std::declval(), std::declval())) test(std::ostream &s, const T1 &t); #else template static auto test(std::ostream &s, const T1 &t) -> decltype(s << t); #endif static no test(...); public: static const bool value = std::is_arithmetic::value || std::is_pointer::value || std::is_same())), std::ostream &>::value; }; template <> class is_ostreamable { public: static const bool value = true; }; template class is_ostreamable& (*)(std::basic_ios&)> { public: static const bool value = true; }; template class is_ostreamable& (*)(std::basic_ostream&)> { public: static const bool value = true; }; template struct VTableMethodType { #if defined (__GNUG__) typedef R(*type)(void *, arglist...); #elif defined (_MSC_VER) typedef R(__thiscall *type)(void *, arglist...); #endif }; } #include #include #include #include #include #include namespace fakeit { struct FakeitContext; template struct MockObject { virtual ~MockObject() THROWS { }; virtual C &get() = 0; virtual FakeitContext &getFakeIt() = 0; }; struct MethodInfo { static unsigned int nextMethodOrdinal() { static std::atomic_uint ordinal{0}; return ++ordinal; } MethodInfo(unsigned int anId, std::string aName) : _id(anId), _name(aName) { } unsigned int id() const { return _id; } std::string name() const { return _name; } void setName(const std::string &value) { _name = value; } private: unsigned int _id; std::string _name; }; struct UnknownMethod { static MethodInfo &instance() { static MethodInfo instance(MethodInfo::nextMethodOrdinal(), "unknown"); return instance; } }; } namespace fakeit { class Destructible { public: virtual ~Destructible() {} }; } namespace fakeit { struct Invocation : Destructible { static unsigned int nextInvocationOrdinal() { static std::atomic_uint invocationOrdinal{0}; return ++invocationOrdinal; } struct Matcher { virtual ~Matcher() THROWS { } virtual bool matches(Invocation &invocation) = 0; virtual std::string format() const = 0; }; Invocation(unsigned int ordinal, MethodInfo &method) : _ordinal(ordinal), _method(method), _isVerified(false) { } virtual ~Invocation() override = default; unsigned int getOrdinal() const { return _ordinal; } MethodInfo &getMethod() const { return _method; } void markAsVerified() { _isVerified = true; } bool isVerified() const { return _isVerified; } virtual std::string format() const = 0; private: const unsigned int _ordinal; MethodInfo &_method; bool _isVerified; }; } #include #include #include #include #include namespace fakeit { template struct Formatter; template <> struct Formatter { static std::string format(bool const &val) { return val ? "true" : "false"; } }; template <> struct Formatter { static std::string format(char const &val) { std::string s; s += "'"; s += val; s += "'"; return s; } }; template struct Formatter::value>::type> { static std::string format(C const &) { return "?"; } }; template struct Formatter::value>::type> { static std::string format(C const &val) { std::ostringstream os; os << val; return os.str(); } }; template using TypeFormatter = Formatter::type>; } namespace fakeit { template struct TuplePrinter { static void print(std::ostream &strm, const Tuple &t) { TuplePrinter::print(strm, t); strm << ", " << fakeit::TypeFormatter(t))>::format(std::get(t)); } }; template struct TuplePrinter { static void print(std::ostream &strm, const Tuple &t) { strm << fakeit::TypeFormatter(t))>::format(std::get<0>(t)); } }; template struct TuplePrinter { static void print(std::ostream &, const Tuple &) { } }; template void print(std::ostream &strm, const std::tuple &t) { strm << "("; TuplePrinter::print(strm, t); strm << ")"; } template std::ostream &operator<<(std::ostream &strm, const std::tuple &t) { print(strm, t); return strm; } } namespace fakeit { template struct ActualInvocation : public Invocation { struct Matcher : public virtual Destructible { virtual bool matches(ActualInvocation &actualInvocation) = 0; virtual std::string format() const = 0; }; ActualInvocation(unsigned int ordinal, MethodInfo &method, const typename fakeit::production_arg::type... args) : Invocation(ordinal, method), _matcher{ nullptr } , actualArguments{ std::forward(args)... } { } ArgumentsTuple & getActualArguments() { return actualArguments; } void setActualMatcher(Matcher *matcher) { this->_matcher = matcher; } Matcher *getActualMatcher() { return _matcher; } virtual std::string format() const override { std::ostringstream out; out << getMethod().name(); print(out, actualArguments); return out.str(); } private: Matcher *_matcher; ArgumentsTuple actualArguments; }; template std::ostream &operator<<(std::ostream &strm, const ActualInvocation &ai) { strm << ai.format(); return strm; } } #include namespace fakeit { struct ActualInvocationsContainer { virtual void clear() = 0; virtual ~ActualInvocationsContainer() NO_THROWS { } }; struct ActualInvocationsSource { virtual void getActualInvocations(std::unordered_set &into) const = 0; virtual ~ActualInvocationsSource() NO_THROWS { } }; struct InvocationsSourceProxy : public ActualInvocationsSource { InvocationsSourceProxy(ActualInvocationsSource *inner) : _inner(inner) { } void getActualInvocations(std::unordered_set &into) const override { _inner->getActualInvocations(into); } private: std::shared_ptr _inner; }; struct UnverifiedInvocationsSource : public ActualInvocationsSource { UnverifiedInvocationsSource(InvocationsSourceProxy decorated) : _decorated(decorated) { } void getActualInvocations(std::unordered_set &into) const override { std::unordered_set all; _decorated.getActualInvocations(all); for (fakeit::Invocation *i : all) { if (!i->isVerified()) { into.insert(i); } } } private: InvocationsSourceProxy _decorated; }; struct AggregateInvocationsSource : public ActualInvocationsSource { AggregateInvocationsSource(std::vector &sources) : _sources(sources) { } void getActualInvocations(std::unordered_set &into) const override { std::unordered_set tmp; for (ActualInvocationsSource *source : _sources) { source->getActualInvocations(tmp); } filter(tmp, into); } protected: bool shouldInclude(fakeit::Invocation *) const { return true; } private: std::vector _sources; void filter(std::unordered_set &source, std::unordered_set &target) const { for (Invocation *i:source) { if (shouldInclude(i)) { target.insert(i); } } } }; } namespace fakeit { class Sequence { private: protected: Sequence() { } virtual ~Sequence() THROWS { } public: virtual void getExpectedSequence(std::vector &into) const = 0; virtual void getInvolvedMocks(std::vector &into) const = 0; virtual unsigned int size() const = 0; friend class VerifyFunctor; }; class ConcatenatedSequence : public virtual Sequence { private: const Sequence &s1; const Sequence &s2; protected: ConcatenatedSequence(const Sequence &seq1, const Sequence &seq2) : s1(seq1), s2(seq2) { } public: virtual ~ConcatenatedSequence() { } unsigned int size() const override { return s1.size() + s2.size(); } const Sequence &getLeft() const { return s1; } const Sequence &getRight() const { return s2; } void getExpectedSequence(std::vector &into) const override { s1.getExpectedSequence(into); s2.getExpectedSequence(into); } virtual void getInvolvedMocks(std::vector &into) const override { s1.getInvolvedMocks(into); s2.getInvolvedMocks(into); } friend inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2); }; class RepeatedSequence : public virtual Sequence { private: const Sequence &_s; const int times; protected: RepeatedSequence(const Sequence &s, const int t) : _s(s), times(t) { } public: ~RepeatedSequence() { } unsigned int size() const override { return _s.size() * times; } friend inline RepeatedSequence operator*(const Sequence &s, int times); friend inline RepeatedSequence operator*(int times, const Sequence &s); void getInvolvedMocks(std::vector &into) const override { _s.getInvolvedMocks(into); } void getExpectedSequence(std::vector &into) const override { for (int i = 0; i < times; i++) _s.getExpectedSequence(into); } int getTimes() const { return times; } const Sequence &getSequence() const { return _s; } }; inline ConcatenatedSequence operator+(const Sequence &s1, const Sequence &s2) { return ConcatenatedSequence(s1, s2); } inline RepeatedSequence operator*(const Sequence &s, int times) { if (times <= 0) throw std::invalid_argument("times"); return RepeatedSequence(s, times); } inline RepeatedSequence operator*(int times, const Sequence &s) { if (times <= 0) throw std::invalid_argument("times"); return RepeatedSequence(s, times); } } namespace fakeit { enum class VerificationType { Exact, AtLeast, NoMoreInvocations }; enum class UnexpectedType { Unmocked, Unmatched }; struct VerificationEvent { VerificationEvent(VerificationType aVerificationType) : _verificationType(aVerificationType), _line(0) { } virtual ~VerificationEvent() = default; VerificationType verificationType() const { return _verificationType; } void setFileInfo(const char * aFile, int aLine, const char * aCallingMethod) { _file = aFile; _callingMethod = aCallingMethod; _line = aLine; } const char * file() const { return _file; } int line() const { return _line; } const char * callingMethod() const { return _callingMethod; } private: VerificationType _verificationType; const char * _file; int _line; const char * _callingMethod; }; struct NoMoreInvocationsVerificationEvent : public VerificationEvent { ~NoMoreInvocationsVerificationEvent() = default; NoMoreInvocationsVerificationEvent( std::vector &allTheIvocations, std::vector &anUnverifedIvocations) : VerificationEvent(VerificationType::NoMoreInvocations), _allIvocations(allTheIvocations), _unverifedIvocations(anUnverifedIvocations) { } const std::vector &allIvocations() const { return _allIvocations; } const std::vector &unverifedIvocations() const { return _unverifedIvocations; } private: const std::vector _allIvocations; const std::vector _unverifedIvocations; }; struct SequenceVerificationEvent : public VerificationEvent { ~SequenceVerificationEvent() = default; SequenceVerificationEvent(VerificationType aVerificationType, std::vector &anExpectedPattern, std::vector &anActualSequence, int anExpectedCount, int anActualCount) : VerificationEvent(aVerificationType), _expectedPattern(anExpectedPattern), _actualSequence(anActualSequence), _expectedCount(anExpectedCount), _actualCount(anActualCount) { } const std::vector &expectedPattern() const { return _expectedPattern; } const std::vector &actualSequence() const { return _actualSequence; } int expectedCount() const { return _expectedCount; } int actualCount() const { return _actualCount; } private: const std::vector _expectedPattern; const std::vector _actualSequence; const int _expectedCount; const int _actualCount; }; struct UnexpectedMethodCallEvent { UnexpectedMethodCallEvent(UnexpectedType unexpectedType, const Invocation &invocation) : _unexpectedType(unexpectedType), _invocation(invocation) { } const Invocation &getInvocation() const { return _invocation; } UnexpectedType getUnexpectedType() const { return _unexpectedType; } const UnexpectedType _unexpectedType; const Invocation &_invocation; }; } namespace fakeit { struct VerificationEventHandler { virtual void handle(const SequenceVerificationEvent &e) = 0; virtual void handle(const NoMoreInvocationsVerificationEvent &e) = 0; }; struct EventHandler : public VerificationEventHandler { using VerificationEventHandler::handle; virtual void handle(const UnexpectedMethodCallEvent &e) = 0; }; } #include #include namespace fakeit { struct UnexpectedMethodCallEvent; struct SequenceVerificationEvent; struct NoMoreInvocationsVerificationEvent; struct EventFormatter { virtual std::string format(const fakeit::UnexpectedMethodCallEvent &e) = 0; virtual std::string format(const fakeit::SequenceVerificationEvent &e) = 0; virtual std::string format(const fakeit::NoMoreInvocationsVerificationEvent &e) = 0; }; } namespace fakeit { struct FakeitContext : public EventHandler, protected EventFormatter { virtual ~FakeitContext() = default; void handle(const UnexpectedMethodCallEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); eh.handle(e); } void handle(const SequenceVerificationEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); return eh.handle(e); } void handle(const NoMoreInvocationsVerificationEvent &e) override { fireEvent(e); auto &eh = getTestingFrameworkAdapter(); return eh.handle(e); } std::string format(const UnexpectedMethodCallEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } std::string format(const SequenceVerificationEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } std::string format(const NoMoreInvocationsVerificationEvent &e) override { auto &eventFormatter = getEventFormatter(); return eventFormatter.format(e); } void addEventHandler(EventHandler &eventListener) { _eventListeners.push_back(&eventListener); } void clearEventHandlers() { _eventListeners.clear(); } protected: virtual EventHandler &getTestingFrameworkAdapter() = 0; virtual EventFormatter &getEventFormatter() = 0; private: std::vector _eventListeners; void fireEvent(const NoMoreInvocationsVerificationEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } void fireEvent(const UnexpectedMethodCallEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } void fireEvent(const SequenceVerificationEvent &evt) { for (auto listener : _eventListeners) listener->handle(evt); } }; } #include #include namespace fakeit { struct DefaultEventFormatter : public EventFormatter { virtual std::string format(const UnexpectedMethodCallEvent &e) override { std::ostringstream out; out << "Unexpected method invocation: "; out << e.getInvocation().format() << std::endl; if (UnexpectedType::Unmatched == e.getUnexpectedType()) { out << " Could not find Any recorded behavior to support this method call."; } else { out << " An unmocked method was invoked. All used virtual methods must be stubbed!"; } return out.str(); } virtual std::string format(const SequenceVerificationEvent &e) override { std::ostringstream out; out << "Verification error" << std::endl; out << "Expected pattern: "; const std::vector expectedPattern = e.expectedPattern(); out << formatExpectedPattern(expectedPattern) << std::endl; out << "Expected matches: "; formatExpectedCount(out, e.verificationType(), e.expectedCount()); out << std::endl; out << "Actual matches : " << e.actualCount() << std::endl; auto actualSequence = e.actualSequence(); out << "Actual sequence : total of " << actualSequence.size() << " actual invocations"; if (actualSequence.size() == 0) { out << "."; } else { out << ":" << std::endl; } formatInvocationList(out, actualSequence); return out.str(); } virtual std::string format(const NoMoreInvocationsVerificationEvent &e) override { std::ostringstream out; out << "Verification error" << std::endl; out << "Expected no more invocations!! But the following unverified invocations were found:" << std::endl; formatInvocationList(out, e.unverifedIvocations()); return out.str(); } private: static std::string formatSequence(const Sequence &val) { const ConcatenatedSequence *cs = dynamic_cast(&val); if (cs) { return format(*cs); } const RepeatedSequence *rs = dynamic_cast(&val); if (rs) { return format(*rs); } std::vector vec; val.getExpectedSequence(vec); return vec[0]->format(); } static void formatExpectedCount(std::ostream &out, fakeit::VerificationType verificationType, int expectedCount) { if (verificationType == fakeit::VerificationType::Exact) out << "exactly "; if (verificationType == fakeit::VerificationType::AtLeast) out << "at least "; out << expectedCount; } static void formatInvocationList(std::ostream &out, const std::vector &actualSequence) { size_t max_size = actualSequence.size(); if (max_size > 5) max_size = 5; for (unsigned int i = 0; i < max_size; i++) { out << " "; auto invocation = actualSequence[i]; out << invocation->format(); if (i < max_size - 1) out << std::endl; } if (actualSequence.size() > max_size) out << std::endl << " ..."; } static std::string format(const ConcatenatedSequence &val) { std::ostringstream out; out << formatSequence(val.getLeft()) << " + " << formatSequence(val.getRight()); return out.str(); } static std::string format(const RepeatedSequence &val) { std::ostringstream out; const ConcatenatedSequence *cs = dynamic_cast(&val.getSequence()); const RepeatedSequence *rs = dynamic_cast(&val.getSequence()); if (rs || cs) out << '('; out << formatSequence(val.getSequence()); if (rs || cs) out << ')'; out << " * " << val.getTimes(); return out.str(); } static std::string formatExpectedPattern(const std::vector &expectedPattern) { std::string expectedPatternStr; for (unsigned int i = 0; i < expectedPattern.size(); i++) { Sequence *s = expectedPattern[i]; expectedPatternStr += formatSequence(*s); if (i < expectedPattern.size() - 1) expectedPatternStr += " ... "; } return expectedPatternStr; } }; } namespace fakeit { struct FakeitException { std::exception err; virtual ~FakeitException() = default; virtual std::string what() const = 0; friend std::ostream &operator<<(std::ostream &os, const FakeitException &val) { os << val.what(); return os; } }; struct UnexpectedMethodCallException : public FakeitException { UnexpectedMethodCallException(std::string format) : _format(format) { } virtual std::string what() const override { return _format; } private: std::string _format; }; } namespace fakeit { struct DefaultEventLogger : public fakeit::EventHandler { DefaultEventLogger(EventFormatter &formatter) : _formatter(formatter), _out(std::cout) { } virtual void handle(const UnexpectedMethodCallEvent &e) override { _out << _formatter.format(e) << std::endl; } virtual void handle(const SequenceVerificationEvent &e) override { _out << _formatter.format(e) << std::endl; } virtual void handle(const NoMoreInvocationsVerificationEvent &e) override { _out << _formatter.format(e) << std::endl; } private: EventFormatter &_formatter; std::ostream &_out; }; } namespace fakeit { class AbstractFakeit : public FakeitContext { public: virtual ~AbstractFakeit() = default; protected: virtual fakeit::EventHandler &accessTestingFrameworkAdapter() = 0; virtual EventFormatter &accessEventFormatter() = 0; }; class DefaultFakeit : public AbstractFakeit { DefaultEventFormatter _formatter; fakeit::EventFormatter *_customFormatter; fakeit::EventHandler *_testingFrameworkAdapter; public: DefaultFakeit() : _formatter(), _customFormatter(nullptr), _testingFrameworkAdapter(nullptr) { } virtual ~DefaultFakeit() = default; void setCustomEventFormatter(fakeit::EventFormatter &customEventFormatter) { _customFormatter = &customEventFormatter; } void resetCustomEventFormatter() { _customFormatter = nullptr; } void setTestingFrameworkAdapter(fakeit::EventHandler &testingFrameforkAdapter) { _testingFrameworkAdapter = &testingFrameforkAdapter; } void resetTestingFrameworkAdapter() { _testingFrameworkAdapter = nullptr; } protected: fakeit::EventHandler &getTestingFrameworkAdapter() override { if (_testingFrameworkAdapter) return *_testingFrameworkAdapter; return accessTestingFrameworkAdapter(); } EventFormatter &getEventFormatter() override { if (_customFormatter) return *_customFormatter; return accessEventFormatter(); } EventFormatter &accessEventFormatter() override { return _formatter; } }; } namespace fakeit { struct VerificationException : public FakeitException { virtual ~VerificationException() = default; void setFileInfo(const char *file, int line, const char *callingMethod) { _file = file; _callingMethod = callingMethod; _line = line; } const char *file() const { return _file; } int line() const { return _line; } const char *callingMethod() const { return _callingMethod; } private: const char *_file; int _line; const char *_callingMethod; }; struct NoMoreInvocationsVerificationException : public VerificationException { NoMoreInvocationsVerificationException(std::string format) : _format(format) { } virtual std::string what() const override { return _format; } private: std::string _format; }; struct SequenceVerificationException : public VerificationException { SequenceVerificationException(const std::string &format) : _format(format) { } virtual std::string what() const override { return _format; } private: std::string _format; }; class CatchAdapter : public EventHandler { EventFormatter &_formatter; std::string formatLineNumber(std::string file, int num) { #ifndef __GNUG__ return file + std::string("(") + std::to_string(num) + std::string(")"); #else return file + std::string(":") + std::to_string(num); #endif } public: virtual ~CatchAdapter() = default; CatchAdapter(EventFormatter &formatter) : _formatter(formatter) {} virtual void handle(const UnexpectedMethodCallEvent &evt) override { std::string format = _formatter.format(evt); Catch::ResultBuilder __catchResult("FAIL", ::Catch::SourceLineInfo(), "", Catch::ResultDisposition::Normal); __catchResult << format + ::Catch::StreamEndStop(); __catchResult.captureResult(Catch::ResultWas::ExplicitFailure); INTERNAL_CATCH_REACT(__catchResult) throw Catch::TestFailureException(); } virtual void handle(const SequenceVerificationEvent &evt) override { std::string format(formatLineNumber(evt.file(), evt.line()) + ": " + _formatter.format(evt)); Catch::ResultBuilder __catchResult("FAIL", ::Catch::SourceLineInfo(evt.file(), static_cast( evt.line())), "", Catch::ResultDisposition::Normal); __catchResult << format + ::Catch::StreamEndStop(); __catchResult.captureResult(Catch::ResultWas::ExplicitFailure); INTERNAL_CATCH_REACT(__catchResult) throw Catch::TestFailureException(); } virtual void handle(const NoMoreInvocationsVerificationEvent &evt) override { std::string format(formatLineNumber(evt.file(), evt.line()) + ": " + _formatter.format(evt)); Catch::ResultBuilder __catchResult("FAIL", ::Catch::SourceLineInfo(evt.file(), static_cast( evt.line())), "", Catch::ResultDisposition::Normal); __catchResult << format + ::Catch::StreamEndStop(); __catchResult.captureResult(Catch::ResultWas::ExplicitFailure); INTERNAL_CATCH_REACT(__catchResult) throw Catch::TestFailureException(); } }; class CatchFakeit : public DefaultFakeit { public: virtual ~CatchFakeit() = default; CatchFakeit() : _formatter(), _catchAdapter(_formatter) {} static CatchFakeit &getInstance() { static CatchFakeit instance; return instance; } protected: fakeit::EventHandler &accessTestingFrameworkAdapter() override { return _catchAdapter; } EventFormatter &accessEventFormatter() override { return _formatter; } private: DefaultEventFormatter _formatter; CatchAdapter _catchAdapter; }; } static fakeit::DefaultFakeit& Fakeit = fakeit::CatchFakeit::getInstance(); #include #include #include #include #include #include #include #include #include #include namespace fakeit { struct VirtualOffsetSelector { unsigned int offset; virtual unsigned int offset0(int) { return offset = 0; } virtual unsigned int offset1(int) { return offset = 1; } virtual unsigned int offset2(int) { return offset = 2; } virtual unsigned int offset3(int) { return offset = 3; } virtual unsigned int offset4(int) { return offset = 4; } virtual unsigned int offset5(int) { return offset = 5; } virtual unsigned int offset6(int) { return offset = 6; } virtual unsigned int offset7(int) { return offset = 7; } virtual unsigned int offset8(int) { return offset = 8; } virtual unsigned int offset9(int) { return offset = 9; } virtual unsigned int offset10(int) { return offset = 10; } virtual unsigned int offset11(int) { return offset = 11; } virtual unsigned int offset12(int) { return offset = 12; } virtual unsigned int offset13(int) { return offset = 13; } virtual unsigned int offset14(int) { return offset = 14; } virtual unsigned int offset15(int) { return offset = 15; } virtual unsigned int offset16(int) { return offset = 16; } virtual unsigned int offset17(int) { return offset = 17; } virtual unsigned int offset18(int) { return offset = 18; } virtual unsigned int offset19(int) { return offset = 19; } virtual unsigned int offset20(int) { return offset = 20; } virtual unsigned int offset21(int) { return offset = 21; } virtual unsigned int offset22(int) { return offset = 22; } virtual unsigned int offset23(int) { return offset = 23; } virtual unsigned int offset24(int) { return offset = 24; } virtual unsigned int offset25(int) { return offset = 25; } virtual unsigned int offset26(int) { return offset = 26; } virtual unsigned int offset27(int) { return offset = 27; } virtual unsigned int offset28(int) { return offset = 28; } virtual unsigned int offset29(int) { return offset = 29; } virtual unsigned int offset30(int) { return offset = 30; } virtual unsigned int offset31(int) { return offset = 31; } virtual unsigned int offset32(int) { return offset = 32; } virtual unsigned int offset33(int) { return offset = 33; } virtual unsigned int offset34(int) { return offset = 34; } virtual unsigned int offset35(int) { return offset = 35; } virtual unsigned int offset36(int) { return offset = 36; } virtual unsigned int offset37(int) { return offset = 37; } virtual unsigned int offset38(int) { return offset = 38; } virtual unsigned int offset39(int) { return offset = 39; } virtual unsigned int offset40(int) { return offset = 40; } virtual unsigned int offset41(int) { return offset = 41; } virtual unsigned int offset42(int) { return offset = 42; } virtual unsigned int offset43(int) { return offset = 43; } virtual unsigned int offset44(int) { return offset = 44; } virtual unsigned int offset45(int) { return offset = 45; } virtual unsigned int offset46(int) { return offset = 46; } virtual unsigned int offset47(int) { return offset = 47; } virtual unsigned int offset48(int) { return offset = 48; } virtual unsigned int offset49(int) { return offset = 49; } virtual unsigned int offset50(int) { return offset = 50; } virtual unsigned int offset51(int) { return offset = 51; } virtual unsigned int offset52(int) { return offset = 52; } virtual unsigned int offset53(int) { return offset = 53; } virtual unsigned int offset54(int) { return offset = 54; } virtual unsigned int offset55(int) { return offset = 55; } virtual unsigned int offset56(int) { return offset = 56; } virtual unsigned int offset57(int) { return offset = 57; } virtual unsigned int offset58(int) { return offset = 58; } virtual unsigned int offset59(int) { return offset = 59; } virtual unsigned int offset60(int) { return offset = 60; } virtual unsigned int offset61(int) { return offset = 61; } virtual unsigned int offset62(int) { return offset = 62; } virtual unsigned int offset63(int) { return offset = 63; } virtual unsigned int offset64(int) { return offset = 64; } virtual unsigned int offset65(int) { return offset = 65; } virtual unsigned int offset66(int) { return offset = 66; } virtual unsigned int offset67(int) { return offset = 67; } virtual unsigned int offset68(int) { return offset = 68; } virtual unsigned int offset69(int) { return offset = 69; } virtual unsigned int offset70(int) { return offset = 70; } virtual unsigned int offset71(int) { return offset = 71; } virtual unsigned int offset72(int) { return offset = 72; } virtual unsigned int offset73(int) { return offset = 73; } virtual unsigned int offset74(int) { return offset = 74; } virtual unsigned int offset75(int) { return offset = 75; } virtual unsigned int offset76(int) { return offset = 76; } virtual unsigned int offset77(int) { return offset = 77; } virtual unsigned int offset78(int) { return offset = 78; } virtual unsigned int offset79(int) { return offset = 79; } virtual unsigned int offset80(int) { return offset = 80; } virtual unsigned int offset81(int) { return offset = 81; } virtual unsigned int offset82(int) { return offset = 82; } virtual unsigned int offset83(int) { return offset = 83; } virtual unsigned int offset84(int) { return offset = 84; } virtual unsigned int offset85(int) { return offset = 85; } virtual unsigned int offset86(int) { return offset = 86; } virtual unsigned int offset87(int) { return offset = 87; } virtual unsigned int offset88(int) { return offset = 88; } virtual unsigned int offset89(int) { return offset = 89; } virtual unsigned int offset90(int) { return offset = 90; } virtual unsigned int offset91(int) { return offset = 91; } virtual unsigned int offset92(int) { return offset = 92; } virtual unsigned int offset93(int) { return offset = 93; } virtual unsigned int offset94(int) { return offset = 94; } virtual unsigned int offset95(int) { return offset = 95; } virtual unsigned int offset96(int) { return offset = 96; } virtual unsigned int offset97(int) { return offset = 97; } virtual unsigned int offset98(int) { return offset = 98; } virtual unsigned int offset99(int) { return offset = 99; } virtual unsigned int offset100(int) { return offset = 100; } virtual unsigned int offset101(int) { return offset = 101; } virtual unsigned int offset102(int) { return offset = 102; } virtual unsigned int offset103(int) { return offset = 103; } virtual unsigned int offset104(int) { return offset = 104; } virtual unsigned int offset105(int) { return offset = 105; } virtual unsigned int offset106(int) { return offset = 106; } virtual unsigned int offset107(int) { return offset = 107; } virtual unsigned int offset108(int) { return offset = 108; } virtual unsigned int offset109(int) { return offset = 109; } virtual unsigned int offset110(int) { return offset = 110; } virtual unsigned int offset111(int) { return offset = 111; } virtual unsigned int offset112(int) { return offset = 112; } virtual unsigned int offset113(int) { return offset = 113; } virtual unsigned int offset114(int) { return offset = 114; } virtual unsigned int offset115(int) { return offset = 115; } virtual unsigned int offset116(int) { return offset = 116; } virtual unsigned int offset117(int) { return offset = 117; } virtual unsigned int offset118(int) { return offset = 118; } virtual unsigned int offset119(int) { return offset = 119; } virtual unsigned int offset120(int) { return offset = 120; } virtual unsigned int offset121(int) { return offset = 121; } virtual unsigned int offset122(int) { return offset = 122; } virtual unsigned int offset123(int) { return offset = 123; } virtual unsigned int offset124(int) { return offset = 124; } virtual unsigned int offset125(int) { return offset = 125; } virtual unsigned int offset126(int) { return offset = 126; } virtual unsigned int offset127(int) { return offset = 127; } virtual unsigned int offset128(int) { return offset = 128; } virtual unsigned int offset129(int) { return offset = 129; } virtual unsigned int offset130(int) { return offset = 130; } virtual unsigned int offset131(int) { return offset = 131; } virtual unsigned int offset132(int) { return offset = 132; } virtual unsigned int offset133(int) { return offset = 133; } virtual unsigned int offset134(int) { return offset = 134; } virtual unsigned int offset135(int) { return offset = 135; } virtual unsigned int offset136(int) { return offset = 136; } virtual unsigned int offset137(int) { return offset = 137; } virtual unsigned int offset138(int) { return offset = 138; } virtual unsigned int offset139(int) { return offset = 139; } virtual unsigned int offset140(int) { return offset = 140; } virtual unsigned int offset141(int) { return offset = 141; } virtual unsigned int offset142(int) { return offset = 142; } virtual unsigned int offset143(int) { return offset = 143; } virtual unsigned int offset144(int) { return offset = 144; } virtual unsigned int offset145(int) { return offset = 145; } virtual unsigned int offset146(int) { return offset = 146; } virtual unsigned int offset147(int) { return offset = 147; } virtual unsigned int offset148(int) { return offset = 148; } virtual unsigned int offset149(int) { return offset = 149; } virtual unsigned int offset150(int) { return offset = 150; } virtual unsigned int offset151(int) { return offset = 151; } virtual unsigned int offset152(int) { return offset = 152; } virtual unsigned int offset153(int) { return offset = 153; } virtual unsigned int offset154(int) { return offset = 154; } virtual unsigned int offset155(int) { return offset = 155; } virtual unsigned int offset156(int) { return offset = 156; } virtual unsigned int offset157(int) { return offset = 157; } virtual unsigned int offset158(int) { return offset = 158; } virtual unsigned int offset159(int) { return offset = 159; } virtual unsigned int offset160(int) { return offset = 160; } virtual unsigned int offset161(int) { return offset = 161; } virtual unsigned int offset162(int) { return offset = 162; } virtual unsigned int offset163(int) { return offset = 163; } virtual unsigned int offset164(int) { return offset = 164; } virtual unsigned int offset165(int) { return offset = 165; } virtual unsigned int offset166(int) { return offset = 166; } virtual unsigned int offset167(int) { return offset = 167; } virtual unsigned int offset168(int) { return offset = 168; } virtual unsigned int offset169(int) { return offset = 169; } virtual unsigned int offset170(int) { return offset = 170; } virtual unsigned int offset171(int) { return offset = 171; } virtual unsigned int offset172(int) { return offset = 172; } virtual unsigned int offset173(int) { return offset = 173; } virtual unsigned int offset174(int) { return offset = 174; } virtual unsigned int offset175(int) { return offset = 175; } virtual unsigned int offset176(int) { return offset = 176; } virtual unsigned int offset177(int) { return offset = 177; } virtual unsigned int offset178(int) { return offset = 178; } virtual unsigned int offset179(int) { return offset = 179; } virtual unsigned int offset180(int) { return offset = 180; } virtual unsigned int offset181(int) { return offset = 181; } virtual unsigned int offset182(int) { return offset = 182; } virtual unsigned int offset183(int) { return offset = 183; } virtual unsigned int offset184(int) { return offset = 184; } virtual unsigned int offset185(int) { return offset = 185; } virtual unsigned int offset186(int) { return offset = 186; } virtual unsigned int offset187(int) { return offset = 187; } virtual unsigned int offset188(int) { return offset = 188; } virtual unsigned int offset189(int) { return offset = 189; } virtual unsigned int offset190(int) { return offset = 190; } virtual unsigned int offset191(int) { return offset = 191; } virtual unsigned int offset192(int) { return offset = 192; } virtual unsigned int offset193(int) { return offset = 193; } virtual unsigned int offset194(int) { return offset = 194; } virtual unsigned int offset195(int) { return offset = 195; } virtual unsigned int offset196(int) { return offset = 196; } virtual unsigned int offset197(int) { return offset = 197; } virtual unsigned int offset198(int) { return offset = 198; } virtual unsigned int offset199(int) { return offset = 199; } virtual unsigned int offset200(int) { return offset = 200; } virtual unsigned int offset201(int) { return offset = 201; } virtual unsigned int offset202(int) { return offset = 202; } virtual unsigned int offset203(int) { return offset = 203; } virtual unsigned int offset204(int) { return offset = 204; } virtual unsigned int offset205(int) { return offset = 205; } virtual unsigned int offset206(int) { return offset = 206; } virtual unsigned int offset207(int) { return offset = 207; } virtual unsigned int offset208(int) { return offset = 208; } virtual unsigned int offset209(int) { return offset = 209; } virtual unsigned int offset210(int) { return offset = 210; } virtual unsigned int offset211(int) { return offset = 211; } virtual unsigned int offset212(int) { return offset = 212; } virtual unsigned int offset213(int) { return offset = 213; } virtual unsigned int offset214(int) { return offset = 214; } virtual unsigned int offset215(int) { return offset = 215; } virtual unsigned int offset216(int) { return offset = 216; } virtual unsigned int offset217(int) { return offset = 217; } virtual unsigned int offset218(int) { return offset = 218; } virtual unsigned int offset219(int) { return offset = 219; } virtual unsigned int offset220(int) { return offset = 220; } virtual unsigned int offset221(int) { return offset = 221; } virtual unsigned int offset222(int) { return offset = 222; } virtual unsigned int offset223(int) { return offset = 223; } virtual unsigned int offset224(int) { return offset = 224; } virtual unsigned int offset225(int) { return offset = 225; } virtual unsigned int offset226(int) { return offset = 226; } virtual unsigned int offset227(int) { return offset = 227; } virtual unsigned int offset228(int) { return offset = 228; } virtual unsigned int offset229(int) { return offset = 229; } virtual unsigned int offset230(int) { return offset = 230; } virtual unsigned int offset231(int) { return offset = 231; } virtual unsigned int offset232(int) { return offset = 232; } virtual unsigned int offset233(int) { return offset = 233; } virtual unsigned int offset234(int) { return offset = 234; } virtual unsigned int offset235(int) { return offset = 235; } virtual unsigned int offset236(int) { return offset = 236; } virtual unsigned int offset237(int) { return offset = 237; } virtual unsigned int offset238(int) { return offset = 238; } virtual unsigned int offset239(int) { return offset = 239; } virtual unsigned int offset240(int) { return offset = 240; } virtual unsigned int offset241(int) { return offset = 241; } virtual unsigned int offset242(int) { return offset = 242; } virtual unsigned int offset243(int) { return offset = 243; } virtual unsigned int offset244(int) { return offset = 244; } virtual unsigned int offset245(int) { return offset = 245; } virtual unsigned int offset246(int) { return offset = 246; } virtual unsigned int offset247(int) { return offset = 247; } virtual unsigned int offset248(int) { return offset = 248; } virtual unsigned int offset249(int) { return offset = 249; } virtual unsigned int offset250(int) { return offset = 250; } virtual unsigned int offset251(int) { return offset = 251; } virtual unsigned int offset252(int) { return offset = 252; } virtual unsigned int offset253(int) { return offset = 253; } virtual unsigned int offset254(int) { return offset = 254; } virtual unsigned int offset255(int) { return offset = 255; } virtual unsigned int offset256(int) { return offset = 256; } virtual unsigned int offset257(int) { return offset = 257; } virtual unsigned int offset258(int) { return offset = 258; } virtual unsigned int offset259(int) { return offset = 259; } virtual unsigned int offset260(int) { return offset = 260; } virtual unsigned int offset261(int) { return offset = 261; } virtual unsigned int offset262(int) { return offset = 262; } virtual unsigned int offset263(int) { return offset = 263; } virtual unsigned int offset264(int) { return offset = 264; } virtual unsigned int offset265(int) { return offset = 265; } virtual unsigned int offset266(int) { return offset = 266; } virtual unsigned int offset267(int) { return offset = 267; } virtual unsigned int offset268(int) { return offset = 268; } virtual unsigned int offset269(int) { return offset = 269; } virtual unsigned int offset270(int) { return offset = 270; } virtual unsigned int offset271(int) { return offset = 271; } virtual unsigned int offset272(int) { return offset = 272; } virtual unsigned int offset273(int) { return offset = 273; } virtual unsigned int offset274(int) { return offset = 274; } virtual unsigned int offset275(int) { return offset = 275; } virtual unsigned int offset276(int) { return offset = 276; } virtual unsigned int offset277(int) { return offset = 277; } virtual unsigned int offset278(int) { return offset = 278; } virtual unsigned int offset279(int) { return offset = 279; } virtual unsigned int offset280(int) { return offset = 280; } virtual unsigned int offset281(int) { return offset = 281; } virtual unsigned int offset282(int) { return offset = 282; } virtual unsigned int offset283(int) { return offset = 283; } virtual unsigned int offset284(int) { return offset = 284; } virtual unsigned int offset285(int) { return offset = 285; } virtual unsigned int offset286(int) { return offset = 286; } virtual unsigned int offset287(int) { return offset = 287; } virtual unsigned int offset288(int) { return offset = 288; } virtual unsigned int offset289(int) { return offset = 289; } virtual unsigned int offset290(int) { return offset = 290; } virtual unsigned int offset291(int) { return offset = 291; } virtual unsigned int offset292(int) { return offset = 292; } virtual unsigned int offset293(int) { return offset = 293; } virtual unsigned int offset294(int) { return offset = 294; } virtual unsigned int offset295(int) { return offset = 295; } virtual unsigned int offset296(int) { return offset = 296; } virtual unsigned int offset297(int) { return offset = 297; } virtual unsigned int offset298(int) { return offset = 298; } virtual unsigned int offset299(int) { return offset = 299; } virtual unsigned int offset300(int) { return offset = 300; } virtual unsigned int offset301(int) { return offset = 301; } virtual unsigned int offset302(int) { return offset = 302; } virtual unsigned int offset303(int) { return offset = 303; } virtual unsigned int offset304(int) { return offset = 304; } virtual unsigned int offset305(int) { return offset = 305; } virtual unsigned int offset306(int) { return offset = 306; } virtual unsigned int offset307(int) { return offset = 307; } virtual unsigned int offset308(int) { return offset = 308; } virtual unsigned int offset309(int) { return offset = 309; } virtual unsigned int offset310(int) { return offset = 310; } virtual unsigned int offset311(int) { return offset = 311; } virtual unsigned int offset312(int) { return offset = 312; } virtual unsigned int offset313(int) { return offset = 313; } virtual unsigned int offset314(int) { return offset = 314; } virtual unsigned int offset315(int) { return offset = 315; } virtual unsigned int offset316(int) { return offset = 316; } virtual unsigned int offset317(int) { return offset = 317; } virtual unsigned int offset318(int) { return offset = 318; } virtual unsigned int offset319(int) { return offset = 319; } virtual unsigned int offset320(int) { return offset = 320; } virtual unsigned int offset321(int) { return offset = 321; } virtual unsigned int offset322(int) { return offset = 322; } virtual unsigned int offset323(int) { return offset = 323; } virtual unsigned int offset324(int) { return offset = 324; } virtual unsigned int offset325(int) { return offset = 325; } virtual unsigned int offset326(int) { return offset = 326; } virtual unsigned int offset327(int) { return offset = 327; } virtual unsigned int offset328(int) { return offset = 328; } virtual unsigned int offset329(int) { return offset = 329; } virtual unsigned int offset330(int) { return offset = 330; } virtual unsigned int offset331(int) { return offset = 331; } virtual unsigned int offset332(int) { return offset = 332; } virtual unsigned int offset333(int) { return offset = 333; } virtual unsigned int offset334(int) { return offset = 334; } virtual unsigned int offset335(int) { return offset = 335; } virtual unsigned int offset336(int) { return offset = 336; } virtual unsigned int offset337(int) { return offset = 337; } virtual unsigned int offset338(int) { return offset = 338; } virtual unsigned int offset339(int) { return offset = 339; } virtual unsigned int offset340(int) { return offset = 340; } virtual unsigned int offset341(int) { return offset = 341; } virtual unsigned int offset342(int) { return offset = 342; } virtual unsigned int offset343(int) { return offset = 343; } virtual unsigned int offset344(int) { return offset = 344; } virtual unsigned int offset345(int) { return offset = 345; } virtual unsigned int offset346(int) { return offset = 346; } virtual unsigned int offset347(int) { return offset = 347; } virtual unsigned int offset348(int) { return offset = 348; } virtual unsigned int offset349(int) { return offset = 349; } virtual unsigned int offset350(int) { return offset = 350; } virtual unsigned int offset351(int) { return offset = 351; } virtual unsigned int offset352(int) { return offset = 352; } virtual unsigned int offset353(int) { return offset = 353; } virtual unsigned int offset354(int) { return offset = 354; } virtual unsigned int offset355(int) { return offset = 355; } virtual unsigned int offset356(int) { return offset = 356; } virtual unsigned int offset357(int) { return offset = 357; } virtual unsigned int offset358(int) { return offset = 358; } virtual unsigned int offset359(int) { return offset = 359; } virtual unsigned int offset360(int) { return offset = 360; } virtual unsigned int offset361(int) { return offset = 361; } virtual unsigned int offset362(int) { return offset = 362; } virtual unsigned int offset363(int) { return offset = 363; } virtual unsigned int offset364(int) { return offset = 364; } virtual unsigned int offset365(int) { return offset = 365; } virtual unsigned int offset366(int) { return offset = 366; } virtual unsigned int offset367(int) { return offset = 367; } virtual unsigned int offset368(int) { return offset = 368; } virtual unsigned int offset369(int) { return offset = 369; } virtual unsigned int offset370(int) { return offset = 370; } virtual unsigned int offset371(int) { return offset = 371; } virtual unsigned int offset372(int) { return offset = 372; } virtual unsigned int offset373(int) { return offset = 373; } virtual unsigned int offset374(int) { return offset = 374; } virtual unsigned int offset375(int) { return offset = 375; } virtual unsigned int offset376(int) { return offset = 376; } virtual unsigned int offset377(int) { return offset = 377; } virtual unsigned int offset378(int) { return offset = 378; } virtual unsigned int offset379(int) { return offset = 379; } virtual unsigned int offset380(int) { return offset = 380; } virtual unsigned int offset381(int) { return offset = 381; } virtual unsigned int offset382(int) { return offset = 382; } virtual unsigned int offset383(int) { return offset = 383; } virtual unsigned int offset384(int) { return offset = 384; } virtual unsigned int offset385(int) { return offset = 385; } virtual unsigned int offset386(int) { return offset = 386; } virtual unsigned int offset387(int) { return offset = 387; } virtual unsigned int offset388(int) { return offset = 388; } virtual unsigned int offset389(int) { return offset = 389; } virtual unsigned int offset390(int) { return offset = 390; } virtual unsigned int offset391(int) { return offset = 391; } virtual unsigned int offset392(int) { return offset = 392; } virtual unsigned int offset393(int) { return offset = 393; } virtual unsigned int offset394(int) { return offset = 394; } virtual unsigned int offset395(int) { return offset = 395; } virtual unsigned int offset396(int) { return offset = 396; } virtual unsigned int offset397(int) { return offset = 397; } virtual unsigned int offset398(int) { return offset = 398; } virtual unsigned int offset399(int) { return offset = 399; } virtual unsigned int offset400(int) { return offset = 400; } virtual unsigned int offset401(int) { return offset = 401; } virtual unsigned int offset402(int) { return offset = 402; } virtual unsigned int offset403(int) { return offset = 403; } virtual unsigned int offset404(int) { return offset = 404; } virtual unsigned int offset405(int) { return offset = 405; } virtual unsigned int offset406(int) { return offset = 406; } virtual unsigned int offset407(int) { return offset = 407; } virtual unsigned int offset408(int) { return offset = 408; } virtual unsigned int offset409(int) { return offset = 409; } virtual unsigned int offset410(int) { return offset = 410; } virtual unsigned int offset411(int) { return offset = 411; } virtual unsigned int offset412(int) { return offset = 412; } virtual unsigned int offset413(int) { return offset = 413; } virtual unsigned int offset414(int) { return offset = 414; } virtual unsigned int offset415(int) { return offset = 415; } virtual unsigned int offset416(int) { return offset = 416; } virtual unsigned int offset417(int) { return offset = 417; } virtual unsigned int offset418(int) { return offset = 418; } virtual unsigned int offset419(int) { return offset = 419; } virtual unsigned int offset420(int) { return offset = 420; } virtual unsigned int offset421(int) { return offset = 421; } virtual unsigned int offset422(int) { return offset = 422; } virtual unsigned int offset423(int) { return offset = 423; } virtual unsigned int offset424(int) { return offset = 424; } virtual unsigned int offset425(int) { return offset = 425; } virtual unsigned int offset426(int) { return offset = 426; } virtual unsigned int offset427(int) { return offset = 427; } virtual unsigned int offset428(int) { return offset = 428; } virtual unsigned int offset429(int) { return offset = 429; } virtual unsigned int offset430(int) { return offset = 430; } virtual unsigned int offset431(int) { return offset = 431; } virtual unsigned int offset432(int) { return offset = 432; } virtual unsigned int offset433(int) { return offset = 433; } virtual unsigned int offset434(int) { return offset = 434; } virtual unsigned int offset435(int) { return offset = 435; } virtual unsigned int offset436(int) { return offset = 436; } virtual unsigned int offset437(int) { return offset = 437; } virtual unsigned int offset438(int) { return offset = 438; } virtual unsigned int offset439(int) { return offset = 439; } virtual unsigned int offset440(int) { return offset = 440; } virtual unsigned int offset441(int) { return offset = 441; } virtual unsigned int offset442(int) { return offset = 442; } virtual unsigned int offset443(int) { return offset = 443; } virtual unsigned int offset444(int) { return offset = 444; } virtual unsigned int offset445(int) { return offset = 445; } virtual unsigned int offset446(int) { return offset = 446; } virtual unsigned int offset447(int) { return offset = 447; } virtual unsigned int offset448(int) { return offset = 448; } virtual unsigned int offset449(int) { return offset = 449; } virtual unsigned int offset450(int) { return offset = 450; } virtual unsigned int offset451(int) { return offset = 451; } virtual unsigned int offset452(int) { return offset = 452; } virtual unsigned int offset453(int) { return offset = 453; } virtual unsigned int offset454(int) { return offset = 454; } virtual unsigned int offset455(int) { return offset = 455; } virtual unsigned int offset456(int) { return offset = 456; } virtual unsigned int offset457(int) { return offset = 457; } virtual unsigned int offset458(int) { return offset = 458; } virtual unsigned int offset459(int) { return offset = 459; } virtual unsigned int offset460(int) { return offset = 460; } virtual unsigned int offset461(int) { return offset = 461; } virtual unsigned int offset462(int) { return offset = 462; } virtual unsigned int offset463(int) { return offset = 463; } virtual unsigned int offset464(int) { return offset = 464; } virtual unsigned int offset465(int) { return offset = 465; } virtual unsigned int offset466(int) { return offset = 466; } virtual unsigned int offset467(int) { return offset = 467; } virtual unsigned int offset468(int) { return offset = 468; } virtual unsigned int offset469(int) { return offset = 469; } virtual unsigned int offset470(int) { return offset = 470; } virtual unsigned int offset471(int) { return offset = 471; } virtual unsigned int offset472(int) { return offset = 472; } virtual unsigned int offset473(int) { return offset = 473; } virtual unsigned int offset474(int) { return offset = 474; } virtual unsigned int offset475(int) { return offset = 475; } virtual unsigned int offset476(int) { return offset = 476; } virtual unsigned int offset477(int) { return offset = 477; } virtual unsigned int offset478(int) { return offset = 478; } virtual unsigned int offset479(int) { return offset = 479; } virtual unsigned int offset480(int) { return offset = 480; } virtual unsigned int offset481(int) { return offset = 481; } virtual unsigned int offset482(int) { return offset = 482; } virtual unsigned int offset483(int) { return offset = 483; } virtual unsigned int offset484(int) { return offset = 484; } virtual unsigned int offset485(int) { return offset = 485; } virtual unsigned int offset486(int) { return offset = 486; } virtual unsigned int offset487(int) { return offset = 487; } virtual unsigned int offset488(int) { return offset = 488; } virtual unsigned int offset489(int) { return offset = 489; } virtual unsigned int offset490(int) { return offset = 490; } virtual unsigned int offset491(int) { return offset = 491; } virtual unsigned int offset492(int) { return offset = 492; } virtual unsigned int offset493(int) { return offset = 493; } virtual unsigned int offset494(int) { return offset = 494; } virtual unsigned int offset495(int) { return offset = 495; } virtual unsigned int offset496(int) { return offset = 496; } virtual unsigned int offset497(int) { return offset = 497; } virtual unsigned int offset498(int) { return offset = 498; } virtual unsigned int offset499(int) { return offset = 499; } virtual unsigned int offset500(int) { return offset = 500; } virtual unsigned int offset501(int) { return offset = 501; } virtual unsigned int offset502(int) { return offset = 502; } virtual unsigned int offset503(int) { return offset = 503; } virtual unsigned int offset504(int) { return offset = 504; } virtual unsigned int offset505(int) { return offset = 505; } virtual unsigned int offset506(int) { return offset = 506; } virtual unsigned int offset507(int) { return offset = 507; } virtual unsigned int offset508(int) { return offset = 508; } virtual unsigned int offset509(int) { return offset = 509; } virtual unsigned int offset510(int) { return offset = 510; } virtual unsigned int offset511(int) { return offset = 511; } virtual unsigned int offset512(int) { return offset = 512; } virtual unsigned int offset513(int) { return offset = 513; } virtual unsigned int offset514(int) { return offset = 514; } virtual unsigned int offset515(int) { return offset = 515; } virtual unsigned int offset516(int) { return offset = 516; } virtual unsigned int offset517(int) { return offset = 517; } virtual unsigned int offset518(int) { return offset = 518; } virtual unsigned int offset519(int) { return offset = 519; } virtual unsigned int offset520(int) { return offset = 520; } virtual unsigned int offset521(int) { return offset = 521; } virtual unsigned int offset522(int) { return offset = 522; } virtual unsigned int offset523(int) { return offset = 523; } virtual unsigned int offset524(int) { return offset = 524; } virtual unsigned int offset525(int) { return offset = 525; } virtual unsigned int offset526(int) { return offset = 526; } virtual unsigned int offset527(int) { return offset = 527; } virtual unsigned int offset528(int) { return offset = 528; } virtual unsigned int offset529(int) { return offset = 529; } virtual unsigned int offset530(int) { return offset = 530; } virtual unsigned int offset531(int) { return offset = 531; } virtual unsigned int offset532(int) { return offset = 532; } virtual unsigned int offset533(int) { return offset = 533; } virtual unsigned int offset534(int) { return offset = 534; } virtual unsigned int offset535(int) { return offset = 535; } virtual unsigned int offset536(int) { return offset = 536; } virtual unsigned int offset537(int) { return offset = 537; } virtual unsigned int offset538(int) { return offset = 538; } virtual unsigned int offset539(int) { return offset = 539; } virtual unsigned int offset540(int) { return offset = 540; } virtual unsigned int offset541(int) { return offset = 541; } virtual unsigned int offset542(int) { return offset = 542; } virtual unsigned int offset543(int) { return offset = 543; } virtual unsigned int offset544(int) { return offset = 544; } virtual unsigned int offset545(int) { return offset = 545; } virtual unsigned int offset546(int) { return offset = 546; } virtual unsigned int offset547(int) { return offset = 547; } virtual unsigned int offset548(int) { return offset = 548; } virtual unsigned int offset549(int) { return offset = 549; } virtual unsigned int offset550(int) { return offset = 550; } virtual unsigned int offset551(int) { return offset = 551; } virtual unsigned int offset552(int) { return offset = 552; } virtual unsigned int offset553(int) { return offset = 553; } virtual unsigned int offset554(int) { return offset = 554; } virtual unsigned int offset555(int) { return offset = 555; } virtual unsigned int offset556(int) { return offset = 556; } virtual unsigned int offset557(int) { return offset = 557; } virtual unsigned int offset558(int) { return offset = 558; } virtual unsigned int offset559(int) { return offset = 559; } virtual unsigned int offset560(int) { return offset = 560; } virtual unsigned int offset561(int) { return offset = 561; } virtual unsigned int offset562(int) { return offset = 562; } virtual unsigned int offset563(int) { return offset = 563; } virtual unsigned int offset564(int) { return offset = 564; } virtual unsigned int offset565(int) { return offset = 565; } virtual unsigned int offset566(int) { return offset = 566; } virtual unsigned int offset567(int) { return offset = 567; } virtual unsigned int offset568(int) { return offset = 568; } virtual unsigned int offset569(int) { return offset = 569; } virtual unsigned int offset570(int) { return offset = 570; } virtual unsigned int offset571(int) { return offset = 571; } virtual unsigned int offset572(int) { return offset = 572; } virtual unsigned int offset573(int) { return offset = 573; } virtual unsigned int offset574(int) { return offset = 574; } virtual unsigned int offset575(int) { return offset = 575; } virtual unsigned int offset576(int) { return offset = 576; } virtual unsigned int offset577(int) { return offset = 577; } virtual unsigned int offset578(int) { return offset = 578; } virtual unsigned int offset579(int) { return offset = 579; } virtual unsigned int offset580(int) { return offset = 580; } virtual unsigned int offset581(int) { return offset = 581; } virtual unsigned int offset582(int) { return offset = 582; } virtual unsigned int offset583(int) { return offset = 583; } virtual unsigned int offset584(int) { return offset = 584; } virtual unsigned int offset585(int) { return offset = 585; } virtual unsigned int offset586(int) { return offset = 586; } virtual unsigned int offset587(int) { return offset = 587; } virtual unsigned int offset588(int) { return offset = 588; } virtual unsigned int offset589(int) { return offset = 589; } virtual unsigned int offset590(int) { return offset = 590; } virtual unsigned int offset591(int) { return offset = 591; } virtual unsigned int offset592(int) { return offset = 592; } virtual unsigned int offset593(int) { return offset = 593; } virtual unsigned int offset594(int) { return offset = 594; } virtual unsigned int offset595(int) { return offset = 595; } virtual unsigned int offset596(int) { return offset = 596; } virtual unsigned int offset597(int) { return offset = 597; } virtual unsigned int offset598(int) { return offset = 598; } virtual unsigned int offset599(int) { return offset = 599; } virtual unsigned int offset600(int) { return offset = 600; } virtual unsigned int offset601(int) { return offset = 601; } virtual unsigned int offset602(int) { return offset = 602; } virtual unsigned int offset603(int) { return offset = 603; } virtual unsigned int offset604(int) { return offset = 604; } virtual unsigned int offset605(int) { return offset = 605; } virtual unsigned int offset606(int) { return offset = 606; } virtual unsigned int offset607(int) { return offset = 607; } virtual unsigned int offset608(int) { return offset = 608; } virtual unsigned int offset609(int) { return offset = 609; } virtual unsigned int offset610(int) { return offset = 610; } virtual unsigned int offset611(int) { return offset = 611; } virtual unsigned int offset612(int) { return offset = 612; } virtual unsigned int offset613(int) { return offset = 613; } virtual unsigned int offset614(int) { return offset = 614; } virtual unsigned int offset615(int) { return offset = 615; } virtual unsigned int offset616(int) { return offset = 616; } virtual unsigned int offset617(int) { return offset = 617; } virtual unsigned int offset618(int) { return offset = 618; } virtual unsigned int offset619(int) { return offset = 619; } virtual unsigned int offset620(int) { return offset = 620; } virtual unsigned int offset621(int) { return offset = 621; } virtual unsigned int offset622(int) { return offset = 622; } virtual unsigned int offset623(int) { return offset = 623; } virtual unsigned int offset624(int) { return offset = 624; } virtual unsigned int offset625(int) { return offset = 625; } virtual unsigned int offset626(int) { return offset = 626; } virtual unsigned int offset627(int) { return offset = 627; } virtual unsigned int offset628(int) { return offset = 628; } virtual unsigned int offset629(int) { return offset = 629; } virtual unsigned int offset630(int) { return offset = 630; } virtual unsigned int offset631(int) { return offset = 631; } virtual unsigned int offset632(int) { return offset = 632; } virtual unsigned int offset633(int) { return offset = 633; } virtual unsigned int offset634(int) { return offset = 634; } virtual unsigned int offset635(int) { return offset = 635; } virtual unsigned int offset636(int) { return offset = 636; } virtual unsigned int offset637(int) { return offset = 637; } virtual unsigned int offset638(int) { return offset = 638; } virtual unsigned int offset639(int) { return offset = 639; } virtual unsigned int offset640(int) { return offset = 640; } virtual unsigned int offset641(int) { return offset = 641; } virtual unsigned int offset642(int) { return offset = 642; } virtual unsigned int offset643(int) { return offset = 643; } virtual unsigned int offset644(int) { return offset = 644; } virtual unsigned int offset645(int) { return offset = 645; } virtual unsigned int offset646(int) { return offset = 646; } virtual unsigned int offset647(int) { return offset = 647; } virtual unsigned int offset648(int) { return offset = 648; } virtual unsigned int offset649(int) { return offset = 649; } virtual unsigned int offset650(int) { return offset = 650; } virtual unsigned int offset651(int) { return offset = 651; } virtual unsigned int offset652(int) { return offset = 652; } virtual unsigned int offset653(int) { return offset = 653; } virtual unsigned int offset654(int) { return offset = 654; } virtual unsigned int offset655(int) { return offset = 655; } virtual unsigned int offset656(int) { return offset = 656; } virtual unsigned int offset657(int) { return offset = 657; } virtual unsigned int offset658(int) { return offset = 658; } virtual unsigned int offset659(int) { return offset = 659; } virtual unsigned int offset660(int) { return offset = 660; } virtual unsigned int offset661(int) { return offset = 661; } virtual unsigned int offset662(int) { return offset = 662; } virtual unsigned int offset663(int) { return offset = 663; } virtual unsigned int offset664(int) { return offset = 664; } virtual unsigned int offset665(int) { return offset = 665; } virtual unsigned int offset666(int) { return offset = 666; } virtual unsigned int offset667(int) { return offset = 667; } virtual unsigned int offset668(int) { return offset = 668; } virtual unsigned int offset669(int) { return offset = 669; } virtual unsigned int offset670(int) { return offset = 670; } virtual unsigned int offset671(int) { return offset = 671; } virtual unsigned int offset672(int) { return offset = 672; } virtual unsigned int offset673(int) { return offset = 673; } virtual unsigned int offset674(int) { return offset = 674; } virtual unsigned int offset675(int) { return offset = 675; } virtual unsigned int offset676(int) { return offset = 676; } virtual unsigned int offset677(int) { return offset = 677; } virtual unsigned int offset678(int) { return offset = 678; } virtual unsigned int offset679(int) { return offset = 679; } virtual unsigned int offset680(int) { return offset = 680; } virtual unsigned int offset681(int) { return offset = 681; } virtual unsigned int offset682(int) { return offset = 682; } virtual unsigned int offset683(int) { return offset = 683; } virtual unsigned int offset684(int) { return offset = 684; } virtual unsigned int offset685(int) { return offset = 685; } virtual unsigned int offset686(int) { return offset = 686; } virtual unsigned int offset687(int) { return offset = 687; } virtual unsigned int offset688(int) { return offset = 688; } virtual unsigned int offset689(int) { return offset = 689; } virtual unsigned int offset690(int) { return offset = 690; } virtual unsigned int offset691(int) { return offset = 691; } virtual unsigned int offset692(int) { return offset = 692; } virtual unsigned int offset693(int) { return offset = 693; } virtual unsigned int offset694(int) { return offset = 694; } virtual unsigned int offset695(int) { return offset = 695; } virtual unsigned int offset696(int) { return offset = 696; } virtual unsigned int offset697(int) { return offset = 697; } virtual unsigned int offset698(int) { return offset = 698; } virtual unsigned int offset699(int) { return offset = 699; } virtual unsigned int offset700(int) { return offset = 700; } virtual unsigned int offset701(int) { return offset = 701; } virtual unsigned int offset702(int) { return offset = 702; } virtual unsigned int offset703(int) { return offset = 703; } virtual unsigned int offset704(int) { return offset = 704; } virtual unsigned int offset705(int) { return offset = 705; } virtual unsigned int offset706(int) { return offset = 706; } virtual unsigned int offset707(int) { return offset = 707; } virtual unsigned int offset708(int) { return offset = 708; } virtual unsigned int offset709(int) { return offset = 709; } virtual unsigned int offset710(int) { return offset = 710; } virtual unsigned int offset711(int) { return offset = 711; } virtual unsigned int offset712(int) { return offset = 712; } virtual unsigned int offset713(int) { return offset = 713; } virtual unsigned int offset714(int) { return offset = 714; } virtual unsigned int offset715(int) { return offset = 715; } virtual unsigned int offset716(int) { return offset = 716; } virtual unsigned int offset717(int) { return offset = 717; } virtual unsigned int offset718(int) { return offset = 718; } virtual unsigned int offset719(int) { return offset = 719; } virtual unsigned int offset720(int) { return offset = 720; } virtual unsigned int offset721(int) { return offset = 721; } virtual unsigned int offset722(int) { return offset = 722; } virtual unsigned int offset723(int) { return offset = 723; } virtual unsigned int offset724(int) { return offset = 724; } virtual unsigned int offset725(int) { return offset = 725; } virtual unsigned int offset726(int) { return offset = 726; } virtual unsigned int offset727(int) { return offset = 727; } virtual unsigned int offset728(int) { return offset = 728; } virtual unsigned int offset729(int) { return offset = 729; } virtual unsigned int offset730(int) { return offset = 730; } virtual unsigned int offset731(int) { return offset = 731; } virtual unsigned int offset732(int) { return offset = 732; } virtual unsigned int offset733(int) { return offset = 733; } virtual unsigned int offset734(int) { return offset = 734; } virtual unsigned int offset735(int) { return offset = 735; } virtual unsigned int offset736(int) { return offset = 736; } virtual unsigned int offset737(int) { return offset = 737; } virtual unsigned int offset738(int) { return offset = 738; } virtual unsigned int offset739(int) { return offset = 739; } virtual unsigned int offset740(int) { return offset = 740; } virtual unsigned int offset741(int) { return offset = 741; } virtual unsigned int offset742(int) { return offset = 742; } virtual unsigned int offset743(int) { return offset = 743; } virtual unsigned int offset744(int) { return offset = 744; } virtual unsigned int offset745(int) { return offset = 745; } virtual unsigned int offset746(int) { return offset = 746; } virtual unsigned int offset747(int) { return offset = 747; } virtual unsigned int offset748(int) { return offset = 748; } virtual unsigned int offset749(int) { return offset = 749; } virtual unsigned int offset750(int) { return offset = 750; } virtual unsigned int offset751(int) { return offset = 751; } virtual unsigned int offset752(int) { return offset = 752; } virtual unsigned int offset753(int) { return offset = 753; } virtual unsigned int offset754(int) { return offset = 754; } virtual unsigned int offset755(int) { return offset = 755; } virtual unsigned int offset756(int) { return offset = 756; } virtual unsigned int offset757(int) { return offset = 757; } virtual unsigned int offset758(int) { return offset = 758; } virtual unsigned int offset759(int) { return offset = 759; } virtual unsigned int offset760(int) { return offset = 760; } virtual unsigned int offset761(int) { return offset = 761; } virtual unsigned int offset762(int) { return offset = 762; } virtual unsigned int offset763(int) { return offset = 763; } virtual unsigned int offset764(int) { return offset = 764; } virtual unsigned int offset765(int) { return offset = 765; } virtual unsigned int offset766(int) { return offset = 766; } virtual unsigned int offset767(int) { return offset = 767; } virtual unsigned int offset768(int) { return offset = 768; } virtual unsigned int offset769(int) { return offset = 769; } virtual unsigned int offset770(int) { return offset = 770; } virtual unsigned int offset771(int) { return offset = 771; } virtual unsigned int offset772(int) { return offset = 772; } virtual unsigned int offset773(int) { return offset = 773; } virtual unsigned int offset774(int) { return offset = 774; } virtual unsigned int offset775(int) { return offset = 775; } virtual unsigned int offset776(int) { return offset = 776; } virtual unsigned int offset777(int) { return offset = 777; } virtual unsigned int offset778(int) { return offset = 778; } virtual unsigned int offset779(int) { return offset = 779; } virtual unsigned int offset780(int) { return offset = 780; } virtual unsigned int offset781(int) { return offset = 781; } virtual unsigned int offset782(int) { return offset = 782; } virtual unsigned int offset783(int) { return offset = 783; } virtual unsigned int offset784(int) { return offset = 784; } virtual unsigned int offset785(int) { return offset = 785; } virtual unsigned int offset786(int) { return offset = 786; } virtual unsigned int offset787(int) { return offset = 787; } virtual unsigned int offset788(int) { return offset = 788; } virtual unsigned int offset789(int) { return offset = 789; } virtual unsigned int offset790(int) { return offset = 790; } virtual unsigned int offset791(int) { return offset = 791; } virtual unsigned int offset792(int) { return offset = 792; } virtual unsigned int offset793(int) { return offset = 793; } virtual unsigned int offset794(int) { return offset = 794; } virtual unsigned int offset795(int) { return offset = 795; } virtual unsigned int offset796(int) { return offset = 796; } virtual unsigned int offset797(int) { return offset = 797; } virtual unsigned int offset798(int) { return offset = 798; } virtual unsigned int offset799(int) { return offset = 799; } virtual unsigned int offset800(int) { return offset = 800; } virtual unsigned int offset801(int) { return offset = 801; } virtual unsigned int offset802(int) { return offset = 802; } virtual unsigned int offset803(int) { return offset = 803; } virtual unsigned int offset804(int) { return offset = 804; } virtual unsigned int offset805(int) { return offset = 805; } virtual unsigned int offset806(int) { return offset = 806; } virtual unsigned int offset807(int) { return offset = 807; } virtual unsigned int offset808(int) { return offset = 808; } virtual unsigned int offset809(int) { return offset = 809; } virtual unsigned int offset810(int) { return offset = 810; } virtual unsigned int offset811(int) { return offset = 811; } virtual unsigned int offset812(int) { return offset = 812; } virtual unsigned int offset813(int) { return offset = 813; } virtual unsigned int offset814(int) { return offset = 814; } virtual unsigned int offset815(int) { return offset = 815; } virtual unsigned int offset816(int) { return offset = 816; } virtual unsigned int offset817(int) { return offset = 817; } virtual unsigned int offset818(int) { return offset = 818; } virtual unsigned int offset819(int) { return offset = 819; } virtual unsigned int offset820(int) { return offset = 820; } virtual unsigned int offset821(int) { return offset = 821; } virtual unsigned int offset822(int) { return offset = 822; } virtual unsigned int offset823(int) { return offset = 823; } virtual unsigned int offset824(int) { return offset = 824; } virtual unsigned int offset825(int) { return offset = 825; } virtual unsigned int offset826(int) { return offset = 826; } virtual unsigned int offset827(int) { return offset = 827; } virtual unsigned int offset828(int) { return offset = 828; } virtual unsigned int offset829(int) { return offset = 829; } virtual unsigned int offset830(int) { return offset = 830; } virtual unsigned int offset831(int) { return offset = 831; } virtual unsigned int offset832(int) { return offset = 832; } virtual unsigned int offset833(int) { return offset = 833; } virtual unsigned int offset834(int) { return offset = 834; } virtual unsigned int offset835(int) { return offset = 835; } virtual unsigned int offset836(int) { return offset = 836; } virtual unsigned int offset837(int) { return offset = 837; } virtual unsigned int offset838(int) { return offset = 838; } virtual unsigned int offset839(int) { return offset = 839; } virtual unsigned int offset840(int) { return offset = 840; } virtual unsigned int offset841(int) { return offset = 841; } virtual unsigned int offset842(int) { return offset = 842; } virtual unsigned int offset843(int) { return offset = 843; } virtual unsigned int offset844(int) { return offset = 844; } virtual unsigned int offset845(int) { return offset = 845; } virtual unsigned int offset846(int) { return offset = 846; } virtual unsigned int offset847(int) { return offset = 847; } virtual unsigned int offset848(int) { return offset = 848; } virtual unsigned int offset849(int) { return offset = 849; } virtual unsigned int offset850(int) { return offset = 850; } virtual unsigned int offset851(int) { return offset = 851; } virtual unsigned int offset852(int) { return offset = 852; } virtual unsigned int offset853(int) { return offset = 853; } virtual unsigned int offset854(int) { return offset = 854; } virtual unsigned int offset855(int) { return offset = 855; } virtual unsigned int offset856(int) { return offset = 856; } virtual unsigned int offset857(int) { return offset = 857; } virtual unsigned int offset858(int) { return offset = 858; } virtual unsigned int offset859(int) { return offset = 859; } virtual unsigned int offset860(int) { return offset = 860; } virtual unsigned int offset861(int) { return offset = 861; } virtual unsigned int offset862(int) { return offset = 862; } virtual unsigned int offset863(int) { return offset = 863; } virtual unsigned int offset864(int) { return offset = 864; } virtual unsigned int offset865(int) { return offset = 865; } virtual unsigned int offset866(int) { return offset = 866; } virtual unsigned int offset867(int) { return offset = 867; } virtual unsigned int offset868(int) { return offset = 868; } virtual unsigned int offset869(int) { return offset = 869; } virtual unsigned int offset870(int) { return offset = 870; } virtual unsigned int offset871(int) { return offset = 871; } virtual unsigned int offset872(int) { return offset = 872; } virtual unsigned int offset873(int) { return offset = 873; } virtual unsigned int offset874(int) { return offset = 874; } virtual unsigned int offset875(int) { return offset = 875; } virtual unsigned int offset876(int) { return offset = 876; } virtual unsigned int offset877(int) { return offset = 877; } virtual unsigned int offset878(int) { return offset = 878; } virtual unsigned int offset879(int) { return offset = 879; } virtual unsigned int offset880(int) { return offset = 880; } virtual unsigned int offset881(int) { return offset = 881; } virtual unsigned int offset882(int) { return offset = 882; } virtual unsigned int offset883(int) { return offset = 883; } virtual unsigned int offset884(int) { return offset = 884; } virtual unsigned int offset885(int) { return offset = 885; } virtual unsigned int offset886(int) { return offset = 886; } virtual unsigned int offset887(int) { return offset = 887; } virtual unsigned int offset888(int) { return offset = 888; } virtual unsigned int offset889(int) { return offset = 889; } virtual unsigned int offset890(int) { return offset = 890; } virtual unsigned int offset891(int) { return offset = 891; } virtual unsigned int offset892(int) { return offset = 892; } virtual unsigned int offset893(int) { return offset = 893; } virtual unsigned int offset894(int) { return offset = 894; } virtual unsigned int offset895(int) { return offset = 895; } virtual unsigned int offset896(int) { return offset = 896; } virtual unsigned int offset897(int) { return offset = 897; } virtual unsigned int offset898(int) { return offset = 898; } virtual unsigned int offset899(int) { return offset = 899; } virtual unsigned int offset900(int) { return offset = 900; } virtual unsigned int offset901(int) { return offset = 901; } virtual unsigned int offset902(int) { return offset = 902; } virtual unsigned int offset903(int) { return offset = 903; } virtual unsigned int offset904(int) { return offset = 904; } virtual unsigned int offset905(int) { return offset = 905; } virtual unsigned int offset906(int) { return offset = 906; } virtual unsigned int offset907(int) { return offset = 907; } virtual unsigned int offset908(int) { return offset = 908; } virtual unsigned int offset909(int) { return offset = 909; } virtual unsigned int offset910(int) { return offset = 910; } virtual unsigned int offset911(int) { return offset = 911; } virtual unsigned int offset912(int) { return offset = 912; } virtual unsigned int offset913(int) { return offset = 913; } virtual unsigned int offset914(int) { return offset = 914; } virtual unsigned int offset915(int) { return offset = 915; } virtual unsigned int offset916(int) { return offset = 916; } virtual unsigned int offset917(int) { return offset = 917; } virtual unsigned int offset918(int) { return offset = 918; } virtual unsigned int offset919(int) { return offset = 919; } virtual unsigned int offset920(int) { return offset = 920; } virtual unsigned int offset921(int) { return offset = 921; } virtual unsigned int offset922(int) { return offset = 922; } virtual unsigned int offset923(int) { return offset = 923; } virtual unsigned int offset924(int) { return offset = 924; } virtual unsigned int offset925(int) { return offset = 925; } virtual unsigned int offset926(int) { return offset = 926; } virtual unsigned int offset927(int) { return offset = 927; } virtual unsigned int offset928(int) { return offset = 928; } virtual unsigned int offset929(int) { return offset = 929; } virtual unsigned int offset930(int) { return offset = 930; } virtual unsigned int offset931(int) { return offset = 931; } virtual unsigned int offset932(int) { return offset = 932; } virtual unsigned int offset933(int) { return offset = 933; } virtual unsigned int offset934(int) { return offset = 934; } virtual unsigned int offset935(int) { return offset = 935; } virtual unsigned int offset936(int) { return offset = 936; } virtual unsigned int offset937(int) { return offset = 937; } virtual unsigned int offset938(int) { return offset = 938; } virtual unsigned int offset939(int) { return offset = 939; } virtual unsigned int offset940(int) { return offset = 940; } virtual unsigned int offset941(int) { return offset = 941; } virtual unsigned int offset942(int) { return offset = 942; } virtual unsigned int offset943(int) { return offset = 943; } virtual unsigned int offset944(int) { return offset = 944; } virtual unsigned int offset945(int) { return offset = 945; } virtual unsigned int offset946(int) { return offset = 946; } virtual unsigned int offset947(int) { return offset = 947; } virtual unsigned int offset948(int) { return offset = 948; } virtual unsigned int offset949(int) { return offset = 949; } virtual unsigned int offset950(int) { return offset = 950; } virtual unsigned int offset951(int) { return offset = 951; } virtual unsigned int offset952(int) { return offset = 952; } virtual unsigned int offset953(int) { return offset = 953; } virtual unsigned int offset954(int) { return offset = 954; } virtual unsigned int offset955(int) { return offset = 955; } virtual unsigned int offset956(int) { return offset = 956; } virtual unsigned int offset957(int) { return offset = 957; } virtual unsigned int offset958(int) { return offset = 958; } virtual unsigned int offset959(int) { return offset = 959; } virtual unsigned int offset960(int) { return offset = 960; } virtual unsigned int offset961(int) { return offset = 961; } virtual unsigned int offset962(int) { return offset = 962; } virtual unsigned int offset963(int) { return offset = 963; } virtual unsigned int offset964(int) { return offset = 964; } virtual unsigned int offset965(int) { return offset = 965; } virtual unsigned int offset966(int) { return offset = 966; } virtual unsigned int offset967(int) { return offset = 967; } virtual unsigned int offset968(int) { return offset = 968; } virtual unsigned int offset969(int) { return offset = 969; } virtual unsigned int offset970(int) { return offset = 970; } virtual unsigned int offset971(int) { return offset = 971; } virtual unsigned int offset972(int) { return offset = 972; } virtual unsigned int offset973(int) { return offset = 973; } virtual unsigned int offset974(int) { return offset = 974; } virtual unsigned int offset975(int) { return offset = 975; } virtual unsigned int offset976(int) { return offset = 976; } virtual unsigned int offset977(int) { return offset = 977; } virtual unsigned int offset978(int) { return offset = 978; } virtual unsigned int offset979(int) { return offset = 979; } virtual unsigned int offset980(int) { return offset = 980; } virtual unsigned int offset981(int) { return offset = 981; } virtual unsigned int offset982(int) { return offset = 982; } virtual unsigned int offset983(int) { return offset = 983; } virtual unsigned int offset984(int) { return offset = 984; } virtual unsigned int offset985(int) { return offset = 985; } virtual unsigned int offset986(int) { return offset = 986; } virtual unsigned int offset987(int) { return offset = 987; } virtual unsigned int offset988(int) { return offset = 988; } virtual unsigned int offset989(int) { return offset = 989; } virtual unsigned int offset990(int) { return offset = 990; } virtual unsigned int offset991(int) { return offset = 991; } virtual unsigned int offset992(int) { return offset = 992; } virtual unsigned int offset993(int) { return offset = 993; } virtual unsigned int offset994(int) { return offset = 994; } virtual unsigned int offset995(int) { return offset = 995; } virtual unsigned int offset996(int) { return offset = 996; } virtual unsigned int offset997(int) { return offset = 997; } virtual unsigned int offset998(int) { return offset = 998; } virtual unsigned int offset999(int) { return offset = 999; } virtual unsigned int offset1000(int) { return offset = 1000; } }; } namespace fakeit { template TARGET union_cast(SOURCE source) { union { SOURCE source; TARGET target; } u; u.source = source; return u.target; } } namespace fakeit { class NoVirtualDtor { }; class VTUtils { public: template static unsigned int getOffset(R (C::*vMethod)(arglist...)) { auto sMethod = reinterpret_cast(vMethod); VirtualOffsetSelector offsetSelctor; return (offsetSelctor.*sMethod)(0); } template static typename std::enable_if::value, unsigned int>::type getDestructorOffset() { VirtualOffsetSelector offsetSelctor; union_cast(&offsetSelctor)->~C(); return offsetSelctor.offset; } template static typename std::enable_if::value, unsigned int>::type getDestructorOffset() { throw NoVirtualDtor(); } template static unsigned int getVTSize() { struct Derrived : public C { virtual void endOfVt() { } }; unsigned int vtSize = getOffset(&Derrived::endOfVt); return vtSize; } }; } #ifdef _MSC_VER namespace fakeit { typedef unsigned long DWORD; struct TypeDescriptor { TypeDescriptor() : ptrToVTable(0), spare(0) { int **tiVFTPtr = (int **) (&typeid(void)); int *i = (int *) tiVFTPtr[0]; char *type_info_vft_ptr = (char *) i; ptrToVTable = type_info_vft_ptr; } char *ptrToVTable; DWORD spare; char name[8]; }; struct PMD { int mdisp; int pdisp; int vdisp; PMD() : mdisp(0), pdisp(-1), vdisp(0) { } }; struct RTTIBaseClassDescriptor { RTTIBaseClassDescriptor() : pTypeDescriptor(nullptr), numContainedBases(0), attributes(0) { } const std::type_info *pTypeDescriptor; DWORD numContainedBases; struct PMD where; DWORD attributes; }; template struct RTTIClassHierarchyDescriptor { RTTIClassHierarchyDescriptor() : signature(0), attributes(0), numBaseClasses(0), pBaseClassArray(nullptr) { pBaseClassArray = new RTTIBaseClassDescriptor *[1 + sizeof...(baseclasses)]; addBaseClass < C, baseclasses...>(); } ~RTTIClassHierarchyDescriptor() { for (int i = 0; i < 1 + sizeof...(baseclasses); i++) { RTTIBaseClassDescriptor *desc = pBaseClassArray[i]; delete desc; } delete[] pBaseClassArray; } DWORD signature; DWORD attributes; DWORD numBaseClasses; RTTIBaseClassDescriptor **pBaseClassArray; template void addBaseClass() { static_assert(std::is_base_of::value, "C must be a derived class of BaseType"); RTTIBaseClassDescriptor *desc = new RTTIBaseClassDescriptor(); desc->pTypeDescriptor = &typeid(BaseType); pBaseClassArray[numBaseClasses] = desc; for (unsigned int i = 0; i < numBaseClasses; i++) { pBaseClassArray[i]->numContainedBases++; } numBaseClasses++; } template void addBaseClass() { static_assert(std::is_base_of::value, "invalid inheritance list"); addBaseClass(); addBaseClass(); } }; template struct RTTICompleteObjectLocator { #ifdef _WIN64 RTTICompleteObjectLocator(const std::type_info &unused) : signature(0), offset(0), cdOffset(0), typeDescriptorOffset(0), classDescriptorOffset(0) { } DWORD signature; DWORD offset; DWORD cdOffset; DWORD typeDescriptorOffset; DWORD classDescriptorOffset; #else RTTICompleteObjectLocator(const std::type_info &info) : signature(0), offset(0), cdOffset(0), pTypeDescriptor(&info), pClassDescriptor(new RTTIClassHierarchyDescriptor()) { } ~RTTICompleteObjectLocator() { delete pClassDescriptor; } DWORD signature; DWORD offset; DWORD cdOffset; const std::type_info *pTypeDescriptor; struct RTTIClassHierarchyDescriptor *pClassDescriptor; #endif }; struct VirtualTableBase { static VirtualTableBase &getVTable(void *instance) { fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); return *vt; } VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } void *getCookie(int index) { return _firstMethod[-2 - index]; } void setCookie(int index, void *value) { _firstMethod[-2 - index] = value; } void *getMethod(unsigned int index) const { return _firstMethod[index]; } void setMethod(unsigned int index, void *method) { _firstMethod[index] = method; } protected: void **_firstMethod; }; template struct VirtualTable : public VirtualTableBase { class Handle { friend struct VirtualTable; void **firstMethod; Handle(void **method) : firstMethod(method) { } public: VirtualTable &restore() { VirtualTable *vt = (VirtualTable *) this; return *vt; } }; static VirtualTable &getVTable(C &instance) { fakeit::VirtualTable *vt = (fakeit::VirtualTable *) (&instance); return *vt; } void copyFrom(VirtualTable &from) { unsigned int size = VTUtils::getVTSize(); for (unsigned int i = 0; i < size; i++) { _firstMethod[i] = from.getMethod(i); } } VirtualTable() : VirtualTable(buildVTArray()) { } ~VirtualTable() { } void dispose() { _firstMethod--; RTTICompleteObjectLocator *locator = (RTTICompleteObjectLocator *) _firstMethod[0]; delete locator; _firstMethod -= numOfCookies; delete[] _firstMethod; } unsigned int dtor(int) { C *c = (C *) this; C &cRef = *c; auto vt = VirtualTable::getVTable(cRef); void *dtorPtr = vt.getCookie(numOfCookies - 1); void(*method)(C *) = reinterpret_cast(dtorPtr); method(c); return 0; } void setDtor(void *method) { void *dtorPtr = union_cast(&VirtualTable::dtor); unsigned int index = VTUtils::getDestructorOffset(); _firstMethod[index] = dtorPtr; setCookie(numOfCookies - 1, method); } unsigned int getSize() { return VTUtils::getVTSize(); } void initAll(void *value) { auto size = getSize(); for (unsigned int i = 0; i < size; i++) { setMethod(i, value); } } Handle createHandle() { Handle h(_firstMethod); return h; } private: class SimpleType { }; static_assert(sizeof(unsigned int (SimpleType::*)()) == sizeof(unsigned int (C::*)()), "Can't mock a type with multiple inheritance or with non-polymorphic base class"); static const unsigned int numOfCookies = 3; static void **buildVTArray() { int vtSize = VTUtils::getVTSize(); auto array = new void *[vtSize + numOfCookies + 1]{}; RTTICompleteObjectLocator *objectLocator = new RTTICompleteObjectLocator( typeid(C)); array += numOfCookies; array[0] = objectLocator; array++; return array; } VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { } }; } #else #ifndef __clang__ #include #include namespace fakeit { template class has_one_base { }; template class has_one_base> : public std::false_type { }; template class has_one_base> : public has_one_base::type> { }; template<> class has_one_base> : public std::true_type { }; template class is_simple_inheritance_layout : public has_one_base::type> { }; } #endif namespace fakeit { struct VirtualTableBase { static VirtualTableBase &getVTable(void *instance) { fakeit::VirtualTableBase *vt = (fakeit::VirtualTableBase *) (instance); return *vt; } VirtualTableBase(void **firstMethod) : _firstMethod(firstMethod) { } void *getCookie(int index) { return _firstMethod[-3 - index]; } void setCookie(int index, void *value) { _firstMethod[-3 - index] = value; } void *getMethod(unsigned int index) const { return _firstMethod[index]; } void setMethod(unsigned int index, void *method) { _firstMethod[index] = method; } protected: void **_firstMethod; }; template struct VirtualTable : public VirtualTableBase { #ifndef __clang__ static_assert(is_simple_inheritance_layout::value, "Can't mock a type with multiple inheritance"); #endif class Handle { friend struct VirtualTable; void **firstMethod; Handle(void **method) : firstMethod(method) { } public: VirtualTable &restore() { VirtualTable *vt = (VirtualTable *) this; return *vt; } }; static VirtualTable &getVTable(C &instance) { fakeit::VirtualTable *vt = (fakeit::VirtualTable *) (&instance); return *vt; } void copyFrom(VirtualTable &from) { unsigned int size = VTUtils::getVTSize(); for (size_t i = 0; i < size; ++i) { _firstMethod[i] = from.getMethod(i); } } VirtualTable() : VirtualTable(buildVTArray()) { } void dispose() { _firstMethod--; _firstMethod--; _firstMethod -= numOfCookies; delete[] _firstMethod; } unsigned int dtor(int) { C *c = (C *) this; C &cRef = *c; auto vt = VirtualTable::getVTable(cRef); unsigned int index = VTUtils::getDestructorOffset(); void *dtorPtr = vt.getMethod(index); void(*method)(C *) = union_cast(dtorPtr); method(c); return 0; } void setDtor(void *method) { unsigned int index = VTUtils::getDestructorOffset(); void *dtorPtr = union_cast(&VirtualTable::dtor); _firstMethod[index] = method; _firstMethod[index + 1] = dtorPtr; } unsigned int getSize() { return VTUtils::getVTSize(); } void initAll(void *value) { unsigned int size = getSize(); for (unsigned int i = 0; i < size; i++) { setMethod(i, value); } } const std::type_info *getTypeId() { return (const std::type_info *) (_firstMethod[-1]); } Handle createHandle() { Handle h(_firstMethod); return h; } private: static const unsigned int numOfCookies = 2; static void **buildVTArray() { int size = VTUtils::getVTSize(); auto array = new void *[size + 2 + numOfCookies]{}; array += numOfCookies; array++; array[0] = const_cast(&typeid(C)); array++; return array; } VirtualTable(void **firstMethod) : VirtualTableBase(firstMethod) { } }; } #endif namespace fakeit { struct NoMoreRecordedActionException { }; template struct MethodInvocationHandler : Destructible { virtual R handleMethodInvocation(const typename fakeit::production_arg::type... args) = 0; }; } #include namespace fakeit { #ifdef __GNUG__ #ifndef __clang__ #pragma GCC diagnostic ignored "-Wpedantic" #endif #endif #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4200 ) #endif template class FakeObject { VirtualTable vtable; static const size_t SIZE = sizeof(C) - sizeof(VirtualTable); char instanceArea[SIZE ? SIZE : 0]; FakeObject(FakeObject const &) = delete; FakeObject &operator=(FakeObject const &) = delete; public: FakeObject() : vtable() { initializeDataMembersArea(); } ~FakeObject() { vtable.dispose(); } void initializeDataMembersArea() { for (size_t i = 0; i < SIZE; ++i) instanceArea[i] = (char) 0; } void setMethod(unsigned int index, void *method) { vtable.setMethod(index, method); } VirtualTable &getVirtualTable() { return vtable; } void setVirtualTable(VirtualTable &t) { vtable = t; } void setDtor(void *dtor) { vtable.setDtor(dtor); } }; #ifdef _MSC_VER #pragma warning( pop ) #endif #ifdef __GNUG__ #ifndef __clang__ #pragma GCC diagnostic pop #endif #endif } namespace fakeit { struct MethodProxy { MethodProxy(unsigned int id, unsigned int offset, void *vMethod) : _id(id), _offset(offset), _vMethod(vMethod) { } unsigned int getOffset() const { return _offset; } unsigned int getId() const { return _id; } void *getProxy() const { return union_cast(_vMethod); } private: unsigned int _id; unsigned int _offset; void *_vMethod; }; } #include namespace fakeit { struct InvocationHandlerCollection { static const unsigned int VT_COOKIE_INDEX = 0; virtual Destructible *getInvocatoinHandlerPtrById(unsigned int index) = 0; static InvocationHandlerCollection *getInvocationHandlerCollection(void *instance) { VirtualTableBase &vt = VirtualTableBase::getVTable(instance); InvocationHandlerCollection *invocationHandlerCollection = (InvocationHandlerCollection *) vt.getCookie( InvocationHandlerCollection::VT_COOKIE_INDEX); return invocationHandlerCollection; } }; template class MethodProxyCreator { public: template MethodProxy createMethodProxy(unsigned int offset) { return MethodProxy(id, offset, union_cast(&MethodProxyCreator::methodProxyX < id > )); } protected: R methodProxy(unsigned int id, const typename fakeit::production_arg::type... args) { InvocationHandlerCollection *invocationHandlerCollection = InvocationHandlerCollection::getInvocationHandlerCollection( this); MethodInvocationHandler *invocationHandler = (MethodInvocationHandler *) invocationHandlerCollection->getInvocatoinHandlerPtrById( id); return invocationHandler->handleMethodInvocation(std::forward::type>(args)...); } template R methodProxyX(arglist ... args) { return methodProxy(id, std::forward::type>(args)...); } }; } namespace fakeit { class InvocationHandlers : public InvocationHandlerCollection { std::vector> &_methodMocks; std::vector &_offsets; unsigned int getOffset(unsigned int id) const { unsigned int offset = 0; for (; offset < _offsets.size(); offset++) { if (_offsets[offset] == id) { break; } } return offset; } public: InvocationHandlers( std::vector> &methodMocks, std::vector &offsets) : _methodMocks(methodMocks), _offsets(offsets) { } Destructible *getInvocatoinHandlerPtrById(unsigned int id) override { unsigned int offset = getOffset(id); std::shared_ptr ptr = _methodMocks[offset]; return ptr.get(); } }; template struct DynamicProxy { static_assert(std::is_polymorphic::value, "DynamicProxy requires a polymorphic type"); DynamicProxy(C &inst) : instance(inst), originalVtHandle(VirtualTable::getVTable(instance).createHandle()), _methodMocks(VTUtils::getVTSize()), _offsets(VTUtils::getVTSize()), _invocationHandlers(_methodMocks, _offsets) { _cloneVt.copyFrom(originalVtHandle.restore()); _cloneVt.setCookie(InvocationHandlerCollection::VT_COOKIE_INDEX, &_invocationHandlers); getFake().setVirtualTable(_cloneVt); } void detach() { getFake().setVirtualTable(originalVtHandle.restore()); } ~DynamicProxy() { _cloneVt.dispose(); } C &get() { return instance; } void Reset() { _methodMocks = {}; _methodMocks.resize(VTUtils::getVTSize()); _members = {}; _offsets = {}; _offsets.resize(VTUtils::getVTSize()); _cloneVt.copyFrom(originalVtHandle.restore()); } void Clear() { } template void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler *methodInvocationHandler) { auto offset = VTUtils::getOffset(vMethod); MethodProxyCreator creator; bind(creator.template createMethodProxy(offset), methodInvocationHandler); } void stubDtor(MethodInvocationHandler *methodInvocationHandler) { auto offset = VTUtils::getDestructorOffset(); MethodProxyCreator creator; bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler); } template bool isMethodStubbed(R(C::*vMethod)(arglist...)) { unsigned int offset = VTUtils::getOffset(vMethod); return isBinded(offset); } bool isDtorStubbed() { unsigned int offset = VTUtils::getDestructorOffset(); return isBinded(offset); } template Destructible *getMethodMock(R(C::*vMethod)(arglist...)) { auto offset = VTUtils::getOffset(vMethod); std::shared_ptr ptr = _methodMocks[offset]; return ptr.get(); } Destructible *getDtorMock() { auto offset = VTUtils::getDestructorOffset(); std::shared_ptr ptr = _methodMocks[offset]; return ptr.get(); } template void stubDataMember(DATA_TYPE C::*member, const arglist &... initargs) { DATA_TYPE C::*theMember = (DATA_TYPE C::*) member; C &mock = get(); DATA_TYPE *memberPtr = &(mock.*theMember); _members.push_back( std::shared_ptr > {new DataMemeberWrapper < DATA_TYPE, arglist...>(memberPtr, initargs...)}); } template void getMethodMocks(std::vector &into) const { for (std::shared_ptr ptr : _methodMocks) { DATA_TYPE p = dynamic_cast(ptr.get()); if (p) { into.push_back(p); } } } VirtualTable &getOriginalVT() { VirtualTable &vt = originalVtHandle.restore(); return vt; } private: template class DataMemeberWrapper : public Destructible { private: DATA_TYPE *dataMember; public: DataMemeberWrapper(DATA_TYPE *dataMem, const arglist &... initargs) : dataMember(dataMem) { new(dataMember) DATA_TYPE{initargs ...}; } ~DataMemeberWrapper() override { dataMember->~DATA_TYPE(); } }; static_assert(sizeof(C) == sizeof(FakeObject), "This is a problem"); C &instance; typename VirtualTable::Handle originalVtHandle; VirtualTable _cloneVt; std::vector> _methodMocks; std::vector> _members; std::vector _offsets; InvocationHandlers _invocationHandlers; FakeObject &getFake() { return reinterpret_cast &>(instance); } void bind(const MethodProxy &methodProxy, Destructible *invocationHandler) { getFake().setMethod(methodProxy.getOffset(), methodProxy.getProxy()); _methodMocks[methodProxy.getOffset()].reset(invocationHandler); _offsets[methodProxy.getOffset()] = methodProxy.getId(); } void bindDtor(const MethodProxy &methodProxy, Destructible *invocationHandler) { getFake().setDtor(methodProxy.getProxy()); _methodMocks[methodProxy.getOffset()].reset(invocationHandler); _offsets[methodProxy.getOffset()] = methodProxy.getId(); } template DATA_TYPE getMethodMock(unsigned int offset) { std::shared_ptr ptr = _methodMocks[offset]; return dynamic_cast(ptr.get()); } template void checkMultipleInheritance() { C *ptr = (C *) (unsigned int) 1; BaseClass *basePtr = ptr; int delta = (unsigned long) basePtr - (unsigned long) ptr; if (delta > 0) { throw std::invalid_argument(std::string("multiple inheritance is not supported")); } } bool isBinded(unsigned int offset) { std::shared_ptr ptr = _methodMocks[offset]; return ptr.get() != nullptr; } }; } #include #include #include #include #include #include #include #include namespace fakeit { template struct apply_func { template static R applyTuple(std::function f, std::tuple &t, Args &... args) { return apply_func::template applyTuple(f, t, std::get(t), args...); } }; template<> struct apply_func < 0 > { template static R applyTuple(std::function f, std::tuple & , Args &... args) { return f(args...); } }; struct TupleDispatcher { template static R applyTuple(std::function f, std::tuple &t) { return apply_func::template applyTuple(f, t); } template static R invoke(std::function func, const std::tuple &arguments) { std::tuple &args = const_cast &>(arguments); return applyTuple(func, args); } template static void for_each(TupleType &&, FunctionType &, std::integral_constant::type>::value>) { } template::type>::value>::type> static void for_each(TupleType &&t, FunctionType &f, std::integral_constant) { f(I, std::get < I >(t)); for_each(std::forward < TupleType >(t), f, std::integral_constant()); } template static void for_each(TupleType &&t, FunctionType &f) { for_each(std::forward < TupleType >(t), f, std::integral_constant()); } template static void for_each(TupleType1 &&, TupleType2 &&, FunctionType &, std::integral_constant::type>::value>) { } template::type>::value>::type> static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f, std::integral_constant) { f(I, std::get < I >(t), std::get < I >(t2)); for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant()); } template static void for_each(TupleType1 &&t, TupleType2 &&t2, FunctionType &f) { for_each(std::forward < TupleType1 >(t), std::forward < TupleType2 >(t2), f, std::integral_constant()); } }; } namespace fakeit { template struct ActualInvocationHandler : Destructible { virtual R handleMethodInvocation(ArgumentsTuple & args) = 0; }; } #include #include #include #include #include #include namespace fakeit { struct DefaultValueInstatiationException { virtual ~DefaultValueInstatiationException() = default; virtual std::string what() const = 0; }; template struct is_constructible_type { static const bool value = std::is_default_constructible::type>::value && !std::is_abstract::type>::value; }; template struct DefaultValue; template struct DefaultValue::value>::type> { static C &value() { if (std::is_reference::value) { typename naked_type::type *ptr = nullptr; return *ptr; } class Exception : public DefaultValueInstatiationException { virtual std::string what() const override { return (std::string("Type ") + std::string(typeid(C).name()) + std::string( " is not default constructible. Could not instantiate a default return value")).c_str(); } }; throw Exception(); } }; template struct DefaultValue::value>::type> { static C &value() { static typename naked_type::type val{}; return val; } }; template<> struct DefaultValue { static void value() { return; } }; template<> struct DefaultValue { static bool &value() { static bool value{false}; return value; } }; template<> struct DefaultValue { static char &value() { static char value{0}; return value; } }; template<> struct DefaultValue { static char16_t &value() { static char16_t value{0}; return value; } }; template<> struct DefaultValue { static char32_t &value() { static char32_t value{0}; return value; } }; template<> struct DefaultValue { static wchar_t &value() { static wchar_t value{0}; return value; } }; template<> struct DefaultValue { static short &value() { static short value{0}; return value; } }; template<> struct DefaultValue { static int &value() { static int value{0}; return value; } }; template<> struct DefaultValue { static long &value() { static long value{0}; return value; } }; template<> struct DefaultValue { static long long &value() { static long long value{0}; return value; } }; template<> struct DefaultValue { static std::string &value() { static std::string value{}; return value; } }; } namespace fakeit { struct IMatcher : Destructible { ~IMatcher() = default; virtual std::string format() const = 0; }; template struct TypedMatcher : IMatcher { virtual bool matches(const T &actual) const = 0; }; template struct TypedMatcherCreator { virtual ~TypedMatcherCreator() = default; virtual TypedMatcher *createMatcher() const = 0; }; template struct ComparisonMatcherCreator : public TypedMatcherCreator { virtual ~ComparisonMatcherCreator() = default; ComparisonMatcherCreator(const T &arg) : _expected(arg) { } struct Matcher : public TypedMatcher { Matcher(const T &expected) : _expected(expected) { } const T _expected; }; const T &_expected; }; namespace internal { template struct TypedAnyMatcher : public TypedMatcherCreator { virtual ~TypedAnyMatcher() = default; TypedAnyMatcher() { } struct Matcher : public TypedMatcher { virtual bool matches(const T &) const override { return true; } virtual std::string format() const override { return "Any"; } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(); } }; template struct EqMatcherCreator : public ComparisonMatcherCreator { virtual ~EqMatcherCreator() = default; EqMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual std::string format() const override { return TypeFormatter::format(this->_expected); } virtual bool matches(const T &actual) const override { return actual == this->_expected; } }; virtual TypedMatcher *createMatcher() const { return new Matcher(this->_expected); } }; template struct GtMatcherCreator : public ComparisonMatcherCreator { virtual ~GtMatcherCreator() = default; GtMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual > this->_expected; } virtual std::string format() const override { return std::string(">") + TypeFormatter::format(this->_expected); } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(this->_expected); } }; template struct GeMatcherCreator : public ComparisonMatcherCreator { virtual ~GeMatcherCreator() = default; GeMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual >= this->_expected; } virtual std::string format() const override { return std::string(">=") + TypeFormatter::format(this->_expected); } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(this->_expected); } }; template struct LtMatcherCreator : public ComparisonMatcherCreator { virtual ~LtMatcherCreator() = default; LtMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual < this->_expected; } virtual std::string format() const override { return std::string("<") + TypeFormatter::format(this->_expected); } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(this->_expected); } }; template struct LeMatcherCreator : public ComparisonMatcherCreator { virtual ~LeMatcherCreator() = default; LeMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual <= this->_expected; } virtual std::string format() const override { return std::string("<=") + TypeFormatter::format(this->_expected); } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(this->_expected); } }; template struct NeMatcherCreator : public ComparisonMatcherCreator { virtual ~NeMatcherCreator() = default; NeMatcherCreator(const T &expected) : ComparisonMatcherCreator(expected) { } struct Matcher : public ComparisonMatcherCreator::Matcher { Matcher(const T &expected) : ComparisonMatcherCreator::Matcher(expected) { } virtual bool matches(const T &actual) const override { return actual != this->_expected; } virtual std::string format() const override { return std::string("!=") + TypeFormatter::format(this->_expected); } }; virtual TypedMatcher *createMatcher() const override { return new Matcher(this->_expected); } }; } struct AnyMatcher { } static _; template internal::TypedAnyMatcher Any() { internal::TypedAnyMatcher rv; return rv; } template internal::EqMatcherCreator Eq(const T &arg) { internal::EqMatcherCreator rv(arg); return rv; } template internal::GtMatcherCreator Gt(const T &arg) { internal::GtMatcherCreator rv(arg); return rv; } template internal::GeMatcherCreator Ge(const T &arg) { internal::GeMatcherCreator rv(arg); return rv; } template internal::LtMatcherCreator Lt(const T &arg) { internal::LtMatcherCreator rv(arg); return rv; } template internal::LeMatcherCreator Le(const T &arg) { internal::LeMatcherCreator rv(arg); return rv; } template internal::NeMatcherCreator Ne(const T &arg) { internal::NeMatcherCreator rv(arg); return rv; } } namespace fakeit { template struct ArgumentsMatcherInvocationMatcher : public ActualInvocation::Matcher { virtual ~ArgumentsMatcherInvocationMatcher() { for (unsigned int i = 0; i < _matchers.size(); i++) delete _matchers[i]; } ArgumentsMatcherInvocationMatcher(const std::vector &args) : _matchers(args) { } virtual bool matches(ActualInvocation &invocation) override { if (invocation.getActualMatcher() == this) return true; return matches(invocation.getActualArguments()); } virtual std::string format() const override { std::ostringstream out; out << "("; for (unsigned int i = 0; i < _matchers.size(); i++) { if (i > 0) out << ", "; IMatcher *m = dynamic_cast(_matchers[i]); out << m->format(); } out << ")"; return out.str(); } private: struct MatchingLambda { MatchingLambda(const std::vector &matchers) : _matchers(matchers) { } template void operator()(int index, A &actualArg) { TypedMatcher::type> *matcher = dynamic_cast::type> *>(_matchers[index]); if (_matching) _matching = matcher->matches(actualArg); } bool isMatching() { return _matching; } private: bool _matching = true; const std::vector &_matchers; }; virtual bool matches(ArgumentsTuple& actualArguments) { MatchingLambda l(_matchers); fakeit::TupleDispatcher::for_each(actualArguments, l); return l.isMatching(); } const std::vector _matchers; }; template struct UserDefinedInvocationMatcher : ActualInvocation::Matcher { virtual ~UserDefinedInvocationMatcher() = default; UserDefinedInvocationMatcher(std::function match) : matcher{match} { } virtual bool matches(ActualInvocation &invocation) override { if (invocation.getActualMatcher() == this) return true; return matches(invocation.getActualArguments()); } virtual std::string format() const override { return {"( user defined matcher )"}; } private: virtual bool matches(ArgumentsTuple& actualArguments) { return TupleDispatcher::invoke::type...>(matcher, actualArguments); } const std::function matcher; }; template struct DefaultInvocationMatcher : public ActualInvocation::Matcher { virtual ~DefaultInvocationMatcher() = default; DefaultInvocationMatcher() { } virtual bool matches(ActualInvocation &invocation) override { return matches(invocation.getActualArguments()); } virtual std::string format() const override { return {"( Any arguments )"}; } private: virtual bool matches(const ArgumentsTuple&) { return true; } }; } namespace fakeit { template class RecordedMethodBody : public MethodInvocationHandler, public ActualInvocationsSource, public ActualInvocationsContainer { struct MatchedInvocationHandler : ActualInvocationHandler { virtual ~MatchedInvocationHandler() = default; MatchedInvocationHandler(typename ActualInvocation::Matcher *matcher, ActualInvocationHandler *invocationHandler) : _matcher{matcher}, _invocationHandler{invocationHandler} { } virtual R handleMethodInvocation(ArgumentsTuple & args) override { Destructible &destructable = *_invocationHandler; ActualInvocationHandler &invocationHandler = dynamic_cast &>(destructable); return invocationHandler.handleMethodInvocation(args); } typename ActualInvocation::Matcher &getMatcher() const { Destructible &destructable = *_matcher; typename ActualInvocation::Matcher &matcher = dynamic_cast::Matcher &>(destructable); return matcher; } private: std::shared_ptr _matcher; std::shared_ptr _invocationHandler; }; FakeitContext &_fakeit; MethodInfo _method; std::vector> _invocationHandlers; std::vector> _actualInvocations; MatchedInvocationHandler *buildMatchedInvocationHandler( typename ActualInvocation::Matcher *invocationMatcher, ActualInvocationHandler *invocationHandler) { return new MatchedInvocationHandler(invocationMatcher, invocationHandler); } MatchedInvocationHandler *getInvocationHandlerForActualArgs(ActualInvocation &invocation) { for (auto i = _invocationHandlers.rbegin(); i != _invocationHandlers.rend(); ++i) { std::shared_ptr curr = *i; Destructible &destructable = *curr; MatchedInvocationHandler &im = asMatchedInvocationHandler(destructable); if (im.getMatcher().matches(invocation)) { return &im; } } return nullptr; } MatchedInvocationHandler &asMatchedInvocationHandler(Destructible &destructable) { MatchedInvocationHandler &im = dynamic_cast(destructable); return im; } ActualInvocation &asActualInvocation(Destructible &destructable) const { ActualInvocation &invocation = dynamic_cast &>(destructable); return invocation; } public: RecordedMethodBody(FakeitContext &fakeit, std::string name) : _fakeit(fakeit), _method{MethodInfo::nextMethodOrdinal(), name} { } virtual ~RecordedMethodBody() NO_THROWS { } MethodInfo &getMethod() { return _method; } bool isOfMethod(MethodInfo &method) { return method.id() == _method.id(); } void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, ActualInvocationHandler *invocationHandler) { ActualInvocationHandler *mock = buildMatchedInvocationHandler(matcher, invocationHandler); std::shared_ptr destructable{mock}; _invocationHandlers.push_back(destructable); } void reset() { _invocationHandlers.clear(); _actualInvocations.clear(); } void clear() override { _actualInvocations.clear(); } R handleMethodInvocation(const typename fakeit::production_arg::type... args) override { unsigned int ordinal = Invocation::nextInvocationOrdinal(); MethodInfo &method = this->getMethod(); auto actualInvocation = new ActualInvocation(ordinal, method, std::forward::type>(args)...); std::shared_ptr actualInvocationDtor{actualInvocation}; auto invocationHandler = getInvocationHandlerForActualArgs(*actualInvocation); if (invocationHandler) { auto &matcher = invocationHandler->getMatcher(); actualInvocation->setActualMatcher(&matcher); _actualInvocations.push_back(actualInvocationDtor); try { return invocationHandler->handleMethodInvocation(actualInvocation->getActualArguments()); } catch (NoMoreRecordedActionException &) { } } UnexpectedMethodCallEvent event(UnexpectedType::Unmatched, *actualInvocation); _fakeit.handle(event); std::string format{_fakeit.format(event)}; UnexpectedMethodCallException e(format); throw e; } void scanActualInvocations(const std::function &)> &scanner) { for (auto destructablePtr : _actualInvocations) { ActualInvocation &invocation = asActualInvocation(*destructablePtr); scanner(invocation); } } void getActualInvocations(std::unordered_set &into) const override { for (auto destructablePtr : _actualInvocations) { Invocation &invocation = asActualInvocation(*destructablePtr); into.insert(&invocation); } } void setMethodDetails(const std::string &mockName, const std::string &methodName) { const std::string fullName{mockName + "." + methodName}; _method.setName(fullName); } }; } #include #include #include #include #include #include namespace fakeit { struct Quantity { Quantity(const int q) : quantity(q) { } const int quantity; } static Once(1); template struct Quantifier : public Quantity { Quantifier(const int q, const R &val) : Quantity(q), value(val) { } const R &value; }; template<> struct Quantifier : public Quantity { explicit Quantifier(const int q) : Quantity(q) { } }; struct QuantifierFunctor : public Quantifier { QuantifierFunctor(const int q) : Quantifier(q) { } template Quantifier operator()(const R &value) { return Quantifier(quantity, value); } }; template struct Times : public Quantity { Times() : Quantity(q) { } template static Quantifier of(const R &value) { return Quantifier(q, value); } static Quantifier Void() { return Quantifier(q); } }; #if defined (__GNUG__) || (_MSC_VER >= 1900) inline QuantifierFunctor operator "" _Times(unsigned long long n) { return QuantifierFunctor((int) n); } inline QuantifierFunctor operator "" _Time(unsigned long long n) { if (n != 1) throw std::invalid_argument("Only 1_Time is supported. Use X_Times (with s) if X is bigger than 1"); return QuantifierFunctor((int) n); } #endif } #include #include #include #include namespace fakeit { template struct Action : Destructible { virtual R invoke(const ArgumentsTuple &) = 0; virtual bool isDone() = 0; }; template struct Repeat : Action { virtual ~Repeat() = default; Repeat(std::function::type...)> func) : f(func), times(1) { } Repeat(std::function::type...)> func, long t) : f(func), times(t) { } virtual R invoke(const ArgumentsTuple & args) override { times--; return TupleDispatcher::invoke(f, args); } virtual bool isDone() override { return times == 0; } private: std::function::type...)> f; long times; }; template struct RepeatForever : public Action { virtual ~RepeatForever() = default; RepeatForever(std::function::type...)> func) : f(func) { } virtual R invoke(const ArgumentsTuple & args) override { return TupleDispatcher::invoke(f, args); } virtual bool isDone() override { return false; } private: std::function::type...)> f; }; template struct ReturnDefaultValue : public Action { virtual ~ReturnDefaultValue() = default; virtual R invoke(const ArgumentsTuple &) override { return DefaultValue::value(); } virtual bool isDone() override { return false; } }; template struct ReturnDelegateValue : public Action { ReturnDelegateValue(std::function::type...)> delegate) : _delegate(delegate) { } virtual ~ReturnDelegateValue() = default; virtual R invoke(const ArgumentsTuple & args) override { return TupleDispatcher::invoke(_delegate, args); } virtual bool isDone() override { return false; } private: std::function::type...)> _delegate; }; } namespace fakeit { template struct MethodStubbingProgress { virtual ~MethodStubbingProgress() THROWS { } template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { return Do([r](const typename fakeit::test_arg::type...) -> R { return r; }); } template typename std::enable_if::value, MethodStubbingProgress &>::type Return(const R &r) { return Do([&r](const typename fakeit::test_arg::type...) -> R { return r; }); } MethodStubbingProgress & Return(const Quantifier &q) { const R &value = q.value; auto method = [value](const arglist &...) -> R { return value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Return(const first &f, const second &s, const tail &... t) { Return(f); return Return(s, t...); } template typename std::enable_if::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([r](const typename fakeit::test_arg::type...) -> R { return r; }); } template typename std::enable_if::value, void>::type AlwaysReturn(const R &r) { return AlwaysDo([&r](const typename fakeit::test_arg::type...) -> R { return r; }); } MethodStubbingProgress & Return() { return Do([](const typename fakeit::test_arg::type...) -> R { return DefaultValue::value(); }); } void AlwaysReturn() { return AlwaysDo([](const typename fakeit::test_arg::type...) -> R { return DefaultValue::value(); }); } template MethodStubbingProgress &Throw(const E &e) { return Do([e](const typename fakeit::test_arg::type...) -> R { throw e; }); } template MethodStubbingProgress & Throw(const Quantifier &q) { const E &value = q.value; auto method = [value](const arglist &...) -> R { throw value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template void AlwaysThrow(const E &e) { return AlwaysDo([e](const typename fakeit::test_arg::type...) -> R { throw e; }); } virtual MethodStubbingProgress & Do(std::function::type...)> method) { return DoImpl(new Repeat(method)); } template MethodStubbingProgress & Do(const Quantifier &q) { return DoImpl(new Repeat(q.value, q.quantity)); } template MethodStubbingProgress & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function::type...)> method) { DoImpl(new RepeatForever(method)); } protected: virtual MethodStubbingProgress &DoImpl(Action *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; }; template struct MethodStubbingProgress { virtual ~MethodStubbingProgress() THROWS { } MethodStubbingProgress &Return() { auto lambda = [](const typename fakeit::test_arg::type...) -> void { return DefaultValue::value(); }; return Do(lambda); } virtual MethodStubbingProgress &Do( std::function::type...)> method) { return DoImpl(new Repeat(method)); } void AlwaysReturn() { return AlwaysDo([](const typename fakeit::test_arg::type...) -> void { return DefaultValue::value(); }); } MethodStubbingProgress & Return(const Quantifier &q) { auto method = [](const arglist &...) -> void { return DefaultValue::value(); }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress &Throw(const E &e) { return Do([e](const typename fakeit::test_arg::type...) -> void { throw e; }); } template MethodStubbingProgress & Throw(const Quantifier &q) { const E &value = q.value; auto method = [value](const typename fakeit::test_arg::type...) -> void { throw value; }; return DoImpl(new Repeat(method, q.quantity)); } template MethodStubbingProgress & Throw(const first &f, const second &s, const tail &... t) { Throw(f); return Throw(s, t...); } template void AlwaysThrow(const E e) { return AlwaysDo([e](const typename fakeit::test_arg::type...) -> void { throw e; }); } template MethodStubbingProgress & Do(const Quantifier &q) { return DoImpl(new Repeat(q.value, q.quantity)); } template MethodStubbingProgress & Do(const first &f, const second &s, const tail &... t) { Do(f); return Do(s, t...); } virtual void AlwaysDo(std::function::type...)> method) { DoImpl(new RepeatForever(method)); } protected: virtual MethodStubbingProgress &DoImpl(Action *action) = 0; private: MethodStubbingProgress &operator=(const MethodStubbingProgress &other) = delete; }; } #include #include namespace fakeit { class Finally { private: std::function _finallyClause; Finally(const Finally &); Finally &operator=(const Finally &); public: explicit Finally(std::function f) : _finallyClause(f) { } ~Finally() { _finallyClause(); } }; } namespace fakeit { template struct ActionSequence : ActualInvocationHandler { ActionSequence() { clear(); } void AppendDo(Action *action) { append(action); } virtual R handleMethodInvocation(ArgumentsTuple & args) override { std::shared_ptr destructablePtr = _recordedActions.front(); Destructible &destructable = *destructablePtr; Action &action = dynamic_cast &>(destructable); std::function finallyClause = [&]() -> void { if (action.isDone()) _recordedActions.erase(_recordedActions.begin()); }; Finally onExit(finallyClause); return action.invoke(args); } private: struct NoMoreRecordedAction : Action { virtual R invoke(const ArgumentsTuple &) override { throw NoMoreRecordedActionException(); } virtual bool isDone() override { return false; } }; void append(Action *action) { std::shared_ptr destructable{action}; _recordedActions.insert(_recordedActions.end() - 1, destructable); } void clear() { _recordedActions.clear(); auto actionPtr = std::shared_ptr {new NoMoreRecordedAction()}; _recordedActions.push_back(actionPtr); } std::vector> _recordedActions; }; } namespace fakeit { template class DataMemberStubbingRoot { private: public: DataMemberStubbingRoot(const DataMemberStubbingRoot &) = default; DataMemberStubbingRoot() = default; void operator=(const DATA_TYPE&) { } }; } #include #include #include #include #include #include #include #include #include namespace fakeit { struct Xaction { virtual void commit() = 0; }; } namespace fakeit { template struct SpyingContext : Xaction { virtual void appendAction(Action *action) = 0; virtual std::function getOriginalMethod() = 0; }; } namespace fakeit { template struct StubbingContext : public Xaction { virtual void appendAction(Action *action) = 0; }; } #include #include #include #include #include #include namespace fakeit { template class MatchersCollector { std::vector &_matchers; public: template using ArgType = typename std::tuple_element>::type; template using NakedArgType = typename naked_type>::type; template using ArgMatcherCreatorType = decltype(std::declval>>()); MatchersCollector(std::vector &matchers) : _matchers(matchers) { } void CollectMatchers() { } template typename std::enable_if< std::is_constructible, Head>::value, void> ::type CollectMatchers(const Head &value) { TypedMatcher> *d = Eq>(value).createMatcher(); _matchers.push_back(d); } template typename std::enable_if< std::is_constructible, Head>::value , void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector c(_matchers); c.CollectMatchers(tail...); } template typename std::enable_if< std::is_base_of>, Head>::value, void> ::type CollectMatchers(const Head &creator) { TypedMatcher> *d = creator.createMatcher(); _matchers.push_back(d); } template typename std::enable_if< std::is_base_of>, Head>::value, void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector c(_matchers); c.CollectMatchers(tail...); } template typename std::enable_if< std::is_same::value, void> ::type CollectMatchers(const Head &) { TypedMatcher> *d = Any>().createMatcher(); _matchers.push_back(d); } template typename std::enable_if< std::is_same::value, void> ::type CollectMatchers(const Head &head, const Tail &... tail) { CollectMatchers(head); MatchersCollector c(_matchers); c.CollectMatchers(tail...); } }; } namespace fakeit { template class MethodMockingContext : public Sequence, public ActualInvocationsSource, public virtual StubbingContext, public virtual SpyingContext, private Invocation::Matcher { public: struct Context : Destructible { virtual typename std::function getOriginalMethod() = 0; virtual std::string getMethodName() = 0; virtual void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, ActualInvocationHandler *invocationHandler) = 0; virtual void scanActualInvocations(const std::function &)> &scanner) = 0; virtual void setMethodDetails(std::string mockName, std::string methodName) = 0; virtual bool isOfMethod(MethodInfo &method) = 0; virtual ActualInvocationsSource &getInvolvedMock() = 0; }; private: class Implementation { Context *_stubbingContext; ActionSequence *_recordedActionSequence; typename ActualInvocation::Matcher *_invocationMatcher; bool _commited; Context &getStubbingContext() const { return *_stubbingContext; } public: Implementation(Context *stubbingContext) : _stubbingContext(stubbingContext), _recordedActionSequence(new ActionSequence()), _invocationMatcher { new DefaultInvocationMatcher()}, _commited(false) { } ~Implementation() { delete _stubbingContext; if (!_commited) { delete _recordedActionSequence; delete _invocationMatcher; } } ActionSequence &getRecordedActionSequence() { return *_recordedActionSequence; } std::string format() const { std::string s = getStubbingContext().getMethodName(); s += _invocationMatcher->format(); return s; } void getActualInvocations(std::unordered_set &into) const { auto scanner = [&](ActualInvocation &a) { if (_invocationMatcher->matches(a)) { into.insert(&a); } }; getStubbingContext().scanActualInvocations(scanner); } bool matches(Invocation &invocation) { MethodInfo &actualMethod = invocation.getMethod(); if (!getStubbingContext().isOfMethod(actualMethod)) { return false; } ActualInvocation &actualInvocation = dynamic_cast &>(invocation); return _invocationMatcher->matches(actualInvocation); } void commit() { getStubbingContext().addMethodInvocationHandler(_invocationMatcher, _recordedActionSequence); _commited = true; } void appendAction(Action *action) { getRecordedActionSequence().AppendDo(action); } void setMethodBodyByAssignment(std::function::type...)> method) { appendAction(new RepeatForever(method)); commit(); } void setMethodDetails(std::string mockName, std::string methodName) { getStubbingContext().setMethodDetails(mockName, methodName); } void getInvolvedMocks(std::vector &into) const { into.push_back(&getStubbingContext().getInvolvedMock()); } typename std::function getOriginalMethod() { return getStubbingContext().getOriginalMethod(); } void setInvocationMatcher(typename ActualInvocation::Matcher *matcher) { delete _invocationMatcher; _invocationMatcher = matcher; } }; protected: MethodMockingContext(Context *stubbingContext) : _impl{new Implementation(stubbingContext)} { } MethodMockingContext(MethodMockingContext &) = default; MethodMockingContext(MethodMockingContext &&other) : _impl(std::move(other._impl)) { } virtual ~MethodMockingContext() NO_THROWS { } std::string format() const override { return _impl->format(); } unsigned int size() const override { return 1; } void getInvolvedMocks(std::vector &into) const override { _impl->getInvolvedMocks(into); } void getExpectedSequence(std::vector &into) const override { const Invocation::Matcher *b = this; Invocation::Matcher *c = const_cast(b); into.push_back(c); } void getActualInvocations(std::unordered_set &into) const override { _impl->getActualInvocations(into); } bool matches(Invocation &invocation) override { return _impl->matches(invocation); } void commit() override { _impl->commit(); } void setMethodDetails(std::string mockName, std::string methodName) { _impl->setMethodDetails(mockName, methodName); } void setMatchingCriteria(std::function predicate) { typename ActualInvocation::Matcher *matcher{ new UserDefinedInvocationMatcher(predicate)}; _impl->setInvocationMatcher(matcher); } void setMatchingCriteria(const std::vector &matchers) { typename ActualInvocation::Matcher *matcher{ new ArgumentsMatcherInvocationMatcher(matchers)}; _impl->setInvocationMatcher(matcher); } void appendAction(Action *action) override { _impl->appendAction(action); } void setMethodBodyByAssignment(std::function::type...)> method) { _impl->setMethodBodyByAssignment(method); } template::type> void setMatchingCriteria(const matcherCreators &... matcherCreator) { std::vector matchers; MatchersCollector<0, arglist...> c(matchers); c.CollectMatchers(matcherCreator...); MethodMockingContext::setMatchingCriteria(matchers); } private: typename std::function getOriginalMethod() override { return _impl->getOriginalMethod(); } std::shared_ptr _impl; }; template class MockingContext : public MethodMockingContext { MockingContext &operator=(const MockingContext &) = delete; public: MockingContext(typename MethodMockingContext::Context *stubbingContext) : MethodMockingContext(stubbingContext) { } MockingContext(MockingContext &) = default; MockingContext(MockingContext &&other) : MethodMockingContext(std::move(other)) { } MockingContext &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext::setMethodDetails(mockName, methodName); return *this; } MockingContext &Using(const arglist &... args) { MethodMockingContext::setMatchingCriteria(args...); return *this; } template MockingContext &Using(const arg_matcher &... arg_matchers) { MethodMockingContext::setMatchingCriteria(arg_matchers...); return *this; } MockingContext &Matching(std::function matcher) { MethodMockingContext::setMatchingCriteria(matcher); return *this; } MockingContext &operator()(const arglist &... args) { MethodMockingContext::setMatchingCriteria(args...); return *this; } MockingContext &operator()(std::function matcher) { MethodMockingContext::setMatchingCriteria(matcher); return *this; } void operator=(std::function method) { MethodMockingContext::setMethodBodyByAssignment(method); } template typename std::enable_if::value, void>::type operator=(const R &r) { auto method = [r](const typename fakeit::test_arg::type...) -> R { return r; }; MethodMockingContext::setMethodBodyByAssignment(method); } template typename std::enable_if::value, void>::type operator=(const R &r) { auto method = [&r](const typename fakeit::test_arg::type...) -> R { return r; }; MethodMockingContext::setMethodBodyByAssignment(method); } }; template class MockingContext : public MethodMockingContext { MockingContext &operator=(const MockingContext &) = delete; public: MockingContext(typename MethodMockingContext::Context *stubbingContext) : MethodMockingContext(stubbingContext) { } MockingContext(MockingContext &) = default; MockingContext(MockingContext &&other) : MethodMockingContext(std::move(other)) { } MockingContext &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext::setMethodDetails(mockName, methodName); return *this; } MockingContext &Using(const arglist &... args) { MethodMockingContext::setMatchingCriteria(args...); return *this; } template MockingContext &Using(const arg_matcher &... arg_matchers) { MethodMockingContext::setMatchingCriteria(arg_matchers...); return *this; } MockingContext &Matching(std::function matcher) { MethodMockingContext::setMatchingCriteria(matcher); return *this; } MockingContext &operator()(const arglist &... args) { MethodMockingContext::setMatchingCriteria(args...); return *this; } MockingContext &operator()(std::function matcher) { MethodMockingContext::setMatchingCriteria(matcher); return *this; } void operator=(std::function method) { MethodMockingContext::setMethodBodyByAssignment(method); } }; class DtorMockingContext : public MethodMockingContext { public: DtorMockingContext(MethodMockingContext::Context *stubbingContext) : MethodMockingContext(stubbingContext) { } DtorMockingContext(DtorMockingContext &other) : MethodMockingContext(other) { } DtorMockingContext(DtorMockingContext &&other) : MethodMockingContext(std::move(other)) { } void operator=(std::function method) { MethodMockingContext::setMethodBodyByAssignment(method); } DtorMockingContext &setMethodDetails(std::string mockName, std::string methodName) { MethodMockingContext::setMethodDetails(mockName, methodName); return *this; } }; } namespace fakeit { template class MockImpl : private MockObject, public virtual ActualInvocationsSource { public: MockImpl(FakeitContext &fakeit, C &obj) : MockImpl(fakeit, obj, true) { } MockImpl(FakeitContext &fakeit) : MockImpl(fakeit, *(createFakeInstance()), false) { FakeObject *fake = reinterpret_cast *>(_instance); fake->getVirtualTable().setCookie(1, this); } virtual ~MockImpl() NO_THROWS { _proxy.detach(); if (_isOwner) { FakeObject *fake = reinterpret_cast *>(_instance); delete fake; } } void detach() { _isOwner = false; _proxy.detach(); } void getActualInvocations(std::unordered_set &into) const override { std::vector vec; _proxy.getMethodMocks(vec); for (ActualInvocationsSource *s : vec) { s->getActualInvocations(into); } } void initDataMembersIfOwner() { if (_isOwner) { FakeObject *fake = reinterpret_cast *>(_instance); fake->initializeDataMembersArea(); } } void reset() { _proxy.Reset(); initDataMembersIfOwner(); } void clear() { std::vector vec; _proxy.getMethodMocks(vec); for (ActualInvocationsContainer *s : vec) { s->clear(); } initDataMembersIfOwner(); } virtual C &get() override { return _proxy.get(); } virtual FakeitContext &getFakeIt() override { return _fakeit; } template::value>::type> DataMemberStubbingRoot stubDataMember(DATA_TYPE T::*member, const arglist &... ctorargs) { _proxy.stubDataMember(member, ctorargs...); return DataMemberStubbingRoot(); } template::value>::type> MockingContext stubMethod(R(T::*vMethod)(arglist...)) { return MockingContext(new UniqueMethodMockingContextImpl < id, R, arglist... > (*this, vMethod)); } DtorMockingContext stubDtor() { return DtorMockingContext(new DtorMockingContextImpl(*this)); } private: DynamicProxy _proxy; C *_instance; bool _isOwner; FakeitContext &_fakeit; template class MethodMockingContextBase : public MethodMockingContext::Context { protected: MockImpl &_mock; virtual RecordedMethodBody &getRecordedMethodBody() = 0; public: MethodMockingContextBase(MockImpl &mock) : _mock(mock) { } virtual ~MethodMockingContextBase() = default; void addMethodInvocationHandler(typename ActualInvocation::Matcher *matcher, ActualInvocationHandler *invocationHandler) { getRecordedMethodBody().addMethodInvocationHandler(matcher, invocationHandler); } void scanActualInvocations(const std::function &)> &scanner) { getRecordedMethodBody().scanActualInvocations(scanner); } void setMethodDetails(std::string mockName, std::string methodName) { getRecordedMethodBody().setMethodDetails(mockName, methodName); } bool isOfMethod(MethodInfo &method) { return getRecordedMethodBody().isOfMethod(method); } ActualInvocationsSource &getInvolvedMock() { return _mock; } std::string getMethodName() { return getRecordedMethodBody().getMethod().name(); } }; template class MethodMockingContextImpl : public MethodMockingContextBase { protected: R (C::*_vMethod)(arglist...); public: virtual ~MethodMockingContextImpl() = default; MethodMockingContextImpl(MockImpl &mock, R (C::*vMethod)(arglist...)) : MethodMockingContextBase(mock), _vMethod(vMethod) { } virtual std::function getOriginalMethod() override { void *mPtr = MethodMockingContextBase::_mock.getOriginalMethod(_vMethod); C * instance = &(MethodMockingContextBase::_mock.get()); return [=](arglist&... args) -> R { auto m = union_cast::type>(mPtr); return m(instance, std::forward(args)...); }; } }; template class UniqueMethodMockingContextImpl : public MethodMockingContextImpl { protected: virtual RecordedMethodBody &getRecordedMethodBody() override { return MethodMockingContextBase::_mock.template stubMethodIfNotStubbed( MethodMockingContextBase::_mock._proxy, MethodMockingContextImpl::_vMethod); } public: UniqueMethodMockingContextImpl(MockImpl &mock, R (C::*vMethod)(arglist...)) : MethodMockingContextImpl(mock, vMethod) { } }; class DtorMockingContextImpl : public MethodMockingContextBase { protected: virtual RecordedMethodBody &getRecordedMethodBody() override { return MethodMockingContextBase::_mock.stubDtorIfNotStubbed( MethodMockingContextBase::_mock._proxy); } public: virtual ~DtorMockingContextImpl() = default; DtorMockingContextImpl(MockImpl &mock) : MethodMockingContextBase(mock) { } virtual std::function getOriginalMethod() override { C &instance = MethodMockingContextBase::_mock.get(); return [=, &instance]() -> void { }; } }; static MockImpl *getMockImpl(void *instance) { FakeObject *fake = reinterpret_cast *>(instance); MockImpl *mock = reinterpret_cast *>(fake->getVirtualTable().getCookie( 1)); return mock; } void unmocked() { ActualInvocation<> invocation(Invocation::nextInvocationOrdinal(), UnknownMethod::instance()); UnexpectedMethodCallEvent event(UnexpectedType::Unmocked, invocation); auto &fakeit = getMockImpl(this)->_fakeit; fakeit.handle(event); std::string format = fakeit.format(event); UnexpectedMethodCallException e(format); throw e; } static C *createFakeInstance() { FakeObject *fake = new FakeObject(); void *unmockedMethodStubPtr = union_cast(&MockImpl::unmocked); fake->getVirtualTable().initAll(unmockedMethodStubPtr); return reinterpret_cast(fake); } template void *getOriginalMethod(R (C::*vMethod)(arglist...)) { auto vt = _proxy.getOriginalVT(); auto offset = VTUtils::getOffset(vMethod); void *origMethodPtr = vt.getMethod(offset); return origMethodPtr; } void *getOriginalDtor() { auto vt = _proxy.getOriginalVT(); auto offset = VTUtils::getDestructorOffset(); void *origMethodPtr = vt.getMethod(offset); return origMethodPtr; } template RecordedMethodBody &stubMethodIfNotStubbed(DynamicProxy &proxy, R (C::*vMethod)(arglist...)) { if (!proxy.isMethodStubbed(vMethod)) { proxy.template stubMethod(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod)); } Destructible *d = proxy.getMethodMock(vMethod); RecordedMethodBody *methodMock = dynamic_cast *>(d); return *methodMock; } RecordedMethodBody &stubDtorIfNotStubbed(DynamicProxy &proxy) { if (!proxy.isDtorStubbed()) { proxy.stubDtor(createRecordedDtorBody(*this)); } Destructible *d = proxy.getDtorMock(); RecordedMethodBody *dtorMock = dynamic_cast *>(d); return *dtorMock; } MockImpl(FakeitContext &fakeit, C &obj, bool isSpy) : _proxy{obj}, _instance(&obj), _isOwner(!isSpy), _fakeit(fakeit) { } template static RecordedMethodBody *createRecordedMethodBody(MockObject &mock, R(C::*vMethod)(arglist...)) { return new RecordedMethodBody(mock.getFakeIt(), typeid(vMethod).name()); } static RecordedMethodBody *createRecordedDtorBody(MockObject &mock) { return new RecordedMethodBody(mock.getFakeIt(), "dtor"); } }; } namespace fakeit { template struct Prototype; template struct Prototype { typedef R Type(Args...); typedef R ConstType(Args...) const; template struct MemberType { typedef Type(C::*type); typedef ConstType(C::*cosntType); static type get(type t) { return t; } static cosntType getconst(cosntType t) { return t; } }; }; template struct UniqueMethod { R (C::*method)(arglist...); UniqueMethod(R (C::*vMethod)(arglist...)) : method(vMethod) { } int uniqueId() { return X; } }; } namespace fakeit { namespace internal { } using namespace fakeit; using namespace fakeit::internal; template class Mock : public ActualInvocationsSource { MockImpl impl; public: virtual ~Mock() = default; static_assert(std::is_polymorphic::value, "Can only mock a polymorphic type"); Mock() : impl(Fakeit) { } explicit Mock(C &obj) : impl(Fakeit, obj) { } virtual C &get() { return impl.get(); } C &operator()() { return get(); } void Reset() { impl.reset(); } void ClearInvocationHistory() { impl.clear(); } template::value>::type> DataMemberStubbingRoot Stub(DATA_TYPE C::* member, const arglist &... ctorargs) { return impl.stubDataMember(member, ctorargs...); } template::value && std::is_base_of::value>::type> MockingContext stub(R (T::*vMethod)(arglist...) const) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...) volatile) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...) const volatile) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...)) { return impl.template stubMethod(vMethod); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...) const) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...) volatile) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...) const volatile) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } template::value && std::is_base_of::value>::type> MockingContext stub(R(T::*vMethod)(arglist...)) { auto methodWithoutConstVolatile = reinterpret_cast(vMethod); return impl.template stubMethod(methodWithoutConstVolatile); } DtorMockingContext dtor() { return impl.stubDtor(); } void getActualInvocations(std::unordered_set &into) const override { impl.getActualInvocations(into); } }; } #include namespace fakeit { class RefCount { private: int count; public: void AddRef() { count++; } int Release() { return --count; } }; template class smart_ptr { private: T *pData; RefCount *reference; public: smart_ptr() : pData(0), reference(0) { reference = new RefCount(); reference->AddRef(); } smart_ptr(T *pValue) : pData(pValue), reference(0) { reference = new RefCount(); reference->AddRef(); } smart_ptr(const smart_ptr &sp) : pData(sp.pData), reference(sp.reference) { reference->AddRef(); } ~smart_ptr() THROWS { if (reference->Release() == 0) { delete reference; delete pData; } } T &operator*() { return *pData; } T *operator->() { return pData; } smart_ptr &operator=(const smart_ptr &sp) { if (this != &sp) { if (reference->Release() == 0) { delete reference; delete pData; } pData = sp.pData; reference = sp.reference; reference->AddRef(); } return *this; } }; } namespace fakeit { class WhenFunctor { struct StubbingChange { friend class WhenFunctor; virtual ~StubbingChange() THROWS { if (std::uncaught_exception()) { return; } _xaction.commit(); } StubbingChange(StubbingChange &other) : _xaction(other._xaction) { } private: StubbingChange(Xaction &xaction) : _xaction(xaction) { } Xaction &_xaction; }; public: template struct MethodProgress : MethodStubbingProgress { friend class WhenFunctor; virtual ~MethodProgress() override = default; MethodProgress(MethodProgress &other) : _progress(other._progress), _context(other._context) { } MethodProgress(StubbingContext &xaction) : _progress(new StubbingChange(xaction)), _context(xaction) { } protected: virtual MethodStubbingProgress &DoImpl(Action *action) override { _context.appendAction(action); return *this; } private: smart_ptr _progress; StubbingContext &_context; }; WhenFunctor() { } template MethodProgress operator()(const StubbingContext &stubbingContext) { StubbingContext &rootWithoutConst = const_cast &>(stubbingContext); MethodProgress progress(rootWithoutConst); return progress; } }; } namespace fakeit { class FakeFunctor { private: template void fake(const StubbingContext &root) { StubbingContext &rootWithoutConst = const_cast &>(root); rootWithoutConst.appendAction(new ReturnDefaultValue()); rootWithoutConst.commit(); } void operator()() { } public: template void operator()(const H &head, const M &... tail) { fake(head); this->operator()(tail...); } }; } #include #include namespace fakeit { struct InvocationUtils { static void sortByInvocationOrder(std::unordered_set &ivocations, std::vector &result) { auto comparator = [](Invocation *a, Invocation *b) -> bool { return a->getOrdinal() < b->getOrdinal(); }; std::set sortedIvocations(comparator); for (auto i : ivocations) sortedIvocations.insert(i); for (auto i : sortedIvocations) result.push_back(i); } static void collectActualInvocations(std::unordered_set &actualInvocations, std::vector &invocationSources) { for (auto source : invocationSources) { source->getActualInvocations(actualInvocations); } } static void selectNonVerifiedInvocations(std::unordered_set &actualInvocations, std::unordered_set &into) { for (auto invocation : actualInvocations) { if (!invocation->isVerified()) { into.insert(invocation); } } } static void collectInvocationSources(std::vector &) { } template static void collectInvocationSources(std::vector &into, const ActualInvocationsSource &mock, const list &... tail) { into.push_back(const_cast(&mock)); collectInvocationSources(into, tail...); } static void collectSequences(std::vector &) { } template static void collectSequences(std::vector &vec, const Sequence &sequence, const list &... tail) { vec.push_back(&const_cast(sequence)); collectSequences(vec, tail...); } static void collectInvolvedMocks(std::vector &allSequences, std::vector &involvedMocks) { for (auto sequence : allSequences) { sequence->getInvolvedMocks(involvedMocks); } } template static T &remove_const(const T &s) { return const_cast(s); } }; } #include #include #include namespace fakeit { struct MatchAnalysis { std::vector actualSequence; std::vector matchedInvocations; int count; void run(InvocationsSourceProxy &involvedInvocationSources, std::vector &expectedPattern) { getActualInvocationSequence(involvedInvocationSources, actualSequence); count = countMatches(expectedPattern, actualSequence, matchedInvocations); } private: static void getActualInvocationSequence(InvocationsSourceProxy &involvedMocks, std::vector &actualSequence) { std::unordered_set actualInvocations; collectActualInvocations(involvedMocks, actualInvocations); InvocationUtils::sortByInvocationOrder(actualInvocations, actualSequence); } static int countMatches(std::vector &pattern, std::vector &actualSequence, std::vector &matchedInvocations) { int end = -1; int count = 0; int startSearchIndex = 0; while (findNextMatch(pattern, actualSequence, startSearchIndex, end, matchedInvocations)) { count++; startSearchIndex = end; } return count; } static void collectActualInvocations(InvocationsSourceProxy &involvedMocks, std::unordered_set &actualInvocations) { involvedMocks.getActualInvocations(actualInvocations); } static bool findNextMatch(std::vector &pattern, std::vector &actualSequence, int startSearchIndex, int &end, std::vector &matchedInvocations) { for (auto sequence : pattern) { int index = findNextMatch(sequence, actualSequence, startSearchIndex); if (index == -1) { return false; } collectMatchedInvocations(actualSequence, matchedInvocations, index, sequence->size()); startSearchIndex = index + sequence->size(); } end = startSearchIndex; return true; } static void collectMatchedInvocations(std::vector &actualSequence, std::vector &matchedInvocations, int start, int length) { int indexAfterMatchedPattern = start + length; for (; start < indexAfterMatchedPattern; start++) { matchedInvocations.push_back(actualSequence[start]); } } static bool isMatch(std::vector &actualSequence, std::vector &expectedSequence, int start) { bool found = true; for (unsigned int j = 0; found && j < expectedSequence.size(); j++) { Invocation *actual = actualSequence[start + j]; Invocation::Matcher *expected = expectedSequence[j]; found = found && expected->matches(*actual); } return found; } static int findNextMatch(Sequence *&pattern, std::vector &actualSequence, int startSearchIndex) { std::vector expectedSequence; pattern->getExpectedSequence(expectedSequence); for (int i = startSearchIndex; i < ((int) actualSequence.size() - (int) expectedSequence.size() + 1); i++) { if (isMatch(actualSequence, expectedSequence, i)) { return i; } } return -1; } }; } namespace fakeit { struct SequenceVerificationExpectation { friend class SequenceVerificationProgress; ~SequenceVerificationExpectation() THROWS { if (std::uncaught_exception()) { return; } VerifyExpectation(_fakeit); } void setExpectedPattern(std::vector expectedPattern) { _expectedPattern = expectedPattern; } void setExpectedCount(const int count) { _expectedCount = count; } void setFileInfo(const char * file, int line, const char * callingMethod) { _file = file; _line = line; _testMethod = callingMethod; } private: VerificationEventHandler &_fakeit; InvocationsSourceProxy _involvedInvocationSources; std::vector _expectedPattern; int _expectedCount; const char * _file; int _line; const char * _testMethod; bool _isVerified; SequenceVerificationExpectation( VerificationEventHandler &fakeit, InvocationsSourceProxy mocks, std::vector &expectedPattern) : _fakeit(fakeit), _involvedInvocationSources(mocks), _expectedPattern(expectedPattern), _expectedCount(-1), _line(0), _isVerified(false) { } void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { if (_isVerified) return; _isVerified = true; MatchAnalysis ma; ma.run(_involvedInvocationSources, _expectedPattern); if (isAtLeastVerification() && atLeastLimitNotReached(ma.count)) { return handleAtLeastVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); } if (isExactVerification() && exactLimitNotMatched(ma.count)) { return handleExactVerificationEvent(verificationErrorHandler, ma.actualSequence, ma.count); } markAsVerified(ma.matchedInvocations); } std::vector &collectSequences(std::vector &vec) { return vec; } template std::vector &collectSequences(std::vector &vec, const Sequence &sequence, const list &... tail) { vec.push_back(&const_cast(sequence)); return collectSequences(vec, tail...); } static void markAsVerified(std::vector &matchedInvocations) { for (auto i : matchedInvocations) { i->markAsVerified(); } } bool isAtLeastVerification() { return _expectedCount < 0; } bool isExactVerification() { return !isAtLeastVerification(); } bool atLeastLimitNotReached(int count) { return count < -_expectedCount; } bool exactLimitNotMatched(int count) { return count != _expectedCount; } void handleExactVerificationEvent(VerificationEventHandler &verificationErrorHandler, std::vector actualSequence, int count) { SequenceVerificationEvent evt(VerificationType::Exact, _expectedPattern, actualSequence, _expectedCount, count); evt.setFileInfo(_file, _line, _testMethod); return verificationErrorHandler.handle(evt); } void handleAtLeastVerificationEvent(VerificationEventHandler &verificationErrorHandler, std::vector actualSequence, int count) { SequenceVerificationEvent evt(VerificationType::AtLeast, _expectedPattern, actualSequence, -_expectedCount, count); evt.setFileInfo(_file, _line, _testMethod); return verificationErrorHandler.handle(evt); } }; } namespace fakeit { class ThrowFalseEventHandler : public VerificationEventHandler { void handle(const SequenceVerificationEvent &) override { throw false; } void handle(const NoMoreInvocationsVerificationEvent &) override { throw false; } }; } #include #include #include namespace fakeit { template static std::string to_string(const T &n) { std::ostringstream stm; stm << n; return stm.str(); } } namespace fakeit { struct FakeitContext; class SequenceVerificationProgress { friend class UsingFunctor; friend class VerifyFunctor; friend class UsingProgress; smart_ptr _expectationPtr; SequenceVerificationProgress(SequenceVerificationExpectation *ptr) : _expectationPtr(ptr) { } SequenceVerificationProgress( FakeitContext &fakeit, InvocationsSourceProxy sources, std::vector &allSequences) : SequenceVerificationProgress(new SequenceVerificationExpectation(fakeit, sources, allSequences)) { } virtual void verifyInvocations(const int times) { _expectationPtr->setExpectedCount(times); } class Terminator { smart_ptr _expectationPtr; bool toBool() { try { ThrowFalseEventHandler eh; _expectationPtr->VerifyExpectation(eh); return true; } catch (bool e) { return e; } } public: Terminator(smart_ptr expectationPtr) : _expectationPtr(expectationPtr) { }; operator bool() { return toBool(); } bool operator!() const { return !const_cast(this)->toBool(); } }; public: ~SequenceVerificationProgress() THROWS { }; operator bool() { return Terminator(_expectationPtr); } bool operator!() const { return !Terminator(_expectationPtr); } Terminator Never() { Exactly(0); return Terminator(_expectationPtr); } Terminator Once() { Exactly(1); return Terminator(_expectationPtr); } Terminator Twice() { Exactly(2); return Terminator(_expectationPtr); } Terminator AtLeastOnce() { verifyInvocations(-1); return Terminator(_expectationPtr); } Terminator Exactly(const int times) { if (times < 0) { throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times))); } verifyInvocations(times); return Terminator(_expectationPtr); } Terminator Exactly(const Quantity &q) { Exactly(q.quantity); return Terminator(_expectationPtr); } Terminator AtLeast(const int times) { if (times < 0) { throw std::invalid_argument(std::string("bad argument times:").append(fakeit::to_string(times))); } verifyInvocations(-times); return Terminator(_expectationPtr); } Terminator AtLeast(const Quantity &q) { AtLeast(q.quantity); return Terminator(_expectationPtr); } SequenceVerificationProgress setFileInfo(const char * file, int line, const char * callingMethod) { _expectationPtr->setFileInfo(file, line, callingMethod); return *this; } }; } namespace fakeit { class UsingProgress { fakeit::FakeitContext &_fakeit; InvocationsSourceProxy _sources; void collectSequences(std::vector &) { } template void collectSequences(std::vector &vec, const fakeit::Sequence &sequence, const list &... tail) { vec.push_back(&const_cast(sequence)); collectSequences(vec, tail...); } public: UsingProgress(fakeit::FakeitContext &fakeit, InvocationsSourceProxy source) : _fakeit(fakeit), _sources(source) { } template SequenceVerificationProgress Verify(const fakeit::Sequence &sequence, const list &... tail) { std::vector allSequences; collectSequences(allSequences, sequence, tail...); SequenceVerificationProgress progress(_fakeit, _sources, allSequences); return progress; } }; } namespace fakeit { class UsingFunctor { friend class VerifyFunctor; FakeitContext &_fakeit; public: UsingFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template UsingProgress operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector allMocks{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; UsingProgress progress(_fakeit, aggregateInvocationsSource); return progress; } }; } #include namespace fakeit { class VerifyFunctor { FakeitContext &_fakeit; public: VerifyFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { std::vector allSequences{&InvocationUtils::remove_const(sequence), &InvocationUtils::remove_const(tail)...}; std::vector involvedSources; InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; UsingProgress usingProgress(_fakeit, aggregateInvocationsSource); return usingProgress.Verify(sequence, tail...); } }; } #include #include namespace fakeit { class VerifyNoOtherInvocationsVerificationProgress { friend class VerifyNoOtherInvocationsFunctor; struct VerifyNoOtherInvocationsExpectation { friend class VerifyNoOtherInvocationsVerificationProgress; ~VerifyNoOtherInvocationsExpectation() THROWS { if (std::uncaught_exception()) { return; } VerifyExpectation(_fakeit); } void setFileInfo(const char * file, int line, const char * callingMethod) { _file = file; _line = line; _callingMethod = callingMethod; } private: VerificationEventHandler &_fakeit; std::vector _mocks; const char * _file; int _line; const char * _callingMethod; bool _isVerified; VerifyNoOtherInvocationsExpectation(VerificationEventHandler &fakeit, std::vector mocks) : _fakeit(fakeit), _mocks(mocks), _line(0), _isVerified(false) { } VerifyNoOtherInvocationsExpectation(VerifyNoOtherInvocationsExpectation &other) = default; void VerifyExpectation(VerificationEventHandler &verificationErrorHandler) { if (_isVerified) return; _isVerified = true; std::unordered_set actualInvocations; InvocationUtils::collectActualInvocations(actualInvocations, _mocks); std::unordered_set nonVerifiedInvocations; InvocationUtils::selectNonVerifiedInvocations(actualInvocations, nonVerifiedInvocations); if (nonVerifiedInvocations.size() > 0) { std::vector sortedNonVerifiedInvocations; InvocationUtils::sortByInvocationOrder(nonVerifiedInvocations, sortedNonVerifiedInvocations); std::vector sortedActualInvocations; InvocationUtils::sortByInvocationOrder(actualInvocations, sortedActualInvocations); NoMoreInvocationsVerificationEvent evt(sortedActualInvocations, sortedNonVerifiedInvocations); evt.setFileInfo(_file, _line, _callingMethod); return verificationErrorHandler.handle(evt); } } }; fakeit::smart_ptr _ptr; VerifyNoOtherInvocationsVerificationProgress(VerifyNoOtherInvocationsExpectation *ptr) : _ptr(ptr) { } VerifyNoOtherInvocationsVerificationProgress(FakeitContext &fakeit, std::vector &invocationSources) : VerifyNoOtherInvocationsVerificationProgress( new VerifyNoOtherInvocationsExpectation(fakeit, invocationSources) ) { } bool toBool() { try { ThrowFalseEventHandler ev; _ptr->VerifyExpectation(ev); return true; } catch (bool e) { return e; } } public: ~VerifyNoOtherInvocationsVerificationProgress() THROWS { }; VerifyNoOtherInvocationsVerificationProgress setFileInfo(const char * file, int line, const char * callingMethod) { _ptr->setFileInfo(file, line, callingMethod); return *this; } operator bool() { return toBool(); } bool operator!() const { return !const_cast(this)->toBool(); } }; } namespace fakeit { class VerifyNoOtherInvocationsFunctor { FakeitContext &_fakeit; public: VerifyNoOtherInvocationsFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } void operator()() { } template VerifyNoOtherInvocationsVerificationProgress operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector invocationSources{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; VerifyNoOtherInvocationsVerificationProgress progress{_fakeit, invocationSources}; return progress; } }; } namespace fakeit { class SpyFunctor { private: template void spy(const SpyingContext &root) { SpyingContext &rootWithoutConst = const_cast &>(root); auto methodFromOriginalVT = rootWithoutConst.getOriginalMethod(); rootWithoutConst.appendAction(new ReturnDelegateValue(methodFromOriginalVT)); rootWithoutConst.commit(); } void operator()() { } public: template void operator()(const H &head, const M &... tail) { spy(head); this->operator()(tail...); } }; } #include #include namespace fakeit { class VerifyUnverifiedFunctor { FakeitContext &_fakeit; public: VerifyUnverifiedFunctor(FakeitContext &fakeit) : _fakeit(fakeit) { } template SequenceVerificationProgress operator()(const Sequence &sequence, const list &... tail) { std::vector allSequences{&InvocationUtils::remove_const(sequence), &InvocationUtils::remove_const(tail)...}; std::vector involvedSources; InvocationUtils::collectInvolvedMocks(allSequences, involvedSources); InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(involvedSources)}; InvocationsSourceProxy unverifiedInvocationsSource{ new UnverifiedInvocationsSource(aggregateInvocationsSource)}; UsingProgress usingProgress(_fakeit, unverifiedInvocationsSource); return usingProgress.Verify(sequence, tail...); } }; class UnverifiedFunctor { public: UnverifiedFunctor(FakeitContext &fakeit) : Verify(fakeit) { } VerifyUnverifiedFunctor Verify; template UnverifiedInvocationsSource operator()(const ActualInvocationsSource &head, const list &... tail) { std::vector allMocks{&InvocationUtils::remove_const(head), &InvocationUtils::remove_const(tail)...}; InvocationsSourceProxy aggregateInvocationsSource{new AggregateInvocationsSource(allMocks)}; UnverifiedInvocationsSource unverifiedInvocationsSource{aggregateInvocationsSource}; return unverifiedInvocationsSource; } }; } namespace fakeit { static UsingFunctor Using(Fakeit); static VerifyFunctor Verify(Fakeit); static VerifyNoOtherInvocationsFunctor VerifyNoOtherInvocations(Fakeit); static UnverifiedFunctor Unverified(Fakeit); static SpyFunctor Spy; static FakeFunctor Fake; static WhenFunctor When; template class SilenceUnusedVariableWarnings { void use(void *) { } SilenceUnusedVariableWarnings() { use(&Fake); use(&When); use(&Spy); use(&Using); use(&Verify); use(&VerifyNoOtherInvocations); use(&_); } }; } #ifdef _MSC_VER #define __func__ __FUNCTION__ #endif #define MOCK_TYPE(mock) \ std::remove_reference::type #define OVERLOADED_METHOD_PTR(mock, method, prototype) \ fakeit::Prototype::MemberType::get(&MOCK_TYPE(mock)::method) #define CONST_OVERLOADED_METHOD_PTR(mock, method, prototype) \ fakeit::Prototype::MemberType::getconst(&MOCK_TYPE(mock)::method) #define Dtor(mock) \ mock.dtor().setMethodDetails(#mock,"destructor") #define Method(mock, method) \ mock.template stub<__COUNTER__>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method) #define OverloadedMethod(mock, method, prototype) \ mock.template stub<__COUNTER__>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define ConstOverloadedMethod(mock, method, prototype) \ mock.template stub<__COUNTER__>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define Verify(...) \ Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) #define Using(...) \ Using( __VA_ARGS__ ) #define VerifyNoOtherInvocations(...) \ VerifyNoOtherInvocations( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) #define Fake(...) \ Fake( __VA_ARGS__ ) #define When(call) \ When(call) #endif ================================================ FILE: ci/.gitattributes ================================================ *.sh test eol=lf ================================================ FILE: ci/build.sh ================================================ #!/bin/sh source /opt/qt511/bin/qt511-env.sh if [ ! -d build ]; then mkdir build fi cd build # build echo Building cmake -DCMAKE_BUILD_TYPE=Release .. && cmake --build . || exit 1 # if succeeds, run unit tests echo Running unit tests ./cliTest/cliTest && ./GuiUnitTest/GuiUnitTest && ./mgraph440Test/mgraph440Test && ./salaTest/salaTest && ./genlibTest/genlibTest && ./depthmapXTest/depthmapXTest && ./moduleTest/moduleTest || exit 1 # if that succeeds, run regression tests echo testing regression test framework cd ../RegressionTest/test && echo pwd && python3.5 -u test_main.py || exit 1 echo running standard regression tests cd .. && pwd && python3.5 -u RegressionTestRunner.py || exit 1 echo running agent test python3.5 -u RegressionTestRunner.py regressionconfig_agents.json || exit 1 # search the modules directory for regression tests and run them for subdir in ../modules/*/; do regressionFile="${subdir}RegressionTest/regressionconfig.json" if [ -e "$regressionFile" ]; then python3.5 -u RegressionTestRunner.py "${regressionFile}" || exit 1 fi done ================================================ FILE: cliTest/CMakeLists.txt ================================================ set(cliTest cliTest) set(cliTest_SRCS main.cpp ../depthmapXcli/printcommunicator.cpp ../depthmapXcli/commandlineparser.cpp testcommandlineparser.cpp testradiusconverter.cpp ../depthmapXcli/radiusconverter.cpp testsimpletimer.cpp testvgaparser.cpp ../depthmapXcli/vgaparser.cpp testlinkparser.cpp ../depthmapXcli/linkparser.cpp testagentparser.cpp ../depthmapXcli/agentparser.cpp testargumentholder.cpp ../depthmapXcli/performancewriter.cpp testperformancewriter.cpp testselfcleaningfile.cpp ../depthmapXcli/runmethods.cpp ../depthmapXcli/modeparserregistry.cpp testvisprepparser.cpp ../depthmapXcli/visprepparser.cpp testaxialparser.cpp ../depthmapXcli/axialparser.cpp testparsingutils.cpp ../depthmapXcli/parsingutils.cpp testisovistparser.cpp ../depthmapXcli/isovistparser.cpp testexportparser.cpp ../depthmapXcli/exportparser.cpp ../depthmapXcli/importparser.cpp testimportparser.cpp ../depthmapXcli/stepdepthparser.cpp teststepdepthparser.cpp ../depthmapXcli/segmentparser.cpp testsegmentparser.cpp ../depthmapXcli/mapconvertparser.cpp testmapconvertparser.cpp) include_directories("../ThirdParty/Catch" "../ThirdParty/FakeIt") set(LINK_LIBS salalib genlib mgraph440) set(modules_cliTest "" CACHE INTERNAL "modules_cliTest" FORCE) set(MODULES_GUI FALSE) set(MODULES_CLI FALSE) set(MODULES_CLI_TEST TRUE) set(MODULES_CORE FALSE) set(MODULES_CORE_TEST FALSE) add_subdirectory(../modules modules) add_executable(${cliTest} ${cliTest_SRCS}) target_link_libraries(${cliTest} ${LINK_LIBS} ${modules_cli} ${modules_cliTest} ${modules_core}) ================================================ FILE: cliTest/argumentholder.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef ARGUMENTHOLDER_H #define ARGUMENTHOLDER_H #include #include class ArgumentHolder{ public: ArgumentHolder(std::initializer_list l ): mArguments(l){ for (auto& arg : mArguments) { mArgv.push_back(arg.data()); } } char** argv() const{ return (char**) mArgv.data(); } size_t argc() const{ return mArgv.size(); } private: std::vector mArguments; std::vector mArgv; }; #endif // ARGUMENTHOLDER_H ================================================ FILE: cliTest/main.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: cliTest/selfcleaningfile.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include class SelfCleaningFile { public: SelfCleaningFile(const std::string &filename) : _filename(filename) {} ~SelfCleaningFile() { std::remove(_filename.c_str()); } const std::string &Filename() { return _filename; } private: const std::string _filename; }; ================================================ FILE: cliTest/testagentparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/agentparser.h" #include "argumentholder.h" #include "selfcleaningfile.h" TEST_CASE("AgentParserFail", "Parsing errors") { // missing arguments SECTION("Missing argument to -am") { AgentParser parser; ArgumentHolder ah{"prog", "-am"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-am requires an argument")); } SECTION("Missing argument to -ats") { AgentParser parser; ArgumentHolder ah{"prog", "-ats"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-ats requires an argument")); } SECTION("Missing argument to -arr") { AgentParser parser; ArgumentHolder ah{"prog", "-arr"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-arr requires an argument")); } SECTION("Missing argument to -afov") { AgentParser parser; ArgumentHolder ah{"prog", "-afov"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-afov requires an argument")); } SECTION("Missing argument to -asteps") { AgentParser parser; ArgumentHolder ah{"prog", "-asteps"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-asteps requires an argument")); } SECTION("Missing argument to -alife") { AgentParser parser; ArgumentHolder ah{"prog", "-alife"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alife requires an argument")); } SECTION("Missing argument to -alife") { AgentParser parser; ArgumentHolder ah{"prog", "-alife"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alife requires an argument")); } SECTION("Missing argument to -alocseed") { AgentParser parser; ArgumentHolder ah{"prog", "-alocseed"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocseed requires an argument")); } SECTION("Missing argument to -alocfile") { AgentParser parser; ArgumentHolder ah{"prog", "-alocfile"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocfile requires an argument")); } SECTION("Missing argument to -aloc") { AgentParser parser; ArgumentHolder ah{"prog", "-aloc"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-aloc requires an argument")); } // rubbish input SECTION("Non-numeric input to -ats") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-ats must be a number >0, got foo")); } SECTION("Non-numeric input to -arr") { AgentParser parser; ArgumentHolder ah{"prog", "-arr", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-arr must be a number >0, got foo")); } SECTION("Non-numeric input to -atrails") { AgentParser parser; ArgumentHolder ah{"prog", "-atrails", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-atrails must be a number >=1 or 0 for all (max possible = 50), got foo")); } SECTION("Non-numeric input to -afov") { AgentParser parser; ArgumentHolder ah{"prog", "-afov", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-afov must be a number between 1 and 32, got foo")); } SECTION("Out of range input to -afov (0)") { AgentParser parser; ArgumentHolder ah{"prog", "-afov", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-afov must be a number between 1 and 32, got 0")); } SECTION("Out of range input to -afov (33)") { AgentParser parser; ArgumentHolder ah{"prog", "-afov", "33"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-afov must be a number between 1 and 32, got 33")); } SECTION("Non-numeric input to -asteps") { AgentParser parser; ArgumentHolder ah{"prog", "-asteps", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-asteps must be a number >0, got foo")); } SECTION("Non-numeric input to -alife") { AgentParser parser; ArgumentHolder ah{"prog", "-alife", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alife must be a number >0, got foo")); } SECTION("Rubbish input to -alocseed") { AgentParser parser; ArgumentHolder ah{"prog", "-alocseed", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid starting location seed provided (foo). Should only contain digits")); } SECTION("Rubbish input to -aloc") { AgentParser parser; ArgumentHolder ah{"prog", "-aloc", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid starting point provided (foo). Should only contain digits dots and commas")); } SECTION("Define graph output twice") { AgentParser parser; ArgumentHolder ah{"prog", "-ot", "graph", "-ot", "graph"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Same output type argument (graph) provided twice")); } SECTION("Define gatecounts output twice") { AgentParser parser; ArgumentHolder ah{"prog", "-ot", "gatecounts", "-ot", "gatecounts"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Same output type argument (gatecounts) provided twice")); } SECTION("Define trails output twice") { AgentParser parser; ArgumentHolder ah{"prog", "-ot", "trails", "-ot", "trails"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Same output type argument (trails) provided twice")); } } TEST_CASE("AgentParserInputFail", "Bad or missing input") { SECTION("-ats not provided") { AgentParser parser; ArgumentHolder ah{"prog", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000", "-alocseed", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Total number of timesteps (-ats ) is required")); } SECTION("-arr not provided") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "5000", "-afov","15", "-asteps", "3", "-alife", "1000", "-alocseed", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Release rate (-arr ) is required")); } SECTION("-afov not provided") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "5000", "-arr", "0.1", "-asteps", "3", "-alife", "1000", "-alocseed", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Agent field-of-view (-afov ) is required")); } SECTION("-asteps not provided") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "5000", "-arr", "0.1", "-afov","15", "-alife", "1000", "-alocseed", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Agent number of steps before turn decision (-asteps ) is required")); } SECTION("-alife not provided") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alocseed", "0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Agent life in timesteps (-alife ) is required")); } SECTION("No random starting poins, manual points or point file provided") { AgentParser parser; ArgumentHolder ah{"prog", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Either -aloc, -alocfile or -alocseed must be given")); } SECTION("Manual points and pointfile provided") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-aloc", "0.1,5.2", "-alocfile", "testpoints.csv", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocfile cannot be used together with -aloc")); } SECTION("Pointfile and manual points provided") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-alocfile", "testpoints.csv", "-aloc", "0.1,5.2", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-aloc cannot be used together with -alocfile")); } SECTION("Manual points and random points provided") { AgentParser parser; ArgumentHolder ah{"prog", "-aloc", "0.1,5.2", "-alocseed", "0", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocseed cannot be used together with -aloc")); } SECTION("Pointfile and random points provided") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-alocfile", "testpoints.csv", "-alocseed", "0", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocseed cannot be used together with -alocfile")); } SECTION("Random points and manual points provided") { AgentParser parser; ArgumentHolder ah{"prog", "-alocseed", "0", "-aloc", "0.1,5.2", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-aloc cannot be used together with -alocseed")); } SECTION("Random points and Pointfile provided") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-alocseed", "0", "-alocfile", "testpoints.csv", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-alocfile cannot be used together with -alocseed")); } SECTION("Non-existing file provided") { AgentParser parser; ArgumentHolder ah{"prog", "-alocfile", "foo.csv", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Failed to load file foo.csv, error")); } SECTION("Malformed pointfile") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-alocfile", "testpoints.csv", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 1")); } SECTION("Malformed point arg") { AgentParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-aloc", "0.1", "-ats", "5000", "-arr", "0.1", "-afov","15", "-asteps", "3", "-alife", "1000"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 0.1")); } } TEST_CASE("AgentParserSuccess", "Read successfully") { AgentParser parser; double x1 = 1.0; double y1 = 2.0; double x2 = 1.1; double y2 = 1.2; int totalTimeSteps = 5000; std::stringstream ats; ats << totalTimeSteps << std::flush; double releaseRate = 0.1; std::stringstream arr; arr << releaseRate << std::flush; int agentFOV = 15; std::stringstream afov; afov << agentFOV << std::flush; int agentStepsBeforeTurnDecision = 3; std::stringstream asteps; asteps << agentStepsBeforeTurnDecision << std::flush; int agentLifeTimesteps = 1000; std::stringstream alife; alife << agentLifeTimesteps << std::flush; SECTION("Random starting locations (points vector should be empty, seed 0)") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0"}; parser.parse(ah.argc(), ah.argv()); auto points = parser.getReleasePoints(); REQUIRE(points.size() == 0); REQUIRE(parser.randomReleaseLocationSeed() == 0); } SECTION("Random starting locations (points vector should be empty, seed 1)") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "1"}; parser.parse(ah.argc(), ah.argv()); auto points = parser.getReleasePoints(); REQUIRE(points.size() == 0); REQUIRE(parser.randomReleaseLocationSeed() == 1); } SECTION("Read from commandline") { std::stringstream p1; p1 << x1 << "," << y1 << std::flush; std::stringstream p2; p2 << x2 << "," << y2 << std::flush; ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-aloc", p1.str(), "-aloc", p2.str()}; parser.parse(ah.argc(), ah.argv()); auto points = parser.getReleasePoints(); REQUIRE(points.size() == 2); REQUIRE(points[0].x == Approx(x1)); REQUIRE(points[0].y == Approx(y1)); REQUIRE(points[1].x == Approx(x2)); REQUIRE(points[1].y == Approx(y2)); } SECTION("Read from file") { SelfCleaningFile scf("testpoints.csv"); { std::ofstream f(scf.Filename().c_str()); f << "x\ty\n" << x1 << "\t" << y1 << "\n" << x2 << "\t" << y2 << "\n" << std::flush; } ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocfile", scf.Filename()}; parser.parse(ah.argc(), ah.argv() ); auto points = parser.getReleasePoints(); REQUIRE(points.size() == 2); REQUIRE(points[0].x == Approx(x1)); REQUIRE(points[0].y == Approx(y1)); REQUIRE(points[1].x == Approx(x2)); REQUIRE(points[1].y == Approx(y2)); } SECTION("Output type not set") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0"}; parser.parse(ah.argc(), ah.argv()); auto outputTypes = parser.outputTypes(); REQUIRE(outputTypes.size() == 0); } SECTION("Set output type to graph") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0", "-ot", "graph"}; parser.parse(ah.argc(), ah.argv()); auto outputTypes = parser.outputTypes(); REQUIRE(outputTypes.size() == 1); REQUIRE(outputTypes[0] == AgentParser::OutputType::GRAPH); } SECTION("Set output type to gatecounts") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0", "-ot", "gatecounts"}; parser.parse(ah.argc(), ah.argv()); auto outputTypes = parser.outputTypes(); REQUIRE(outputTypes.size() == 1); REQUIRE(outputTypes[0] == AgentParser::OutputType::GATECOUNTS); } SECTION("Set output type to trails") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0", "-atrails", "1", "-ot", "trails"}; parser.parse(ah.argc(), ah.argv()); auto noOfTrails = parser.recordTrailsForAgents(); REQUIRE(noOfTrails == 1); auto outputTypes = parser.outputTypes(); REQUIRE(outputTypes.size() == 1); REQUIRE(outputTypes[0] == AgentParser::OutputType::TRAILS); } SECTION("Set two output types") { ArgumentHolder ah{"prog", "-ats", ats.str(), "-arr", arr.str(), "-afov", afov.str(), "-asteps", asteps.str(), "-alife", alife.str(), "-alocseed", "0", "-ot", "graph", "-ot", "gatecounts"}; parser.parse(ah.argc(), ah.argv()); auto outputTypes = parser.outputTypes(); REQUIRE(outputTypes.size() == 2); REQUIRE(outputTypes[0] == AgentParser::OutputType::GRAPH); REQUIRE(outputTypes[1] == AgentParser::OutputType::GATECOUNTS); } REQUIRE(parser.totalSystemTimestemps() == totalTimeSteps); REQUIRE(parser.releaseRate() == Approx(releaseRate)); REQUIRE(parser.agentFOV() == agentFOV); REQUIRE(parser.agentStepsBeforeTurnDecision() == agentStepsBeforeTurnDecision); REQUIRE(parser.agentLifeTimesteps() == agentLifeTimesteps); } ================================================ FILE: cliTest/testargumentholder.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "argumentholder.h" #include TEST_CASE("Test ArgumentHolder", "Constructor") { ArgumentHolder ah{"foo", "bar"}; REQUIRE(ah.argc() == 2); REQUIRE(std::strcmp(ah.argv()[0], "foo") == 0 ); REQUIRE(std::strcmp(ah.argv()[1], "bar") == 0 ); } ================================================ FILE: cliTest/testaxialparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/axialparser.h" #include "argumentholder.h" TEST_CASE("Test mode and help") { AxialParser parser; REQUIRE(parser.getModeName() == "AXIAL"); REQUIRE(parser.getHelp() == "Mode options for Axial Analysis:\n"\ " -xl , Calculate all lines map from this seed point (can be used more than once)\n" " -xf Calculate fewest lines map from all lines map\n"\ " -xa run axial anlysis with specified radii\n"\ " All modes expect to find the required input in the in graph\n"\ " Any combination of flags above can be specified, they will always be run in the order -aa -af -au -ax\n"\ " Further flags for axial analysis are:\n"\ " -xac Include choice (betweenness)\n"\ " -xal Include local measures\n"\ " -xar Include RA, RRA and total depth\n"\ " -xaw perform weighted analysis using this attribute\n"\ "\n"); } TEST_CASE("Test Parsing Exceptions","") { AxialParser parser; SECTION("No axial mode") { ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "No axial analysis mode present" ); } SECTION("Argument missing") { ArgumentHolder ah{"prog", "-xl"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-xl requires an argument" ); } } TEST_CASE("Test mode parsing", "") { AxialParser parser; SECTION("All lines") { ArgumentHolder ah{"prog", "-xl", "1.2,1.5"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.runAllLines()); REQUIRE(parser.getAllAxesRoots().size() == 1); REQUIRE(parser.getAllAxesRoots()[0].x == Approx(1.2)); REQUIRE(parser.getAllAxesRoots()[0].y == Approx(1.5)); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE_FALSE(parser.runAnalysis()); } SECTION("Fewest lines") { ArgumentHolder ah{"prog", "-xf"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.runAllLines()); REQUIRE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE_FALSE(parser.runAnalysis()); } SECTION("Analysis") { ArgumentHolder ah{"prog", "-xa", "n"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.runAllLines()); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE(parser.runAnalysis()); REQUIRE_FALSE(parser.calculateRRA()); REQUIRE_FALSE(parser.useChoice()); REQUIRE_FALSE(parser.useLocal()); } SECTION("Analysis -rra") { ArgumentHolder ah{"prog", "-xa", "n", "-xar"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.runAllLines()); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE(parser.runAnalysis()); REQUIRE(parser.calculateRRA()); REQUIRE_FALSE(parser.useChoice()); REQUIRE_FALSE(parser.useLocal()); } SECTION("Analysis + choice") { ArgumentHolder ah{"prog", "-xa", "n", "-xac"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.runAllLines()); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE(parser.runAnalysis()); REQUIRE_FALSE(parser.calculateRRA()); REQUIRE(parser.useChoice()); REQUIRE_FALSE(parser.useLocal()); } SECTION("Analysis + local") { ArgumentHolder ah{"prog", "-xa", "n", "-xal"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.runAllLines()); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE(parser.runAnalysis()); REQUIRE_FALSE(parser.calculateRRA()); REQUIRE_FALSE(parser.useChoice()); REQUIRE(parser.useLocal()); } SECTION("Multiple") { ArgumentHolder ah{"prog", "-xl", "1.2,1.5", "-xa", "n", "-xl", "2.4,1.0"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.runAllLines()); REQUIRE(parser.getAllAxesRoots().size() == 2); REQUIRE(parser.getAllAxesRoots()[0].x == Approx(1.2)); REQUIRE(parser.getAllAxesRoots()[0].y == Approx(1.5)); REQUIRE(parser.getAllAxesRoots()[1].x == Approx(2.4)); REQUIRE(parser.getAllAxesRoots()[1].y == Approx(1.0)); REQUIRE_FALSE(parser.runFewestLines()); REQUIRE_FALSE(parser.runUnlink()); REQUIRE(parser.runAnalysis()); } } ================================================ FILE: cliTest/testcommandlineparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "Catch/fakeit.hpp" #include "../depthmapXcli/commandlineparser.h" #include "../depthmapXcli/imodeparser.h" #include "../depthmapXcli/imodeparserfactory.h" #include #include #include "argumentholder.h" using namespace fakeit; class TestParser: public IModeParser { public: TestParser(const std::string &modeName) : _parseCalled(false), _runCalled(false), _modeName(modeName) { } virtual std::string getModeName()const { return _modeName; } virtual std::string getHelp() const { return formatTestHelpString(_runCalled, _parseCalled); } virtual void parse(int , char ** ) { _parseCalled = true; } virtual void run(const CommandLineParser &, IPerformanceSink &) const { _runCalled = true; } static std::string formatTestHelpString(bool runCalled, bool parseCalled) { std::stringstream buf; buf << "runCalled " << (runCalled ? "yes" : "no") << " : parseCalled " << (parseCalled? "yes": "no") << std::flush; return buf.str(); } private: bool _parseCalled; mutable bool _runCalled; std::string _modeName; }; TEST_CASE("Invalid Parser","Constructor"){ std::vector > parsers; parsers.push_back(std::unique_ptr(new TestParser("TEST1"))); parsers.push_back(std::unique_ptr(new TestParser("TEST2"))); Mock factoryMock; When(Method(factoryMock,getModeParsers)).AlwaysReturn(parsers); { CommandLineParser cmdP(factoryMock.get()); REQUIRE_THROWS_WITH(cmdP.parse(0, 0), Catch::Contains("No commandline parameters provided - don't know what to do")); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "-m requires an argument"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-f"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "-f requires an argument"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-o"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "-o requires an argument"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-t", "-o"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "-t requires an argument"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "-f"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "-m requires an argument"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "LaLaLa"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), "Invalid mode: LaLaLa"); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-f", "inputfile.graph", "-o", "outputfile.graph"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), Catch::Contains("-m for mode is required")); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-m", "TEST2","-f", "inputfile.graph"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), Catch::Contains("-m can only be used once")); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-o", "outputfile.graph"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), Catch::Contains("-f for input file is required")); } { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-f", "inputfile.graph"}; REQUIRE_THROWS_WITH(cmdP.parse(ah.argc(), ah.argv()), Catch::Contains("-o for output file is required")); } } TEST_CASE("Valid Parser","CheckValues"){ std::vector > parsers; parsers.push_back(std::unique_ptr(new TestParser("TEST1"))); parsers.push_back(std::unique_ptr(new TestParser("TEST2"))); Mock factoryMock; When(Method(factoryMock,getModeParsers)).AlwaysReturn(parsers); SECTION("Parser test2 used") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST2", "-f", "inputfile.graph", "-o", "outputfile.graph", "-lnk", "1.2,3.4,5.6,7.8"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.isValid()); REQUIRE(cmdP.getTimingFile().empty()); REQUIRE(parsers[0]->getHelp() == TestParser::formatTestHelpString(false, false)); REQUIRE(parsers[1]->getHelp() == TestParser::formatTestHelpString(false, true)); } SECTION("Parser test1 used") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.isValid()); REQUIRE_FALSE(cmdP.simpleMode()); REQUIRE(cmdP.getTimingFile().empty()); REQUIRE(cmdP.modeOptions().getModeName() == "TEST1"); REQUIRE(parsers[0]->getHelp() == TestParser::formatTestHelpString(false, true)); REQUIRE(parsers[1]->getHelp() == TestParser::formatTestHelpString(false, false)); } SECTION("Parser test1 used, timings file, simple mode") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph", "-s", "-t", "timings.csv"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.isValid()); REQUIRE(cmdP.simpleMode()); REQUIRE(cmdP.getTimingFile() == "timings.csv"); REQUIRE(parsers[0]->getHelp() == TestParser::formatTestHelpString(false, true)); REQUIRE(parsers[1]->getHelp() == TestParser::formatTestHelpString(false, false)); } } TEST_CASE("Run Tests","Check we only run if it's appropriate"){ std::vector > parsers; parsers.push_back(std::unique_ptr(new TestParser("TEST1"))); parsers.push_back(std::unique_ptr(new TestParser("TEST2"))); Mock factoryMock; When(Method(factoryMock,getModeParsers)).AlwaysReturn(parsers); Mock perfSink; SECTION("Fail - run without parsing") { CommandLineParser cmdP(factoryMock.get()); REQUIRE_THROWS_WITH(cmdP.run(perfSink.get()), Catch::Contains("Trying to run with invalid command line parameters")); } SECTION("Fail run with help on the command line") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-h", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(cmdP.isValid()); REQUIRE_THROWS_WITH(cmdP.run(perfSink.get()), Catch::Contains("Trying to run with invalid command line parameters")); } SECTION("Fail run with version on the command line") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-v", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(cmdP.isValid()); REQUIRE_THROWS_WITH(cmdP.run(perfSink.get()), Catch::Contains("Trying to run with invalid command line parameters")); } SECTION("Fail run with version on the command line as last parameter") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph", "-v"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(cmdP.isValid()); REQUIRE_THROWS_WITH(cmdP.run(perfSink.get()), Catch::Contains("Trying to run with invalid command line parameters")); } SECTION("Fail run without sub parser") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog" "-f", "inputfile.graph", "-o", "outputfile.graph"}; REQUIRE_THROWS(cmdP.parse(ah.argc(), ah.argv())); REQUIRE_FALSE(cmdP.isValid()); REQUIRE_THROWS_WITH(cmdP.run(perfSink.get()), Catch::Contains("Trying to run with invalid command line parameters")); } SECTION("Parser test1 used, timings file, simple mode") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{"prog", "-m", "TEST1", "-f", "inputfile.graph", "-o", "outputfile.graph", "-s", "-t", "timings.csv"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.isValid()); REQUIRE(cmdP.simpleMode()); REQUIRE(cmdP.getTimingFile() == "timings.csv"); REQUIRE(parsers[0]->getHelp() == TestParser::formatTestHelpString(false, true)); REQUIRE(parsers[1]->getHelp() == TestParser::formatTestHelpString(false, false)); cmdP.run(perfSink.get()); REQUIRE(parsers[0]->getHelp() == TestParser::formatTestHelpString(true, true)); REQUIRE(parsers[1]->getHelp() == TestParser::formatTestHelpString(false, false)); } } TEST_CASE("Invalid Parser Need Help", "CheckForHelp") { std::vector > parsers; parsers.push_back(std::unique_ptr(new TestParser("TEST1"))); parsers.push_back(std::unique_ptr(new TestParser("TEST2"))); Mock factoryMock; When(Method(factoryMock,getModeParsers)).AlwaysReturn(parsers); SECTION("Help requested") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{ "prog", "-h"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(cmdP.isValid()); } SECTION("Version requested") { CommandLineParser cmdP(factoryMock.get()); ArgumentHolder ah{ "prog", "-v"}; cmdP.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(cmdP.isValid()); } } ================================================ FILE: cliTest/testexportparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/exportparser.h" #include "argumentholder.h" TEST_CASE("ExportParser Fail", "Parsing errors") { // missing arguments SECTION("Missing argument to -em") { ExportParser parser; ArgumentHolder ah{"prog", "-em"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-em requires an argument")); } } TEST_CASE("ExportParser Success", "Read successfully") { ExportParser parser; SECTION("Correctly parse mode pointmap-connections-csv") { ArgumentHolder ah{"prog", "-em", "pointmap-connections-csv"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getExportMode() == ExportParser::POINTMAP_CONNECTIONS_CSV); } SECTION("Correctly parse mode pointmap-data-csv") { ArgumentHolder ah{"prog", "-em", "pointmap-data-csv"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getExportMode() == ExportParser::POINTMAP_DATA_CSV); } SECTION("Correctly parse mode pointmap-links-csv") { ArgumentHolder ah{"prog", "-em", "pointmap-links-csv"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getExportMode() == ExportParser::POINTMAP_LINKS_CSV); } } ================================================ FILE: cliTest/testimportparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/importparser.h" #include "argumentholder.h" TEST_CASE("Import args valid", "valid") { { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "IMPORT", "-if", "importfile"}; ImportParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getFilesToImport().size() == 1); REQUIRE(cmdP.getFilesToImport()[0] == "importfile"); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "IMPORT", "-if", "importfile1", "-if", "importfile2"}; ImportParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getFilesToImport().size() == 2); REQUIRE(cmdP.getFilesToImport()[0] == "importfile1"); REQUIRE(cmdP.getFilesToImport()[1] == "importfile2"); } } ================================================ FILE: cliTest/testisovistparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "depthmapXcli/isovistparser.h" #include "argumentholder.h" #include "selfcleaningfile.h" TEST_CASE("Isovistparser string constants") { IsovistParser parser; REQUIRE(parser.getModeName() == "ISOVIST"); REQUIRE(parser.getHelp() == "Arguments for isovist mode:\n" \ " -ii Define an isoivist at position x,y with\n"\ " optional direction angle and view angle for partial isovists\n"\ " -if load isovist definitions from a file (csv)\n"\ " the relevant headers must be called x, y, angle and viewangle\n"\ " the latter two are optional.\n"\ " Those two arguments cannot be mixed\n"\ " Angles for partial isovists are in degrees, counted anti-clockwise with 0°\n"\ " pointing to the right.\n\n" ); } TEST_CASE("Parse isovist on the command line") { ArgumentHolder ah{"prog", "-ii", "1,2", "-ii", "1,5,27,180"}; IsovistParser parser; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getIsovists().size() == 2); REQUIRE(parser.getIsovists()[0].getLocation().y == Approx(2.0)); REQUIRE(parser.getIsovists()[0].getViewAngle() == 0.0); REQUIRE(parser.getIsovists()[1].getLocation().y == Approx(5.0)); REQUIRE(parser.getIsovists()[1].getViewAngle() == Approx(3.141592)); } TEST_CASE("Parse isovists from file") { IsovistParser parser; SECTION("Full isovists") { SelfCleaningFile scf("fullisovists.csv"); { std::ofstream file(scf.Filename()); file << "id,x,y,angle\n1,1,1,27\n2,2.2,1.1,190\n" << std::flush; } ArgumentHolder ah{"prog", "-if", scf.Filename()}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getIsovists().size() == 2); REQUIRE(parser.getIsovists()[0].getLocation().y == Approx(1.0)); REQUIRE(parser.getIsovists()[0].getAngle() == 0.0); REQUIRE(parser.getIsovists()[0].getViewAngle() == 0.0); REQUIRE(parser.getIsovists()[1].getLocation().y == Approx(1.1)); REQUIRE(parser.getIsovists()[1].getAngle() == 0.0); REQUIRE(parser.getIsovists()[1].getViewAngle() == 0.0); } SECTION("Partial isovists") { SelfCleaningFile scf("fullisovists.csv"); { std::ofstream file(scf.Filename()); file << "id,x,y,angle,foo,ViewAngle\n1,1,1,27,bar,180\n2,2.2,1.1,180,baz,90\n" << std::flush; } ArgumentHolder ah{"prog", "-if", scf.Filename()}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getIsovists().size() == 2); REQUIRE(parser.getIsovists()[0].getLocation().y == Approx(1.0)); REQUIRE(parser.getIsovists()[0].getAngle() == Approx(0.4712388) ); REQUIRE(parser.getIsovists()[0].getViewAngle() == Approx(3.141592)); REQUIRE(parser.getIsovists()[1].getLocation().y == Approx(1.1)); REQUIRE(parser.getIsovists()[1].getAngle() == Approx(3.141592)); REQUIRE(parser.getIsovists()[1].getViewAngle() == Approx(1.57079)); } } TEST_CASE("Command line failures") { IsovistParser parser; SECTION( "Missing arguments for -ii") { ArgumentHolder ah{"prog", "-ii"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-ii requires an argument")); } SECTION( "Missing arguments for -if") { ArgumentHolder ah{"prog", "-if"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-if requires an argument")); } SECTION( "Using -if twice") { ArgumentHolder ah{"prog", "-if", "foo.csv", "-if", "bar.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-if can only be used once")); } SECTION( "Using -ii and -if") { ArgumentHolder ah{"prog", "-ii", "1,1", "-if", "bar.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-if cannot be used together with -ii")); } SECTION( "Using -if and -ii") { ArgumentHolder ah{"prog", "-if", "foo.csv", "-ii", "1,1"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-ii cannot be used together with -if")); } SECTION("Nothing to do") { ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("No isovists defined. Use -ii or -if")); } } ================================================ FILE: cliTest/testlinkparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/linkparser.h" #include "argumentholder.h" TEST_CASE("LINK args invalid", "") { { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lf"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-lf requires an argument")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-lnk requires an argument")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lf", "linksfile1", "-lf", "linksfile2"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-lf can only be used once at the moment")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lf", "linksfile1", "-lnk", "0,0,0,0"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-lf can not be used in conjunction with -lnk")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk", "LaLaLaLa"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid link provided")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk", "1.2;3.4;5.6;7.8"}; LinkParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid link provided")); } } TEST_CASE("LINK args valid", "valid") { // for this set of tests a difference less than 0.001 should // suffice to signify that two floats are the same const float EPSILON = 0.001f; { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk", "1.2,3.4,5.6,7.8"}; LinkParser cmdP; cmdP.parse(int(ah.argc()), ah.argv()); REQUIRE(cmdP.getManualLinks().size() == 1); REQUIRE(cmdP.getManualLinks()[0] == "1.2,3.4,5.6,7.8"); REQUIRE(cmdP.getLinkMode() == cmdP.LinkMode::LINK); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk", "1.2,3.4,5.6,7.8", "-lnk", "0.1,0.2,0.3,0.4"}; LinkParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getManualLinks().size() == 2); REQUIRE(cmdP.getManualLinks()[0] == "1.2,3.4,5.6,7.8"); REQUIRE(cmdP.getManualLinks()[1] == "0.1,0.2,0.3,0.4"); REQUIRE(cmdP.getLinkMode() == cmdP.LinkMode::LINK); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "LINK", "-lnk", "1.2,3.4,5.6,7.8", "-lnk", "0.1,0.2,0.3,0.4", "-lm", "unlink", "-lmt", "pointmaps"}; LinkParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getManualLinks().size() == 2); REQUIRE(cmdP.getManualLinks()[0] == "1.2,3.4,5.6,7.8"); REQUIRE(cmdP.getManualLinks()[1] == "0.1,0.2,0.3,0.4"); REQUIRE(cmdP.getLinkMode() == cmdP.LinkMode::UNLINK); } } ================================================ FILE: cliTest/testmapconvertparser.cpp ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "depthmapXcli/mapconvertparser.h" #include "argumentholder.h" #include "selfcleaningfile.h" TEST_CASE("MapConvertParserFail", "Error cases") { SECTION("Missing argument to co") { MapConvertParser parser; ArgumentHolder ah{"prog", "-co"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-co requires an argument")); } SECTION("Missing argument to con") { MapConvertParser parser; ArgumentHolder ah{"prog", "-con"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-con requires an argument")); } SECTION("Missing argument to crsl") { MapConvertParser parser; ArgumentHolder ah{"prog", "-crsl"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-crsl requires an argument")); } SECTION("Non-numeric input to -crsl") { MapConvertParser parser; ArgumentHolder ah{"prog", "-crsl", "foo"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-crsl must be a number >0, got foo")); } SECTION("Under-zero input to -crsl") { MapConvertParser parser; ArgumentHolder ah{"prog", "-crsl", "-1"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-crsl must be a number >0, got -1")); } SECTION("Zero input to -crsl") { MapConvertParser parser; ArgumentHolder ah{"prog", "-crsl", "-1"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-crsl must be a number >0, got -1")); } SECTION("rubbish input to -co") { MapConvertParser parser; ArgumentHolder ah{"prog", "-co", "foo"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("Invalid map output (-co) type: foo")); } SECTION("output type (-co) provided twice") { MapConvertParser parser; ArgumentHolder ah{"prog", "-co", "axial", "-co", "drawing"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("-co can only be used once, modes are mutually exclusive")); } SECTION("Don't provide output type") { MapConvertParser parser; ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("A valid output map type (-co) is required")); } SECTION("Don't provide output name") { MapConvertParser parser; ArgumentHolder ah{"prog", "-co", "axial"}; REQUIRE_THROWS_WITH(parser.parse(int(ah.argc()), ah.argv()), Catch::Contains("A valid output map name (-con) is required")); } } TEST_CASE("MapConvertParserSuccess", "Read successfully") { MapConvertParser parser; SECTION("Plain axial") { ArgumentHolder ah{"prog", "-co", "axial", "-con", "new_axial"}; parser.parse(int(ah.argc()), ah.argv()); REQUIRE(parser.outputMapName() == "new_axial"); REQUIRE(parser.outputMapType() == ShapeMap::AXIALMAP); } } ================================================ FILE: cliTest/testparsingutils.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/parsingutils.h" TEST_CASE("AxialRadiusParsing success") { std::string testString = "5,1,n"; auto result = depthmapX::parseRadiusList(testString); std::vector expectedResult = {1.0 ,5.0,-1.0}; REQUIRE( result == expectedResult ); } TEST_CASE("AxialRadiusParsing failure") { REQUIRE_THROWS_WITH(depthmapX::parseRadiusList("5,1.1"), Catch::Contains("Found non integer radius 1.1")); REQUIRE_THROWS_WITH(depthmapX::parseRadiusList("5,foo"), Catch::Contains("Found either 0 or unparsable radius foo")); REQUIRE_THROWS_WITH(depthmapX::parseRadiusList("5,0"), Catch::Contains("Found either 0 or unparsable radius 0")); REQUIRE_THROWS_WITH(depthmapX::parseRadiusList("5,-1"), Catch::Contains("Radius must be either n or a positive integer")); } ================================================ FILE: cliTest/testperformancewriter.cpp ================================================ #include #include "../depthmapXcli/performancewriter.h" #include "selfcleaningfile.h" #include TEST_CASE("TestPerformanceWriting", "Simple test case") { SelfCleaningFile scf("timertest.csv"); PerformanceWriter writer(scf.Filename()); writer.addData("test1", 100.0); writer.addData("test2", 200.0 ); writer.write(); std::ifstream f(scf.Filename()); REQUIRE(f.good()); char line[1000]; std::vector lines; while( !f.eof()) { f.getline(line, 1000); lines.push_back(line); } std::vector expected{"\"action\",\"duration\"", "\"test1\",100", "\"test2\",200", ""}; REQUIRE(lines == expected); } TEST_CASE("TestPerformanceNotWriting", "No filename no writing") { SelfCleaningFile scf("timertest.csv"); PerformanceWriter writer(""); writer.addData("test1", 100.0); writer.addData("test2", 200.0 ); writer.write(); std::ifstream f(scf.Filename()); REQUIRE_FALSE(f.good()); } ================================================ FILE: cliTest/testradiusconverter.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/radiusconverter.h" TEST_CASE("ConvertForMetric","") { RadiusConverter converter; REQUIRE(converter.ConvertForMetric("2") == Approx(2.0)); REQUIRE(converter.ConvertForMetric("n") == Approx(-1.0)); REQUIRE(converter.ConvertForMetric("2.6") == Approx(2.6)); REQUIRE(converter.ConvertForMetric("2.3e12") == Approx(2.3e12)); REQUIRE_THROWS_WITH(converter.ConvertForMetric("-1"), Catch::Contains("Radius for metric vga must be n for the whole range or a positive number. Got -1")); REQUIRE_THROWS_WITH(converter.ConvertForMetric("foo"), Catch::Contains("Radius for metric vga must be n for the whole range or a positive number. Got foo")); REQUIRE_THROWS_WITH(converter.ConvertForMetric("NaN"), Catch::Contains("Radius NaN?! Really?")); REQUIRE_THROWS_WITH(converter.ConvertForMetric("INFINITY"), Catch::Contains("Radius inf?! Who are you kidding?")); } ================================================ FILE: cliTest/testsegmentparser.cpp ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/segmentparser.h" #include "argumentholder.h" TEST_CASE("Test segment mode and help") { SegmentParser parser; REQUIRE(parser.getModeName() == "SEGMENT"); REQUIRE(parser.getHelp() == "Mode options for Segment Analysis:\n"\ " -st one of:\n" " tulip (Angular Tulip - Faster)\n"\ " angular (Angular Full - Slower)\n"\ " topological\n"\ " metric\n"\ " -sr \n"\ " -srt (only for Tulip) one of:\n"\ " steps\n"\ " metric\n"\ " angular\n"\ " -sic to include choice (only for Tulip)\n"\ " -stb (4 to 1024, 1024 approximates full angular)\n"\ " -swa perform weighted analysis using this attribute (only for Tulip)\n"); } TEST_CASE("Test Segment Parsing Exceptions","") { SegmentParser parser; SECTION("No segment mode") { ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "No analysis type given" ); } SECTION("Argument missing -st") { ArgumentHolder ah{"prog", "-st"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-st requires an argument" ); } SECTION("Invalid SEGMENT mode") { ArgumentHolder ah{"prog", "-st", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "Invalid SEGMENT mode: foo" ); } SECTION("Argument missing -sr") { ArgumentHolder ah{"prog", "-sr"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-sr requires an argument" ); } SECTION("Argument missing -srt") { ArgumentHolder ah{"prog", "-srt"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-srt requires an argument" ); } SECTION("Invalid SEGMENT radius type") { ArgumentHolder ah{"prog", "-srt", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "Invalid SEGMENT radius type: foo" ); } SECTION("Argument missing -stb") { ArgumentHolder ah{"prog", "-stb"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-stb requires an argument" ); } SECTION("Missung radius metric") { ArgumentHolder ah{"prog", "-st", "metric"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "At least one radius must be provided" ); } SECTION("Missung radius topological") { ArgumentHolder ah{"prog", "-st", "topological"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "At least one radius must be provided" ); } SECTION("Missung radius angular") { ArgumentHolder ah{"prog", "-st", "angular"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "At least one radius must be provided" ); } SECTION("Missung radius tulip") { ArgumentHolder ah{"prog", "-st", "tulip"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "At least one radius must be provided" ); } SECTION("Missing tulip radius type") { ArgumentHolder ah{"prog", "-st", "tulip", "-sr", "n"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "Radius type is required for tulip analysis" ); } SECTION("Missing tulip bins") { ArgumentHolder ah{"prog", "-st", "tulip", "-sr", "n", "-srt", "steps"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "Tulip bins are required for tulip analysis" ); } SECTION("Tulip bins out of range") { ArgumentHolder ah{"prog", "-st", "tulip", "-sr", "n", "-srt", "steps", "-stb", "2"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-stb must be a number between 4 and 1024, got 2" ); } SECTION("Tulip bins out of range") { ArgumentHolder ah{"prog", "-st", "tulip", "-sr", "n", "-srt", "steps", "-stb", "1025"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), "-stb must be a number between 4 and 1024, got 1025" ); } } TEST_CASE("Test segment mode parsing", "") { SegmentParser parser; SECTION("Analysis Metric") { ArgumentHolder ah{"prog", "-st", "metric", "-sr", "n"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.includeChoice()); REQUIRE(parser.getTulipBins() == 0); REQUIRE(parser.getAnalysisType() == SegmentParser::AnalysisType::METRIC); REQUIRE(parser.getRadiusType() == SegmentParser::RadiusType::NONE); REQUIRE(parser.getRadii().size() == 1); REQUIRE(int(parser.getRadii()[0]) == -1); } SECTION("Analysis Angular Full") { ArgumentHolder ah{"prog", "-st", "angular", "-sr", "n"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.includeChoice()); REQUIRE(parser.getTulipBins() == 0); REQUIRE(parser.getAnalysisType() == SegmentParser::AnalysisType::ANGULAR_FULL); REQUIRE(parser.getRadiusType() == SegmentParser::RadiusType::NONE); REQUIRE(parser.getRadii().size() == 1); REQUIRE(int(parser.getRadii()[0]) == -1); } SECTION("Analysis Topological") { ArgumentHolder ah{"prog", "-st", "topological", "-sr", "n"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.includeChoice()); REQUIRE(parser.getTulipBins() == 0); REQUIRE(parser.getAnalysisType() == SegmentParser::AnalysisType::TOPOLOGICAL); REQUIRE(parser.getRadiusType() == SegmentParser::RadiusType::NONE); REQUIRE(parser.getRadii().size() == 1); REQUIRE(int(parser.getRadii()[0]) == -1); } SECTION("Analysis Tulip") { ArgumentHolder ah{"prog", "-st", "tulip", "-sr", "n", "-srt", "steps", "-stb", "1024", "-sic"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.includeChoice()); REQUIRE(parser.getTulipBins() == 1024); REQUIRE(parser.getAnalysisType() == SegmentParser::AnalysisType::ANGULAR_TULIP); REQUIRE(parser.getRadiusType() == SegmentParser::RadiusType::SEGMENT_STEPS); REQUIRE(parser.getRadii().size() == 1); REQUIRE(int(parser.getRadii()[0]) == -1); } } ================================================ FILE: cliTest/testselfcleaningfile.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "selfcleaningfile.h" #include namespace { bool fileExists(const std::string &filename) { std::ifstream f(filename.c_str()); return f.good(); } bool writeToFile(const std::string &filename, const std::string &content) { std::ofstream f(filename.c_str()); if (!f.good()) { return false; } f << content; f.flush(); return true; } } TEST_CASE("TestSelfCleaningFile", "Check it is deleted, doesn't fail when not present") { { SelfCleaningFile scf("foo.txt"); REQUIRE(scf.Filename() == "foo.txt"); REQUIRE(fileExists("foo.txt") == false); REQUIRE(writeToFile(scf.Filename(), "bla bla bla")); REQUIRE(fileExists(scf.Filename())); } REQUIRE(fileExists("foo.txt") == false); { SelfCleaningFile scf("foo.txt"); REQUIRE(scf.Filename() == "foo.txt"); REQUIRE(fileExists("foo.txt") == false); } REQUIRE(fileExists("foo.txt") == false); } ================================================ FILE: cliTest/testsimpletimer.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/simpletimer.h" #include #include TEST_CASE("TestSimpleTimer", "") { SimpleTimer timer; std::this_thread::sleep_for(std::chrono::milliseconds(500)); REQUIRE(timer.getTimeInSeconds() == Approx(0.5).epsilon(0.2)); } TEST_CASE("TestSimpleTimerReset", "") { SimpleTimer timer1; SimpleTimer timer2; std::this_thread::sleep_for(std::chrono::milliseconds(500)); REQUIRE(timer1.getTimeInSeconds() == Approx(0.5).epsilon(0.2)); REQUIRE(timer2.getTimeInSeconds() == Approx(0.5).epsilon(0.2)); timer2.reset(); std::this_thread::sleep_for(std::chrono::milliseconds(500)); REQUIRE(timer1.getTimeInSeconds() == Approx(1.0).epsilon(0.2)); REQUIRE(timer2.getTimeInSeconds() == Approx(0.5).epsilon(0.2)); } ================================================ FILE: cliTest/teststepdepthparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "depthmapXcli/stepdepthparser.h" #include "argumentholder.h" #include "selfcleaningfile.h" TEST_CASE("StepDepthParserFail", "Error cases") { SECTION("Missing argument to -sdp") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdp"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sdp requires an argument")); } SECTION("Missing argument to -sdf") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdf"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sdf requires an argument")); } SECTION("Missing argument to -sdt") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdt"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sdt requires an argument")); } SECTION("rubbish input to -sdp") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdp", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid step depth point provided (foo). Should only contain digits dots and commas")); } SECTION("rubbish input to -sdt") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdt", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid step type: foo")); } SECTION("Non-existing file provided") { StepDepthParser parser; ArgumentHolder ah{"prog", "-sdf", "foo.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Failed to load file foo.csv, error")); } SECTION("Neiter points nor point file provided") { StepDepthParser parser; ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Either -sdp or -sdf must be given")); } SECTION("Points and pointfile provided") { StepDepthParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-sdp", "0.1,5.2", "-sdf", "testpoints.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sdf cannot be used together with -sdp")); } SECTION("Pointfile and points provided") { StepDepthParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-sdf", "testpoints.csv", "-sdp", "0.1,5.2"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sdp cannot be used together with -sdf")); } SECTION("Malformed pointfile") { StepDepthParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-sdf", "testpoints.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 1")); } SECTION("Malformed point arg") { StepDepthParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-sdp", "0.1"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 0.1")); } } TEST_CASE("StepDepthParserSuccess", "Read successfully") { StepDepthParser parser; double x1 = 1.0; double y1 = 2.0; double x2 = 1.1; double y2 = 1.2; SECTION("Read from commandline") { std::stringstream p1; p1 << x1 << "," << y1 << std::flush; std::stringstream p2; p2 << x2 << "," << y2 << std::flush; ArgumentHolder ah{"prog", "-sdp", p1.str(), "-sdp", p2.str(), "-sdt", "visual"}; parser.parse(ah.argc(), ah.argv()); } SECTION("Read from file") { SelfCleaningFile scf("testpoints.csv"); { std::ofstream f(scf.Filename().c_str()); f << "x\ty\n" << x1 << "\t" << y1 << "\n" << x2 << "\t" << y2 << "\n" << std::flush; } ArgumentHolder ah{"prog", "-sdf", scf.Filename(), "-sdt", "visual"}; parser.parse(ah.argc(), ah.argv() ); } auto points = parser.getStepDepthPoints(); REQUIRE(points.size() == 2); REQUIRE(points[0].x == Approx(x1)); REQUIRE(points[0].y == Approx(y1)); REQUIRE(points[1].x == Approx(x2)); REQUIRE(points[1].y == Approx(y2)); } ================================================ FILE: cliTest/testvgaparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapXcli/vgaparser.h" #include "argumentholder.h" TEST_CASE("VGA args invalid", "") { { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-vm requires an argument")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "foo"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid VGA mode: foo")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility", "-vm", "metric"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-vm can only be used once")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility", "-vg"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Global measures in VGA/visibility analysis require a radius, use -vr ")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility", "-vg", "-vr"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("-vr requires an argument")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility", "-vg", "-vr", "foo"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Radius must be a positive integer number or n, got foo")); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "metric"}; VgaParser p; REQUIRE_THROWS_WITH(p.parse(ah.argc(), ah.argv()), Catch::Contains("Metric vga requires a radius, use -vr ")); } } TEST_CASE("VGA args valid", "valid") { { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA"}; VgaParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getVgaMode() == VgaParser::VgaMode::ISOVIST); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "isovist"}; VgaParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getVgaMode() == VgaParser::VgaMode::ISOVIST); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility"}; VgaParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getVgaMode() == VgaParser::VgaMode::VISBILITY); REQUIRE_FALSE(cmdP.localMeasures()); REQUIRE_FALSE(cmdP.globalMeasures()); REQUIRE(cmdP.getRadius().empty()); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "visibility", "-vl", "-vg", "-vr", "4"}; VgaParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getVgaMode() == VgaParser::VgaMode::VISBILITY); REQUIRE(cmdP.globalMeasures()); REQUIRE(cmdP.localMeasures()); REQUIRE(cmdP.getRadius() == "4"); } { ArgumentHolder ah{"prog", "-f", "infile", "-o", "outfile", "-m", "VGA", "-vm", "thruvision"}; VgaParser cmdP; cmdP.parse(ah.argc(), ah.argv()); REQUIRE(cmdP.getVgaMode() == VgaParser::VgaMode::THRU_VISION); } } ================================================ FILE: cliTest/testvisprepparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "depthmapXcli/visprepparser.h" #include "argumentholder.h" #include "selfcleaningfile.h" TEST_CASE("VisPrepParserFail", "Error cases") { SECTION("Missing argument to pg") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pg", "-pp", "1.2,1.3"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pg requires an argument")); } SECTION("Missing argument to pp") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pp"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pp requires an argument")); } SECTION("Missing argument to pf") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pf", "-pg", "1.2"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pf requires an argument")); } SECTION("Non-numeric input to -pg") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pg", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pg must be a number >0, got foo")); } SECTION("rubbish input to -pp") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pp", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid fill point provided (foo). Should only contain digits dots and commas")); } SECTION("Non-existing file provide") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pg", "0.1", "-pf", "foo.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Failed to load file foo.csv, error")); } SECTION("Neither points nor point file provided") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pg", "0.1", "-pm"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Either -pp or -pf must be given")); } SECTION("Nothing to do") { VisPrepParser parser; ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Nothing to do")); } SECTION("Points and pointfile provided") { VisPrepParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-pg", "0.1", "-pp", "0.1,5.2", "-pf", "testpoints.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pf cannot be used together with -pp")); } SECTION("Pointfile and points provided") { VisPrepParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\t2\n" << std::flush; } ArgumentHolder ah{"prog", "-pg", "0.1", "-pf", "testpoints.csv", "-pp", "0.1,5.2"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pp cannot be used together with -pf")); } SECTION("Malformed pointfile") { VisPrepParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-pg", "0.1", "-pf", "testpoints.csv"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 1")); } SECTION("Malformed point arg") { VisPrepParser parser; SelfCleaningFile scf("testpoints.csv"); { std::ofstream f("testpoints.csv"); f << "x\ty\n1\n" << std::flush; } ArgumentHolder ah{"prog", "-pg", "0.1", "-pp", "0.1"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Error parsing line: 0.1")); } SECTION("Nonsensical visibility restriction") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pr", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Restricted visibility of 'foo' makes no sense, use a positive number or -1 for unrestricted")); } SECTION("Nonsensical visibility restriction") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pr", "0.0"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Restricted visibility of '0.0' makes no sense, use a positive number or -1 for unrestricted")); } SECTION("Make and unmake") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pm", "-pu"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pu cannot be used together with -pm")); } SECTION("Grid and unmake") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pg", "1", "-pu"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-pu can not be used with any other option apart from -pl")); } } TEST_CASE("VisprepParserMakeSuccess", "Read successfully - Make") { VisPrepParser parser; double x1 = 1.0; double y1 = 2.0; double x2 = 1.1; double y2 = 1.2; double grid = 0.5; std::stringstream gstring; gstring << grid << std::flush; SECTION("Read from commandline") { std::stringstream p1; p1 << x1 << "," << y1 << std::flush; std::stringstream p2; p2 << x2 << "," << y2 << std::flush; ArgumentHolder ah{"prog", "-pg", gstring.str(), "-pp", p1.str(), "-pp", p2.str(), "-pb", "-pr", "2.1", "-pm"}; parser.parse(ah.argc(), ah.argv()); REQUIRE(parser.getBoundaryGraph()); REQUIRE(parser.getMakeGraph()); REQUIRE_FALSE(parser.getUnmakeGraph()); REQUIRE_FALSE(parser.getRemoveLinksWhenUnmaking()); REQUIRE(parser.getMaxVisibility() == Approx(2.1)); } SECTION("Read from file") { SelfCleaningFile scf("testpoints.csv"); { std::ofstream f(scf.Filename().c_str()); f << "x\ty\n" << x1 << "\t" << y1 << "\n" << x2 << "\t" << y2 << "\n" << std::flush; } ArgumentHolder ah{"prog", "-pg", gstring.str(), "-pf", scf.Filename()}; parser.parse(ah.argc(), ah.argv() ); REQUIRE_FALSE(parser.getBoundaryGraph()); REQUIRE_FALSE(parser.getMakeGraph()); REQUIRE_FALSE(parser.getUnmakeGraph()); REQUIRE_FALSE(parser.getRemoveLinksWhenUnmaking()); REQUIRE(parser.getMaxVisibility() == Approx(-1.0)); } REQUIRE(parser.getGrid() == Approx(grid)); auto points = parser.getFillPoints(); REQUIRE(points.size() == 2); REQUIRE(points[0].x == Approx(x1)); REQUIRE(points[0].y == Approx(y1)); REQUIRE(points[1].x == Approx(x2)); REQUIRE(points[1].y == Approx(y2)); } TEST_CASE("VisprepParserUnmakeSuccess", "Read successfully - Unmake") { VisPrepParser parser; ArgumentHolder ah{"prog", "-pu", "-pl"}; parser.parse(ah.argc(), ah.argv()); REQUIRE_FALSE(parser.getBoundaryGraph()); REQUIRE_FALSE(parser.getMakeGraph()); REQUIRE(parser.getUnmakeGraph()); REQUIRE(parser.getRemoveLinksWhenUnmaking()); } ================================================ FILE: depthmapX/CMakeLists.txt ================================================ set(depthmapX depthmapX) # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed set(CMAKE_AUTOMOC ON) # Create code from a list of Qt designer ui files # set(CMAKE_AUTOUIC ON) # set(CMAKE_AUTORCC ON) # Find the QtWidgets library find_package(Qt5 COMPONENTS Core Widgets Gui OpenGL REQUIRED) add_compile_definitions(_DEPTHMAP) set(depthmapX_SRCS GraphDoc.cpp indexWidget.cpp mainwindow.cpp mdichild.cpp renderthread.cpp treeWindow.cpp mainwindowfactory.cpp settingsimpl.cpp compatibilitydefines.h mainwindow.h settings.h GraphDoc.h mainwindowfactory.h settingsimpl.h indexWidget.h mdichild.h treeWindow.h main.cpp coreapplication.cpp coreapplication.h mainwindowhelpers.cpp mainwindowmoduleregistry.cpp imainwindowmodulefactory.h) qt5_wrap_ui(UI_HDRS UI/TopoMetDlg.ui UI/SegmentAnalysisDlg.ui UI/RenameObjectDlg.ui UI/PushDialog.ui UI/PromptReplace.ui UI/OptionsDlg.ui UI/NewLayerDlg.ui UI/MakeOptionsDlg.ui UI/MakeLayerDlg.ui UI/LicenceDialog.ui UI/LayerChooserDlg.ui UI/IsovistPathDlg.ui UI/InsertColumnDlg.ui UI/GridDialog.ui UI/FindLocDlg.ui UI/FilePropertiesDlg.ui UI/FewestLineOptionsDlg.ui UI/EditConnectionsDlg.ui UI/DepthmapOptionsDlg.ui UI/DepthmapAlert.ui UI/ConvertShapesDlg.ui UI/ColumnPropertiesDlg.ui UI/ColourScaleDlg.ui UI/AxialAnalysisOptionsDlg.ui UI/AttributeSummary.ui UI/AttributeChooserDlg.ui UI/AgentAnalysisDlg.ui UI/AboutDlg.ui UI/licenseagreement.ui) qt5_add_resources(DM_RSRC resource.qrc dialogs/settings/settingsdialog.qrc) if (WIN32) add_executable(${depthmapX} WIN32 ${depthmapX_SRCS} ${UI_HDRS} ${DM_RSRC} icons.rc) if(MINGW) # https://stackoverflow.com/a/18138926 # MinGW compilation does not bring in the required DLLs to make the executable self-contained # The missing DLLs are: # - libstdc++-6.dll # - libwinpthread-1.dll # - libgcc_s_seh-1.dll # Additionally, windeployqt does not drag them into the build directory, so it might be # necessary to manually find and copy them after compilation set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -lwsock32 -lws2_32 ${CMAKE_CXX_STANDARD_LIBRARIES}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive") endif(MINGW) endif(WIN32) if(UNIX AND NOT APPLE) add_executable(${depthmapX} ${depthmapX_SRCS} ${UI_HDRS} ${DM_RSRC}) if (Qt5_POSITION_INDEPENDENT_CODE) SET(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() endif() if(APPLE) set(MACOSX_BUNDLE_ICON_FILE depthmapX.icns) set(depthmapX_ICON ${CMAKE_CURRENT_SOURCE_DIR}/icons/depthmapX.icns) set_source_files_properties(${depthmapX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") set(graph_ICON ${CMAKE_CURRENT_SOURCE_DIR}/icons/graph.icns) set_source_files_properties(${graph_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") add_definitions(-DGL_SILENCE_DEPRECATION) add_executable(${depthmapX} MACOSX_BUNDLE ${depthmapX_ICON} ${graph_ICON} ${depthmapX_SRCS} ${UI_HDRS} ${DM_RSRC}) set_target_properties(${depthmapX} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist) endif(APPLE) find_package(OpenGL REQUIRED) set(modules_gui "" CACHE INTERNAL "modules_gui" FORCE) set(MODULES_GUI TRUE) set(MODULES_CLI FALSE) set(MODULES_CLI_TEST FALSE) set(MODULES_CORE FALSE) set(MODULES_CORE_TEST FALSE) add_subdirectory(../modules modules) target_link_libraries(${depthmapX} salalib genlib mgraph440 Qt5::Core Qt5::Gui Qt5::Widgets Qt5::OpenGL OpenGL::GL OpenGL::GLU ${modules_gui} ${modules_core}) add_subdirectory(dialogs) add_subdirectory(views) ================================================ FILE: depthmapX/GraphDoc.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include #include #include "mainwindow.h" #include "dialogs/MakeLayerDlg.h" #include "dialogs/OptionsDlg.h" #include "dialogs/AxialAnalysisOptionsDlg.h" #include "dialogs/SegmentAnalysisDlg.h" #include "dialogs/GridDialog.h" #include "dialogs/MakeOptionsDlg.h" #include "dialogs/EditConnectionsDlg.h" #include "dialogs/ColourScaleDlg.h" #include "dialogs/FewestLineOptionsDlg.h" #include "dialogs/PromptReplace.h" #include "dialogs/FilePropertiesDlg.h" #include "dialogs/InsertColumnDlg.h" #include "dialogs/PushDialog.h" #include "dialogs/AgentAnalysisDlg.h" #include "dialogs/NewLayerDlg.h" #include "dialogs/AttributeChooserDlg.h" #include "dialogs/LayerChooserDlg.h" #include "dialogs/RenameObjectDlg.h" #include "dialogs/ColumnPropertiesDlg.h" #include "dialogs/IsovistPathDlg.h" #include "dialogs/ConvertShapesDlg.h" #include "dialogs/TopoMetDlg.h" #include "dialogs/AttributeSummary.h" #include "views/depthmapview/depthmapview.h" #include "views/viewhelpers.h" #include #ifdef _WIN32 #include #endif #include "compatibilitydefines.h" #include "salalib/importutils.h" QT_BEGIN_NAMESPACE Q_DECLARE_METATYPE(std::string) QGraphDoc::QGraphDoc(const QString &author, const QString &organisation) { m_opened_name = ""; m_flag_lock = false; for (int i = 0; i < VIEW_TYPES; i++) { m_redraw_flag[i] = REDRAW_DONE; m_remenu_flag[i] = false; m_view[i] = NULL; } m_communicator = NULL; m_make_algorithm = 0; // algorithm to make graph m_make_maxdist = -1.0; // maximum distance you can see (set to -1.0 for infinite) m_meta_graph = new MetaGraph; modifiedFlag = false; modify_prog = false; m_num_steps = 0; m_record = 0; m_step = 0; m_num_records = 0; std::string date = ViewHelpers::getCurrentDate(); QString version = QString(TITLE_BASE); m_meta_graph->setProperties(author.toStdString(),organisation.toStdString(),date,version.toStdString()); qRegisterMetaType< std::string >(); connect(&m_thread, &RenderThread::runtimeExceptionThrown, this, &QGraphDoc::exceptionThrownInRenderThread); connect(&m_thread, &RenderThread::showWarningMessage, this, &QGraphDoc::messageFromRenderThread); connect(&m_thread, &RenderThread::closeWaitDialog, this, &QGraphDoc::DestroyWaitDialog); } void QGraphDoc::exceptionThrownInRenderThread(int type, std::string message) { if(type == depthmapX::PointMapExceptionType::NO_ISOVIST_ANALYSIS) { std::stringstream message; message << "This operation requires isovist analysis. To run it go to: "; message << "Tools -> Visibility -> Run Visibility Graph Analysis... "; message << "and select \"Calculate isovist properties\""; QMessageBox::warning(this, tr("Warning"), tr(message.str().c_str()), QMessageBox::Ok, QMessageBox::Ok); } } void QGraphDoc::messageFromRenderThread(QString title, QString message) { QMessageBox::warning(this, title, message, QMessageBox::Ok, QMessageBox::Ok); } bool QGraphDoc::SetRedrawFlag(int viewtype, int flag, int reason, QWidget *originator) // (almost) thread safe { if(viewtype == VIEW_ALL && flag != REDRAW_DONE) { ((MainWindow *) m_mainFrame)->updateGLWindows(true, flag == REDRAW_TOTAL); } if(viewtype == VIEW_MAP && flag == REDRAW_TOTAL) { ((MainWindow *) m_mainFrame)->updateGLWindows(false, true); } if (!m_flag_lock) { m_flag_lock = true; if (viewtype) { // it's the view calling itself if (m_redraw_flag[viewtype] < flag) { m_redraw_flag[viewtype] = flag; QApplication::postEvent(m_view[viewtype], new QEvent(QEvent::FocusIn)); } if (flag == REDRAW_DONE) { m_redraw_flag[viewtype] = flag; } } else { for (int i = 1; i < VIEW_TYPES; i++) { if (m_view[i] && m_redraw_flag[i] < flag) { m_redraw_flag[i] = flag; QApplication::postEvent(m_view[i], new QEvent(QEvent::FocusIn)); } } } m_flag_lock = false; return true; } return false; } void QGraphDoc::UpdateMainframestatus() { QString s1, s2, s3; if (!m_meta_graph->viewingNone()) { int n = 0; int state = m_meta_graph->getState(); // showing the axial graph if ((state & MetaGraph::SHAPEGRAPHS) && m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { n = (int) m_meta_graph->getDisplayedShapeGraph().getShapeCount(); } else if ((state & MetaGraph::DATAMAPS) && m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { n = (int) m_meta_graph->getDisplayedDataMap().getShapeCount(); } // either showing or constructing the VGA graph else if ((state & MetaGraph::POINTMAPS) && m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { n = (int) m_meta_graph->getDisplayedPointMap().getFilledPointCount(); } if (n > 0) { s1 = QString("%1 ").arg(n); } QtRegion r = m_meta_graph->getBoundingBox(); s2 = QString("%1, %2 ").arg(r.width()).arg(r.height()); s3 = QString("%1, %2 ").arg(m_position.x).arg(m_position.y); ((MainWindow *)m_mainFrame)->UpdateStatus(s1, s2, s3); } } void QGraphDoc::SetUpdateFlag(int type, bool modified) { switch (type) { case NEW_FILE: QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_LOADALL)); break; case NEW_DATA: QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_LOADATTRIBUTES)); break; case NEW_TABLE: QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_LOADGRAPH)); break; case DELETED_TABLE: QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_RELOADGRAPH)); break; } SetRemenuFlag(VIEW_ALL,true); // Tell the views to update their menus if (modified) { modifiedFlag = true; } } ///////////////////////////////////////////////////////////////////////////// // QGraphDoc commands // New layer and delete layer void QGraphDoc::OnLayerNew() { CNewLayerDlg dlg; if (QDialog::Accepted == dlg.exec()) { // insert a new layer of the correct type // for now, 0 = axial map, and 1 = data map ShapeMap *map; if (dlg.m_layer_type == 0) { int ref = m_meta_graph->addShapeMap(dlg.m_name.toStdString()); m_meta_graph->setDisplayedDataMapRef(ref); map = &(m_meta_graph->getDataMaps()[ref]); } else if (dlg.m_layer_type == 1) { int ref = m_meta_graph->addShapeGraph(dlg.m_name.toStdString(),ShapeMap::CONVEXMAP); m_meta_graph->setDisplayedShapeGraphRef(ref); map = m_meta_graph->getShapeGraphs()[size_t(ref)].get(); } else if (dlg.m_layer_type == 2) { int ref = m_meta_graph->addShapeGraph(dlg.m_name.toStdString(),ShapeMap::AXIALMAP); m_meta_graph->setDisplayedShapeGraphRef(ref); map = m_meta_graph->getShapeGraphs()[size_t(ref)].get(); } else if (dlg.m_layer_type == 3) { int ref = m_meta_graph->addShapeGraph(dlg.m_name.toStdString(),ShapeMap::PESHMAP); m_meta_graph->setDisplayedShapeGraphRef(ref); map = m_meta_graph->getShapeGraphs()[size_t(ref)].get(); } QtRegion r = m_meta_graph->getBoundingBox(); if (r.atZero()) { r = QtRegion(Point2f(-50.0,-50.0),Point2f(50.0,50.0)); } map->init(0,r); map->setEditable(true); SetUpdateFlag(NEW_TABLE); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); } } void QGraphDoc::OnLayerDelete() { // Delete the currently displayed map if (QMessageBox::Yes == QMessageBox::question(this, tr("depthmapX"), tr("Are you sure you want to delete this map?\nThis action cannot be undone"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)) { m_meta_graph->removeDisplayedMap(); SetUpdateFlag(DELETED_TABLE); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); } } // Note: import and export are now on the Layer menu, not the file menu // Import file types: .cat, .dxf, .ntf // Txt files for points and lines (shapes) void QGraphDoc::CreateWaitDialog(const QString& description, QWidget *pr) { modify_prog = false; m_waitdlg = new QProgressDialog(); connect(m_waitdlg, SIGNAL(canceled()), this, SLOT(cancel_wait())); m_waitdlg->setCancelButtonText(tr("&Cancel")); m_waitdlg->setWindowTitle(description); m_waitdlg->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::Dialog); m_waitdlg->show(); Tid_progress = startTimer(50); m_timer.start(); } void QGraphDoc::DestroyWaitDialog() { modify_prog = true; killTimer(Tid_progress); QApplication::postEvent((QObject*)m_waitdlg, new QEvent(QEvent::Close)); } void QGraphDoc::cancel_wait() { if (m_communicator) { m_waitdlg->setLabelText(QString(" attempting to cancel")); if (m_communicator->IsCancelled()) { } else { m_communicator->Cancel(); } // Don't cancel --- cancel should be handled by the thread! } } void QGraphDoc::timerEvent(QTimerEvent *event) { if (event->timerId() == Tid_progress) { if(modify_prog) { QApplication::postEvent((QObject*)m_waitdlg, new QEvent(QEvent::Close)); killTimer(Tid_progress); return; } QString lstr = QString("Step %1 of %2").arg(m_step).arg(m_num_steps); m_waitdlg->setValue(m_record); double percent = (100.0 * double(m_record)) / double(m_num_records); QString str; int timeleft = 1 + int((100.0 / percent - 1.0) * double(m_timer.elapsed()/1000)); if (percent > 0.5) { if (timeleft >= 3600) { str = QString(" : Estimated %1 hours %2 minutes remaining").arg(timeleft / 3600).arg((timeleft / 60) % 60 ); } else if (timeleft >= 60) { str = QString(" : Estimated %1 minutes %2 seconds remaining").arg((timeleft / 60) % 60).arg(timeleft % 60 ); } else { str = QString(" : Estimated %1 seconds remaining").arg(timeleft % 60); } } lstr += str; m_waitdlg->setLabelText(lstr); } } void QGraphDoc::ProcPostMessage(int m, int x) { switch (m) { case Communicator::NUM_STEPS: m_num_steps = x; break; case Communicator::NUM_RECORDS: if(!modify_prog) m_waitdlg->setRange(0, x); m_record = 0; m_num_records = x; break; case Communicator::CURRENT_STEP: m_step = x; break; case Communicator::CURRENT_RECORD: m_record = x; if (m_record > m_num_records) m_record = m_num_records; break; } } void QGraphDoc::OnVGALinksFileImport() { if (m_communicator) { return; // Locked } // change the view before loading the file to make the changes apparent if(m_view[VIEW_MAP]) ((QDepthmapView*)m_view[VIEW_MAP])->m_showlinks = true; SetRedrawFlag(VIEW_MAP,REDRAW_POINTS, NEW_DEPTHMAPVIEW_SETUP); QString template_string; template_string += "Text files (*.txt *.csv)\n"; template_string += "All files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QString infile = QFileDialog::getOpenFileName( 0, tr("Import Links File"), "", template_string, &selectedFilter, options); if (!infile.size()) { // no file selected return; } std::string fileName = infile.toStdString(); std::ifstream fileStream(fileName); if (fileStream.fail()) { QMessageBox::warning(this, tr("Warning"), tr("Unable to read text file.\nPlease check that another program is not using it."), QMessageBox::Ok, QMessageBox::Ok); return; } else { try { PointMap& currentMap = m_meta_graph->getDisplayedPointMap(); std::vector newLinks = depthmapX::pixelateMergeLines( EntityParsing::parseLines(fileStream, '\t'), currentMap); depthmapX::mergePixelPairs(newLinks, currentMap); SetRedrawFlag(VIEW_MAP,REDRAW_POINTS, NEW_DEPTHMAPVIEW_SETUP); } catch (EntityParsing::EntityParseException& e) { std::stringstream message; message << "Unable to parse text file\n\n"; message << fileName; message << "\n\n Error: "; message << e.what(); QMessageBox::warning(this, tr("Warning"), tr(message.str().c_str()), QMessageBox::Ok, QMessageBox::Ok); } catch (depthmapX::InvalidLinkException& e) { std::stringstream message; message << "Unable to import links\n\n"; message << fileName; message << "\n\n Error: "; message << e.what(); QMessageBox::warning(this, tr("Warning"), tr(message.str().c_str()), QMessageBox::Ok, QMessageBox::Ok); } } } void QGraphDoc::OnGenerateIsovistsFromFile() { if (m_communicator) { return; // Locked } QString template_string; template_string += "Text files (*.txt *.csv)\n"; template_string += "All files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QString infile = QFileDialog::getOpenFileName(0, tr("Import Isovists File"), "", template_string, &selectedFilter, options); if (!infile.size()) { // no file selected return; } std::string fileName = infile.toStdString(); std::ifstream fileStream(fileName); if (fileStream.fail()) { QMessageBox::warning(this, tr("Warning"), tr("Unable to read text file.\nPlease check that another program is not using it."), QMessageBox::Ok, QMessageBox::Ok); return; } else { // communicator and wait dialog to prevent draw while this operation is in progress // and also because the isovist generation requires both m_communicator = new CMSCommunicator; m_communicator->SetInfile2(qPrintable(infile)); CreateWaitDialog(tr("Generating isovists...")); m_communicator->SetFunction(CMSCommunicator::MAKEISOVISTSFROMFILE); m_thread.render(this); } } void QGraphDoc::OnFileImport() { if (m_communicator) { return; // Locked } QString template_string; template_string += "All formats(*.dxf *.ntf *.gml *.cat *.rt1 *.mif *.txt *.csv)\n"; template_string += "Drawing files (*.dxf *.ntf *.gml *.cat *.rt1)\nMapInfo map (*.mif)\nText files (*.txt *.csv)\n"; template_string += "All files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QStringList infiles = QFileDialog::getOpenFileNames( 0, tr("Import Files"), "", template_string, &selectedFilter, options); if (!infiles.size()) { return; } // this is placed here as a proxy to be queried later so that we can find // if there was something else in the graph after importing. If there was // then the view should not be reset, if there wasn't then the view can // be reset to point to the newly imported objects bool graphHadNullBoundsBeforeImport = m_meta_graph->getBoundingBox().atZero(); QFilePath filepath(infiles[0]); QString ext = filepath.m_ext; if (ext == tr("CAT") || ext == tr("DXF") || ext == tr("NTF") || ext == tr("RT1") || ext == tr("MIF") || ext == tr("GML") || ext == tr("")) { for (int i = 1; i < infiles.size(); i++) { QFilePath filepath(infiles[i]); if (filepath.m_ext != ext || !(filepath.m_ext == tr("RT1") || filepath.m_ext == tr("NTF") || filepath.m_ext == tr("GML") || filepath.m_ext == tr(""))) { QMessageBox::warning(this, tr("Warning"), tr("You have selected more than one file. Unfortunately, this feature is only currently available with NTF, GML and Tiger line files.\nPlease select a single file to import only."), QMessageBox::Ok, QMessageBox::Ok); return; } } // OS files don't have GML suffix for some bizarre reason if (ext == tr("")) { ext = tr("GML"); } int graph_option = MetaGraph::ADD; bool ok = true; if (ok) { m_communicator = new CMSCommunicator; if (ext != tr("RT1") && ext != tr("NTF") && ext != tr("GML")) { // ntf, gml & rt1 use filesets (all others use standard file at a time) m_communicator->SetInfile( qPrintable(infiles[0]) ); } if (ext != tr("MIF")) { CreateWaitDialog(tr("Importing file...")); m_communicator->SetFunction( CMSCommunicator::IMPORT ); if (ext == tr("CAT")) { m_communicator->SetOption( MetaGraph::CAT | graph_option ); } else if (ext == tr("DXF")) { m_communicator->SetOption( MetaGraph::DXF | graph_option ); } else if (ext == tr("NTF")) { m_communicator->SetOption( MetaGraph::NTF | graph_option ); m_communicator->SetFileSet( infiles ); } else if (ext == tr("GML")) { m_communicator->SetOption( MetaGraph::GML | graph_option ); m_communicator->SetFileSet( infiles ); } else if (ext == tr("RT1")) { m_communicator->SetOption( MetaGraph::RT1 | graph_option ); m_communicator->SetFileSet( infiles ); } } else { int thedot = infiles[0].lastIndexOf('.'); QString infile2 = infiles[0].left(thedot+1) + tr("mid"); m_communicator->SetInfile2( qPrintable(infile2)); CreateWaitDialog(tr("Importing file...")); m_communicator->SetFunction( CMSCommunicator::IMPORTMIF ); } m_thread.render(this); } } else if (ext == tr("TXT") || ext == tr("CSV")) { std::ifstream file( infiles[0].toLatin1() ); if (file.fail()) { QMessageBox::warning(this, tr("Warning"), tr("Unable to read text file.\nPlease check that another program is not using it."), QMessageBox::Ok, QMessageBox::Ok); } else { std::unique_ptr comm(new ICommunicator()); bool mapParsed = depthmapX::importFile(*m_meta_graph, file, comm.get(), filepath.m_name.toStdString(), depthmapX::ImportType::DATAMAP, (ext == tr("CSV")) ? depthmapX::ImportFileType::CSV : depthmapX::ImportFileType::TSV); if(mapParsed) { // This should have added a new data map: SetUpdateFlag(NEW_TABLE); if(graphHadNullBoundsBeforeImport) { SetRedrawFlag(VIEW_ALL, REDRAW_TOTAL, NEW_TABLE); } else { SetRedrawFlag(VIEW_ALL, REDRAW_GRAPH, NEW_TABLE); } } else { QMessageBox::warning(this, tr("Warning"), tr("Unable to import text file.\n \ Unable to import text file.\n\ Depthmap can import tab-delimited or comma separated files.\n\ There must be some spatial data.\n\ The spatial data can either be:\n\ Points with X and Y values, or\n\ points with Easting and Northing values, or\n\ lines with X1,Y1 and X2,Y2 values"), QMessageBox::Ok, QMessageBox::Ok); } } } else { QMessageBox::warning(this, tr("Warning"), tr("Unrecognised file format. Sorry, unable to import this file."), QMessageBox::Ok, QMessageBox::Ok); } } // Export file types: .txt (point files) void QGraphDoc::OnFileExport() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } QString suffix; int mode = -1; int view_class = m_meta_graph->getViewClass(); if (view_class & MetaGraph::VIEWAXIAL) { mode = 0; suffix = m_meta_graph->getDisplayedShapeGraph().getName().c_str(); } else if (view_class & MetaGraph::VIEWDATA) { mode = 1; suffix = m_meta_graph->getDisplayedDataMap().getName().c_str(); } else if (view_class & MetaGraph::VIEWVGA) { if (m_meta_graph->getDisplayedPointMap().isProcessed()) { mode = 2; suffix = tr("vga"); } else { mode = 3; suffix = tr("points"); } } if (mode == -1) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX does not support saving the currently displayed layer"), QMessageBox::Ok, QMessageBox::Ok); return; } suffix.replace(' ','_'); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("Tab-delimited text file (*.txt)\n"); if (mode < 3) { template_string += tr("Comma separated values file (*.csv)\n"); template_string += tr("Graph file (*.graph)\n"); template_string += tr("MapInfo file (*.mif)\n"); template_string += tr("Pajek (*.net)\n"); } template_string += tr("All files (*.*)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); QFilePath filepath(outfile); QString ext = filepath.m_ext; if (ext != tr("MIF") && ext != tr("GRAPH") && ext != tr("NET")) { std::ofstream stream(outfile.toLatin1()); char delimiter = '\t'; if (ext == tr("CSV")) { delimiter = ','; } if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); mode = -1; } switch (mode) { case 0: m_meta_graph->getDisplayedShapeGraph().output(stream, delimiter); break; case 1: m_meta_graph->getDisplayedDataMap().output(stream, delimiter); break; case 2: m_meta_graph->getDisplayedPointMap().outputSummary( stream, delimiter ); break; case 3: m_meta_graph->getDisplayedPointMap().outputPoints( stream, delimiter ); break; default: break; } stream.close(); } else if (ext == tr("GRAPH")) { if (mode >= 3) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX only supports exporting VGA, axial and shape data to graph files"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->write(outfile.toStdString(), METAGRAPH_VERSION, true) != MetaGraph::OK) { // <- true writes current layer only QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); } } else if (ext == tr("NET")) { if (mode != 0 && mode != 2) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX can only export VGA graphs or shape graphs to Pajek .net files"), QMessageBox::Ok, QMessageBox::Ok); return; } std::ofstream stream(outfile.toLatin1()); if (!stream) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); } else { if (mode == 0) { m_meta_graph->getDisplayedShapeGraph().outputNet(stream); } else if (mode == 2) { m_meta_graph->getDisplayedPointMap().outputNet(stream); } } } else { if (mode >= 3) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX currently only supports exporting VGA, axial and shape data to MapInfo tables"), QMessageBox::Ok, QMessageBox::Ok); return; } int thedot = outfile.indexOf('.'); QString outfile2 = outfile.left(thedot+1) + tr("mid"); std::ofstream miffile(outfile.toLatin1()); if (miffile.fail() || miffile.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); mode = -1; } std::ofstream midfile(outfile2.toLatin1()); if (midfile.fail() || midfile.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open associated .mid file for export"), QMessageBox::Ok, QMessageBox::Ok); mode = -1; } if (mode == 0) { m_meta_graph->getDisplayedShapeGraph().outputMifMap(miffile,midfile); } else if (mode == 1) { m_meta_graph->getDisplayedDataMap().outputMifMap(miffile,midfile); } else if (mode == 2) { m_meta_graph->getDisplayedPointMap().outputMif(miffile,midfile); } } } void QGraphDoc::OnFileExportMapGeometry() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } QString suffix; int mode = -1; int view_class = m_meta_graph->getViewClass(); if (view_class & MetaGraph::VIEWAXIAL) { mode = 0; suffix = m_meta_graph->getDisplayedShapeGraph().getName().c_str(); } else if (view_class & MetaGraph::VIEWDATA) { mode = 1; suffix = m_meta_graph->getDisplayedDataMap().getName().c_str(); } if (mode == -1) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX does not support saving the currently displayed layer"), QMessageBox::Ok, QMessageBox::Ok); return; } suffix.replace(' ', '_'); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("Chiron and Alasdair Transfer Format file (*.cat)\n"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName(0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if (outfile.isEmpty()) { return; } FILE *fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); QFilePath filepath(outfile); QString ext = filepath.m_ext; if (ext == "CAT") { std::ofstream stream(outfile.toLatin1()); if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); mode = -1; } switch (mode) { case 0: m_meta_graph->writeMapShapesAsCat(m_meta_graph->getDisplayedShapeGraph(), stream); break; case 1: m_meta_graph->writeMapShapesAsCat(m_meta_graph->getDisplayedDataMap(), stream); break; default: break; } stream.close(); } } void QGraphDoc::OnFileExportLinks() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } QString suffix; int mode = -1; int view_class = m_meta_graph->getViewClass(); if (view_class & MetaGraph::VIEWAXIAL) { mode = 5; suffix = tr("unlinks"); } else if (view_class & MetaGraph::VIEWDATA) { mode = 6; suffix = tr("links"); } else if (view_class & MetaGraph::VIEWVGA) { if (m_meta_graph->getDisplayedPointMap().isProcessed()) { mode = 4; suffix = tr("merge_lines"); } } if (mode == -1) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, depthmapX does not support saving the currently displayed layer"), QMessageBox::Ok, QMessageBox::Ok); return; } suffix.replace(' ','_'); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("Tab-delimited text file (*.txt)\n"); template_string += tr("Comma separated values file (*.csv)\n"); template_string += tr("All files (*.*)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); QFilePath filepath(outfile); QString ext = filepath.m_ext; std::ofstream stream(outfile.toLatin1()); char delimiter = '\t'; if (ext == "CSV") { delimiter = ','; } if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); mode = -1; } switch (mode) { case 0: m_meta_graph->getDisplayedShapeGraph().output(stream, delimiter); break; case 1: m_meta_graph->getDisplayedDataMap().output(stream, delimiter); break; case 2: m_meta_graph->getDisplayedPointMap().outputSummary( stream, delimiter ); break; case 3: m_meta_graph->getDisplayedPointMap().outputPoints( stream, delimiter ); break; case 4: m_meta_graph->getDisplayedPointMap().outputMergeLines( stream, delimiter ); break; case 5: // note: specific to line graphs m_meta_graph->getDisplayedShapeGraph().outputUnlinkPoints( stream, delimiter ); break; default: break; } stream.close(); } void QGraphDoc::OnAxialConnectionsExportAsDot() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } ShapeGraph& shapeGraph = m_meta_graph->getDisplayedShapeGraph(); QString suffix = tr("axial_connections"); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("Dot graph file (*.dot)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); std::ofstream stream(outfile.toLatin1()); if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); return; } shapeGraph.writeAxialConnectionsAsDotGraph(stream); stream.close(); } void QGraphDoc::OnAxialConnectionsExportAsPairCSV() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } ShapeGraph& shapeGraph = m_meta_graph->getDisplayedShapeGraph(); QString suffix = tr("axial_connections"); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("CSV graph file (*.csv)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); std::ofstream stream(outfile.toLatin1()); if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); return; } shapeGraph.writeAxialConnectionsAsPairsCSV(stream); stream.close(); } void QGraphDoc::OnSegmentConnectionsExportAsPairCSV() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } ShapeGraph& shapeGraph = m_meta_graph->getDisplayedShapeGraph(); QString suffix = tr("segment_connections"); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("CSV graph file (*.csv)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); std::ofstream stream(outfile.toLatin1()); if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); return; } shapeGraph.writeSegmentConnectionsAsPairsCSV(stream); stream.close(); } void QGraphDoc::OnPointmapExportConnectionsAsCSV() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; // Locked } if (m_meta_graph->viewingNone()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, cannot export as there is no data to export"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } if (!(m_meta_graph->getViewClass() & MetaGraph::VIEWVGA)) { QMessageBox::warning(this, tr("Error"), tr("Make sure a Visibility Graph is visible"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } if (!m_meta_graph->viewingProcessedPoints()) { QMessageBox::warning(this, tr("Error"), tr("Make sure the visibility graph was created (Tools -> Visibility -> Make Visibility Graph)"), QMessageBox::Ok, QMessageBox::Ok); return; // No graph to export } PointMap& pointMap = m_meta_graph->getDisplayedPointMap(); QString suffix = tr("connectivity"); QFilePath path(m_opened_name); QString defaultname = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name) + tr("_") + suffix; QString template_string = tr("CSV graph file (*.csv)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save Output As"), defaultname, template_string, &selectedFilter, options); if(outfile.isEmpty()) { return; } FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); std::ofstream stream(outfile.toLatin1()); if (stream.fail() || stream.bad()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, unable to open file for export"), QMessageBox::Ok, QMessageBox::Ok); return; } pointMap.outputConnectionsAsCSV(stream, ","); stream.close(); } void QGraphDoc::OnSwapColours() { DisplayParams displayparams; if (m_meta_graph->getViewClass() & MetaGraph::VIEWVGA ) { displayparams = m_meta_graph->getDisplayedPointMap().getDisplayParams(); float blue = displayparams.blue; displayparams.blue = displayparams.red; displayparams.red = blue; m_meta_graph->getDisplayedPointMap().setDisplayParams( displayparams ); } else if (m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { displayparams = m_meta_graph->getDisplayedShapeGraph().getDisplayParams(); float blue = displayparams.blue; displayparams.blue = displayparams.red; displayparams.red = blue; m_meta_graph->getDisplayedShapeGraph().setDisplayParams( displayparams ); } else if (m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { displayparams = m_meta_graph->getDisplayedDataMap().getDisplayParams(); float blue = displayparams.blue; displayparams.blue = displayparams.red; displayparams.red = blue; m_meta_graph->getDisplayedDataMap().setDisplayParams( displayparams ); } SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, NEW_DEPTHMAPVIEW_SETUP); } ///////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnEditGrid() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } bool newmap = false; if (m_meta_graph->getPointMaps().empty() || m_meta_graph->getDisplayedPointMap().isProcessed()) { // this can happen if there are no displayed maps -- so flag new map required: newmap = true; } else if (m_meta_graph->getDisplayedPointMap().getFilledPointCount() != 0) { if ( QMessageBox::Yes != QMessageBox::question(this, tr("depthmapX"), tr("This will clear existing points. Do you want to continue?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) ) return; } QtRegion r = m_meta_graph->getRegion(); CGridDialog dlg(__max(r.width(), r.height())); if (QDialog::Accepted == dlg.exec()) { if (newmap) { m_meta_graph->addNewPointMap(); } m_meta_graph->setGrid( dlg.getSpacing(), Point2f(0.0f, 0.0f) ); m_meta_graph->m_showgrid = true; SetUpdateFlag(NEW_TABLE); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); } } // AV TV // semifilled void QGraphDoc::OnFillPoints( const Point2f& p, int fill_type ) // semifilled = 0 (intention to use semifilled steps for part filled) { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::LINEDATA) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, line drawing data must be loaded before points may be filled"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::POINTMAPS) { QMessageBox::warning(this, tr("Notice"), tr("Please make grid before filling"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessed()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, once the graph has been constructed, more points may not be added"), QMessageBox::Ok, QMessageBox::Ok); return; } m_communicator = new CMSCommunicator(); m_communicator->SetSeedPoint( p ); m_communicator->SetOption( fill_type ); // AV TV CreateWaitDialog(tr("Generating grid points...")); m_communicator->SetFunction( CMSCommunicator::MAKEPOINTS ); m_thread.render(this); } // convert any shape layer to any other (certain rules apply) void QGraphDoc::OnLayerConvert() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } CMakeLayerDlg dlg; dlg.m_mapin = MAKELAYER_DATA; // mapin is a data map (assume) dlg.m_mapout = 0; // no possible map out if (m_meta_graph->viewingProcessedLines()) { int type = m_meta_graph->getDisplayedShapeGraph().getMapType(); // map in is an axial map (of sorts, something with a graph...) dlg.m_mapin = MAKELAYER_AXIAL; dlg.m_origin = QString("Shape Graphs: ") + QString(m_meta_graph->getDisplayedShapeGraph().getName().c_str()); if (type == ShapeMap::AXIALMAP) { // note, ShapeMap::ALLLINEMAP is deliberately excluded, as making a segment map from it would overproduce segments: dlg.m_mapout = MAKELAYER_DRAWING | MAKELAYER_DATA | MAKELAYER_SEGMENT; } else { // convex, segment, pesh and all line maps cannot be converted to segment maps: dlg.m_mapout = MAKELAYER_DRAWING | MAKELAYER_DATA; } } else if (m_meta_graph->viewingProcessedShapes()) { // dlg.m_origin = QString("Data Maps: ") + QString(m_meta_graph->getDisplayedDataMap().getName().c_str()); // possible to go to anything apart from a data map dlg.m_mapout = MAKELAYER_DRAWING | MAKELAYER_AXIAL | MAKELAYER_CONVEX | MAKELAYER_SEGMENT; } if (dlg.m_mapout != 0 && QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator(); m_communicator->SetString( dlg.m_layer_name ); m_communicator->SetOption( dlg.m_keeporiginal ? 1 : 0, 0); // <- option 0 used for retain original flag m_communicator->SetOption( dlg.m_push_values ? 1 : 0, 1); // <- option 1 used for push values flag // if (dlg.m_mapout == MAKELAYER_DRAWING) { // this one new: data or graph (any sort) -> drawing m_communicator->SetOption( dlg.m_mapin == MAKELAYER_DATA ? 0 : 1, 1); // <- option 1 in this case signifies base as graph or data // (option 1 overidden, as data cannot be pushed to a drawing layer) CreateWaitDialog(tr("Constructing segment map...")); m_communicator->SetFunction( CMSCommunicator::MAKEDRAWING ); } if (dlg.m_mapout == MAKELAYER_DATA) { // this one new: graph (any sort) -> data CreateWaitDialog(tr("Constructing segment map...")); m_communicator->SetFunction( CMSCommunicator::MAKEGATESMAP ); } else if (dlg.m_mapout == MAKELAYER_CONVEX) { // this one new: data -> convex map CreateWaitDialog(tr("Constructing convex map...")); m_communicator->SetFunction( CMSCommunicator::MAKECONVEXMAP ); } else if (dlg.m_mapout == MAKELAYER_AXIAL) { // this one originally data -> axial map CreateWaitDialog(tr("Constructing axial map...")); m_communicator->SetFunction( CMSCommunicator::MAKEUSERMAPSHAPE ); } else if (dlg.m_mapout == MAKELAYER_SEGMENT) { if (dlg.m_mapin == MAKELAYER_AXIAL) { // this one originally axial -> segment map // use option 2 to specify percentage removal m_communicator->SetOption( dlg.m_remove_stubs ? dlg.m_percentage : 0, 2); CreateWaitDialog(tr("Constructing segment map...")); m_communicator->SetFunction( CMSCommunicator::MAKESEGMENTMAP ); } else { // this one originally data -> segment map CreateWaitDialog(tr("Constructing segment map...")); m_communicator->SetFunction( CMSCommunicator::MAKEUSERSEGMAPSHAPE ); } } m_thread.render(this); } } void QGraphDoc::OnLayerConvertDrawing() { if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } CMakeLayerDlg dlg; dlg.m_mapin = MAKELAYER_DRAWING; // mapin is a drawing map dlg.m_mapout = MAKELAYER_DATA | MAKELAYER_AXIAL | MAKELAYER_CONVEX | MAKELAYER_SEGMENT; dlg.m_origin = QString(tr("Drawing Layers: All Displayed")); if (QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator(); m_communicator->SetString( dlg.m_layer_name ); m_communicator->SetOption( dlg.m_keeporiginal ? 1 : 0, 0); // <- option 0 used for retain original flag m_communicator->SetOption( -1, 1); // this is used to distinguish between 0 or 1 used when converting data layer // if (dlg.m_mapout == MAKELAYER_DATA) { // this one originally drawing -> data map CreateWaitDialog(tr("Constructing data map...")); m_communicator->SetFunction( CMSCommunicator::MAKEGATESMAP ); } else if (dlg.m_mapout == MAKELAYER_AXIAL) { // this one originally drawing -> axial map CreateWaitDialog(tr("Constructing axial map...")); m_communicator->SetFunction( CMSCommunicator::MAKEUSERMAP ); } else if (dlg.m_mapout == MAKELAYER_CONVEX) { // this one new: drawing -> convex map CreateWaitDialog(tr("Constructing convex map...")); m_communicator->SetFunction( CMSCommunicator::MAKECONVEXMAP ); } else if (dlg.m_mapout == MAKELAYER_SEGMENT) { // this one originally drawing -> seg map CreateWaitDialog(tr("Constructing segment map...")); m_communicator->SetFunction( CMSCommunicator::MAKEUSERSEGMAP ); } m_thread.render(this); } } // arbitrary isovist void QGraphDoc::OnMakeIsovist(const Point2f& seed, double angle) { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::LINEDATA) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, line drawing data must be loaded before an isovist can be constructed"), QMessageBox::Ok, QMessageBox::Ok); return; } m_communicator = new CMSCommunicator(); m_communicator->SetSeedPoint(seed); m_communicator->SetSeedAngle(angle); if (angle >= 0) { CIsovistPathDlg dlg; if (dlg.exec() == QDialog::Accepted) { m_communicator->SetSeedFoV(dlg.fov_angle); } } CreateWaitDialog(tr("Constructing BSP tree to calculate isovist...")); m_communicator->SetFunction(CMSCommunicator::MAKEISOVIST); m_thread.render(this); } void QGraphDoc::OnToolsIsovistpath() { int state = m_meta_graph->getState(); if (state & MetaGraph::LINEDATA) { int view = m_meta_graph->getViewClass(); if ((view & (MetaGraph::VIEWDATA | MetaGraph::VIEWAXIAL)) != 0 && m_meta_graph->isSelected()) { CIsovistPathDlg dlg; if (dlg.exec() == QDialog::Accepted) { double angle = dlg.fov_angle; m_communicator = new CMSCommunicator(); m_communicator->SetSeedAngle( angle ); CreateWaitDialog(tr("Constructing BSP tree to calculate isovists...")); m_communicator->SetFunction( CMSCommunicator::MAKEISOVISTPATH ); m_thread.render(this); } } else { // an explanation of what you need to do as it isn't obvious! QMessageBox::warning(this, tr("Notice"), tr("To get a path you will need some lines for a path.\nTo do so, have an active map which is either a data map or line map of some sort.\nNext, select lines or polylines that you wish to turn into isovist paths.\nThere is no need for you to have a grid set.\n"), QMessageBox::Ok, QMessageBox::Ok); } } } // all line map void QGraphDoc::OnToolsAxialMap(const Point2f& seed) { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::LINEDATA) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, line drawing data must be loaded before an axial map can be constructed"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->hasAllLineMap()) { int ret = QMessageBox::warning(this, tr("My Application"), tr("This will overwrite your existing all-line map, do you want to continue?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Yes, QMessageBox::No); if(ret != QMessageBox::Yes) return; } // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); m_communicator->SetSeedPoint( seed ); CreateWaitDialog(tr("Constructing all line axial map...")); m_communicator->SetFunction( CMSCommunicator::MAKEALLLINEMAP ); m_thread.render(this); } // fewest line map void QGraphDoc::OnToolsMakeFewestLineMap() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::SHAPEGRAPHS) { QMessageBox::warning(this, tr("Warning"), tr("Sorry, all line map must exist in order to construct fewest line map"), QMessageBox::Ok, QMessageBox::Ok); return; } else if (!m_meta_graph->hasAllLineMap()) { QMessageBox::warning(this, tr("Warning"), tr("Sorry, all line map must exist in order to construct fewest line map"), QMessageBox::Ok, QMessageBox::Ok); return; } int replace = 0; // check for existing axial maps and warn user if necessary: if (m_meta_graph->hasFewestLineMaps()) { CPromptReplace dlg; dlg.m_message = tr("There is already a fewest line axial map, would you like to add to it or replace it?"); int result = dlg.exec(); if (result == QDialog::Rejected) { return; } else if (result == 2) { replace = 1; } } // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Constructing fewest line axial map...")); m_communicator->SetFunction( CMSCommunicator::MAKEFEWESTLINEMAP ); m_communicator->SetOption( replace ); m_thread.render(this); } void QGraphDoc::OnToolsRunAxa() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } CAxialAnalysisOptionsDlg dlg(m_meta_graph); if (QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Performing axial line analysis...")); m_communicator->SetFunction( CMSCommunicator::AXIALANALYSIS ); m_thread.render(this); } } void QGraphDoc::OnToolsRunSeg() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } CSegmentAnalysisDlg dlg(m_meta_graph); if (QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Performing segment line analysis...")); m_communicator->SetFunction( dlg.m_analysis_type == 1 ? CMSCommunicator::SEGMENTANALYSISANGULAR : CMSCommunicator::SEGMENTANALYSISTULIP ); m_thread.render(this); } } void QGraphDoc::OnToolsTopomet() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } CTopoMetDlg dlg; if (QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator(); ((MainWindow*)m_mainFrame)->m_options.output_type = dlg.m_topological; ((MainWindow*)m_mainFrame)->m_options.radius = dlg.m_dradius; ((MainWindow*)m_mainFrame)->m_options.sel_only = dlg.m_selected_only; if (dlg.isAnalysisTopological()) { CreateWaitDialog(tr("Performing topological analysis...")); } else { CreateWaitDialog(tr("Performing metric analysis...")); } m_communicator->SetFunction( CMSCommunicator::TOPOMETANALYSIS ); m_thread.render(this); } } /////////////////////////////////////////////////////////////////////////////////////////// // New agent functionality: void QGraphDoc::OnToolsAgentRun() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } AgentEngine& eng = m_meta_graph->getAgentEngine(); // set up eng here... if (!eng.agentSets.size()) { eng.agentSets.push_back(AgentSet()); } CAgentAnalysisDlg dlg; dlg.m_timesteps = eng.m_timesteps; dlg.m_release_rate = eng.agentSets.back().m_release_rate; dlg.m_release_location = eng.agentSets.back().m_release_locations.size() ? 1 : 0; dlg.m_frames = eng.agentSets.back().m_lifetime; if (eng.agentSets.back().m_vbin == -1) { dlg.m_fov = 32; } else { dlg.m_fov = eng.agentSets.back().m_vbin * 2 + 1; } dlg.m_steps = eng.agentSets.back().m_steps; dlg.m_record_trails = eng.m_record_trails; dlg.m_trail_count = eng.m_trail_count; dlg.m_names.push_back(""); for (size_t i = 0; i < m_meta_graph->getDataMaps().size(); i++) { dlg.m_names.push_back(m_meta_graph->getDataMaps()[i].getName()); } dlg.m_gatelayer = eng.m_gatelayer; if (QDialog::Accepted != dlg.exec()) { return; } eng.m_timesteps = dlg.m_timesteps; eng.agentSets.back().m_release_rate = dlg.m_release_rate; eng.agentSets.back().m_lifetime = dlg.m_frames; if (dlg.m_fov == 32) { eng.agentSets.back().m_vbin = -1; } else { eng.agentSets.back().m_vbin = (dlg.m_fov - 1) / 2; } eng.agentSets.back().m_steps = dlg.m_steps; if (dlg.m_occlusion == 0) { eng.agentSets.back().m_sel_type = AgentProgram::SEL_STANDARD; } else if (dlg.m_occlusion == 1) { eng.agentSets.back().m_sel_type = AgentProgram::SEL_LOS; } else if (dlg.m_occlusion == 2) { eng.agentSets.back().m_sel_type = AgentProgram::SEL_LOS_OCC; } else { // (dlg.m_occlusion - 2) should be from 1...8 eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCCLUSION + (dlg.m_occlusion - 2); } if (dlg.m_release_location == 1) { std::set selected = m_meta_graph->getSelSet(); std::copy(selected.begin(), selected.end(), std::back_inserter(eng.agentSets.back().m_release_locations));; } else { eng.agentSets.back().m_release_locations.clear(); } eng.m_gatelayer = dlg.m_gatelayer; // note, trails currently per run, but output per engine if (dlg.m_record_trails) { eng.m_record_trails = true; eng.m_trail_count = dlg.m_trail_count; } // then go: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Performing agent analysis...")); m_communicator->SetFunction( CMSCommunicator::AGENTANALYSIS ); m_thread.render(this); } ///////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnEditUndo() { if (!m_meta_graph->canUndo()) { QMessageBox::warning(this, tr("Warning"), tr("Sorry, no undo available for this map"), QMessageBox::Ok, QMessageBox::Ok); return; } m_meta_graph->undo(); modifiedFlag = true; SetRedrawFlag(VIEW_ALL, REDRAW_GRAPH, NEW_DATA ); } void QGraphDoc::OnEditClear() { int state = m_meta_graph->getState(); int editable = m_meta_graph->isEditable(); if (editable == MetaGraph::NOT_EDITABLE) { QMessageBox::warning(this, tr("Warning"), tr("Cannot delete: the geometry forming this graph cannot be edited."), QMessageBox::Ok, QMessageBox::Ok); return; } else if (editable == MetaGraph::EDITABLE_OFF) { QMessageBox::warning(this, tr("Warning"), tr("Cannot delete: this graph is currently uneditable."), QMessageBox::Ok, QMessageBox::Ok); return; } bool modified = false; if (m_meta_graph->viewingUnprocessedPoints()) { modified = m_meta_graph->clearPoints(); } else if (m_meta_graph->viewingProcessedLines()) { modified = m_meta_graph->getDisplayedShapeGraph().removeSelected(); } else if (m_meta_graph->viewingProcessedShapes()) { modified = m_meta_graph->getDisplayedDataMap().removeSelected(); } if(modified) { modifiedFlag = true; } SetRedrawFlag(VIEW_ALL, REDRAW_GRAPH, NEW_DATA ); } ///////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnToolsMakeGraph() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (!m_meta_graph->viewingUnprocessedPoints()) { QMessageBox::warning(this, tr("Warning"), tr("Sorry, you need an unprocessed set of points to make the visibility graph"), QMessageBox::Ok, QMessageBox::Ok); return; } CMakeOptionsDlg dlg; dlg.m_boundarygraph = false; if (dlg.exec() != QDialog::Accepted) { return; } if (dlg.m_boundarygraph) { m_make_algorithm = 1; } else { m_make_algorithm = 0; } if (dlg.m_restrict_visibility) { m_make_maxdist = dlg.m_maxdist; } else { m_make_maxdist = -1.0; } m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Constructing graph...")); m_communicator->SetFunction( CMSCommunicator::MAKEGRAPH ); m_thread.render(this); } void QGraphDoc::OnToolsUnmakeGraph() { int state = m_meta_graph->getState(); if (m_communicator) { QMessageBox::warning(this, tr("Notice"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (~state & MetaGraph::POINTMAPS) { QMessageBox::warning(this, tr("Notice"), tr("Please make grid before filling"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessed()) { if ( QMessageBox::Yes != QMessageBox::question(this, tr("Notice"), tr("This will clear existing data and attributes. Do you want to continue?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) ) return; } bool removeLinks = false; if(m_meta_graph->getDisplayedPointMap().getMergedPixelPairs().size() > 0) { removeLinks = QMessageBox::Yes == QMessageBox::question(this, tr("Notice"), tr("Would you also like to clear the links?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No); } bool ok = m_meta_graph->unmakeGraph(removeLinks); if (ok) { SetUpdateFlag(QGraphDoc::NEW_DATA); } SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); } ///////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnToolsRun() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another task is running"), QMessageBox::Ok, QMessageBox::Ok); return; } // This is easy! COptionsDlg dlg; dlg.m_layer_names.push_back(""); for (auto& dataMap: m_meta_graph->getDataMaps()) { dlg.m_layer_names.push_back(dataMap.getName()); } if (QDialog::Accepted != dlg.exec()) { return; } // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Analysing graph...")); m_communicator->SetFunction( CMSCommunicator::ANALYSEGRAPH ); m_thread.render(this); } void QGraphDoc::OnToolsPD() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessed()) { if (m_meta_graph->isSelected()) { // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Calculating step depth...")); m_communicator->SetFunction( CMSCommunicator::POINTDEPTH ); m_thread.render(this); } } } void QGraphDoc::OnToolsMPD() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessedPoints() || (m_meta_graph->viewingProcessedLines() && m_meta_graph->getDisplayedShapeGraph().isSegmentMap())) { if (m_meta_graph->isSelected()) { // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Calculating metric depth...")); m_communicator->SetFunction( CMSCommunicator::METRICPOINTDEPTH ); m_thread.render(this); } } } void QGraphDoc::OnToolsAPD() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessedPoints()) { if (m_meta_graph->isSelected()) { // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Calculating angular depth...")); m_communicator->SetFunction( CMSCommunicator::ANGULARPOINTDEPTH ); m_thread.render(this); } } } void QGraphDoc::OnToolsTPD() { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (m_meta_graph->viewingProcessedLines() && m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) { if (m_meta_graph->isSelected()) { // This is easy too... too easy... hmm... crossed-fingers, here goes: m_communicator = new CMSCommunicator(); CreateWaitDialog(tr("Calculating topological depth...")); m_communicator->SetFunction( CMSCommunicator::TOPOLOGICALPOINTDEPTH ); m_thread.render(this); } } } ///////////////////////////////////////////////////////////////////////////// static int sequenceNumber = 1; bool QGraphDoc::OnNewDocument() { m_base_title = tr("Untitled%1").arg(sequenceNumber++); SetRemenuFlag(QGraphDoc::VIEW_ALL, true); return TRUE; } int QGraphDoc::OnOpenDocument(char* lpszPathName) { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return FALSE; } m_opened_name = QString(lpszPathName); int ok = m_meta_graph->readFromFile( lpszPathName ); QFilePath path(m_opened_name); SetUpdateFlag(QGraphDoc::NEW_FILE,false); int ret = FALSE; switch (ok) { case MetaGraph::OK: m_base_title = path.m_name; ret = TRUE; break; case MetaGraph::WARN_BUGGY_VERSION: QMessageBox::warning(this, tr("Warning"), tr("this graph was made with a version of depthmapX that contained slight errors"), QMessageBox::Ok, QMessageBox::Ok); ret = TRUE; break; case MetaGraph::WARN_CONVERTED: QMessageBox::warning(this, tr("Warning"), tr("Warning: this graph was made with an older version of depthmapX.\n" \ "Some aspects of the graph may not have been translated to the new depthmapX properly."), QMessageBox::Ok, QMessageBox::Ok); ret = TRUE; break; case MetaGraph::NOT_A_GRAPH: QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: not recognised as a graph file."), QMessageBox::Ok, QMessageBox::Ok); break; case MetaGraph::DAMAGED_FILE: QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: the graph file is damaged."), QMessageBox::Ok, QMessageBox::Ok); break; case MetaGraph::DISK_ERROR: QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: an error occurred while trying to read from the disk."), QMessageBox::Ok, QMessageBox::Ok); break; case MetaGraph::NEWER_VERSION: QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: this graph has been written by a newer version of depthmapX."), QMessageBox::Ok, QMessageBox::Ok); break; case MetaGraph::DEPRECATED_VERSION: QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: this is a graph file format not supported by this version of depthmapX."), QMessageBox::Ok, QMessageBox::Ok); break; default: { std::string err = dXstring::formatString(ok); QMessageBox::warning(this, tr("Warning"), tr("Unable to open graph: error number "), QMessageBox::Ok, QMessageBox::Ok); } break; } return ret; } bool QGraphDoc::OnFileSave() { QString newName = m_opened_name; if (newName.isEmpty()) { newName = m_base_title + tr(".graph"); QFileDialog::Options options = 0; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save As"), newName, tr("Graph file (*.graph)\nAll files (*.*)"), 0, options); if (outfile.isEmpty()) return false; m_opened_name = outfile; FILE* fp = fopen(m_opened_name.toLatin1(), "wb"); fclose(fp); OnSaveDocument(outfile); QFilePath path(m_opened_name); m_base_title = path.m_name; return true; } OnSaveDocument(newName); return true; } bool QGraphDoc::OnFileSaveAs() { // This is based on Microsoft's "DoSave" function, but // it allows two options for saving: one as the current // graph format, and one as the original QString newName = m_opened_name; if (newName.isEmpty()) { newName = m_base_title + tr(".graph"); } QFileDialog::Options options = 0; QString outfile = QFileDialog::getSaveFileName( 0, tr("Save As"), newName, tr("Graph file (*.graph)\ndepthmapX 8 graph (*.graph)\nAll files (*.*)"), 0, options); if (outfile.isEmpty()) return false; FILE* fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); OnSaveDocument(outfile.toLatin1()); // reset the title and change the document name m_opened_name = outfile; QFilePath path(m_opened_name); m_base_title = path.m_name; return true; } int QGraphDoc::OnSaveDocument(QString lpszPathName) { // default: save in current version format int version = m_meta_graph->getVersion(); // version == -1 is unsaved, which is fine to save in current version if (version != -1 && version != METAGRAPH_VERSION) { if(QMessageBox::Yes == QMessageBox::question(this, tr("depthmapX"), tr("This will overwrite the file with the latest graph format, which may not be readable by previous versions of depthmapX.\nDo you want to overwrite it?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)) return OnSaveDocument(lpszPathName, METAGRAPH_VERSION); else return TRUE; } return OnSaveDocument(lpszPathName, METAGRAPH_VERSION); } int QGraphDoc::OnSaveDocument(QString lpszPathName, int version) { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return FALSE; } if (m_meta_graph->getState() & MetaGraph::BUGGY) { if(QMessageBox::No == QMessageBox::question(this, tr("depthmapX"), tr("This graph file was created by a version of depthmapX with slight errors. Are you sure you want to save it?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)) return FALSE; } modifiedFlag = true; int ok = m_meta_graph->write( lpszPathName.toStdString(), version ); if (ok == MetaGraph::OK) { modifiedFlag = false; return TRUE; } else if (ok == MetaGraph::DISK_ERROR) { QMessageBox::warning(this, tr("Warning"), tr("Unable to save graph: is there enough disk space?"), QMessageBox::Ok, QMessageBox::Ok); } return FALSE; } bool QGraphDoc::OnCloseDocument(int index) { if (m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("depthmapX is processing, please kill the process to continue"), QMessageBox::Ok, QMessageBox::Ok); return false; } int i; for (i = 1; i < VIEW_TYPES; i++) if (m_view[i]) break; if(modifiedFlag) { int result = QMessageBox::question(this, tr("depthmapX"), tr("Do you want to save the changes?"), QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::Cancel); if(QMessageBox::Yes == result) { OnFileSave(); if (i == VIEW_TYPES) { modifiedFlag = false; QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_DESTROYALL)); } return true; } else if (QMessageBox::No == result) { if (i == VIEW_TYPES) { modifiedFlag = false; QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_DESTROYALL)); } return true; } else return false; } if (i == VIEW_TYPES) { QApplication::postEvent((QObject*)m_mainFrame, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)this, CONTROLS_DESTROYALL)); } return true; } void QGraphDoc::OnPushToLayer() { if (m_meta_graph->viewingProcessed()) { int toplayerclass = (m_meta_graph->getViewClass() & MetaGraph::VIEWFRONT); std::string origin_layer; std::string origin_attribute; std::map, std::string> names; // I'm just going to allow push from any layer to any other layer // (apart from VGA graphs, which cannot map onto themselves if (toplayerclass == MetaGraph::VIEWVGA) { // bit clunky just to get two names out... PointMap& map = m_meta_graph->getDisplayedPointMap(); origin_layer = std::string("Visibility Graphs: ") + map.getName(); origin_attribute = map.getAttributeTable().getColumnName(map.getDisplayedAttribute()); } else if (toplayerclass == MetaGraph::VIEWAXIAL) { // bit clunky just to get two names out... ShapeGraph& map = m_meta_graph->getDisplayedShapeGraph(); origin_layer = std::string("Shape Graphs: ") + map.getName(); origin_attribute = map.getAttributeTable().getColumnName(map.getDisplayedAttribute()); } else if (toplayerclass == MetaGraph::VIEWDATA) { // bit clunky just to get two names out... ShapeMap& map = m_meta_graph->getDisplayedDataMap(); origin_layer = std::string("Data Maps: ") + map.getName(); origin_attribute = map.getAttributeTable().getColumnName(map.getDisplayedAttribute()); } else { // eek! QMessageBox::warning(this, tr("Warning"), tr("No valid map displayed from which to push data"), QMessageBox::Ok, QMessageBox::Ok); return; } // layers to push to: size_t i; std::vector& datamaps = m_meta_graph->getDataMaps(); for (i = 0; i < datamaps.size(); i++) { if (toplayerclass != MetaGraph::VIEWDATA || i != m_meta_graph->getDisplayedDataMapRef()) { names.insert(std::make_pair(std::pair(MetaGraph::VIEWDATA,int(i)),std::string("Data Maps: ") + datamaps[i].getName())); } } auto& shapegraphs = m_meta_graph->getShapeGraphs(); for (i = 0; i < shapegraphs.size(); i++) { if (toplayerclass != MetaGraph::VIEWAXIAL || i != m_meta_graph->getDisplayedShapeGraphRef()) { names.insert(std::make_pair(std::pair(MetaGraph::VIEWAXIAL,int(i)), std::string("Shape Graphs: ") + shapegraphs[i]->getName())); } } for (i = 0; i < m_meta_graph->getPointMaps().size(); i++) { // note 1: no VGA graph can push to another VGA graph (point onto point transforms) if (toplayerclass != MetaGraph::VIEWVGA) { names.insert(std::make_pair(std::pair(MetaGraph::VIEWVGA,int(i)),std::string("Visibility Graphs: ") + m_meta_graph->getPointMaps()[i].getName())); } } CPushDialog dlg(names); dlg.m_origin_layer = QString(origin_layer.c_str()); dlg.m_origin_attribute = QString(origin_attribute.c_str()); if (QDialog::Accepted == dlg.exec()) { m_communicator = new CMSCommunicator; // dummy value to prevent draw while this operation is in progress // now have to separate vga and axial layers again: int sel = dlg.m_layer_selection; std::pair dest = depthmapX::getMapAtIndex(names, sel)->first; // CWaitCursor c; m_meta_graph->pushValuesToLayer(dest.first, dest.second, dlg.m_function, dlg.m_count_intersections); delete m_communicator; m_communicator = NULL; SetUpdateFlag(NEW_TABLE); } } } void QGraphDoc::OnAddColumn() { CRenameObjectDlg dlg(tr("Column")); // using the constructor without a column name sets rename column dialog to insert column name mode bool success = false; while (dlg.exec() == QDialog::Accepted && !success) { if (dlg.m_object_name.isEmpty()) { QMessageBox::warning(this, tr("Warning"), tr("Column name cannot be empty"), QMessageBox::Ok, QMessageBox::Ok); } else { AttributeTable& tab = m_meta_graph->getAttributeTable(); bool found = false; for (int i = 0; i < tab.getNumColumns(); i++) { if (tab.getColumnName(i) == dlg.m_object_name.toStdString()) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, another column already has this name, please choose a unique column name"), QMessageBox::Ok, QMessageBox::Ok); found = true; break; } } if (!found) { success = true; break; } } } if (success) { int col = m_meta_graph->addAttribute(dlg.m_object_name.toStdString()); m_meta_graph->setDisplayedAttribute(col); SetUpdateFlag(QGraphDoc::NEW_DATA); // Tell the views to update their menus SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_COLUMN ); } } void QGraphDoc::OnRenameColumn() { AttributeTable *tab = &(m_meta_graph->getAttributeTable()); int col = m_meta_graph->getDisplayedAttribute(); // -1 is reference number, -2 is displaying nothing (-2 shouldn't happen but is) if (col == -1 || col == -2 || m_meta_graph->isAttributeLocked(col)) { QMessageBox::warning(this, tr("Warning"), tr("Cannot rename locked column"), QMessageBox::Ok, QMessageBox::Ok); return; } int newcol = RenameColumn(tab,col); if (newcol != -1) { m_meta_graph->setDisplayedAttribute(newcol); SetUpdateFlag(QGraphDoc::NEW_DATA); SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_COLUMN ); } } int QGraphDoc::RenameColumn(AttributeTable *tab, int col) { QString colname = QString(tab->getColumnName(col).c_str()); CRenameObjectDlg dlg("Column",colname); // using the column name sets the dialog to replace column name mode bool success = false; while (dlg.exec() == QDialog::Accepted && !success && dlg.m_object_name != colname) { std::string newColName = dlg.m_object_name.toStdString(); if (tab->hasColumn(newColName)) { QMessageBox::warning(this, tr("Notice"), tr("Sorry, another column already has this name, please choose a unique column name"), QMessageBox::Ok, QMessageBox::Ok); } else { tab->renameColumn(tab->getColumnName(col), newColName); return tab->getColumnIndex(newColName); } } return -1; } void QGraphDoc::OnColumnProperties() { AttributeTable *tab = &(m_meta_graph->getAttributeTable()); LayerManagerImpl *layers = &(m_meta_graph->getLayers()); int col = m_meta_graph->getDisplayedAttribute(); CColumnPropertiesDlg dlg(tab, layers, col); dlg.exec(); } /////////////////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnUpdateColumn() { int col = m_meta_graph->getDisplayedAttribute(); // -1 is reference number, -2 is displaying nothing (-2 shouldn't happen but is) if (col == -1 || col == -2 || m_meta_graph->isAttributeLocked(col)) { QMessageBox::warning(this, tr("Warning"), tr("Cannot edit locked column"), QMessageBox::Ok, QMessageBox::Ok); return; } PointMap *pointmap = NULL; ShapeMap *shapemap = NULL; int vc = m_meta_graph->getViewClass(); if (vc & MetaGraph::VIEWVGA) { pointmap = &(m_meta_graph->getDisplayedPointMap()); } else if (vc & MetaGraph::VIEWAXIAL) { shapemap = &(m_meta_graph->getDisplayedShapeGraph()); } else if (vc & MetaGraph::VIEWDATA) { shapemap = &(m_meta_graph->getDisplayedDataMap()); } if (ReplaceColumnContents(pointmap,shapemap,col)) { m_meta_graph->setDisplayedAttribute(col); SetUpdateFlag(QGraphDoc::NEW_DATA); SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); } } // Either shapemap or pointmap should be NULL: bool QGraphDoc::ReplaceColumnContents(PointMap *pointmap, ShapeMap *shapemap, int col) { SalaObj program_context; SalaGrf graph; if (pointmap != NULL) { graph.map.point = pointmap; program_context = SalaObj(SalaObj::S_POINTMAPOBJ, graph); } else if (shapemap != NULL) { SalaGrf graph; graph.map.shape = shapemap; program_context = SalaObj(SalaObj::S_SHAPEMAPOBJ, graph); } else { QMessageBox::warning(this, tr("Warning"), tr("Replace column contents requires either a shape map or visibility graph"), QMessageBox::Ok, QMessageBox::Ok); return false; } AttributeTable *table = program_context.getTable(); // insert dialog is a misnomer now! CInsertColumnDlg dlg(table,col); // Using a column number sets it to use the replace text rather than select text bool error = true; while (error && QDialog::Accepted == dlg.exec()) { error = false; size_t n = dlg.m_formula_text.length(); char *text = new char[n+1]; if (n == 0) { QMessageBox::warning(this, tr("Notice"), tr("Please enter a formula"), QMessageBox::Ok, QMessageBox::Ok); error = true; } else { strcpy(text,dlg.m_formula_text.c_str()); std::istringstream stream(text); SalaProgram proggy(program_context); if (!proggy.parse(stream)) { QString msg = QString("There was an error parsing your formula:\n\n") + proggy.getLastErrorMessage().c_str(); QMessageBox::warning(this, tr("Warning"), msg, QMessageBox::Ok, QMessageBox::Ok); error = true; } else { // just check you really are viewing the layers: bool retvar; if (dlg.m_selection_only) { retvar = proggy.runupdate(col,pointmap ? pointmap->getSelSet() : shapemap->getSelSet()); } else { retvar = proggy.runupdate(col); } if (!retvar) { QString msg = QString("There was an error running your formula:\n\n") + proggy.getLastErrorMessage().c_str(); QMessageBox::warning(this, tr("Warning"), msg, QMessageBox::Ok, QMessageBox::Ok); error = true; } } } if (!error) { table->getColumn(col).setFormula(text); } delete [] text; } return !error; } void QGraphDoc::OnEditQuery() { PointMap *pointmap = NULL; ShapeMap *shapemap = NULL; int vc = m_meta_graph->getViewClass(); if (vc & MetaGraph::VIEWVGA) { pointmap = &(m_meta_graph->getDisplayedPointMap()); } else if (vc & MetaGraph::VIEWAXIAL) { shapemap = &(m_meta_graph->getDisplayedShapeGraph()); } else if (vc & MetaGraph::VIEWDATA) { shapemap = &(m_meta_graph->getDisplayedDataMap()); } if (SelectByQuery(pointmap,shapemap)) { SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); } } // Either shapemap or pointmap should be NULL: bool QGraphDoc::SelectByQuery(PointMap *pointmap, ShapeMap *shapemap) { SalaObj program_context; SalaGrf graph; if (pointmap != NULL) { graph.map.point = pointmap; program_context = SalaObj(SalaObj::S_POINTMAPOBJ, graph); } else if (shapemap != NULL) { SalaGrf graph; graph.map.shape = shapemap; program_context = SalaObj(SalaObj::S_SHAPEMAPOBJ, graph); } else { QMessageBox::warning(this, tr("Warning"), tr("Replace column contents requires either a shape map or visibility graph"), QMessageBox::Ok, QMessageBox::Ok); return false; } AttributeTable *table = program_context.getTable(); // insert dialog is a misnomer now! CInsertColumnDlg dlg(table,-1); // -1 sets it to use the select text rather than replace text bool error = true; while (error && QDialog::Accepted == dlg.exec()) { error = false; std::string multibytetext(((MainWindow*)m_mainFrame)->m_formula_cache.toStdString()); char *text = new char[multibytetext.length()+1]; strcpy(text,multibytetext.c_str()); std::istringstream stream(text); SalaProgram proggy(program_context); if (!proggy.parse(stream)) { QString msg = QString("There was an error parsing your formula:\n") + QString(proggy.getLastErrorMessage().c_str()); QMessageBox::warning(this, tr("depthmapX"), msg, QMessageBox::Ok, QMessageBox::Ok); error = true; } else { // just check you really are viewing the layers: bool retvar; std::vector selset; if (dlg.m_selection_only) { retvar = proggy.runselect(selset,pointmap ? pointmap->getSelSet() : shapemap->getSelSet()); } else { retvar = proggy.runselect(selset); } if (!retvar) { QString msg = QString("There was an error running your formula:\n") + QString(proggy.getLastErrorMessage().c_str()); QMessageBox::warning(this, tr("depthmapX"), msg, QMessageBox::Ok, QMessageBox::Ok); error = true; } else { // make the selection using the selset: if (pointmap) { pointmap->setCurSel(selset); } else { // note, shape maps have been working with rowids directly: shapemap->setCurSelDirect(selset); } } } delete [] text; if (!error) { return true; } } return false; } void QGraphDoc::OnEditSelectToLayer() { if ((m_meta_graph->getViewClass() & (MetaGraph::VIEWAXIAL|MetaGraph::VIEWDATA)) && m_meta_graph->isSelected()) { CRenameObjectDlg dlg("Layer"); // note, without specifying existing layer name, this defaults to "New layer" behaviour if (QDialog::Accepted == dlg.exec()) { auto layer_name = dlg.m_object_name.toStdString(); if (layer_name.empty()) { layer_name = "Untitled"; } bool retvar = false; if (m_meta_graph->getViewClass() & (MetaGraph::VIEWAXIAL)) { retvar = m_meta_graph->getDisplayedShapeGraph().selectionToLayer(layer_name); } else { retvar = m_meta_graph->getDisplayedDataMap().selectionToLayer(layer_name); } if (retvar) { SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); SetUpdateFlag(QGraphDoc::NEW_TABLE); } else { QMessageBox::warning(this, tr("Warning"), tr("Couldn't create new layer.\nPlease note there is a limit of 64 layers per map."), QMessageBox::Ok, QMessageBox::Ok); } } } } /////////////////////////////////////////////////////////////////////// void QGraphDoc::OnRemoveColumn() { // just check you really are viewing the layers: int col = m_meta_graph->getDisplayedAttribute(); // -1 is reference number, -2 is displaying nothing (-2 shouldn't happen but is) if (col == -1 || col == -2 || m_meta_graph->isAttributeLocked(col)) { QMessageBox::warning(this, tr("Warning"), tr("Cannot remove locked column"), QMessageBox::Ok, QMessageBox::Ok); } else if (QMessageBox::Yes == QMessageBox::question(this, tr("depthmapX"), tr("Are you sure you want to delete the currently displayed column?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No)) { // note this -1 simply means shift back one m_meta_graph->setDisplayedAttribute(col-1); m_meta_graph->removeAttribute(col); SetUpdateFlag(QGraphDoc::NEW_DATA); SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_COLUMN ); } } //////////////////////////////////////////////////////////////////////////////// void QGraphDoc::OnFileProperties() { if (!m_meta_graph) { QMessageBox::warning(this, tr("Warning"), tr("No graph"), QMessageBox::Ok, QMessageBox::Ok); } else { CFilePropertiesDlg dlg; // editables dlg.m_title = QString(m_meta_graph->getTitle().c_str()); dlg.m_location = QString(m_meta_graph->getLocation().c_str()); dlg.m_description = QString(m_meta_graph->getDescription().c_str()); // non-editables dlg.m_author = QString(m_meta_graph->getPerson().c_str()); dlg.m_create_date = QString(m_meta_graph->getDate().c_str()); dlg.m_create_program = QString(m_meta_graph->getProgram().c_str()); dlg.m_organization = QString(m_meta_graph->getOrganization().c_str()); if (m_meta_graph && m_meta_graph->getVersion() != -1) { QString info; info.sprintf("%d", m_meta_graph->getVersion()); dlg.m_file_version = info; } else { dlg.m_file_version = tr(""); } if (QDialog::Accepted == dlg.exec()) { m_meta_graph->setTitle(dlg.m_title.toStdString()); m_meta_graph->setLocation(dlg.m_location.toStdString()); m_meta_graph->setDescription(dlg.m_description.toStdString()); } } } void QGraphDoc::OnViewShowGrid() { if (m_meta_graph->m_showgrid) { m_meta_graph->m_showgrid = false; } else { m_meta_graph->m_showgrid = true; } SetRedrawFlag(VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP); } //#include "AttributeSummary.h" void QGraphDoc::OnViewSummary() { CAttributeSummary dlg(this); dlg.exec(); } void QGraphDoc::OnToolsPointConvShapeMap() { //CWaitCursor wait; m_meta_graph->getDisplayedPointMap().mergeFromShapeMap(m_meta_graph->getDisplayedDataMap()); m_meta_graph->setViewClass(MetaGraph::SHOWVGATOP); SetUpdateFlag(QGraphDoc::NEW_TABLE); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); } // this is unlink from a set of points! void QGraphDoc::OnToolsAxialConvShapeMap() { if (m_meta_graph->getDataMaps().empty()) { QMessageBox::warning(this, tr("Warning"), tr("No data source layers for unlink points"), QMessageBox::Ok, QMessageBox::Ok); return; } std::vector names; for (size_t i = 0; i < m_meta_graph->getDataMaps().size(); i++) { names.push_back(std::string("Data Maps: ") + m_meta_graph->getDataMaps()[i].getName()); } // choose shape map... CLayerChooserDlg dlg(names); dlg.m_text = tr("Please select source layer for unlink points"); if (dlg.exec()) { //CWaitCursor wait; m_meta_graph->getDisplayedShapeGraph().unlinkFromShapeMap(m_meta_graph->getDataMaps()[dlg.m_layer]); m_meta_graph->setViewClass(MetaGraph::SHOWAXIALTOP); SetUpdateFlag(QGraphDoc::NEW_TABLE); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH, NEW_DATA); } } void QGraphDoc::OnToolsLineLoadUnlinks() { // Get file from user QFileDialog::Options options = 0; QString outfile = QFileDialog::getOpenFileName( 0, tr("Import Unlink IDs"), "", tr("Text files (*.txt)\nAll files (*.*)"), 0, options); if(outfile.isEmpty()) return; std::ifstream stream(outfile.toLatin1()); if (stream.fail()) { QMessageBox::warning(this, tr("Warning"), tr("There was an error opening the file.\nPlease check the file is not already open"), QMessageBox::Ok, QMessageBox::Ok); return; } // Check to see if they want to use another key column for the unlink: CAttributeChooserDlg dlg(m_meta_graph->getDisplayedShapeGraph().getAttributeTable()); dlg.m_text = tr("Please select the attribute the file uses as the key for the unlinks"); if (dlg.exec() == QDialog::Accepted) { // Run the process if (!m_meta_graph->getDisplayedShapeGraph().unlinkShapeSet(stream,dlg.m_attribute)) { QMessageBox::warning(this, tr("Warning"), tr("There was an error reading the unlink file.\ndepthmapX is expecting a tab delimited set of unlink IDs"), QMessageBox::Ok, QMessageBox::Ok); return; } m_meta_graph->setViewClass(MetaGraph::SHOWAXIALTOP); SetUpdateFlag(QGraphDoc::NEW_DATA); SetRedrawFlag(VIEW_ALL,REDRAW_GRAPH,NEW_DATA); } } void QGraphDoc::OnConvertMapShapes() { if (m_meta_graph && m_meta_graph->viewingShapes()) { CConvertShapesDlg dlg; if (QDialog::Accepted == dlg.exec()) { int viewclass = m_meta_graph->getViewClass(); if (viewclass & MetaGraph::VIEWDATA) { m_meta_graph->getDisplayedDataMap().convertPointsToPolys(dlg.m_radius,dlg.m_selected_only); } else if (viewclass & MetaGraph::VIEWAXIAL) { m_meta_graph->getDisplayedDataMap().convertPointsToPolys(dlg.m_radius,dlg.m_selected_only); } else { QMessageBox::warning(this, tr("Warning"), tr("Cannot perform conversion on this map type"), QMessageBox::Ok, QMessageBox::Ok); } } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// QT_END_NAMESPACE ================================================ FILE: depthmapX/GraphDoc.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef GRAPHDOC_H #define GRAPHDOC_H #include #include #include #include #include #include #include // My standard stuff: #include #include #include #include #include #include // Sala #include #include "salalib/salaprogram.h" #include #include #include "salalib/ianalysis.h" QT_BEGIN_NAMESPACE //! [0] class RenderThread : public QThread { Q_OBJECT public: RenderThread(QObject *parent = 0); ~RenderThread(); void* m_parent; bool simple_version; void render(void* param); signals: void renderedImage(const QImage &image, double scaleFactor); void runtimeExceptionThrown(int type, std::string message); void showWarningMessage(QString title, QString message); void closeWaitDialog(); protected: void run(); private: bool restart; bool abort; QMutex mutex; QWaitCondition condition; }; class QGraphDoc; // forward declaration required by CMSCommunicator::run(QGraphDoc *) class CMSCommunicator : public Communicator { public: enum { IMPORT, IMPORTMIF, MAKEPOINTS, MAKEGRAPH, ANALYSEGRAPH, POINTDEPTH, METRICPOINTDEPTH, ANGULARPOINTDEPTH, TOPOLOGICALPOINTDEPTH, MAKEISOVIST, MAKEISOVISTPATH, MAKEISOVISTSFROMFILE, MAKEALLLINEMAP, MAKEFEWESTLINEMAP, MAKEDRAWING, MAKEUSERMAP, MAKEUSERMAPSHAPE, MAKEUSERSEGMAP, MAKEUSERSEGMAPSHAPE, MAKEGATESMAP, MAKEBOUNDARYMAP, MAKESEGMENTMAP, MAKECONVEXMAP, AXIALANALYSIS, SEGMENTANALYSISTULIP, SEGMENTANALYSISANGULAR, TOPOMETANALYSIS, AGENTANALYSIS, FROMCONNECTOR}; public: CMSCommunicator(); virtual ~CMSCommunicator(); virtual void CommPostMessage(int m, int x) const; // Inline below CWaitDialog void * parent_doc; bool simple_version; // public is not a good thing but will do for now! // TV void SetFunction(int function) { m_function = function; } void setAnalysis(int function) { m_function = function; } int GetFunction() const { return m_function; } void SetOption(int option, size_t which = 0) { while (which >= m_options.size()) m_options.push_back(-1); m_options[which] = option; } int GetOption(size_t which = 0) const { return (which >= m_options.size()) ? -1 : m_options[which]; } void SetSeedPoint(const Point2f& p) { m_seed_point = p; } const Point2f& GetSeedPoint() const { return m_seed_point; } void SetSeedAngle(const double angle) { m_seed_angle = angle; } double GetSeedAngle() const { return m_seed_angle; } void SetSeedFoV(const double fov) { m_seed_fov = fov; } double GetSeedFoV() const { return m_seed_fov; } // void SetString(const QString& str) { m_string= str; } const QString& GetString() const { return m_string; } void SetFileSet(QStringList strings) { m_fileset.clear(); for (int i = 0; i < strings.size(); i++) { m_fileset.push_back(strings[i].toStdString()); } } void setAnalysis(std::unique_ptr analysis) { m_analysis = std::move(analysis); } void setSuccessUpdateFlags(int type, bool modified = true) { m_successUpdateFlagType = type; m_successUpdateFlagModified = modified; } void setSuccessRedrawFlags(int viewtype, int flag, int reason) { m_successRedrawFlagViewType = viewtype; m_successRedrawFlag = flag; m_successRedrawReason = reason; } void runAnalysis(QGraphDoc &graphDoc); protected: std::vector m_options; int m_function; Point2f m_seed_point; double m_seed_angle; double m_seed_fov; //CImportedModule m_module; QString m_string; // for a generic string std::unique_ptr m_analysis; int m_successUpdateFlagType; bool m_successUpdateFlagModified = true; int m_successRedrawFlagViewType; bool m_successRedrawFlag; int m_successRedrawReason; }; struct QFilePath { QString m_path; QString m_name; QString m_ext; QFilePath(const QString& pathname) { int dot = pathname.lastIndexOf('.'); int slash = pathname.lastIndexOf('\\'); if (slash != -1) { m_path = pathname.left(slash+1); } else { slash = pathname.lastIndexOf ('/'); if (slash != -1) m_path = pathname.left(slash+1); } if (dot != -1) { m_name = pathname.mid(slash+1, dot-slash-1); m_ext = pathname.mid(dot+1); m_ext = m_ext.toUpper(); } else { m_name = pathname.mid(slash+1); } } }; class QGraphDoc : public QWidget { Q_OBJECT private: void exceptionThrownInRenderThread(int type, std::string message); void messageFromRenderThread(QString title, QString message); public: QGraphDoc(const QString &author, const QString &organisation); CMSCommunicator *m_communicator; int m_make_algorithm; // algorithm to make graph double m_make_maxdist; // maximum distance you can see (set to -1.0 for infinite) MetaGraph *m_meta_graph; QString m_base_title; QString m_opened_name; bool modifiedFlag; // Redraw commands enum {REDRAW_DONE, REDRAW_POINTS, REDRAW_GRAPH, REDRAW_TOTAL }; // Redraw reasons enum {UNDECLARED, NEW_FOCUS, NEW_DEPTHMAPVIEW_SETUP, NEW_LINESET, NEW_DATA, NEW_SELECTION, NEW_TABLE, NEW_COLUMN, NEW_FILE, DELETED_TABLE }; // Mainframe table changes: enum {CONTROLS_DESTROYALL,CONTROLS_LOADALL, CONTROLS_LOADGRAPH,CONTROLS_RELOADGRAPH,CONTROLS_LOADCONVERT,CONTROLS_LOADDRAWING, CONTROLS_LOADATTRIBUTES,CONTROLS_CHANGEATTRIBUTE}; // Views attached (by viewtypes) enum {VIEW_ALL = 0, VIEW_MAP = 1, VIEW_SCATTER = 2, VIEW_TABLE = 3, VIEW_3D = 4, VIEW_MAP_GL = 5, VIEW_TYPES = 6}; void* m_mainFrame; QWidget *m_view[VIEW_TYPES]; // now individual to each view bool m_flag_lock; int m_redraw_flag[VIEW_TYPES]; bool SetRedrawFlag(int viewtype, int flag, int reason = UNDECLARED, QWidget *originator = NULL); // (almost) thread safe int GetRedrawFlag(int viewtype) const { return m_redraw_flag[viewtype]; } bool m_remenu_flag[VIEW_TYPES]; void SetRemenuFlag(int viewtype, bool on) { if (viewtype) { m_remenu_flag[viewtype] = on; } else { for (int i = 1; i < VIEW_TYPES; i++) { m_remenu_flag[i] = on; } } } bool GetRemenuFlag(int viewtype) const { return m_remenu_flag[viewtype]; } void SetUpdateFlag(int type, bool modified = true); Point2f m_position; // Last known mouse position, in DXF units // Paths for the March 05 evolved agents // (loaded from file using the test button) std::vector> m_evolved_paths; RenderThread m_thread; QProgressDialog* m_waitdlg; QString m_base_description; bool modify_prog; int Tid_progress; int m_num_steps; int m_record; int m_step; int m_num_records; QTime m_timer; void ProcPostMessage(int m, int x); void UpdateMainframestatus(); public slots: void cancel_wait(); // Operations public: void CreateWaitDialog(const QString& description, QWidget *pr = NULL); void DestroyWaitDialog(); void OnFillPoints(const Point2f& p, int fill_type = 0 ); void OnMakeIsovist(const Point2f& seed, double angle = -1.0); void OnToolsAxialMap( const Point2f& seed ); int RenameColumn(AttributeTable *tab, int col); bool ReplaceColumnContents(PointMap* pointmap, ShapeMap *shapemap, int col); bool SelectByQuery(PointMap* pointmap, ShapeMap *shapemap); void OnToolsTopomet(); bool OnNewDocument(); int OnSaveDocument(QString lpszPathName); int OnSaveDocument(QString lpszPathName, int version); bool OnCloseDocument(int); int OnOpenDocument(char* lpszPathName); void OnToolsTPD(); void OnVGALinksFileImport(); void OnGenerateIsovistsFromFile(); void OnFileImport(); void OnFileExport(); void OnFileExportMapGeometry(); void OnFileExportLinks(); void OnAxialConnectionsExportAsDot(); void OnAxialConnectionsExportAsPairCSV(); void OnSegmentConnectionsExportAsPairCSV(); void OnToolsMakeGraph(); void OnToolsUnmakeGraph(); void OnEditClear(); void OnToolsRun(); void OnEditUndo(); void OnToolsPD(); void OnPushToLayer(); void OnEditGrid(); void OnToolsMPD(); void OnToolsMakeFewestLineMap(); void OnToolsRunSeg(); void OnAddColumn(); void OnRemoveColumn(); void OnFileProperties(); void OnToolsAPD(); void OnViewShowGrid(); void OnToolsRunAxa(); void OnSwapColours(); void OnViewSummary(); void OnToolsPointConvShapeMap(); void OnToolsAxialConvShapeMap(); void OnUpdateColumn(); void OnToolsAgentRun(); void OnRenameColumn(); void OnEditQuery(); void OnColumnProperties(); void OnLayerNew(); void OnLayerDelete(); void OnLayerConvert(); void OnLayerConvertDrawing(); void OnEditSelectToLayer(); void OnToolsIsovistpath(); bool OnFileSave(); bool OnFileSaveAs(); void OnConvertMapShapes(); void OnToolsLineLoadUnlinks(); void OnPointmapExportConnectionsAsCSV(); protected: virtual void timerEvent(QTimerEvent *event); }; QT_END_NAMESPACE #endif ================================================ FILE: depthmapX/UI/AboutDlg.ui ================================================ CAboutDlg 0 0 499 420 About depthmapX 20 20 461 381 depthmapX Version information Copyright message (overwritten at runtime) In memory of Alasdair Turner <html><head/><body><p><a href="http://en.wikipedia.org/wiki/Alasdair_Turner"><span style=" text-decoration: underline; color:#0000ff;">http://en.wikipedia.org/wiki/Alasdair_Turner</span></a></p></body></html> Qt::ScrollBarAlwaysOn true For more information or to submit a bug see: <html><head/><body><p><a href="https://github.com/SpaceGroupUCL/depthmapX"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/varoudis/depthmapX</span></a></p></body></html> OK c_ok clicked() CAboutDlg OnOK() 103 374 209 329 OnOK() ================================================ FILE: depthmapX/UI/AgentAnalysisDlg.ui ================================================ CAgentAnalysisDlg 0 0 380 557 Agent Analysis Setup 10 10 361 111 Global setup 20 30 320 24 Analysis length(timesteps) 20 70 321 26 Record gate counts in data map true 0 10 130 361 131 Agent set parameters 20 60 191 21 Release from any location 20 90 231 21 Release from selected locations 20 30 321 24 Release rate (agents per timestep) 10 270 361 141 Agent program parameters 21 31 321 24 Field of view (bins) 32 20 70 320 24 Steps before turn decision 20 110 321 24 Timesteps in system 30 430 321 29 Record trails for agents 30 470 321 26 Movement rule: Standard Line of Sight Length Occluded Length Any occlusions Occlusions Group bins (45 degrees) Occlusions Group bins (60 degrees) Furthest occlusion per bin Per bin far distance weighted Per bin angle weighted Per bin far distance and angle weighted Per bin memory 190 510 164 32 OK Cancel c_ok clicked() CAgentAnalysisDlg OnOK() 168 536 55 520 c_cancel clicked() CAgentAnalysisDlg OnCancel() 257 537 335 509 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/AttributeChooserDlg.ui ================================================ CAttributeChooserDlg 0 0 342 152 Choose Attribute 20 20 311 51 Attribute Atrribute 20 80 301 26 Attribute 160 110 164 32 OK Cancel c_ok clicked() CAttributeChooserDlg OnOK() 174 135 56 123 c_cancel clicked() CAttributeChooserDlg OnCancel() 267 136 333 126 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/AttributeSummary.ui ================================================ CAttributeSummary 0 0 531 319 Attribute Summary Qt::Horizontal 388 20 OK c_ok clicked() CAttributeSummary OnOK() 464 286 316 280 OnOK() OnDblclkList(QModelIndex) ================================================ FILE: depthmapX/UI/AxialAnalysisOptionsDlg.ui ================================================ CAxialAnalysisOptionsDlg 0 0 276 296 Axial Analysis Options Qt::LeftToRight Radius / list of radii, e.g., 2,3,n Qt::LeftToRight false Include choice (betweenness) false Qt::LeftToRight Include local measures Include RA, RRA and total depth Include weighted measures Weight by Qt::Horizontal 58 20 OK Cancel c_radius textChanged(QString) CAxialAnalysisOptionsDlg OnUpdateRadius() 102 51 148 66 c_weighted clicked() CAxialAnalysisOptionsDlg OnWeighted() 100 187 156 205 c_ok clicked() CAxialAnalysisOptionsDlg OnOK() 53 292 107 254 c_cancel clicked() CAxialAnalysisOptionsDlg OnCancel() 158 289 186 256 OnUpdateRadius() OnWeighted() OnOK() OnCancel() ================================================ FILE: depthmapX/UI/ColourScaleDlg.ui ================================================ CColourScaleDlg 0 0 347 376 depthmapX - Set Colour Scale false Qt::Horizontal Blue false Qt::Horizontal Red false Show polygon edges Show polygon centroids Show polygons filled Apply Apply to All Close c_blue_value_window textChanged(QString) CColourScaleDlg OnChangeBlueValue() 202 102 184 78 c_red_value_window textChanged(QString) CColourScaleDlg OnChangeRedValue() 252 199 258 224 c_red_slider_ctrl sliderMoved(int) CColourScaleDlg OnReleasedRedSlider(int) 50 150 51 172 c_blue_slider_ctrl sliderMoved(int) CColourScaleDlg OnReleasedBlueSlider(int) 110 53 116 80 c_color_type currentIndexChanged(int) CColourScaleDlg OnSelchangeColor(int) 223 28 256 47 c_show_lines clicked(bool) CColourScaleDlg OnBnClickedShowLines(bool) 111 237 301 248 c_show_fill clicked(bool) CColourScaleDlg OnBnClickedShowFill(bool) 189 292 308 322 c_show_centroids clicked(bool) CColourScaleDlg OnBnClickedShowCentroids(bool) 229 269 335 275 c_applytoall clicked() CColourScaleDlg OnBnClickedApplytoall() 142 337 15 322 c_ok clicked() CColourScaleDlg OnOK() 81 343 23 354 c_cancel clicked() CColourScaleDlg OnCancel() 336 344 321 349 OnChangeBlueValue() OnChangeRedValue() OnReleasedRedSlider() OnReleasedBlueSlider() OnSelchangeColor(int) OnBnClickedShowLines(bool) OnBnClickedShowFill(bool) OnBnClickedShowCentroids(bool) OnBnClickedApplytoall() OnOK() OnCancel() OnReleasedRedSlider(int) OnReleasedBlueSlider(int) ================================================ FILE: depthmapX/UI/ColourScaleDlg.ui.bak ================================================ CColourScaleDlg 0 0 347 376 depthmapX - Set Colour Scale false Qt::Horizontal Blue false Qt::Horizontal Red false Show polygon edges Show polygon centroids Show polygons filled Apply Apply to All Close c_blue_value_window textChanged(QString) CColourScaleDlg OnChangeBlueValue() 166 120 184 78 c_red_value_window textChanged(QString) CColourScaleDlg OnChangeRedValue() 217 204 258 224 c_red_slider_ctrl valueChanged(int) CColourScaleDlg OnReleasedRedSlider(int) 41 157 51 172 c_blue_slider_ctrl valueChanged(int) CColourScaleDlg OnReleasedBlueSlider(int) 101 70 116 80 c_color_type currentIndexChanged(int) CColourScaleDlg OnSelchangeColor(int) 214 29 256 47 c_show_lines clicked(bool) CColourScaleDlg OnBnClickedShowLines(bool) 111 237 301 248 c_show_fill clicked(bool) CColourScaleDlg OnBnClickedShowFill(bool) 179 304 308 322 c_show_centroids clicked(bool) CColourScaleDlg OnBnClickedShowCentroids(bool) 219 271 335 275 c_applytoall clicked() CColourScaleDlg OnBnClickedApplytoall() 142 337 15 322 c_ok clicked() CColourScaleDlg OnOK() 81 343 23 354 c_cancel clicked() CColourScaleDlg OnCancel() 242 350 321 349 OnChangeBlueValue() OnChangeRedValue() OnReleasedRedSlider() OnReleasedBlueSlider() OnSelchangeColor(int) OnBnClickedShowLines(bool) OnBnClickedShowFill(bool) OnBnClickedShowCentroids(bool) OnBnClickedApplytoall() OnOK() OnCancel() ================================================ FILE: depthmapX/UI/ColumnPropertiesDlg.ui ================================================ CColumnPropertiesDlg 0 0 440 565 Attribute Properties Name true Values Formula Qt::ScrollBarAlwaysOn true Note: the formula may have been applied to a subset of objects Qt::Horizontal 248 20 OK c_ok clicked() CColumnPropertiesDlg OnOK() 339 527 224 517 OnOK() ================================================ FILE: depthmapX/UI/ConvertShapesDlg.ui ================================================ CConvertShapesDlg 0 0 320 180 Convert Map Shapes Convert points to polygons; Polygon radius Apply to selected shapes only Qt::Horizontal 98 20 OK Cancel c_ok clicked() CConvertShapesDlg OnOK() 125 156 42 147 c_cancel clicked() CConvertShapesDlg OnCancel() 212 154 295 138 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/DepthmapAlert.ui ================================================ CDepthmapAlert 0 0 515 263 depthmapX Alert To see this and other depthmapX alerts, please visit: (Not USED!) http://www.vr.ucl.ac.uk/depthmap/alerts I have read this message, please do not display it again Continue c_ok clicked() CDepthmapAlert OnOK() 282 259 171 242 OnOK() ================================================ FILE: depthmapX/UI/DepthmapOptionsDlg.ui ================================================ CDepthmapOptionsDlg 0 0 365 192 depthmapX Options 'depthmapX' runs with basic measures by default, only change it if you know what you are doing... Simple Version true Qt::Vertical 20 37 Show research toolbar (Don't USE!) Qt::Horizontal 40 20 OK Cancel c_ok clicked() CDepthmapOptionsDlg OnOK() 267 148 16 81 c_cancel clicked() CDepthmapOptionsDlg OnCancel() 352 148 192 53 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/EditConnectionsDlg.ui ================================================ CEditConnectionsDlg 0 0 302 256 Edit Connections Change to make &Add connections &Merge connections &Break connections GroupBox &Selected area &Pinned area Qt::Horizontal 40 20 OK Cancel c_ok clicked() CEditConnectionsDlg OnOK() 100 256 38 255 c_cancel clicked() CEditConnectionsDlg OnCancel() 189 262 270 253 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/FewestLineOptionsDlg.ui ================================================ CFewestLineOptionsDlg 0 0 261 99 Make Fewest Line Map Options Remove all subsets Reduce to fewest connections Qt::Horizontal 40 20 OK Cancel c_ok clicked() CFewestLineOptionsDlg OnOK() 96 119 26 97 c_cancel clicked() CFewestLineOptionsDlg OnCancel() 193 115 242 60 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/FilePropertiesDlg.ui ================================================ CFilePropertiesDlg 0 0 400 430 Graph File Properties Title Location Description Qt::Vertical 20 40 Author true Organization true Created on true Created by true File version true Qt::Horizontal 40 20 OK Cancel c_ok clicked() CFilePropertiesDlg OnOK() 180 396 80 386 c_cancel clicked() CFilePropertiesDlg OnCancel() 268 392 330 389 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/FindLocDlg.ui ================================================ CFindLocDlg 0 0 207 150 Find Location x y Qt::Horizontal 40 20 OK Cancel c_ok clicked() CFindLocDlg OnOK() 49 119 16 118 c_cancel clicked() CFindLocDlg OnCancel() 148 130 192 114 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/GridDialog.ui ================================================ CGridDialog 0 0 248 93 Set Grid Properties Spacing 3 0.001000000000000 Qt::Horizontal 40 20 OK Cancel c_spacing_ctrl valueChanged(double) CGridDialog OnDeltaposSpinSpacing(double) 189 39 40 55 c_ok clicked() CGridDialog OnOK() 110 82 37 77 c_cancel clicked() CGridDialog OnCancel() 212 86 271 73 OnDeltaposSpinSpacing(double) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/InsertColumnDlg.ui ================================================ CInsertColumnDlg 0 0 546 296 Replace Attribute Values Formula Existing attributes Apply formula to selected objects only << Use attribute false Qt::Horizontal 40 20 OK Cancel c_use_column clicked() CInsertColumnDlg OnUseAttribute() 318 191 292 206 c_ok clicked() CInsertColumnDlg OnOK() 283 253 138 241 c_cancel clicked() CInsertColumnDlg OnCancel() 338 252 372 212 OnUseAttribute() OnSelChangeColumnNames(QModelIndex) OnDblclkColumnNames(QModelIndex) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/IsovistPathDlg.ui ================================================ CIsovistPathDlg 0 0 317 116 Isovist Options Isovist field of view Quarter isovist (90 degrees) Third isovist (120 degrees) Half isovist (180 degrees) Full isovist (360 degrees) Qt::Horizontal 40 20 OK Cancel c_ok clicked() CIsovistPathDlg OnOK() 149 113 44 103 c_cancel clicked() CIsovistPathDlg OnCancel() 217 117 291 101 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/LayerChooserDlg.ui ================================================ CLayerChooserDlg 0 0 274 134 Choose Layer Layer Layer Layer Qt::Horizontal 40 20 OK Cancel c_ok clicked() CLayerChooserDlg OnOK() 95 117 18 112 c_cancel clicked() CLayerChooserDlg OnCancel() 170 124 242 121 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/LicenceDialog.ui ================================================ CLicenceDialog 0 0 364 274 depthmapX Welcome to depthmapX Licence message Qt::AutoText Qt::Horizontal 40 20 Qt::ScrollBarAlwaysOn true Qt::Horizontal 40 20 Accept Cancel c_ok clicked() CLicenceDialog OnOK() 189 246 64 229 c_cancel clicked() CLicenceDialog OnCancel() 270 240 343 234 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/MakeLayerDlg.ui ================================================ CMakeLayerDlg 0 0 511 318 Create New Map Orgin Map true New Map Type New Map Name Retain original map Copy attributes to new map Remove axial stubs less than false % of line length Qt::Horizontal 40 20 OK Cancel c_layer_type currentIndexChanged(int) CMakeLayerDlg OnSelchangeLayerType(int) 167 114 196 80 c_remove_stubs clicked(bool) CMakeLayerDlg OnRemoveStubs(bool) 103 292 64 321 c_ok clicked() CMakeLayerDlg OnOK() 141 344 49 344 c_cancel clicked() CMakeLayerDlg OnCancel() 250 349 315 330 OnSelchangeLayerType(int) OnRemoveStubs(bool) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/MakeOptionsDlg.ui ================================================ CMakeOptionsDlg 0 0 385 118 Make Graph Options Restrict visibile distance to false Make boundary graph Qt::Horizontal 40 20 OK Cancel c_restrict_visibility clicked(bool) CMakeOptionsDlg OnRestrict(bool) 117 28 209 46 c_ok clicked() CMakeOptionsDlg OnOK() 104 94 29 81 c_cancel clicked() CMakeOptionsDlg OnCancel() 204 96 279 82 OnRestrict(bool) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/NewLayerDlg.ui ================================================ CNewLayerDlg 0 0 255 126 New Map Map type Data Map Convex Map Axial Map Pesh Map Name Qt::Horizontal 40 20 OK Cancel c_layer_selector currentIndexChanged(int) CNewLayerDlg OnSelchangeLayerType(int) 147 40 75 10 c_ok clicked() CNewLayerDlg OnOK() 108 121 22 118 c_cancel clicked() CNewLayerDlg OnCancel() 207 120 248 98 OnSelchangeLayerType(int) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/OptionsDlg.ui ================================================ COptionsDlg 0 0 577 338 Analysis Options Analysis Type Calculate isovist properties Calculate visibility relationships Include &global measures | Select radius (n or number)-> Include &local measures Calculate metric relationships Radius Calculate angular relationships Calculate through vision Record gate counts in data map Qt::Horizontal 40 20 OK Cancel c_output_type clicked(bool) COptionsDlg OnOutputType(bool) 92 35 246 1 c_radio1 clicked(bool) COptionsDlg OnOutputType(bool) 148 72 330 52 c_radio2 clicked(bool) COptionsDlg OnOutputType(bool) 141 156 329 164 c_radio3 clicked(bool) COptionsDlg OnOutputType(bool) 132 231 328 231 c_radio4 clicked(bool) COptionsDlg OnOutputType(bool) 122 256 324 315 c_radius textChanged(QString) COptionsDlg OnUpdateRadius(QString) 248 106 331 93 c_radius2 textChanged(QString) COptionsDlg OnUpdateRadius2(QString) 110 188 331 192 c_ok clicked() COptionsDlg OnOK() 115 337 29 324 c_cancel clicked() COptionsDlg OnCancel() 249 330 301 328 OnOutputType(bool) OnUpdateRadius(QString) OnUpdateRadius2(QString) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/PromptReplace.ui ================================================ CPromptReplace 0 0 362 112 depthmapX You already have line data loaded. Do you want to add this new file to the existing line data, replace the existing line data, or cancel? Add Replace Cancel c_add clicked() CPromptReplace OnAdd() 79 92 25 87 c_replace clicked() CPromptReplace OnReplace() 170 97 231 65 c_cancel clicked() CPromptReplace OnCancel() 264 93 291 92 OnAdd() OnReplace() OnCancel() ================================================ FILE: depthmapX/UI/PushDialog.ui ================================================ CPushDialog 0 0 337 329 Push Values to Map Origin map true Origin attribute true Push values to If destination object intersects more than one object in origin map Take maximum attribute value Take minimum attribute value Take average attribute value Take total of attribute values Record object intersection count Qt::Horizontal 40 20 OK Cancel c_ok clicked() CPushDialog OnOK() 133 288 46 277 c_cancel clicked() CPushDialog OnCancel() 206 289 248 271 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/RenameObjectDlg.ui ================================================ CRenameObjectDlg 0 0 264 114 Rename Column Rename column to: OK Cancel c_ok clicked() CRenameObjectDlg OnOK() 107 110 26 103 c_cancel clicked() CRenameObjectDlg OnCancel() 211 113 250 103 OnOK() OnCancel() ================================================ FILE: depthmapX/UI/SegmentAnalysisDlg.ui ================================================ CSegmentAnalysisDlg 0 0 319 501 Segment Analysis Options Analysis Type Tulip Analysis (Faster) Qt::LeftToRight Tulip Bins (4 to 1024) (1024 approximates full angular analysis) Include choice (betweenness) Full Angular (Slower) Radius Type Segment Steps Metric Angular Radius / List of radii Weighted measures Include weighted measures Weight by Qt::Horizontal 40 20 OK Cancel c_analysis_type clicked(bool) CSegmentAnalysisDlg OnAnalysisType(bool) 170 44 332 64 c_radio2 clicked(bool) CSegmentAnalysisDlg OnAnalysisTulip(bool) 82 158 328 184 c_radius textChanged(QString) CSegmentAnalysisDlg OnUpdateRadius(QString) 250 304 328 304 c_weighted clicked(bool) CSegmentAnalysisDlg OnWeighted(bool) 196 358 327 361 c_ok clicked() CSegmentAnalysisDlg OnOK() 151 460 63 455 c_cancel clicked() CSegmentAnalysisDlg OnCancel() 225 466 314 456 OnAnalysisType(bool) OnAnalysisTulip(bool) OnUpdateRadius(QString) OnWeighted(bool) OnOK() OnCancel() ================================================ FILE: depthmapX/UI/TopoMetDlg.ui ================================================ CTopoMetDlg 0 0 311 214 Analysis Options Analysis Type Topological (Axial) Metric (Physical Distance) Radius (Metric units) Selected segments only (Note: does not perform choice calculation) Qt::Horizontal 40 20 OK Cancel c_ok clicked() CTopoMetDlg OnOK() 147 205 45 192 OnOK() ================================================ FILE: depthmapX/UI/doAll.sh ================================================ uic -o ../CompiledUI/ui_AboutDlg.h AboutDlg.ui uic -o ../CompiledUI/ui_AgentAnalysisDlg.h AgentAnalysisDlg.ui uic -o ../CompiledUI/ui_AttributeChooserDlg.h AttributeChooserDlg.ui uic -o ../CompiledUI/ui_AttributeSummary.h AttributeSummary.ui uic -o ../CompiledUI/ui_AxialAnalysisOptionsDlg.h AxialAnalysisOptionsDlg.ui uic -o ../CompiledUI/ui_ColourScaleDlg.h ColourScaleDlg.ui uic -o ../CompiledUI/ui_ColumnPropertiesDlg.h ColumnPropertiesDlg.ui uic -o ../CompiledUI/ui_ConvertShapesDlg.h ConvertShapesDlg.ui uic -o ../CompiledUI/ui_DepthmapAlert.h DepthmapAlert.ui uic -o ../CompiledUI/ui_DepthmapOptionsDlg.h DepthmapOptionsDlg.ui uic -o ../CompiledUI/ui_EditConnectionsDlg.h EditConnectionsDlg.ui uic -o ../CompiledUI/ui_FewestLineOptionsDlg.h FewestLineOptionsDlg.ui uic -o ../CompiledUI/ui_FilePropertiesDlg.h FilePropertiesDlg.ui uic -o ../CompiledUI/ui_FindLocDlg.h FindLocDlg.ui uic -o ../CompiledUI/ui_GridDialog.h GridDialog.ui uic -o ../CompiledUI/ui_InsertColumnDlg.h InsertColumnDlg.ui uic -o ../CompiledUI/ui_IsovistPathDlg.h IsovistPathDlg.ui uic -o ../CompiledUI/ui_LayerChooserDlg.h LayerChooserDlg.ui uic -o ../CompiledUI/ui_LicenceDialog.h LicenceDialog.ui uic -o ../CompiledUI/ui_MakeLayerDlg.h MakeLayerDlg.ui uic -o ../CompiledUI/ui_MakeOptionsDlg.h MakeOptionsDlg.ui uic -o ../CompiledUI/ui_NewLayerDlg.h NewLayerDlg.ui uic -o ../CompiledUI/ui_OptionsDlg.h OptionsDlg.ui uic -o ../CompiledUI/ui_PromptReplace.h PromptReplace.ui uic -o ../CompiledUI/ui_PushDialog.h PushDialog.ui uic -o ../CompiledUI/ui_RenameObjectDlg.h RenameObjectDlg.ui uic -o ../CompiledUI/ui_SegmentAnalysisDlg.h SegmentAnalysisDlg.ui uic -o ../CompiledUI/ui_TopoMetDlg.h TopoMetDlg.ui ================================================ FILE: depthmapX/UI/licenseagreement.ui ================================================ LicenseAgreement 0 0 661 509 Dialog <html><head/><body><p><img src=":/images/depthmapX.png"/></p></body></html> 426 0 <html><head/><body><p><span style=" font-size:24pt;">depthmapX</span></p><p><span style=" font-size:12pt;">Multi-Platform Spatial Network Analysis Software</span></p><p><a href="https://github.com/varoudis/depthmapX"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/varoudis/depthmapX</span></a></p><p><span style=" font-size:10pt;">(C) 2000-2010 University College London, Alasdair Turner, Eva Friedrich<br/>(C) 2011-2014 Tasos Varoudis, UCL<br/>(C) 2017 Christian Sailer, Petros Koutsolampros</span></p><p><br/></p><p><span style=" font-size:12pt;">In memory of Alasdair Turner </span></p></body></html> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'.SF NS Text'; font-size:13pt; font-weight:400; font-style:normal;"> <p style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier New,courier'; font-size:14pt; color:#000000;">(c) 2000-2010 University College London, Alasdair Turner, Eva Friedrich<br />(c) 2011-2014, Tasos Varoudis<br />(c) 2017 Christian Sailer, Petros Koutsolampros</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt;"><br /></span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier New,courier'; font-size:14pt; color:#000000;">This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt;"><br /></span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier New,courier'; font-size:14pt; color:#000000;">This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.</span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt;"><br /></span></p> <p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Courier New,courier'; font-size:14pt; color:#000000;">You should have received a copy of the GNU General Public License along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span></p></body></html> Click "OK" to Accept the License or Cancel to Exit... Qt::Horizontal 68 20 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() LicenseAgreement accept() 248 254 157 274 buttonBox rejected() LicenseAgreement reject() 316 260 286 274 ================================================ FILE: depthmapX/compatibilitydefines.h ================================================ #ifndef COMPATIBILITYDEFINES_H #define COMPATIBILITYDEFINES_H #ifndef _WIN32 #define TRUE 1 #define FALSE 0 #define LOBYTE(w) ((unsigned char)((w) & 0xff)) #define GetRValue(rgb) (LOBYTE(rgb)) #define GetGValue(rgb) (LOBYTE((rgb) >> 8)) #define GetBValue(rgb) (LOBYTE((rgb)>>16)) #endif #ifdef _WIN32 # ifdef MODULE_API_EXPORTS # define MODULE_API __declspec(dllexport) # else # define MODULE_API __declspec(dllimport) # endif #else # define MODULE_API #endif #endif // COMPATIBILITYDEFINES_H ================================================ FILE: depthmapX/coreapplication.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "depthmapX/coreapplication.h" #include int CoreApplication::exec() { SettingsImpl settings(new DefaultSettingsFactory); if (!settings.readSetting(SettingTag::licenseAccepted, false).toBool()) { auto dummy = MainWindowFactory::getLicenseDialog(); dummy->setModal(true); dummy->setWindowTitle(TITLE_BASE); dummy->exec(); if ( dummy->result() == QDialog::Rejected) { return 0; } settings.writeSetting(SettingTag::licenseAccepted, true); } auto args = arguments(); QString fileToLoad = mFileToLoad; if (args.length() == 2) { fileToLoad = args[1]; } mMainWindow = MainWindowFactory::getMainWindow(fileToLoad, settings); mMainWindow->show(); QApplication::setWindowIcon(QIcon(":/images/depthmapX.png")); return QApplication::exec(); } ================================================ FILE: depthmapX/coreapplication.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/mainwindowfactory.h" #include "version.h" #include "settingsimpl.h" #include #include #include class CoreApplication : public QApplication { private: QString mFileToLoad; std::unique_ptr mMainWindow; public: CoreApplication(int &argc, char **argv) : QApplication(argc, argv) { } bool event(QEvent *event) { // this event is triggered in macOS, either by calling "Open with..." // in Finder, or by dropping a file on the depthmapX icon on the dock // more info: http://doc.qt.io/qt-5/qfileopenevent.html if (event->type() == QEvent::FileOpen) { QFileOpenEvent *openEvent = static_cast(event); mFileToLoad = openEvent->file(); mMainWindow->loadFile(openEvent->file()); } return QApplication::event(event); } int exec(); }; ================================================ FILE: depthmapX/dialogs/AboutDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "AboutDlg.h" #include "version.h" CAboutDlg::CAboutDlg(QWidget *parent) : QDialog(parent) { setupUi(this); QString m_version_info; m_version_info = QString(tr("Version %1.%2.%3 (%4, %5)")).arg(DEPTHMAPX_MAJOR_VERSION).arg(DEPTHMAPX_MINOR_VERSION).arg(DEPTHMAPX_REVISION_VERSION).arg(APP_GIT_BRANCH).arg(APP_GIT_COMMIT); QString m_copyright; m_copyright = QString(tr("(C) 2000-2010 University College London, Alasdair Turner, Eva Friedrich\n(C) 2011-2014 Tasos Varoudis\n(C) 2017 Christian Sailer, Petros Koutsolampros")); QString m_agreement; m_agreement = QString(tr("This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\x0D\x0D\x0A\x0D\x0D\x0AThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\x0D\x0D\x0A\x0D\x0D\x0AYou should have received a copy of the GNU General Public License along with this program. If not, see .")); c_version_info->setText(m_version_info); c_copyright->setText(m_copyright); c_agreement->setText(m_agreement); } void CAboutDlg::OnOK() { accept(); } ================================================ FILE: depthmapX/dialogs/AboutDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_AboutDlg.h" class CAboutDlg : public QDialog, public Ui::CAboutDlg { Q_OBJECT public: CAboutDlg(QWidget *parent = 0); private slots: void OnOK(); }; ================================================ FILE: depthmapX/dialogs/AgentAnalysisDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "AgentAnalysisDlg.h" CAgentAnalysisDlg::CAgentAnalysisDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_release_location = -1; m_fov = 0; m_frames = 0; m_release_rate = 0.0; m_steps = 0; m_timesteps = 0; m_occlusion = -1; m_record_trails = false; m_trail_count = 0; m_trail_count = 50; m_occlusion = 0; m_gatelayer = -1; m_release_location = 0; } void CAgentAnalysisDlg::OnOK() { m_timesteps = c_timesteps->text().toInt(); m_release_location = c_release_location->isChecked(); m_release_rate = c_release_rate->text().toDouble(); m_fov = c_fov->text().toInt(); m_steps = c_steps->text().toInt(); m_frames = c_frames->text().toInt(); if (c_record_trails->checkState()) { m_record_trails = true; } else m_record_trails = false; m_occlusion = c_occlusion->currentIndex(); m_trail_count = c_trail_count->text().toInt(); m_gatelayer = c_layer_selector->currentIndex() - 1; accept(); } void CAgentAnalysisDlg::OnCancel() { reject(); } void CAgentAnalysisDlg::UpdateData(bool value) { if (value) { } else { } } void CAgentAnalysisDlg::showEvent(QShowEvent * event) { c_timesteps->setText(QString("%1").arg(m_timesteps)); c_release_location->setChecked(m_release_location); c_release_rate->setText(QString("%1").arg(m_release_rate)); c_fov->setValue(m_fov); c_steps->setValue(m_steps); c_frames->setText(QString("%1").arg(m_frames)); if (m_record_trails) { c_record_trails->setCheckState(Qt::Checked); } else c_record_trails->setCheckState(Qt::Unchecked); c_occlusion->setCurrentIndex(m_occlusion); c_trail_count->setText(QString("%1").arg(m_trail_count)); for (size_t i = 0; i < m_names.size(); i++) { c_layer_selector->addItem( QString(m_names[i].c_str()) ); } c_layer_selector->setCurrentIndex(m_gatelayer + 1); } ================================================ FILE: depthmapX/dialogs/AgentAnalysisDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_AgentAnalysisDlg.h" #include #include #include class CAgentAnalysisDlg : public QDialog, public Ui::CAgentAnalysisDlg { Q_OBJECT public: CAgentAnalysisDlg(QWidget *parent = 0); int m_release_location; int m_fov; int m_frames; double m_release_rate; int m_steps; int m_timesteps; int m_occlusion; bool m_record_trails; int m_trail_count; //}}AFX_DATA int m_gatelayer; std::vector m_names; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/AttributeChooserDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "AttributeChooserDlg.h" CAttributeChooserDlg::CAttributeChooserDlg(AttributeTable& table, QWidget *parent) : QDialog(parent) { setupUi(this); c_attribute_chooser->setCurrentIndex(-1);//m_attribute = -1; c_text->setText(QString(tr(""))); m_table = &table; } void CAttributeChooserDlg::OnOK() { m_attribute = c_attribute_chooser->currentIndex(); m_text = c_text->text(); m_attribute--; accept(); } void CAttributeChooserDlg::OnCancel() { reject(); } void CAttributeChooserDlg::UpdateData(bool value) { } void CAttributeChooserDlg::showEvent(QShowEvent * event) { c_attribute_chooser->addItem(QString(tr("Ref Number"))); for (int i = 0; i < m_table->getNumColumns(); i++) { c_attribute_chooser->addItem( QString(m_table->getColumnName(i).c_str()) ); } c_attribute_chooser->setCurrentIndex(0); } ================================================ FILE: depthmapX/dialogs/AttributeChooserDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_AttributeChooserDlg.h" #include #include #include class CAttributeChooserDlg : public QDialog, public Ui::CAttributeChooserDlg { Q_OBJECT public: CAttributeChooserDlg(AttributeTable& table, QWidget *parent = 0); int m_attribute; QString m_text; AttributeTable *m_table; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/AttributeSummary.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "AttributeSummary.h" #include "GraphDoc.h" #include "ColumnPropertiesDlg.h" CAttributeSummary::CAttributeSummary(QGraphDoc *pDoc, QWidget *parent) : QDialog(parent) { setupUi(this); m_pDoc = pDoc; } void CAttributeSummary::OnOK() { accept(); } void CAttributeSummary::OnDblclkList(int row, int column) { if (row != -1) { CColumnPropertiesDlg dlg(&(m_pDoc->m_meta_graph->getAttributeTable()), &(m_pDoc->m_meta_graph->getLayers()), row); dlg.exec(); } } void CAttributeSummary::UpdateData(bool value) { } void CAttributeSummary::showEvent(QShowEvent * event) { const AttributeTable& table = m_pDoc->m_meta_graph->getAttributeTable(); c_list->setSelectionBehavior(QAbstractItemView::SelectRows); c_list->setColumnCount(4); QTableWidgetItem *Item; Item = new QTableWidgetItem("Attribute"); c_list->setColumnWidth(0, 220); Item->setTextAlignment(Qt::AlignLeft); c_list->setHorizontalHeaderItem(0, Item); Item = new QTableWidgetItem("Minimum"); c_list->setColumnWidth(1, 100); Item->setTextAlignment(Qt::AlignRight); c_list->setHorizontalHeaderItem(1, Item); Item = new QTableWidgetItem("Average"); c_list->setColumnWidth(2, 100); Item->setTextAlignment(Qt::AlignRight); c_list->setHorizontalHeaderItem(2, Item); Item = new QTableWidgetItem("Maximum"); c_list->setColumnWidth(3, 100); Item->setTextAlignment(Qt::AlignRight); c_list->setHorizontalHeaderItem(3, Item); c_list->clearContents(); c_list->setRowCount(table.getNumColumns()); for (int i = 0; i < table.getNumColumns(); i++) { const AttributeColumn& column = table.getColumn(i); Item = new QTableWidgetItem(QString(column.getName().c_str())); Item->setFlags(Qt::NoItemFlags); c_list->setRowHeight(i, 20); c_list->setItem(i, 0, Item); // char text[64]; // Min sprintf(text, "%g", column.getStats().min); Item = new QTableWidgetItem(QString(text)); Item->setFlags(Qt::NoItemFlags); c_list->setItem(i, 1, Item); // Avg sprintf(text,"%g", column.getStats().total/table.getNumRows()); Item = new QTableWidgetItem(QString(text)); Item->setFlags(Qt::NoItemFlags); c_list->setItem(i, 2, Item); // Max sprintf(text,"%g",column.getStats().max); Item = new QTableWidgetItem(QString(text)); Item->setFlags(Qt::NoItemFlags); c_list->setItem(i, 3, Item); } } ================================================ FILE: depthmapX/dialogs/AttributeSummary.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_AttributeSummary.h" class QGraphDoc; class CAttributeSummary : public QDialog, public Ui::CAttributeSummary { Q_OBJECT public: CAttributeSummary(QGraphDoc *pDoc, QWidget *parent = 0); QGraphDoc *m_pDoc; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnDblclkList(int row, int column); }; ================================================ FILE: depthmapX/dialogs/AxialAnalysisOptionsDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "AxialAnalysisOptionsDlg.h" #include "mainwindow.h" #include CAxialAnalysisOptionsDlg::CAxialAnalysisOptionsDlg(MetaGraph *graph, QWidget *parent) : QDialog(parent) { setupUi(this); m_radius = QString(tr("")); m_choice = false; m_attribute = -1; m_weighted = false; m_rra = false; m_local = false; m_meta_graph = graph; foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { m_choice = mainWin->m_options.choice; m_local = mainWin->m_options.local; m_rra = mainWin->m_options.fulloutput; m_radius = QString(tr("n")); if (mainWin->m_options.weighted_measure_col == -1) { m_weighted = false; m_attribute = -1; } else { m_weighted = true; m_attribute = 0; } break; } } if (m_choice) c_choice->setCheckState(Qt::Checked); else c_choice->setCheckState(Qt::Unchecked); if (m_local) c_local->setCheckState(Qt::Checked); else c_local->setCheckState(Qt::Unchecked); if (m_rra) c_rra->setCheckState(Qt::Checked); else c_rra->setCheckState(Qt::Unchecked); if (m_weighted) c_weighted->setCheckState(Qt::Checked); else c_weighted->setCheckState(Qt::Unchecked); c_attribute_chooser->setCurrentIndex(m_attribute); c_radius->setText(m_radius); } void CAxialAnalysisOptionsDlg::OnUpdateRadius() { QString text; text = c_radius->text(); if (!text.isEmpty() && text.indexOf("n") == -1 && text.indexOf("N") == -1 && text.indexOf("1") == -1 && text.indexOf("2") == -1 && text.indexOf("3") == -1 && text.indexOf("4") == -1 && text.indexOf("5") == -1 && text.indexOf("6") == -1 && text.indexOf("7") == -1 && text.indexOf("8") == -1 && text.indexOf("9") == -1) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be numeric or 'n'\n Alternatively, for multiple radii, type a " "list of comma separated numeric radii (you can include 'n')"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setText(tr("n")); c_radius->setFocus(Qt::OtherFocusReason); } } void CAxialAnalysisOptionsDlg::OnWeighted() { if (c_weighted->checkState()) { UpdateData(true); c_attribute_chooser->setEnabled(true); m_attribute = 0; UpdateData(false); } else { UpdateData(true); c_attribute_chooser->setEnabled(false); m_attribute = -1; UpdateData(false); } } void CAxialAnalysisOptionsDlg::OnOK() { UpdateData(true); if (m_radius.isEmpty() || (m_radius.indexOf("n") == -1 && m_radius.indexOf("N") == -1 && m_radius.indexOf("1") == -1 && m_radius.indexOf("2") == -1 && m_radius.indexOf("3") == -1 && m_radius.indexOf("4") == -1 && m_radius.indexOf("5") == -1 && m_radius.indexOf("6") == -1 && m_radius.indexOf("7") == -1 && m_radius.indexOf("8") == -1 && m_radius.indexOf("9") == -1)) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be numeric or 'n'\n Alternatively, for multiple radii, type a " "list of comma separated numeric radii (you can include 'n')"), QMessageBox::Ok, QMessageBox::Ok); m_radius = tr("n"); UpdateData(false); c_radius->setFocus(Qt::OtherFocusReason); return; } // now parse radius list: foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { mainWin->m_options.radius_set.clear(); QString curr_radius; int curr_comma = -1, last_comma = 0; bool add_rn = false; do { curr_comma = m_radius.indexOf(',', last_comma); if (curr_comma != -1) { curr_radius = m_radius.mid(last_comma, curr_comma - last_comma); last_comma = curr_comma + 1; } else { curr_radius = m_radius.mid(last_comma); } if (!curr_radius.isEmpty()) { if (curr_radius == "n" || curr_radius == "N") { add_rn = true; } else { int radius = curr_radius.toInt(); if (radius <= 0) { QMessageBox::warning( this, tr("Warning"), tr("Each radius in the list must either be 'n' or a number in the range 1-99"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setFocus(Qt::OtherFocusReason); return; } mainWin->m_options.radius_set.insert(static_cast(radius)); } } } while (curr_comma != -1); if (mainWin->m_options.radius_set.size() == 0 || add_rn) { mainWin->m_options.radius_set.insert(-1); } mainWin->m_options.choice = m_choice; mainWin->m_options.local = m_local; mainWin->m_options.fulloutput = m_rra; // attributes: if (!m_weighted) { mainWin->m_options.weighted_measure_col = -1; } else { mainWin->m_options.weighted_measure_col = m_attribute; } break; } } accept(); } void CAxialAnalysisOptionsDlg::UpdateData(bool value) { if (value) { m_radius = c_radius->text(); if (c_choice->checkState()) m_choice = true; else m_choice = false; m_attribute = c_attribute_chooser->currentIndex(); if (c_weighted->checkState()) m_weighted = true; else m_weighted = false; if (c_rra->checkState()) m_rra = true; else m_rra = false; if (c_local->checkState()) m_local = true; else m_local = false; } else { c_radius->setText(m_radius); if (m_choice) c_choice->setCheckState(Qt::Checked); else c_choice->setCheckState(Qt::Unchecked); c_attribute_chooser->setCurrentIndex(m_attribute); if (m_weighted) c_weighted->setCheckState(Qt::Checked); else c_weighted->setCheckState(Qt::Unchecked); if (m_rra) c_rra->setCheckState(Qt::Checked); else c_rra->setCheckState(Qt::Unchecked); if (m_local) c_local->setCheckState(Qt::Checked); else c_local->setCheckState(Qt::Unchecked); } } void CAxialAnalysisOptionsDlg::showEvent(QShowEvent *event) { const ShapeGraph &map = m_meta_graph->getDisplayedShapeGraph(); const AttributeTable &table = map.getAttributeTable(); for (int i = 0; i < table.getNumColumns(); i++) { c_attribute_chooser->addItem(QString(table.getColumnName(i).c_str())); } if (m_weighted) { c_attribute_chooser->setEnabled(true); m_attribute = 0; c_attribute_chooser->setCurrentIndex(m_attribute); } else { m_attribute = -1; c_attribute_chooser->setCurrentIndex(m_attribute); c_attribute_chooser->setEnabled(true); } // UpdateData(false); } ================================================ FILE: depthmapX/dialogs/AxialAnalysisOptionsDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_AxialAnalysisOptionsDlg.h" #include #include #include class CAxialAnalysisOptionsDlg : public QDialog, public Ui::CAxialAnalysisOptionsDlg { Q_OBJECT public: CAxialAnalysisOptionsDlg(MetaGraph *graph, QWidget *parent = 0); void UpdateData(bool value); QString m_radius; bool m_choice; int m_attribute; bool m_weighted; bool m_rra; bool m_local; MetaGraph *m_meta_graph; void showEvent(QShowEvent * event); private slots: void OnUpdateRadius(); void OnWeighted(); void OnOK(); void OnCancel() { reject(); } }; ================================================ FILE: depthmapX/dialogs/CMakeLists.txt ================================================ target_sources(depthmapX PUBLIC TopoMetDlg.h SegmentAnalysisDlg.h RenameObjectDlg.h PushDialog.h PromptReplace.h OptionsDlg.h NewLayerDlg.h MakeOptionsDlg.h MakeLayerDlg.h LicenceDialog.h LayerChooserDlg.h IsovistPathDlg.h InsertColumnDlg.h GridDialog.h FindLocDlg.h FilePropertiesDlg.h FewestLineOptionsDlg.h EditConnectionsDlg.h ConvertShapesDlg.h ColumnPropertiesDlg.h ColourScaleDlg.h AxialAnalysisOptionsDlg.h AttributeSummary.h AttributeChooserDlg.h AgentAnalysisDlg.h AboutDlg.h licenseagreement.h settings/generalpage.h settings/interfacepage.h settings/settingspage.h settings/settingsdialog.h PRIVATE TopoMetDlg.cpp SegmentAnalysisDlg.cpp RenameObjectDlg.cpp PushDialog.cpp PromptReplace.cpp OptionsDlg.cpp NewLayerDlg.cpp MakeOptionsDlg.cpp MakeLayerDlg.cpp LicenceDialog.cpp LayerChooserDlg.cpp IsovistPathDlg.cpp InsertColumnDlg.cpp GridDialog.cpp FindLocDlg.cpp FilePropertiesDlg.cpp FewestLineOptionsDlg.cpp EditConnectionsDlg.cpp ConvertShapesDlg.cpp ColumnPropertiesDlg.cpp ColourScaleDlg.cpp AxialAnalysisOptionsDlg.cpp AttributeSummary.cpp AttributeChooserDlg.cpp AgentAnalysisDlg.cpp AboutDlg.cpp licenseagreement.cpp settings/generalpage.cpp settings/interfacepage.cpp settings/settingsdialog.cpp) ================================================ FILE: depthmapX/dialogs/ColourScaleDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mainwindow.h" CColourScaleDlg::CColourScaleDlg(QWidget *parent) : QDialog(parent) { setupUi(this); setWindowFlags(Qt::WindowStaysOnTopHint); m_show_lines = false; m_show_fill = false; m_show_centroids = false; m_blue = tr(""); m_red = tr(""); m_color = -1; m_docked = false; m_viewDoc = NULL; m_red_brush.setColor(QColor(255, 128, 128)); // CreateSolidBrush(RGB(255,128,128)); m_blue_brush.setColor(QColor(128, 128, 255)); c_blue_slider_ctrl->setMinimum(0); c_blue_slider_ctrl->setMaximum(100); c_red_slider_ctrl->setMinimum(0); c_red_slider_ctrl->setMaximum(100); c_blue_slider_ctrl->setTickInterval(10); c_red_slider_ctrl->setTickInterval(10); // these are out of order... c_color_type->addItem(QString(tr("Equal Ranges (3-Colour)"))); // AXMANESQUE c_color_type->addItem(QString(tr("Equal Ranges (Blue-Red)"))); // BLUERED c_color_type->addItem(QString(tr("Equal Ranges (Purple-Orange)"))); // PURPLEORANGE c_color_type->addItem(QString(tr("depthmapX Classic"))); // DEPTHMAPCLASSIC c_color_type->addItem(QString(tr("Equal Ranges (Greyscale)"))); // GREYSCALE c_color_type->addItem(QString(tr("Equal Ranges (Monochrome)"))); // MONOCHROME c_color_type->addItem(QString(tr("Equal Ranges (3-Colour Hue Only)"))); // HUEONLYAXMANESQUE m_color_type_map.push_back(DisplayParams::AXMANESQUE); m_color_type_map.push_back(DisplayParams::BLUERED); m_color_type_map.push_back(DisplayParams::PURPLEORANGE); m_color_type_map.push_back(DisplayParams::DEPTHMAPCLASSIC); m_color_type_map.push_back(DisplayParams::GREYSCALE); m_color_type_map.push_back(DisplayParams::MONOCHROME); m_color_type_map.push_back(DisplayParams::HUEONLYAXMANESQUE); Clear(); UpdateData(false); } void CColourScaleDlg::OnChangeBlueValue() { QString str; str = c_blue_value_window->text(); m_displayparams.blue = GetNormValue(str.toDouble()); c_blue_slider_ctrl->setValue(m_displayparams.blue * 100.0); c_ok->setEnabled(true); c_applytoall->setEnabled(true); } void CColourScaleDlg::OnChangeRedValue() { QString str; str = c_red_value_window->text(); m_displayparams.red = GetNormValue(str.toDouble()); c_red_slider_ctrl->setValue(m_displayparams.red * 100); c_ok->setEnabled(true); c_applytoall->setEnabled(true); } void CColourScaleDlg::OnReleasedRedSlider(int val) { double value = double(c_red_slider_ctrl->value()) / 100.0; QString text; text.sprintf("%.2f", GetActualValue(value)); c_red_value_window->setText(text); } void CColourScaleDlg::OnReleasedBlueSlider(int val) { double value = double(c_blue_slider_ctrl->value()) / 100.0; QString text; text.sprintf("%.2f", GetActualValue(value)); c_blue_value_window->setText(text); } void CColourScaleDlg::OnSelchangeColor(int value) { UpdateData(true); if (m_color_type_map.size() <= (size_t)value) return; m_color = m_color_type_map[value]; if (m_color == 0 || m_color == 3 || m_color == 5 || m_color == 6) { m_red = "Red"; m_blue = "Blue"; } else if (m_color == 4) { m_red = "Orange"; m_blue = "Purple"; } else if (m_color == 1) { m_red = "White"; m_blue = "Black"; } else { m_red = "Thick"; m_blue = "Thin"; } UpdateData(false); c_ok->setEnabled(true); c_applytoall->setEnabled(true); } void CColourScaleDlg::OnBnClickedShowLines(bool value) { c_ok->setEnabled(true); } void CColourScaleDlg::OnBnClickedShowFill(bool value) { c_ok->setEnabled(true); } void CColourScaleDlg::OnBnClickedShowCentroids(bool value) { c_ok->setEnabled(true); } void CColourScaleDlg::OnBnClickedApplytoall() { MyUpdateData(true, true); // don't destroy c_ok->setEnabled(false); c_applytoall->setEnabled(false); } void CColourScaleDlg::OnOK() { MyUpdateData(true, false); // don't destroy c_ok->setEnabled(false); } void CColourScaleDlg::OnCancel() { // don't destroy, simply hide: hide(); } void CColourScaleDlg::UpdateData(bool value) { if (value) { m_blue = c_blue->text(); m_red = c_red->text(); if (c_show_lines->checkState()) m_show_lines = true; else m_show_lines = false; if (c_show_fill->checkState()) m_show_fill = true; else m_show_fill = false; if (c_show_centroids->checkState()) m_show_centroids = true; else m_show_centroids = false; } else // push data to controls: { c_blue->setText(m_blue); c_red->setText(m_red); if (m_show_lines) c_show_lines->setCheckState(Qt::Checked); else c_show_lines->setCheckState(Qt::Unchecked); if (m_show_fill) c_show_fill->setCheckState(Qt::Checked); else c_show_fill->setCheckState(Qt::Unchecked); if (m_show_centroids) c_show_centroids->setCheckState(Qt::Checked); else c_show_centroids->setCheckState(Qt::Unchecked); } } void CColourScaleDlg::Clear() { m_color = -1; c_color_type->setEnabled(false); m_blue = "Min"; m_red = "Max"; c_blue_value_window->setEnabled(false); c_blue_value_window->setText(tr("")); c_red_value_window->setEnabled(false); c_red_value_window->setText(tr("")); c_blue_slider_ctrl->setEnabled(false); c_blue_slider_ctrl->setValue(0); c_red_slider_ctrl->setEnabled(false); c_red_slider_ctrl->setValue(100); c_ok->setEnabled(false); c_applytoall->setEnabled(false); UpdateData(false); } double CColourScaleDlg::GetActualValue(double sliderpos) { return sliderpos * (m_display_max - m_display_min) + m_display_min; } float CColourScaleDlg::GetNormValue(double actualval) { return ((actualval - m_display_min) / (m_display_max - m_display_min)); } void CColourScaleDlg::Fill() { if (m_color == 0 || m_color == 3 || m_color == 5) { m_red = "Red"; m_blue = "Blue"; } else if (m_color == 4) { m_red = "Orange"; m_blue = "Purple"; } else if (m_color == 1) { m_red = "White"; m_blue = "Black"; } else { m_red = "Thick"; m_blue = "Thin"; } QString text; text.sprintf("%.2f", GetActualValue(m_displayparams.blue)); c_blue_value_window->setText(text); text.sprintf("%.2f", GetActualValue(m_displayparams.red)); c_red_value_window->setText(text); c_blue_slider_ctrl->setValue(int(m_displayparams.blue * 100)); c_red_slider_ctrl->setValue(int(m_displayparams.red * 100)); c_color_type->setEnabled(true); c_blue_value_window->setEnabled(true); c_red_value_window->setEnabled(true); c_blue_slider_ctrl->setEnabled(true); c_red_slider_ctrl->setEnabled(true); c_ok->setEnabled(false); c_applytoall->setEnabled(false); UpdateData(false); } void CColourScaleDlg::OnFocusGraph(QGraphDoc *pDoc, int lParam) { if (lParam == QGraphDoc::CONTROLS_DESTROYALL && pDoc == m_viewDoc) { // Lost graph m_viewDoc = NULL; MyUpdateData(false, false); } else if (lParam == QGraphDoc::CONTROLS_LOADALL && pDoc != m_viewDoc) { // [Possible] change of window (sent on focus) m_viewDoc = pDoc; MyUpdateData(false, false); } else if (lParam != QGraphDoc::CONTROLS_LOADALL && pDoc == m_viewDoc) { // Force update if match current window MyUpdateData(false, false); } } void CColourScaleDlg::MyUpdateData(bool dir, bool apply_to_all) { if (dir == false) { // push data to controls: if (m_viewDoc == NULL) { Clear(); } else { MetaGraph *graph = m_viewDoc->m_meta_graph; if (graph->viewingProcessed()) { if (graph->getViewClass() & MetaGraph::VIEWVGA) { PointMap &map = graph->getDisplayedPointMap(); m_display_min = map.getDisplayMinValue(); m_display_max = map.getDisplayMaxValue(); m_displayparams = map.getDisplayParams(); m_color = m_displayparams.colorscale; } else if (graph->getViewClass() & MetaGraph::VIEWAXIAL) { ShapeGraph &map = graph->getDisplayedShapeGraph(); if (map.getShapeCount() > 0) { m_display_min = map.getDisplayMinValue(); m_display_max = map.getDisplayMaxValue(); } m_displayparams = map.getDisplayParams(); m_color = m_displayparams.colorscale; bool show_lines = m_show_lines, show_fill = m_show_fill, show_centroids = m_show_centroids; map.getPolygonDisplay(show_lines, show_fill, show_centroids); m_show_lines = show_lines; m_show_fill = show_fill; m_show_centroids = show_centroids; } else if (graph->getViewClass() & MetaGraph::VIEWDATA) { ShapeMap &map = graph->getDisplayedDataMap(); if (map.getShapeCount() > 0) { m_display_min = map.getDisplayMinValue(); m_display_max = map.getDisplayMaxValue(); } m_displayparams = map.getDisplayParams(); m_color = m_displayparams.colorscale; bool show_lines = m_show_lines, show_fill = m_show_fill, show_centroids = m_show_centroids; map.getPolygonDisplay(show_lines, show_fill, show_centroids); m_show_lines = show_lines; m_show_fill = show_fill; m_show_centroids = show_centroids; } for (size_t i = 0; i < m_color_type_map.size(); i++) { if (m_color == m_color_type_map[i]) { c_color_type->setCurrentIndex(i); } } Fill(); } else { Clear(); } } UpdateData(false); } else { // get data from controls: UpdateData(true); if (m_viewDoc != NULL) { MetaGraph *graph = m_viewDoc->m_meta_graph; m_color = m_color_type_map[c_color_type->currentIndex()]; m_displayparams.colorscale = m_color; if (graph->getViewClass() & MetaGraph::VIEWVGA) { graph->getDisplayedPointMap().setDisplayParams(m_displayparams, apply_to_all); } else if (graph->getViewClass() & MetaGraph::VIEWAXIAL) { graph->getDisplayedShapeGraph().setDisplayParams(m_displayparams, apply_to_all); graph->getDisplayedShapeGraph().setPolygonDisplay(m_show_lines, m_show_fill, m_show_centroids); } else if (graph->getViewClass() & MetaGraph::VIEWDATA) { graph->getDisplayedDataMap().setDisplayParams(m_displayparams, apply_to_all); graph->getDisplayedDataMap().setPolygonDisplay(m_show_lines, m_show_fill, m_show_centroids); } } m_viewDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP); } } void CColourScaleDlg::showEvent(QShowEvent *event) { // UpdateData(false); } ================================================ FILE: depthmapX/dialogs/ColourScaleDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef ColourScaleDlg_H #define ColourScaleDlg_H #include "depthmapX/GraphDoc.h" #include "depthmapX/ui_ColourScaleDlg.h" class CColourScaleDlg : public QDialog, public Ui::CColourScaleDlg { Q_OBJECT public: CColourScaleDlg(QWidget *parent = 0); QGraphDoc *m_viewDoc; QString m_blue; QString m_red; int m_color; bool m_docked; double m_display_min; double m_display_max; double GetActualValue(double sliderpos); float GetNormValue(double actualval); QBrush m_red_brush; QBrush m_blue_brush; DisplayParams m_displayparams; void MyUpdateData(bool dir, bool apply_to_all); void Clear(); void Fill(); bool m_show_lines; bool m_show_fill; bool m_show_centroids; std::vector m_color_type_map; void UpdateData(bool value); void showEvent(QShowEvent *event); void OnFocusGraph(QGraphDoc *pDoc, int lParam); private slots: void OnChangeBlueValue(); void OnChangeRedValue(); void OnReleasedRedSlider(int); void OnReleasedBlueSlider(int); void OnSelchangeColor(int); void OnBnClickedShowLines(bool); void OnBnClickedShowFill(bool); void OnBnClickedShowCentroids(bool); void OnBnClickedApplytoall(); void OnOK(); void OnCancel(); }; #endif ================================================ FILE: depthmapX/dialogs/ColumnPropertiesDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ColumnPropertiesDlg.h" #include "genlib/stringutils.h" CColumnPropertiesDlg::CColumnPropertiesDlg(AttributeTable *table, LayerManagerImpl *layers, int col, QWidget *parent) : QDialog(parent) { setupUi(this); m_formula = tr(""); m_name = tr(""); m_name_text = tr(""); m_creator = tr(""); m_formula_note = tr(""); m_table = table; m_layers = layers; m_col = col; AttributeColumn &column = m_table->getColumn(m_col); m_name = column.getName().c_str(); m_formula = column.getFormula().c_str(); if (!column.isLocked()) { m_name_text = "Name"; } else { m_name_text = "Name (column locked and cannot be edited)"; } if (m_formula.isEmpty()) { // m_formula_note.Empty(); } else { m_formula_note = tr("Note: the formula may have been applied to a subset of objects"); } UpdateData(false); } void CColumnPropertiesDlg::OnOK() { UpdateData(true); accept(); } void CColumnPropertiesDlg::UpdateData(bool value) { std::vector rows; std::vector summary_all; std::vector summary_sel; rows.push_back(tr("Average")); rows.push_back(tr("Minimum")); rows.push_back(tr("Maximum")); rows.push_back(tr("Std Dev")); rows.push_back(tr("Count")); int i; for (i = 0; i < 15; i++) { if (i == 1 || i == 2) { // minimum and maximum summary_all.push_back(-1.0); summary_sel.push_back(-1.0); } else { summary_all.push_back(0.0); summary_sel.push_back(0.0); } } for (auto iter = m_table->begin(); iter != m_table->end(); iter++) { auto &row = iter->getRow(); double val = row.getValue(m_col); if (val != -1.0 && isObjectVisible(*m_layers, iter->getRow())) { summary_all[0] += val; summary_all[4] += 1.0; if (summary_all[1] == -1.0 || val < summary_all[1]) { summary_all[1] = val; } if (summary_all[2] == -1.0 || val > summary_all[2]) { summary_all[2] = val; } if (row.isSelected()) { summary_sel[0] += val; summary_sel[4] += 1.0; if (summary_sel[1] == -1.0 || val < summary_sel[1]) { summary_sel[1] = val; } if (summary_sel[2] == -1.0 || val > summary_sel[2]) { summary_sel[2] = val; } } } } bool freqrows = false; double unit; if (summary_all[1] != -1.0 && summary_all[2] != -1.0 && summary_all[1] != summary_all[2]) { freqrows = true; unit = (summary_all[2] - summary_all[1]) / 10.0; for (int i = 0; i < 10; i++) { std::string name; if (i == 0) { name = dXstring::formatString(summary_all[1] + unit, "< %f"); } else if (i == 9) { name = dXstring::formatString(summary_all[2] - unit, "> %f"); } else { name = dXstring::formatString(summary_all[1] + unit * i, "%f") + " to " + dXstring::formatString(summary_all[1] + unit * (i + 1), "%f"); } // Unicode conversion a bit of a mess here AT (01.02.11) rows.push_back(QString(name.c_str())); } } if (summary_all[4] != 0) { summary_all[0] /= summary_all[4]; } if (summary_sel[4] != 0) { summary_sel[0] /= summary_sel[4]; } // count of things rows: just for visible at the moment double var_all = 0.0; double var_sel = 0.0; for (auto iter = m_table->begin(); iter != m_table->end(); iter++) { auto &row = iter->getRow(); double val = row.getValue(m_col); if (val != -1.0 && isObjectVisible(*m_layers, iter->getRow())) { var_all += sqr(val - summary_all[0]); if (freqrows) { int pos = floor((val - summary_all[1]) / unit); if (pos == 10) pos = 9; // irritating exactly equal to max summary_all[5 + pos] += 1; } if (row.isSelected()) { var_sel += sqr(val - summary_sel[0]); if (freqrows) { // note: must use summary_all even on selected to make difference int pos = floor((val - summary_all[1]) / unit); if (pos == 10) pos = 9; // irritating exactly equal to max summary_sel[5 + pos] += 1; } } } } if (summary_all[4] != 0) { summary_all[3] = sqrt(var_all / summary_all[4]); } if (summary_sel[4] != 0) { summary_sel[3] = sqrt(var_sel / summary_sel[4]); } c_summary->setSelectionBehavior(QAbstractItemView::SelectRows); c_summary->setColumnCount(3); QTableWidgetItem *Item; Item = new QTableWidgetItem("Value"); c_summary->setColumnWidth(0, 100); Item->setTextAlignment(Qt::AlignLeft); c_summary->setHorizontalHeaderItem(0, Item); Item = new QTableWidgetItem("Attribute"); c_summary->setColumnWidth(1, 100); Item->setTextAlignment(Qt::AlignRight); c_summary->setHorizontalHeaderItem(1, Item); Item = new QTableWidgetItem("Selection"); c_summary->setColumnWidth(2, 100); Item->setTextAlignment(Qt::AlignRight); c_summary->setHorizontalHeaderItem(2, Item); c_summary->clearContents(); c_summary->setRowCount(15); for (i = 0; i < 15; i++) { if (i == 5 && !freqrows) { break; } Item = new QTableWidgetItem(rows[i]); Item->setFlags(Qt::NoItemFlags); c_summary->setRowHeight(i, 20); c_summary->setItem(i, 0, Item); // char text[64]; // All if (i == 4 || summary_all[4] != 0) { sprintf(text, "%g", summary_all[i]); } else { strcpy(text, "No Value"); } Item = new QTableWidgetItem(QString(text)); Item->setFlags(Qt::NoItemFlags); c_summary->setItem(i, 1, Item); // Sel if (i == 4 || summary_sel[4] != 0) { sprintf(text, "%g", summary_sel[i]); } else { strcpy(text, "No Value"); } Item = new QTableWidgetItem(QString(text)); Item->setFlags(Qt::NoItemFlags); c_summary->setItem(i, 2, Item); } if (value) { m_formula = c_formula->toPlainText(); m_name = c_name->text(); m_name_text = c_name_text->text(); m_formula_note = c_formula_note->text(); } else { c_formula->setPlainText(m_formula); c_name->setText(m_name); c_name_text->setText(m_name_text); c_formula_note->setText(m_formula_note); } } void CColumnPropertiesDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/ColumnPropertiesDlg.h ================================================ #// Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_ColumnPropertiesDlg.h" #include #include #include class CColumnPropertiesDlg : public QDialog, public Ui::CColumnPropertiesDlg { Q_OBJECT public: CColumnPropertiesDlg(AttributeTable *table = NULL, LayerManagerImpl *layers = NULL, int col = -1, QWidget *parent = 0); AttributeTable *m_table; LayerManagerImpl *m_layers; int m_col; QString m_formula; QString m_name; QString m_name_text; QString m_creator; QString m_formula_note; void UpdateData(bool value); void showEvent(QShowEvent *event); private slots: void OnOK(); }; ================================================ FILE: depthmapX/dialogs/ConvertShapesDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ConvertShapesDlg.h" CConvertShapesDlg::CConvertShapesDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_radius = 10.0; m_selected_only = false; m_conversion_type = 0; UpdateData(false); } void CConvertShapesDlg::OnOK() { UpdateData(true); accept(); } void CConvertShapesDlg::OnCancel() { reject(); } void CConvertShapesDlg::UpdateData(bool value) { double m_radius = 0.0; if (value) { m_radius = c_radius->text().toDouble(); if (c_selected_only->checkState()) m_selected_only = true; else m_selected_only = false; m_conversion_type = c_conversion_type->currentIndex(); } else { c_radius->setText(QString("%1").arg(m_radius)); if (m_selected_only) c_selected_only->setCheckState(Qt::Checked); else c_selected_only->setCheckState(Qt::Unchecked); c_conversion_type->setCurrentIndex(m_conversion_type); } } void CConvertShapesDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/ConvertShapesDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_ConvertShapesDlg.h" class CConvertShapesDlg : public QDialog, public Ui::CConvertShapesDlg { Q_OBJECT public: CConvertShapesDlg(QWidget *parent = 0); double m_radius; bool m_selected_only; int m_conversion_type; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/EditConnectionsDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "EditConnectionsDlg.h" CEditConnectionsDlg::CEditConnectionsDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_pin_to_sel = true; m_sel_to_pin = true; m_join_type = false; UpdateData(false); } void CEditConnectionsDlg::OnOK() { UpdateData(true); accept(); } void CEditConnectionsDlg::OnCancel() { reject(); } void CEditConnectionsDlg::UpdateData(bool value) { if (value) { m_join_type = c_join_type->isChecked(); if (c_sel_to_pin->checkState()) m_sel_to_pin = true; else m_sel_to_pin = false; if (c_pin_to_sel->checkState()) m_pin_to_sel = true; else m_pin_to_sel = false; } else { c_join_type->setChecked(m_join_type); if (m_sel_to_pin) c_sel_to_pin->setCheckState(Qt::Checked); else c_sel_to_pin->setCheckState(Qt::Unchecked); if (m_pin_to_sel) c_pin_to_sel->setCheckState(Qt::Checked); else c_pin_to_sel->setCheckState(Qt::Unchecked); } } void CEditConnectionsDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/EditConnectionsDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_EditConnectionsDlg.h" class CEditConnectionsDlg : public QDialog, public Ui::CEditConnectionsDlg { Q_OBJECT public: CEditConnectionsDlg(QWidget *parent = 0); bool m_join_type; bool m_sel_to_pin; bool m_pin_to_sel; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/FewestLineOptionsDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "FewestLineOptionsDlg.h" CFewestLineOptionsDlg::CFewestLineOptionsDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_option = false; UpdateData(false); } void CFewestLineOptionsDlg::OnOK() { UpdateData(true); accept(); } void CFewestLineOptionsDlg::OnCancel() { reject(); } void CFewestLineOptionsDlg::UpdateData(bool value) { if (value) { m_option = c_option->isChecked(); } else { c_option->setChecked(m_option); } } void CFewestLineOptionsDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/FewestLineOptionsDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_FewestLineOptionsDlg.h" class CFewestLineOptionsDlg : public QDialog, public Ui::CFewestLineOptionsDlg { Q_OBJECT public: CFewestLineOptionsDlg(QWidget *parent = 0); bool m_option; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/FilePropertiesDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "FilePropertiesDlg.h" CFilePropertiesDlg::CFilePropertiesDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_author = tr(""); m_create_date = tr(""); m_create_program = tr(""); m_description = tr(""); m_location = tr(""); m_organization = tr(""); m_title = tr(""); m_file_version = tr(""); UpdateData(false); } void CFilePropertiesDlg::OnOK() { UpdateData(true); accept(); } void CFilePropertiesDlg::OnCancel() { reject(); } void CFilePropertiesDlg::UpdateData(bool value) { if (value) { m_author = c_author->text(); m_create_date = c_create_date->text(); m_create_program = c_create_program->text(); m_description = c_description->toPlainText(); m_location = c_location->text(); m_organization = c_organization->text(); m_title = c_title->text(); m_file_version = c_file_version->text(); } else { c_author->setText(m_author); c_create_date->setText(m_create_date); c_create_program->setText(m_create_program); c_description->setPlainText(m_description); c_location->setText(m_location); c_organization->setText(m_organization); c_title->setText(m_title); c_file_version->setText(m_file_version); } } void CFilePropertiesDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/FilePropertiesDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_FilePropertiesDlg.h" class CFilePropertiesDlg : public QDialog, public Ui::CFilePropertiesDlg { Q_OBJECT public: CFilePropertiesDlg(QWidget *parent = 0); QString m_author; QString m_create_date; QString m_create_program; QString m_description; QString m_location; QString m_organization; QString m_title; QString m_file_version; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/FindLocDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "FindLocDlg.h" #include CFindLocDlg::CFindLocDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_x = 0.0; m_y = 0.0; UpdateData(false); } void CFindLocDlg::OnOK() { UpdateData(true); QPoint p((int)m_x, (int)m_y); if (!m_bounds.contains(p)) { QMessageBox::warning(this, tr("Warning"), tr("This point is outside the bounds of your map"), QMessageBox::Ok, QMessageBox::Ok); return; } accept(); } void CFindLocDlg::OnCancel() { reject(); } void CFindLocDlg::UpdateData(bool value) { if (value) { m_x = c_x->text().toDouble(); m_y = c_y->text().toDouble(); } else { c_x->setText(QString("%1").arg(m_x)); c_y->setText(QString("%1").arg(m_y)); } } void CFindLocDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/FindLocDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_FindLocDlg.h" class CFindLocDlg : public QDialog, public Ui::CFindLocDlg { Q_OBJECT public: CFindLocDlg(QWidget *parent = 0); double m_x; double m_y; QRegion m_bounds; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/GridDialog.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "GridDialog.h" #include #include CGridDialog::CGridDialog(double maxDimension, QWidget *parent) : QDialog(parent), m_maxdimension(maxDimension) { setupUi(this); m_spacing = 0.01; } void CGridDialog::showEvent(QShowEvent * event) { GridProperties gp(m_maxdimension); m_spacing = gp.getDefault(); c_spacing_ctrl->setRange(gp.getMin(), gp.getMax()); UpdateData(false); } void CGridDialog::OnDeltaposSpinSpacing(double iDelta) { // New slot for this ready userValue(double value) // slot link here though // TV // m_spacing = c_spacing_ctrl->value(); // bug or not? if (int(iDelta / 1.0) > 1) c_spacing_ctrl->setSingleStep(1); else if (int(iDelta / 0.1) > 1) c_spacing_ctrl->setSingleStep(0.1); else if (int(iDelta / 0.01) > 1) c_spacing_ctrl->setSingleStep(0.01); else c_spacing_ctrl->setSingleStep(0.001); } void CGridDialog::OnOK() { UpdateData(true); accept(); } void CGridDialog::OnCancel() { reject(); } void CGridDialog::UpdateData(bool value) { if (value) { m_spacing = c_spacing_ctrl->value(); } else { c_spacing_ctrl->setValue(m_spacing); } } ================================================ FILE: depthmapX/dialogs/GridDialog.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_GridDialog.h" class CGridDialog : public QDialog, public Ui::CGridDialog { Q_OBJECT public: CGridDialog(double maxDimension, QWidget *parent = 0); void UpdateData(bool value); void showEvent(QShowEvent * event); double getSpacing() const { return m_spacing; } private: double m_spacing; double m_maxdimension; private slots: void OnDeltaposSpinSpacing(double); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/InsertColumnDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "InsertColumnDlg.h" #include "mainwindow.h" CInsertColumnDlg::CInsertColumnDlg(AttributeTable *table, int col, QWidget *parent) : QDialog(parent) { setupUi(this); m_selection_only = false; m_col = col; m_col_names.push_back("Ref Number"); for (int i = 0; i < table->getNumColumns(); i++) { m_col_names.push_back(table->getColumnName(i)); } if (m_col == -1) { foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { m_formula_text = mainWin->m_formula_cache.toStdString(); break; } } } else { m_formula_text = table->getColumn(m_col).getFormula(); } c_use_column->setEnabled(true); } void CInsertColumnDlg::OnUseAttribute() { // take the currently selected list item and use in formula QString string; string = c_column_names->item(c_column_names->currentRow())->text(); string = tr("value(\"") + string + tr("\")"); c_formula->insertPlainText(string); c_formula->setFocus(); } void CInsertColumnDlg::OnSelChangeColumnNames() { c_use_column->setEnabled(true); } void CInsertColumnDlg::OnDblclkColumnNames(QListWidgetItem * item) { QString string; string = c_column_names->item(c_column_names->currentRow())->text(); string = tr("value(\"") + string + tr("\")"); c_formula->insertPlainText(string); c_formula->setFocus(); } void CInsertColumnDlg::OnOK() { UpdateData(true); QString text; text = c_formula->toPlainText(); foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { mainWin->m_formula_cache = text; break; } } m_formula_text = text.toStdString(); // note formula text for column will have to be updated by calling function accept(); } void CInsertColumnDlg::OnCancel() { reject(); } void CInsertColumnDlg::UpdateData(bool value) { if (value) { if (c_selection_desc->checkState()) m_selection_only = true; else m_selection_only = false; } else { if (m_selection_only) c_selection_desc->setCheckState(Qt::Checked); else c_selection_desc->setCheckState(Qt::Unchecked); } } void CInsertColumnDlg::showEvent(QShowEvent * event) { for (size_t i = 0; i < m_col_names.size(); i++) { c_column_names->addItem(QString(m_col_names[i].c_str())); } c_formula->setPlainText(QString(m_formula_text.c_str())); c_column_names->setCurrentRow(-1); //c_use_column->setEnabled(false); if (m_col == -1) { // use for selection query // override title and names: setWindowTitle(tr("Make selection")); c_formula_desc->setText(tr("Query")); c_selection_desc->setText(tr("Apply query to selected objects only")); } else { // it's important for the user to know the column name: // (note our column names lookup has "Ref Number" in the zero position, so add one: setWindowTitle(QString("Replace values for ") + QString(m_col_names[m_col+1].c_str())); c_formula_desc->setText(tr("Formula")); c_selection_desc->setText(tr("Apply formula to selected objects only")); } UpdateData(false); } ================================================ FILE: depthmapX/dialogs/InsertColumnDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_InsertColumnDlg.h" #include #include #include #include #include class CInsertColumnDlg : public QDialog, public Ui::CInsertColumnDlg { Q_OBJECT public: CInsertColumnDlg(AttributeTable *table = NULL, int col = -1, QWidget *parent = 0); bool m_selection_only; int m_col; std::vector m_col_names; std::string m_formula_text; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnUseAttribute(); void OnSelChangeColumnNames(); void OnDblclkColumnNames(QListWidgetItem * item); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/IsovistPathDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "IsovistPathDlg.h" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif CIsovistPathDlg::CIsovistPathDlg(QWidget *parent) : QDialog(parent) { setupUi(this); fov_selection = 0; fov_angle = 0.0; UpdateData(false); } void CIsovistPathDlg::OnOK() { UpdateData(true); switch (fov_selection) { case 0: fov_angle = M_PI * 0.5; break; case 1: fov_angle = 2.0 * M_PI / 3.0; break; case 2: fov_angle = M_PI; break; case 3: fov_angle = 2.0 * M_PI; break; default: fov_angle = 2.0 * M_PI; break; } accept(); } void CIsovistPathDlg::OnCancel() { reject(); } void CIsovistPathDlg::UpdateData(bool value) { if (value) { fov_selection = c_fov_selection->currentIndex(); } else { c_fov_selection->setCurrentIndex(fov_selection); } } void CIsovistPathDlg::showEvent(QShowEvent * event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/IsovistPathDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_IsovistPathDlg.h" class CIsovistPathDlg : public QDialog, public Ui::CIsovistPathDlg { Q_OBJECT public: CIsovistPathDlg(QWidget *parent = 0); double fov_angle; int fov_selection; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/LayerChooserDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "LayerChooserDlg.h" CLayerChooserDlg::CLayerChooserDlg(const std::vector& names, QWidget *parent) : QDialog(parent), m_names(names) { setupUi(this); m_text = tr(""); m_layer = 0; } void CLayerChooserDlg::OnOK() { UpdateData(true); accept(); } void CLayerChooserDlg::OnCancel() { reject(); } void CLayerChooserDlg::UpdateData(bool value) { if (value) { m_text = c_text->text(); m_layer = c_layer_selector->currentIndex(); } else { c_text->setText(m_text); c_layer_selector->setCurrentIndex(m_layer); } } void CLayerChooserDlg::showEvent(QShowEvent * event) { for (size_t i = 0; i < m_names.size(); i++) { c_layer_selector->addItem(QString(m_names[i].c_str())); } c_layer_selector->setCurrentIndex(0); UpdateData(false); } ================================================ FILE: depthmapX/dialogs/LayerChooserDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_LayerChooserDlg.h" #include #include #include class CLayerChooserDlg : public QDialog, public Ui::CLayerChooserDlg { Q_OBJECT public: CLayerChooserDlg(const std::vector& names = std::vector(), QWidget *parent = 0); QString m_text; int m_layer; void UpdateData(bool value); void showEvent(QShowEvent * event); const std::vector& m_names; private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/LicenceDialog.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "LicenceDialog.h" const char *g_agreement = "see http://www.gnu.org/licenses/"; CLicenceDialog::CLicenceDialog(QWidget *parent) : QDialog(parent) { setupUi(this); m_message = tr(""); m_agreement = tr(""); } void CLicenceDialog::OnOK() { UpdateData(true); accept(); } void CLicenceDialog::OnCancel() { reject(); } void CLicenceDialog::UpdateData(bool value) { if (value) { m_message = c_message->text(); m_agreement = c_agreement->toPlainText(); } else { c_message->setText(m_message); c_agreement->setPlainText(m_agreement); } } void CLicenceDialog::showEvent(QShowEvent * event) { setWindowTitle(m_title); m_message = tr("old"); m_agreement = QString("old") + tr("old") + QString("old") + g_agreement; UpdateData(false); } ================================================ FILE: depthmapX/dialogs/LicenceDialog.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_LicenceDialog.h" class CLicenceDialog : public QDialog, public Ui::CLicenceDialog { Q_OBJECT public: CLicenceDialog(QWidget *parent = 0); QString m_message; QString m_agreement; QString m_title; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/MakeLayerDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "MakeLayerDlg.h" CMakeLayerDlg::CMakeLayerDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_keeporiginal = true; m_remove_stubs = false; m_push_values = false; m_percentage = 0; m_origin = tr(""); m_layer_name = tr(""); m_mapin = 0; m_mapout = 0; } void CMakeLayerDlg::OnRemoveStubs(bool value) { if (value) { c_percentage->setText(tr("40")); // Bill: 40% (old 25) c_percentage->setEnabled(true); } else { c_percentage->setText(tr("0")); c_percentage->setEnabled(false); } } void CMakeLayerDlg::OnOK() { UpdateData(true); m_mapout = m_lookup[c_layer_type->currentIndex()]; accept(); } void CMakeLayerDlg::OnCancel() { reject(); } void CMakeLayerDlg::UpdateData(bool value) { if (value) { if (c_remove_stubs->checkState()) m_remove_stubs = true; else m_remove_stubs = false; if (c_push_values->checkState()) m_push_values = true; else m_push_values = false; m_percentage = c_percentage->text().toInt(); m_origin = c_origin->text(); m_layer_name = c_layer_name->text(); if (c_keeporiginal->checkState()) m_keeporiginal = true; else m_keeporiginal = false; } else { if (m_remove_stubs) c_remove_stubs->setCheckState(Qt::Checked); else c_remove_stubs->setCheckState(Qt::Unchecked); if (m_push_values) c_push_values->setCheckState(Qt::Checked); else c_push_values->setCheckState(Qt::Unchecked); c_percentage->setText(QString(tr("%1")).arg(m_percentage)); c_origin->setText(m_origin); c_layer_name->setText(m_layer_name); if (m_keeporiginal) c_keeporiginal->setCheckState(Qt::Checked); else c_keeporiginal->setCheckState(Qt::Unchecked); } } static int item_process = 0; void CMakeLayerDlg::showEvent(QShowEvent * event) { item_process = 1; if (m_mapout & MAKELAYER_DRAWING) { c_layer_type->addItem(QString(tr("Drawing Map"))); m_lookup.push_back(MAKELAYER_DRAWING); } if (m_mapout & MAKELAYER_DATA) { c_layer_type->addItem(QString(tr("Data Map"))); m_lookup.push_back(MAKELAYER_DATA); } if (m_mapout & MAKELAYER_AXIAL) { c_layer_type->addItem(QString(tr("Axial Map"))); m_lookup.push_back(MAKELAYER_AXIAL); } if (m_mapout & MAKELAYER_CONVEX) { c_layer_type->addItem(QString(tr("Convex Map"))); m_lookup.push_back(MAKELAYER_CONVEX); } if (m_mapout & MAKELAYER_SEGMENT) { c_layer_type->addItem(QString(tr("Segment Map"))); m_lookup.push_back(MAKELAYER_SEGMENT); } c_layer_type->setCurrentIndex(0); if (m_mapin == MAKELAYER_DRAWING) { // hide push values: c_push_values->hide(); // hide retain map: c_keeporiginal->hide(); // make the dialog a bit smaller... QRect winrect; winrect = geometry(); winrect.setBottom(winrect.bottom() - 75); setGeometry(winrect); winrect = c_ok->geometry(); winrect.setTop(winrect.top() - 75); winrect.setBottom(winrect.bottom() - 75); c_ok->setGeometry(winrect); //wnd = GetDlgItem(IDCANCEL); winrect = c_cancel->geometry(); winrect.setTop(winrect.top() - 75); winrect.setBottom(winrect.bottom() - 75); c_cancel->setGeometry(winrect); } if (m_mapin != MAKELAYER_AXIAL) { // hide remove stubs: c_remove_stubs->hide(); c_percentage->hide(); label_4->hide(); } c_layer_type->setCurrentIndex(0); UpdateData(false); item_process = 0; OnSelchangeLayerType(0); } void CMakeLayerDlg::OnSelchangeLayerType(int value) { if(item_process) return; int which = m_lookup[value]; switch (which) { case MAKELAYER_DRAWING: c_layer_name->setText(tr("Drawing Map")); break; case MAKELAYER_DATA: c_layer_name->setText(tr("Gate Map")); break; case MAKELAYER_AXIAL: c_layer_name->setText(tr("Axial Map")); break; case MAKELAYER_CONVEX: c_layer_name->setText(tr("Convex Map"));//GetDlgItem(IDC_LAYER_NAME)->SetWindowText(_T("Convex Map")); break; case MAKELAYER_SEGMENT: c_layer_name->setText(tr("Segment Map")); break; } if (which == MAKELAYER_SEGMENT) { c_keeporiginal->setEnabled(true); c_push_values->setEnabled(true); c_remove_stubs->setEnabled(true); c_percentage->setEnabled(true); label_4->setEnabled(true); } else if (which == MAKELAYER_DRAWING) { c_keeporiginal->setEnabled(false); c_keeporiginal->setCheckState(Qt::Checked); c_push_values->setEnabled(false); c_push_values->setCheckState(Qt::Unchecked); c_remove_stubs->setEnabled(false); c_remove_stubs->setCheckState(Qt::Unchecked); c_percentage->setEnabled(false); c_percentage->setText(tr("0"));//GetDlgItem(IDC_PERCENTAGE_LENGTH)->SetWindowText(_T("0")); label_4->setEnabled(false); } else { c_keeporiginal->setEnabled(true); c_push_values->setEnabled(true); c_remove_stubs->setEnabled(false); c_percentage->setEnabled(false); label_4->setEnabled(false); } } ================================================ FILE: depthmapX/dialogs/MakeLayerDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_MakeLayerDlg.h" #include #include #include enum {MAKELAYER_DRAWING = 1, MAKELAYER_DATA = 2, MAKELAYER_AXIAL = 4, MAKELAYER_CONVEX = 8, MAKELAYER_GENERIC = 16, MAKELAYER_SEGMENT = 32 }; class CMakeLayerDlg : public QDialog, public Ui::CMakeLayerDlg { Q_OBJECT public: CMakeLayerDlg(QWidget *parent = 0); bool m_remove_stubs; bool m_push_values; int m_percentage; QString m_origin; QString m_layer_name; int m_mapin; int m_mapout; std::vector m_lookup; bool m_keeporiginal; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnSelchangeLayerType(int); void OnRemoveStubs(bool); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/MakeOptionsDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "MakeOptionsDlg.h" #include CMakeOptionsDlg::CMakeOptionsDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_boundarygraph = false; m_maxdist = 0.0; m_restrict_visibility = false; UpdateData(false); } void CMakeOptionsDlg::OnRestrict(bool) { UpdateData(true); if (m_restrict_visibility) { c_maxdist->setEnabled(true); } else { c_maxdist->setEnabled(false); } } void CMakeOptionsDlg::OnOK() { UpdateData(true); if (m_restrict_visibility && m_maxdist <= 0.0) { QMessageBox::warning(this, tr("Warning"), tr("Maximum distance must be over 0.0 if visibility is restricted"), QMessageBox::Ok, QMessageBox::Ok); return; } accept(); } void CMakeOptionsDlg::OnCancel() { reject(); } void CMakeOptionsDlg::UpdateData(bool value) { if (value) { if (c_boundarygraph->checkState()) m_boundarygraph = true; else m_boundarygraph = false; m_maxdist = c_maxdist->text().toDouble(); if (c_restrict_visibility->checkState()) m_restrict_visibility = true; else m_restrict_visibility = false; } else { if (m_boundarygraph) c_boundarygraph->setCheckState(Qt::Checked); else c_boundarygraph->setCheckState(Qt::Unchecked); c_maxdist->setText(QString("%1").arg(m_maxdist)); if (m_restrict_visibility) c_restrict_visibility->setCheckState(Qt::Checked); else c_restrict_visibility->setCheckState(Qt::Unchecked); } } void CMakeOptionsDlg::showEvent(QShowEvent * event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/MakeOptionsDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_MakeOptionsDlg.h" class CMakeOptionsDlg : public QDialog, public Ui::CMakeOptionsDlg { Q_OBJECT public: CMakeOptionsDlg(QWidget *parent = 0); bool m_boundarygraph; double m_maxdist; bool m_restrict_visibility; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnRestrict(bool); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/NewLayerDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "NewLayerDlg.h" #include CNewLayerDlg::CNewLayerDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_layer_type = 0; m_name = tr("Gate Map"); UpdateData(false); } void CNewLayerDlg::OnSelchangeLayerType(int value) { int which = value; switch (which) { case 0: c_name->setText(tr("Gate Map")); break; case 1: c_name->setText(tr("Convex Map")); break; case 2: c_name->setText(tr("Axial Map")); break; case 3: c_name->setText(tr("Pesh Map")); break; } } void CNewLayerDlg::OnOK() { UpdateData(true); if (m_name.isEmpty()) { QMessageBox::warning(this, tr("Warning"), tr("Please enter a name for the new map"), QMessageBox::Ok, QMessageBox::Ok); return; } accept(); } void CNewLayerDlg::OnCancel() { reject(); } void CNewLayerDlg::UpdateData(bool value) { if (value) { m_layer_type = c_layer_selector->currentIndex(); m_name = c_name->text(); } else { c_layer_selector->setCurrentIndex(m_layer_type); c_name->setText(m_name); } } void CNewLayerDlg::showEvent(QShowEvent *event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/NewLayerDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_NewLayerDlg.h" class CNewLayerDlg : public QDialog, public Ui::CNewLayerDlg { Q_OBJECT public: CNewLayerDlg(QWidget *parent = 0); int m_layer_type; QString m_name; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnSelchangeLayerType(int); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/OptionsDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "OptionsDlg.h" #include "mainwindow.h" #include COptionsDlg::COptionsDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_global = false; m_local = false; m_radius = tr(""); m_gates_only = false; m_output_type = -1; m_radius2 = tr(""); foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { m_output_type = mainWin->m_options.output_type; m_local = mainWin->m_options.local; m_global = mainWin->m_options.global; m_gates_only = mainWin->m_options.gates_only; if ((int) mainWin->m_options.radius == -1) { m_radius = QString("n"); m_radius2 = QString("n"); } else if (m_output_type == Options::OUTPUT_VISUAL) { char number[2]; sprintf( number, "%d", (int) mainWin->m_options.radius ); m_radius = QString(number); m_radius2 = tr("n"); } else { char number[32]; sprintf( number, "%g", mainWin->m_options.radius ); m_radius = tr("n"); m_radius2 = QString(number); } break; } } } void COptionsDlg::OnOutputType(bool value) { UpdateData(true); if (m_output_type == Options::OUTPUT_VISUAL) { c_local->setEnabled(true); c_global->setEnabled(true); c_radius->setEnabled(true); } else { c_local->setEnabled(false); c_global->setEnabled(false); c_radius->setEnabled(false); c_radius->setText(tr("n"));// <- essentially, undo changes } if (m_output_type == Options::OUTPUT_METRIC) { c_radius2->setEnabled(true); } else { c_radius2->setText(tr("n"));// <- essentially, undo changes c_radius2->setEnabled(false); } } void COptionsDlg::OnUpdateRadius(QString text) { if (text.length()) { if (!text.toInt() && text != tr("n")) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be n or number in range 1-99"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setText(tr("n")); } } } void COptionsDlg::OnUpdateRadius2(QString text) { if (text.length()) { if (text.toDouble() == 0.0 && text != tr("n")) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be n or a positive number"), QMessageBox::Ok, QMessageBox::Ok); c_radius2->setText(tr("n")); } } } void COptionsDlg::OnOK() { UpdateData(true); foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { mainWin->m_options.local = m_local; mainWin->m_options.global = m_global; mainWin->m_options.output_type = m_output_type; mainWin->m_options.gates_only = m_gates_only; mainWin->m_options.gatelayer = c_layer_selector->currentIndex() - 1; if (m_output_type == Options::OUTPUT_VISUAL) { if (m_radius.compare(tr("n")) == 0) { // 0 means identical mainWin->m_options.radius = -1.0; } else { mainWin->m_options.radius = (double) m_radius.toInt(); if (mainWin->m_options.radius <= 0.0) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be n or a number in the range 1-99"), QMessageBox::Ok, QMessageBox::Ok); return; } } } else { if (m_radius2.compare(tr("n")) == 0) { // 0 means identical mainWin->m_options.radius = -1.0; } else { mainWin->m_options.radius = m_radius2.toDouble(); if (mainWin->m_options.radius <= 0.0) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be n or a positive number"), QMessageBox::Ok, QMessageBox::Ok); return; } } } break; } } accept(); } void COptionsDlg::OnCancel() { reject(); } void COptionsDlg::UpdateData(bool value) { if (value) { if (c_global->checkState()) m_global = true; else m_global = false; if (c_local->checkState()) m_local = true; else m_local = false; m_radius = c_radius->text(); if (c_output_type->isChecked()) m_output_type = 0; else if (c_radio1->isChecked()) m_output_type = 1; else if (c_radio2->isChecked()) m_output_type = 2; else if (c_radio3->isChecked()) m_output_type = 3; else if (c_radio4->isChecked()) m_output_type = 4; else m_output_type = -1; m_radius2 = c_radius2->text(); } else { if (m_global) c_global->setCheckState(Qt::Checked); else c_global->setCheckState(Qt::Unchecked); if (m_local) c_local->setCheckState(Qt::Checked); else c_local->setCheckState(Qt::Unchecked); c_radius->setText(m_radius); switch (m_output_type) { case 0: c_output_type->setChecked(true); break; case 1: c_radio1->setChecked(true); break; case 2: c_radio2->setChecked(true); break; case 3: c_radio3->setChecked(true); break; case 4: c_radio4->setChecked(true); break; default: break; } c_radius2->setText(m_radius2); } } void COptionsDlg::showEvent(QShowEvent * event) { for (size_t i = 0; i < m_layer_names.size(); i++) { c_layer_selector->addItem(QString(m_layer_names[i].c_str())); } foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { c_layer_selector->setCurrentIndex(mainWin->m_options.gatelayer + 1); break; } } OnOutputType(false); UpdateData(false); } ================================================ FILE: depthmapX/dialogs/OptionsDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_OptionsDlg.h" #include #include #include class COptionsDlg : public QDialog, public Ui::COptionsDlg { Q_OBJECT public: COptionsDlg(QWidget *parent = 0); bool m_global; bool m_local; QString m_radius; bool m_gates_only; int m_output_type; QString m_radius2; void UpdateData(bool value); void showEvent(QShowEvent * event); std::vector m_layer_names; private slots: void OnOutputType(bool); void OnUpdateRadius(QString); void OnUpdateRadius2(QString); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/PromptReplace.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "PromptReplace.h" CPromptReplace::CPromptReplace(QWidget *parent) : QDialog(parent) { setupUi(this); m_message = tr(""); UpdateData(false); } void CPromptReplace::OnAdd() { UpdateData(true); done(1); } void CPromptReplace::OnReplace() { UpdateData(true); done(2); } void CPromptReplace::OnCancel() { reject(); } void CPromptReplace::UpdateData(bool value) { if (value) m_message = c_message->text(); else c_message->setText(m_message); } void CPromptReplace::showEvent(QShowEvent * event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/PromptReplace.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_PromptReplace.h" class CPromptReplace : public QDialog, public Ui::CPromptReplace { Q_OBJECT public: CPromptReplace(QWidget *parent = 0); QString m_message; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnAdd(); void OnReplace(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/PushDialog.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "PushDialog.h" CPushDialog::CPushDialog(std::map, std::string> &names, QWidget *parent) : QDialog(parent) { setupUi(this); m_layer_selection = -1; m_origin_attribute = tr(""); m_origin_layer = tr(""); m_count_intersections = false; m_function = -1; m_function = 0; for (auto name: names) { m_names.push_back(name.second); } } void CPushDialog::OnOK() { UpdateData(true); accept(); } void CPushDialog::OnCancel() { reject(); } void CPushDialog::UpdateData(bool value) { if (value) { m_layer_selection = c_layer_selector->currentIndex(); m_origin_attribute = c_origin_attribute->text(); m_origin_layer = c_origin_layer->text(); if (c_count_intersections->checkState()) m_count_intersections = true; else m_count_intersections = false; m_function = c_function->currentIndex(); } else { c_layer_selector->setCurrentIndex(m_layer_selection); c_origin_attribute->setText(m_origin_attribute); c_origin_layer->setText(m_origin_layer); if (m_count_intersections) c_count_intersections->setCheckState(Qt::Checked); else c_count_intersections->setCheckState(Qt::Unchecked); c_function->setCurrentIndex(m_function); } } void CPushDialog::showEvent(QShowEvent * event) { for (size_t i = 0; i < m_names.size(); i++) { c_layer_selector->addItem(QString(m_names[i].c_str())); } c_layer_selector->setCurrentIndex(0); UpdateData(false); } ================================================ FILE: depthmapX/dialogs/PushDialog.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_PushDialog.h" #include #include #include class CPushDialog : public QDialog, public Ui::CPushDialog { Q_OBJECT public: CPushDialog(std::map, std::string>& names, QWidget *parent = 0); int m_layer_selection; QString m_origin_attribute; QString m_origin_layer; bool m_count_intersections; int m_function; void UpdateData(bool value); void showEvent(QShowEvent * event); std::vector m_names; private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/RenameObjectDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "RenameObjectDlg.h" CRenameObjectDlg::CRenameObjectDlg(const QString& object_type, const QString& existing_name, QWidget *parent) : QDialog(parent) { setupUi(this); m_prompt = tr(""); m_object_name = tr(""); m_object_name = existing_name; m_object_type = object_type; // e.g., Column, Layer, etc } void CRenameObjectDlg::OnOK() { UpdateData(true); accept(); } void CRenameObjectDlg::OnCancel() { reject(); } void CRenameObjectDlg::UpdateData(bool value) { if (value) { m_object_name = c_object_name->text(); m_prompt = c_prompt->text(); } else { c_object_name->setText(m_object_name); c_prompt->setText(m_prompt); } } void CRenameObjectDlg::showEvent(QShowEvent * event) { QString lower_object_type = m_object_type; lower_object_type = lower_object_type.toLower(); if (m_object_name.isEmpty()) { QString title = QString("New ") + m_object_type; setWindowTitle(title); m_prompt = QString("New ") + lower_object_type + QString(" name:"); m_object_name = QString(""); } else { QString title = QString("Rename ") + m_object_type; setWindowTitle(title); m_prompt = QString("Rename ") + lower_object_type + QString(" to:"); } UpdateData(false); } ================================================ FILE: depthmapX/dialogs/RenameObjectDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_RenameObjectDlg.h" class CRenameObjectDlg : public QDialog, public Ui::CRenameObjectDlg { Q_OBJECT public: CRenameObjectDlg(const QString& object_type, const QString& existing_name = QString(), QWidget *parent = 0); QString m_object_name; QString m_object_type; QString m_prompt; void UpdateData(bool value); void showEvent(QShowEvent * event); private slots: void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/SegmentAnalysisDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "SegmentAnalysisDlg.h" #include "mainwindow.h" #include CSegmentAnalysisDlg::CSegmentAnalysisDlg(MetaGraph *graph, QWidget *parent) : QDialog(parent) { setupUi(this); m_analysis_type = -1; m_radius = tr(""); m_tulip_bins = 0; m_radius_type = -1; m_choice = false; m_weighted = false; m_attribute = -1; m_meta_graph = graph; foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { if (mainWin->m_options.tulip_bins == 0) { m_analysis_type = 1; m_tulip_bins = 1024; } else { m_analysis_type = 0; m_tulip_bins = mainWin->m_options.tulip_bins; } m_choice = mainWin->m_options.choice; m_radius_type = mainWin->m_options.radius_type; if ((int) mainWin->m_options.radius == -1) { m_radius = QString("n"); } else { char number[32]; sprintf( number, "%g", mainWin->m_options.radius ); m_radius = QString(number); } if (mainWin->m_options.weighted_measure_col == -1) { m_weighted = false; m_attribute = -1; } else { m_weighted = true; m_attribute = 0; } break; } } } void CSegmentAnalysisDlg::OnAnalysisType(bool value) { UpdateData(true); c_tulip_bins->setEnabled(true); c_choice->setEnabled(true); c_radius_type->setEnabled(true); radioButton->setEnabled(true); c_weighted->setEnabled(true); c_attribute->setEnabled(false); } void CSegmentAnalysisDlg::OnAnalysisTulip(bool value) { // actually, not tulip -- they're switched, this is on analyse angular!! UpdateData(true); m_choice = false; m_radius_type = 2; m_analysis_type = 1; m_weighted = false; m_attribute = -1; UpdateData(false); c_tulip_bins->setEnabled(false); c_choice->setEnabled(false); c_radius_type->setEnabled(false); radioButton->setEnabled(false); c_weighted->setEnabled(false); c_attribute->setEnabled(false); } void CSegmentAnalysisDlg::OnUpdateRadius(QString text) { if (!text.isEmpty() && text.indexOf("n") == -1 && text.indexOf("N") == -1 && text.indexOf("1") == -1 && text.indexOf("2") == -1 && text.indexOf("3") == -1 && text.indexOf("4") == -1 && text.indexOf("5") == -1 && text.indexOf("6") == -1 && text.indexOf("7") == -1 && text.indexOf("8") == -1 && text.indexOf("9") == -1) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be numeric or 'n'\nAlternatively, for multiple radii, type a list of comma separated numeric radii (you can include 'n')"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setText(tr("n")); c_radius->setFocus(Qt::OtherFocusReason); } } void CSegmentAnalysisDlg::OnWeighted(bool value) { if (value) { UpdateData(true); c_attribute->setEnabled(true); m_attribute = 0; UpdateData(false); } else { UpdateData(true); c_attribute->setEnabled(false); m_attribute = -1; UpdateData(false); } } void CSegmentAnalysisDlg::OnOK() { UpdateData(true); // my own validate on the radius (note: on fail to convert, atoi returns 0) if (m_radius.isEmpty() || (m_radius.indexOf("n") == -1 && m_radius.indexOf("N") == -1 && m_radius.indexOf("1") == -1 && m_radius.indexOf("2") == -1 && m_radius.indexOf("3") == -1 && m_radius.indexOf("4") == -1 && m_radius.indexOf("5") == -1 && m_radius.indexOf("6") == -1 && m_radius.indexOf("7") == -1 && m_radius.indexOf("8") == -1 && m_radius.indexOf("9") == -1)) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be numeric or 'n'\nAlternatively, for multiple radii, type a list of comma separated numeric radii (you can include 'n')"), QMessageBox::Ok, QMessageBox::Ok); m_radius = tr("n"); UpdateData(false); c_radius->setFocus(Qt::OtherFocusReason); return; } // now parse radius list: foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { mainWin->m_options.radius_set.clear(); QString curr_radius; int curr_comma = -1, last_comma = 0; bool add_rn = false; do { curr_comma = m_radius.indexOf(',',last_comma); if (curr_comma != -1) { curr_radius = m_radius.mid(last_comma, curr_comma-last_comma); last_comma = curr_comma + 1; } else { curr_radius = m_radius.mid(last_comma); } /*curr_radius.TrimLeft(' '); curr_radius.TrimRight(' ');*/ if (!curr_radius.isEmpty()) { if (curr_radius == "n" || curr_radius == "N") { add_rn = true; } else { double radius; if (m_radius_type == 0) { radius = curr_radius.toDouble(); if (radius < 1 || radius > 99) { QMessageBox::warning(this, tr("Warning"), tr("Each radius in the list must either be 'n' or a number in the range 1-99"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setFocus(Qt::OtherFocusReason); return; } } else { radius = curr_radius.toDouble(); if (radius <= 0.0) { QMessageBox::warning(this, tr("Warning"), tr("Each radius in the list must either be 'n' or a number in the range 0.0 to infinity"), QMessageBox::Ok, QMessageBox::Ok); c_radius->setFocus(Qt::OtherFocusReason); return; } } mainWin->m_options.radius_set.insert(double(radius)); } } } while (curr_comma != -1); if (mainWin->m_options.radius_set.size() == 0 || add_rn) { mainWin->m_options.radius_set.insert(-1); } if (m_tulip_bins % 2 != 0) { QMessageBox::warning(this, tr("Warning"), tr("The number of tulip bins must be an even number"), QMessageBox::Ok, QMessageBox::Ok); return; } mainWin->m_options.choice = m_choice; mainWin->m_options.radius_type = m_radius_type; if (m_analysis_type == 1) { mainWin->m_options.tulip_bins = 0; } else { mainWin->m_options.tulip_bins = m_tulip_bins; } // attributes: if (!m_weighted) { mainWin->m_options.weighted_measure_col = -1; } else { mainWin->m_options.weighted_measure_col = m_attribute; } break; } } accept(); } void CSegmentAnalysisDlg::OnCancel() { reject(); } void CSegmentAnalysisDlg::UpdateData(bool value) { if (value) { if (c_analysis_type->isChecked()) { c_radio2->setChecked(false); m_analysis_type = 0; } else if (c_radio2->isChecked()) { m_analysis_type = 1; c_analysis_type->setChecked(false); } else m_analysis_type = -1; m_radius = c_radius->text(); m_tulip_bins = c_tulip_bins->text().toInt(); if (c_radius_type->isChecked()) m_radius_type = 0; else if (radioButton->isChecked()) m_radius_type = 1; else if (c_radio3->isChecked()) m_radius_type = 2; else m_radius_type = -1; if (c_choice->checkState()) m_choice = true; else m_choice = false; if (c_weighted->checkState()) m_weighted = true; else m_weighted = false; m_attribute = c_attribute->currentIndex(); } else { switch (m_analysis_type) { case 0: c_analysis_type->setChecked(true); break; case 1: c_analysis_type->setChecked(false); break; default: break; } c_radius->setText(m_radius); c_tulip_bins->setText(QString("%1").arg(m_tulip_bins)); switch (m_radius_type) { case 0: c_radius_type->setChecked(true); break; case 1: radioButton->setChecked(true); break; case 2: c_radio3->setChecked(true); break; default: break; } if (m_choice) c_choice->setCheckState(Qt::Checked); else c_choice->setCheckState(Qt::Unchecked); if (m_weighted) c_weighted->setCheckState(Qt::Checked); else c_weighted->setCheckState(Qt::Unchecked); c_attribute->setCurrentIndex(m_attribute); } } void CSegmentAnalysisDlg::showEvent(QShowEvent * event) { const ShapeGraph& map = m_meta_graph->getDisplayedShapeGraph(); const AttributeTable& table = map.getAttributeTable(); for (int i = 0; i < table.getNumColumns(); i++) { c_attribute->addItem(QString(table.getColumnName(i).c_str())); } if (m_analysis_type == 1) { m_choice = false; m_radius_type = 2; m_weighted = false; UpdateData(false); c_tulip_bins->setEnabled(false); c_choice->setEnabled(false); c_radius_type->setEnabled(false); radioButton->setEnabled(false); c_weighted->setEnabled(false); c_attribute->setEnabled(false); } else { c_tulip_bins->setEnabled(true); c_choice->setEnabled(true); c_radius_type->setEnabled(true); radioButton->setEnabled(true); c_weighted->setEnabled(true); if (m_weighted) { c_attribute->setEnabled(true); m_attribute = 0; UpdateData(false); } else { m_attribute = -1; c_attribute->setEnabled(false); } } UpdateData(false); } ================================================ FILE: depthmapX/dialogs/SegmentAnalysisDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_SegmentAnalysisDlg.h" #include #include #include class CSegmentAnalysisDlg : public QDialog, public Ui::CSegmentAnalysisDlg { Q_OBJECT public: CSegmentAnalysisDlg(MetaGraph *graph = NULL, QWidget *parent = 0); int m_analysis_type; QString m_radius; int m_tulip_bins; int m_radius_type; bool m_choice; bool m_weighted; int m_attribute; void UpdateData(bool value); void showEvent(QShowEvent * event); MetaGraph *m_meta_graph; private slots: void OnAnalysisType(bool); void OnAnalysisTulip(bool); void OnUpdateRadius(QString); void OnWeighted(bool); void OnOK(); void OnCancel(); }; ================================================ FILE: depthmapX/dialogs/TopoMetDlg.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "TopoMetDlg.h" #include CTopoMetDlg::CTopoMetDlg(QWidget *parent) : QDialog(parent) { setupUi(this); m_topological = TOPOMET_METHOD_TOPOLOGICAL; m_selected_only = false; m_radius = tr("n"); UpdateData(false); } void CTopoMetDlg::OnOK() { UpdateData(true); /*m_radius.TrimLeft(' '); m_radius.TrimRight(' ');*/ // my own validate on the radius (note: on fail to convert, atoi returns 0) if (m_radius.isEmpty() || (m_radius.indexOf("n") == -1 && m_radius.indexOf("N") == -1 && m_radius.indexOf("1") == -1 && m_radius.indexOf("2") == -1 && m_radius.indexOf("3") == -1 && m_radius.indexOf("4") == -1 && m_radius.indexOf("5") == -1 && m_radius.indexOf("6") == -1 && m_radius.indexOf("7") == -1 && m_radius.indexOf("8") == -1 && m_radius.indexOf("9") == -1)) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be numeric or 'n'"), QMessageBox::Ok, QMessageBox::Ok); m_radius = tr("n"); UpdateData(false); return; } if (m_radius == "n" || m_radius == "N") { m_dradius = -1.0; } else { m_dradius = m_radius.toDouble(); if (m_dradius <= 0.0) { QMessageBox::warning(this, tr("Warning"), tr("The radius must either be 'n' or a number in the range 0.0 to infinity"), QMessageBox::Ok, QMessageBox::Ok); return; } } accept(); } void CTopoMetDlg::UpdateData(bool value) { if (value) { if (c_topological->isChecked()) m_topological = TOPOMET_METHOD_TOPOLOGICAL; else if (radioButton->isChecked()) m_topological = TOPOMET_METHOD_METRIC; else m_topological = -1; m_radius = c_radius->text(); if (checkBox->checkState()) m_selected_only = true; else m_selected_only = false; } else { switch(m_topological) { case TOPOMET_METHOD_TOPOLOGICAL: c_topological->setChecked(true); break; case TOPOMET_METHOD_METRIC: radioButton->setChecked(true); break; default: break; } c_radius->setText(m_radius); if (m_selected_only) checkBox->setCheckState(Qt::Checked); else checkBox->setCheckState(Qt::Unchecked); } } void CTopoMetDlg::showEvent(QShowEvent * event) { UpdateData(false); } ================================================ FILE: depthmapX/dialogs/TopoMetDlg.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "ui_TopoMetDlg.h" class CTopoMetDlg : public QDialog, public Ui::CTopoMetDlg { Q_OBJECT private: enum {TOPOMET_METHOD_TOPOLOGICAL = 0, TOPOMET_METHOD_METRIC = 1}; public: CTopoMetDlg(QWidget *parent = 0); int m_topological; QString m_radius; double m_dradius; bool m_selected_only; void UpdateData(bool value); void showEvent(QShowEvent * event); bool isAnalysisTopological() { return m_topological == TOPOMET_METHOD_TOPOLOGICAL; } private slots: void OnOK(); }; ================================================ FILE: depthmapX/dialogs/licenseagreement.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "licenseagreement.h" LicenseAgreement::LicenseAgreement(QWidget *parent) : QDialog(parent), ui(new Ui::LicenseAgreement) { ui->setupUi(this); } LicenseAgreement::~LicenseAgreement() { delete ui; } ================================================ FILE: depthmapX/dialogs/licenseagreement.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef LICENSEAGREEMENT_H #define LICENSEAGREEMENT_H #include #include "ui_licenseagreement.h" #include "compatibilitydefines.h" namespace Ui { class LicenseAgreement; } class LicenseAgreement : public QDialog { Q_OBJECT public: explicit LicenseAgreement(QWidget *parent = 0); ~LicenseAgreement(); private: Ui::LicenseAgreement *ui; }; #endif // LICENSEAGREEMENT_H ================================================ FILE: depthmapX/dialogs/settings/generalpage.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "generalpage.h" #include #include "depthmapX/settings.h" GeneralPage::GeneralPage(Settings &settings, QWidget *parent) : SettingsPage(settings, parent) { readSettings(settings); QGroupBox *configGroup = new QGroupBox(tr("General configuration")); QCheckBox *simpleModeCheckBox = new QCheckBox(tr("Simple mode")); simpleModeCheckBox->setToolTip(tr("If enabled, only Integration [HH] will be calulcated (or Visual Integration [HH] for VGA)")); simpleModeCheckBox->setChecked(m_simpleVersion); connect(simpleModeCheckBox, &QCheckBox::stateChanged, [=] () {m_simpleVersion = !m_simpleVersion;}); QVBoxLayout *configLayout = new QVBoxLayout; configLayout->addWidget(simpleModeCheckBox); configGroup->setLayout(configLayout); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(configGroup); mainLayout->addStretch(1); setLayout(mainLayout); } ================================================ FILE: depthmapX/dialogs/settings/generalpage.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include "settingspage.h" #include class GeneralPage : public SettingsPage { private: bool m_simpleVersion = false; void readSettings(Settings &settings) { m_simpleVersion = settings.readSetting(SettingTag::simpleVersion, true).toBool(); } public: GeneralPage(Settings &settings, QWidget *parent = 0); virtual void writeSettings(Settings &settings) override { settings.writeSetting(SettingTag::simpleVersion, m_simpleVersion); } }; ================================================ FILE: depthmapX/dialogs/settings/interfacepage.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "interfacepage.h" #include #include InterfacePage::InterfacePage(Settings &settings, QWidget *parent) : SettingsPage(settings, parent) { readSettings(settings); QGroupBox *generalGroup = new QGroupBox(tr("General")); QCheckBox *legacyMapCheckBox = new QCheckBox(tr("Legacy map window as default")); legacyMapCheckBox->setChecked(m_defaultMapWindowIsLegacy); connect(legacyMapCheckBox, &QCheckBox::stateChanged, [=] () {m_defaultMapWindowIsLegacy = !m_defaultMapWindowIsLegacy;}); QCheckBox *hoverCheckBox = new QCheckBox(tr("Allow highlighting shapes on hover")); hoverCheckBox->setChecked(m_highlightOnHover); connect(hoverCheckBox, &QCheckBox::stateChanged, [=] () {m_highlightOnHover = !m_highlightOnHover;}); QVBoxLayout *generalLayout = new QVBoxLayout; generalLayout->addWidget(legacyMapCheckBox); generalLayout->addWidget(hoverCheckBox); generalGroup->setLayout(generalLayout); QGroupBox *interfaceColoursGroup = new QGroupBox(tr("Interface colours")); QListWidget *interfaceColoursList = new QListWidget; connect(interfaceColoursList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(onInterfaceColourlItemClicked(QListWidgetItem*))); QListWidgetItem *bgItem = new QListWidgetItem(interfaceColoursList); bgItem->setText(tr("Background")); QPixmap pixmap(20,20); pixmap.fill(m_background); QIcon bgColourIcon(pixmap); bgItem->setIcon(bgColourIcon); colourMap.insert(std::pair(bgItem, &m_background)); QListWidgetItem *fgItem = new QListWidgetItem(interfaceColoursList); fgItem->setText(tr("Foreground")); pixmap.fill(m_foreground); QIcon fgColourIcon(pixmap); fgItem->setIcon(fgColourIcon); colourMap.insert(std::pair(fgItem, &m_foreground)); QVBoxLayout *interfaceColoursLayout = new QVBoxLayout; interfaceColoursLayout->addWidget(interfaceColoursList); interfaceColoursGroup->setLayout(interfaceColoursLayout); QGroupBox *glOptionsGroup = new QGroupBox(tr("OpenGL view options")); QLabel *samplesLabel = new QLabel(tr("Number of antialising samples:")); QComboBox *samplesCombo = new QComboBox; samplesCombo->addItem(tr("0 (fastest)"), 0); samplesCombo->addItem(tr("2"), 2); samplesCombo->addItem(tr("4"), 4); samplesCombo->addItem(tr("8"), 8); samplesCombo->addItem(tr("16 (prettiest)"), 16); samplesCombo->setToolTip(tr("This will make lines smoother if higher, " "but also the overall rendering slower. " "To see the change close and reopen the file")); int index = samplesCombo->findData(m_antialiasingSamples); if ( index != -1 ) { samplesCombo->setCurrentIndex(index); } connect(samplesCombo, static_cast(&QComboBox::activated), [=](int index){ m_antialiasingSamples = samplesCombo->itemData(index).toInt();}); QHBoxLayout *samplesLayout = new QHBoxLayout; samplesLayout->addWidget(samplesLabel); samplesLayout->addWidget(samplesCombo); QVBoxLayout *configLayout = new QVBoxLayout; configLayout->addLayout(samplesLayout); glOptionsGroup->setLayout(configLayout); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(generalGroup); mainLayout->addSpacing(1); mainLayout->addWidget(interfaceColoursGroup); mainLayout->addSpacing(1); mainLayout->addWidget(glOptionsGroup); mainLayout->addStretch(1); setLayout(mainLayout); } void InterfacePage::onInterfaceColourlItemClicked(QListWidgetItem* item) { QColor colour = QColorDialog::getColor(); colourMap[item]->setRed(colour.red()); colourMap[item]->setGreen(colour.green()); colourMap[item]->setBlue(colour.blue()); QPixmap pixmap(100,100); pixmap.fill(colour); QIcon bgColourIcon(pixmap); item->setIcon(bgColourIcon); } ================================================ FILE: depthmapX/dialogs/settings/interfacepage.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include "settingspage.h" #include #include class InterfacePage : public SettingsPage { Q_OBJECT private: QColor m_background; QColor m_foreground; std::map colourMap; int m_antialiasingSamples = 0; bool m_defaultMapWindowIsLegacy = false; bool m_highlightOnHover = true; void readSettings(Settings &settings) { m_foreground = QColor(settings.readSetting(SettingTag::foregroundColour, qRgb(128,255,128)).toInt()); m_background = QColor(settings.readSetting(SettingTag::backgroundColour, qRgb(0,0,0)).toInt()); m_antialiasingSamples = settings.readSetting(SettingTag::antialiasingSamples, 0).toInt(); m_defaultMapWindowIsLegacy = settings.readSetting(SettingTag::legacyMapWindow, false).toBool(); m_highlightOnHover = settings.readSetting(SettingTag::highlightOnHover, true).toBool(); } private slots: void onInterfaceColourlItemClicked(QListWidgetItem *item); public: InterfacePage(Settings &settings, QWidget *parent = 0); virtual void writeSettings(Settings &settings) override { settings.writeSetting(SettingTag::backgroundColour, m_background.rgb()); settings.writeSetting(SettingTag::foregroundColour, m_foreground.rgb()); settings.writeSetting(SettingTag::antialiasingSamples, m_antialiasingSamples); settings.writeSetting(SettingTag::legacyMapWindow, m_defaultMapWindowIsLegacy); settings.writeSetting(SettingTag::highlightOnHover, m_highlightOnHover); } }; ================================================ FILE: depthmapX/dialogs/settings/settingsdialog.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "settingsdialog.h" #include "generalpage.h" #include "interfacepage.h" SettingsDialog::SettingsDialog(Settings &settings) : m_settings(settings) { contentsWidget = new QListWidget; contentsWidget->setIconSize(QSize(96, 84)); contentsWidget->setMovement(QListView::Static); contentsWidget->setMaximumWidth(150); contentsWidget->setSpacing(5); pagesWidget = new QStackedWidget; settingsPages.push_back(std::unique_ptr(new GeneralPage(m_settings))); settingsPages.push_back(std::unique_ptr(new InterfacePage(m_settings))); std::vector>::iterator iter = settingsPages.begin(), end = settingsPages.end(); for ( ; iter != end; ++iter ) { pagesWidget->addWidget((*iter).get()); } QPushButton *saveButton = new QPushButton(tr("Save")); connect(saveButton, &QAbstractButton::clicked, this, &SettingsDialog::saveChangesAndClose); QPushButton *cancelButton = new QPushButton(tr("Cancel")); connect(cancelButton, &QAbstractButton::clicked, this, &QDialog::reject); createIcons(); contentsWidget->setCurrentRow(0); QHBoxLayout *horizontalLayout = new QHBoxLayout; horizontalLayout->addWidget(contentsWidget); horizontalLayout->addWidget(pagesWidget, 1); QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->addStretch(1); buttonsLayout->addWidget(saveButton); buttonsLayout->addWidget(cancelButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(horizontalLayout); mainLayout->addStretch(1); mainLayout->addSpacing(12); mainLayout->addLayout(buttonsLayout); setLayout(mainLayout); setWindowTitle(tr("Settings")); } void SettingsDialog::saveChanges() { std::vector>::iterator iter = settingsPages.begin(), end = settingsPages.end(); for ( ; iter != end; ++iter ) { (*iter)->writeSettings(m_settings); } } void SettingsDialog::saveChangesAndClose() { saveChanges(); QDialog::accept(); } void SettingsDialog::createIcons() { QListWidgetItem *generalButton = new QListWidgetItem(contentsWidget); generalButton->setIcon(QIcon(":/images/general.png")); generalButton->setText(tr("General")); generalButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); QListWidgetItem *interfaceButton = new QListWidgetItem(contentsWidget); interfaceButton->setIcon(QIcon(":/images/interface.png")); interfaceButton->setText(tr("Interface")); interfaceButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); connect(contentsWidget, &QListWidget::currentItemChanged, this, &SettingsDialog::changePage); } void SettingsDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { if (!current) current = previous; pagesWidget->setCurrentIndex(contentsWidget->row(current)); } ================================================ FILE: depthmapX/dialogs/settings/settingsdialog.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "settingspage.h" #include #include "depthmapX/settings.h" #include #include class QListWidget; class QListWidgetItem; class QStackedWidget; class SettingsDialog : public QDialog { Q_OBJECT public: SettingsDialog(Settings &settings); public slots: void changePage(QListWidgetItem *current, QListWidgetItem *previous); private: void createIcons(); std::vector> settingsPages; QListWidget *contentsWidget; QStackedWidget *pagesWidget; Settings &m_settings; void saveChanges(); void saveChangesAndClose(); }; ================================================ FILE: depthmapX/dialogs/settings/settingsdialog.qrc ================================================ images/general.png images/interface.png ================================================ FILE: depthmapX/dialogs/settings/settingspage.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/settings.h" #include class SettingsPage : public QWidget { public: SettingsPage(Settings &settings, QWidget *parent = 0) : QWidget(parent) {} virtual void writeSettings(Settings &settings) = 0; }; ================================================ FILE: depthmapX/icons.rc ================================================ IDI_ICON1 ICON DISCARDABLE "icons\\depthmapX.ico" ================================================ FILE: depthmapX/imainwindowmodule.h ================================================ // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include class MainWindow; class IMainWindowModule : public QObject { Q_OBJECT public: virtual bool createMenus(MainWindow *m_mainWindow) = 0; virtual ~IMainWindowModule() {} }; ================================================ FILE: depthmapX/imainwindowmodulefactory.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imainwindowmodule.h" #include #include typedef std::vector> MainWindowModuleVec; class IMainWindowModuleFactory { public: virtual const MainWindowModuleVec &getModules() const = 0; virtual ~IMainWindowModuleFactory() {} }; ================================================ FILE: depthmapX/indexWidget.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include #include #include #include "mainwindow.h" QT_BEGIN_NAMESPACE AttribWindow::AttribWindow(QWidget *parent, bool custom) : QListWidget(parent) { custom = false; main_frm = parent; installEventFilter(this); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(showContextMenu(const QPoint&))); connect(this, SIGNAL(itemSelectionChanged()), parent, SLOT(OnSelchangingList())); } AttribWindow::~AttribWindow() { // nothing todo } void AttribWindow::showContextMenu(const QPoint &point) { QListWidgetItem *item = itemAt(point); if (!item) return; QPoint ptt(mapToGlobal(point)); ((MainWindow *)main_frm)->showContextMenu(ptt); } QT_END_NAMESPACE ================================================ FILE: depthmapX/indexWidget.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef treeWindow_H #define treeWindow_H #include QT_BEGIN_NAMESPACE class QEvent; class QListWidgetItem; class AttribWindow : public QListWidget { Q_OBJECT public: AttribWindow(QWidget *parent = 0, bool custom = true); ~AttribWindow(); QWidget* main_frm; private slots: void showContextMenu(const QPoint &point); }; QT_END_NAMESPACE #endif ================================================ FILE: depthmapX/main.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include "coreapplication.h" #ifdef _WIN32 #include #endif int main(int argc, char *argv[]) { Q_INIT_RESOURCE(resource); Q_INIT_RESOURCE(settingsdialog); CoreApplication app(argc, argv); return app.exec(); } ================================================ FILE: depthmapX/mainwindow.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mainwindow.h" #include "depthmapX/views/depthmapview/depthmapview.h" #include "depthmapX/views/3dview/3dview.h" #include "depthmapX/views/plotview/plotview.h" #include "depthmapX/views/tableview/tableview.h" #include "dialogs/AboutDlg.h" #include "dialogs/settings/settingsdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include static int current_view_type = 0; const QString editstatetext[] = {"Not Editable", "Editable Off", "Editable On"}; QmyEvent::QmyEvent(Type type, void* wp, int lp) : QEvent(type) { registerEventType(type); wparam = wp; lparam = lp; } void MainWindow::actionEvent ( QActionEvent * event ) { int id; if((id = event->action()->data().toInt())) { } } bool MainWindow::eventFilter(QObject *object, QEvent *e) { if (object == this && e->type() == (QEvent::Type)FOCUSGRAPH) { OnFocusGraph((QGraphDoc*)((QmyEvent*)e)->wparam, ((QmyEvent*)e)->lparam); return true; } return QObject::eventFilter(object, e); } MainWindow::MainWindow(const QString &fileToLoad, Settings &settings) : mSettings(settings) { m_treeDoc = NULL; mdiArea = new QMdiArea; setCentralWidget(mdiArea); connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(updateActiveWindows())); windowMapper = new QSignalMapper(this); connect(windowMapper, SIGNAL(mapped(QWidget *)), this, SLOT(setActiveSubWindow(QWidget *))); m_indexWidget = new IndexWidget(this); QDockWidget *indexDock = new QDockWidget(tr("Index"), this); indexDock->setObjectName(QLatin1String("IndexWindow")); indexDock->setWidget(m_indexWidget); addDockWidget(Qt::LeftDockWidgetArea, indexDock); QDockWidget *AttributesListDock = new QDockWidget(tr("AttributesList"), this); AttributesListDock->setObjectName(QLatin1String("AttributesListWindow")); AttributesListDock->setWidget(setupAttributesListWidget()); addDockWidget(Qt::LeftDockWidgetArea, AttributesListDock); readSettings(); // read setting or generate default setWindowTitle(TITLE_BASE); createActions(); createMenus(); createToolBars(); createStatusBar(); updateToolbar(); updateActiveWindows(); updateGLWindows(true, true); installEventFilter(this); // setWindowIcon(QIcon(tr(":/images/cur/icon-1-1.png"))); if (fileToLoad.length()>0) { loadFile(fileToLoad); } } QWidget * MainWindow::setupAttributesListWidget() { QWidget *widget = new QWidget(this); QLayout *vlayout = new QVBoxLayout(widget); vlayout->setMargin(1); QLayout *hlayout = new QHBoxLayout(); vlayout->addWidget(m_attrWindow = new AttribWindow(this, false)); vlayout->addItem(hlayout); hlayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); attr_add_button = new QToolButton(widget); attr_add_button->setText(tr("Add")); attr_add_button->setIcon(QIcon(tr(":/images/win/b-5-19.png"))); attr_add_button->setAutoRaise(true); attr_add_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(attr_add_button); connect(attr_add_button, SIGNAL(clicked()), this, SLOT(OnAddColumn())); attr_del_button = new QToolButton(widget); attr_del_button->setText(tr("Remove")); attr_del_button->setIcon(QIcon(tr(":/images/win/b-5-21.png"))); attr_del_button->setAutoRaise(true); attr_del_button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); hlayout->addWidget(attr_del_button); connect(attr_del_button, SIGNAL(clicked()), this, SLOT(OnRemoveColumn())); return widget; } void MainWindow::closeEvent(QCloseEvent *event) { mdiArea->closeAllSubWindows(); if (activeMapView()) { event->ignore(); } else { QApplication::postEvent((QObject*)&m_wndColourScale, new QEvent(QEvent::Close)); writeSettings(); event->accept(); } } void MainWindow::OnFileNew() { MapView *child = createMapView(); child->getGraphDoc()->OnNewDocument(); child->setCurrentFile(""); child->postLoadFile(); child->show(); OnFocusGraph(child->getGraphDoc(), QGraphDoc::CONTROLS_LOADALL); } void MainWindow::loadFile(QString fileName) { QMdiSubWindow *existing = findMapView(fileName); if (existing) { mdiArea->setActiveSubWindow(existing); return; } MapView *child = createMapView(); QByteArray ba = fileName.toUtf8(); // quick fix for weird chars (russian filename bug report) char *file = ba.data(); // quick fix for weird chars (russian filename bug report) if(child->getGraphDoc()->OnOpenDocument(file)) // quick fix for weird chars (russian filename bug report) { child->setCurrentFile(fileName); child->postLoadFile(); statusBar()->showMessage(tr("File loaded"), 2000); child->show(); OnFocusGraph(child->getGraphDoc(), QGraphDoc::CONTROLS_LOADALL); setCurrentFile(fileName); } else { child->close(); QMessageBox::warning(this, "Failed to load", QString("Failed to load file ")+fileName, QMessageBox::Ok, QMessageBox::Ok ); } } void MainWindow::OnFileOpen() { QString template_string; template_string += "Graph Files (*.graph)\nAll files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QString fileName = QFileDialog::getOpenFileName( 0, tr("Open"), "", template_string, &selectedFilter, options); if (!fileName.isEmpty()) { loadFile(fileName); } } void MainWindow::showContextMenu(QPoint &point) { QMenu menu; menu.addAction(renameColumnAct); menu.addAction(updateColumAct); menu.addAction(removeColumAct); menu.addSeparator(); menu.addAction(columnPropertiesAct); menu.exec(point); } void MainWindow::OnFilePrint() { } void MainWindow::OnFilePrintPreview() { } void MainWindow::OnFilePrintSetup() { } void MainWindow::OnEditUndo() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnEditUndo(); } } void MainWindow::OnEditCopyData() { } void MainWindow::OnEditCopy() { MapView* m_p = activeMapView(); if(m_p) m_p->OnEditCopy(); } void MainWindow::OnEditSave() { MapView* m_p = activeMapView(); if(m_p) { m_p->OnEditSave(); } } void MainWindow::OnEditClear() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnEditClear(); } } void MainWindow::OnEditQuery() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnEditQuery(); } } void MainWindow::OnViewZoomsel() { MapView* m_p = activeMapView(); if(m_p) m_p->OnViewZoomsel(); } void MainWindow::OnEditSelectToLayer() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnEditSelectToLayer(); } } void MainWindow::OnFileImport() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnFileImport(); } } void MainWindow::OnLayerNew() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnLayerNew(); } } void MainWindow::OnLayerDelete() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnLayerDelete(); } } void MainWindow::OnLayerConvert() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnLayerConvert(); } } void MainWindow::OnLayerConvertDrawing() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnLayerConvertDrawing(); } } void MainWindow::OnConvertMapShapes() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnConvertMapShapes(); } } void MainWindow::OnFileExport() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnFileExport(); } } void MainWindow::OnFileExportMapGeometry() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnFileExportMapGeometry(); } } void MainWindow::OnFileExportLinks() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnFileExportLinks(); } } void MainWindow::OnAxialConnectionsExportAsDot() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnAxialConnectionsExportAsDot(); } } void MainWindow::OnAxialConnectionsExportAsPairCSV() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnAxialConnectionsExportAsPairCSV(); } } void MainWindow::OnSegmentConnectionsExportAsPairCSV() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnSegmentConnectionsExportAsPairCSV(); } } void MainWindow::OnPointmapExportConnectionsAsCSV() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnPointmapExportConnectionsAsCSV(); } } void MainWindow::OnAddColumn() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnAddColumn(); } } void MainWindow::OnRenameColumn() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnRenameColumn(); } } void MainWindow::OnUpdateColumn() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnUpdateColumn(); } } void MainWindow::OnRemoveColumn() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnRemoveColumn(); } } void MainWindow::OnColumnProperties() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnColumnProperties(); } } void MainWindow::OnPushToLayer() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnPushToLayer(); } } void MainWindow::OnEditGrid() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnEditGrid(); } } void MainWindow::OnToolsMakeGraph() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsMakeGraph(); } } void MainWindow::OnToolsUnmakeGraph() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsUnmakeGraph(); } } void MainWindow::OnToolsImportVGALinks() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnVGALinksFileImport(); } } void MainWindow::OnToolsGenerateIsovistsFromFile() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnGenerateIsovistsFromFile(); } } void MainWindow::OnToolsRun() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsRun(); } } void MainWindow::OnToolsAgentRun() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsAgentRun(); } } void MainWindow::OnToolsIsovistpath() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsIsovistpath(); } } void MainWindow::OnToolsAgentLoadProgram() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { if(m_p->m_view[QGraphDoc::VIEW_3D]) ((Q3DView*)m_p->m_view[QGraphDoc::VIEW_3D])->OnToolsAgentLoadProgram(); } } void MainWindow::OnToolsRunAxa() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsRunAxa(); } } void MainWindow::OnToolsPD() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsPD(); } } void MainWindow::OnToolsMakeFewestLineMap() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsMakeFewestLineMap(); } } void MainWindow::OnToolsAxialConvShapeMap() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsAxialConvShapeMap(); } } void MainWindow::OnToolsLineLoadUnlinks() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsLineLoadUnlinks(); } } void MainWindow::OnToolsRunSeg() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsRunSeg(); } } void MainWindow::OnToolsTopomet() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsTopomet(); } } void MainWindow::OnToolsTPD() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsTPD(); } } void MainWindow::OnToolsMPD() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsMPD(); } } void MainWindow::OnToolsPointConvShapeMap() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsPointConvShapeMap(); } } void MainWindow::OnToolsAPD() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnToolsAPD(); } } void MainWindow::OnToolsOptions() { SettingsDialog dialog(mSettings); if(QDialog::Accepted == dialog.exec()) { readSettings(); } } void MainWindow::OnViewCentreView() { activeMapDoc()->SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_TOTAL, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } void MainWindow::OnViewShowGrid() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnViewShowGrid(); } } void MainWindow::OnViewSummary() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { m_p->OnViewSummary(); } } void MainWindow::OnViewColourRange() { if (m_wndColourScale.isVisible()) { m_wndColourScale.hide(); } else { QRect recta,rectb; recta = geometry(); rectb = m_wndColourScale.geometry(); m_wndColourScale.setGeometry(recta.right() - 7 - rectb.width(), recta.top() + 68, rectb.width(), rectb.height()); m_wndColourScale.m_docked = true; m_wndColourScale.show(); } } void MainWindow::OnHelpBugs() { bool foo = QDesktopServices::openUrl( QUrl("https://github.com/SpaceGroupUCL/depthmapX/issues") ); } void MainWindow::OnHelpManual() { bool foo = QDesktopServices::openUrl( QUrl("http://www.vr.ucl.ac.uk/depthmap/depthmap4r1.pdf") ); } void MainWindow::OnHelpTutorials() { bool foo = QDesktopServices::openUrl( QUrl("http://www.vr.ucl.ac.uk/depthmap/tutorials/") ); } void MainWindow::OnHelpSalaManual() { bool foo = QDesktopServices::openUrl( QUrl("http://www.vr.ucl.ac.uk/depthmap/scripting/") ); } void MainWindow::OnFileClose() { MapView* m_p = activeMapView(); if(m_p) QApplication::postEvent((QObject*)m_p, new QEvent(QEvent::Close)); } void MainWindow::OnFileSave() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { bool saved = m_p->OnFileSave(); if(saved) { statusBar()->showMessage(tr("File saved"), 2000); setCurrentFile(m_p->m_opened_name); updateSubWindowTitles(m_p->m_base_title); } else { statusBar()->showMessage(tr("File not saved"), 2000); } } } void MainWindow::OnFileSaveAs() { QGraphDoc* m_p = activeMapDoc(); if(m_p) { bool saved = m_p->OnFileSaveAs(); if(saved) { statusBar()->showMessage(tr("File saved"), 2000); setCurrentFile(m_p->m_opened_name); updateSubWindowTitles(m_p->m_base_title); } else { statusBar()->showMessage(tr("File not saved"), 2000); } } } void MainWindow::updateSubWindowTitles(QString newTitle) { QList windowList = mdiArea->subWindowList(); QList::iterator iter = windowList.begin(), end = windowList.end(); for ( ; iter != end; ++iter ) { QWidget *p = 0; if (QMdiSubWindow *subWindow = *iter) { p = qobject_cast(subWindow->widget()); if(p) subWindow->setWindowTitle(newTitle +":Map View"); p = qobject_cast(subWindow->widget()); if(p) subWindow->setWindowTitle(newTitle +":Scatter Plot"); p = qobject_cast(subWindow->widget()); if(p) subWindow->setWindowTitle(newTitle +":Table View"); p = qobject_cast(subWindow->widget()); if(p) subWindow->setWindowTitle(newTitle +":3D View"); } } } void MainWindow::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.exec(); } MapView *MainWindow::createMapView() { QGraphDoc* doc = new QGraphDoc("", ""); doc->m_mainFrame = this; if(m_defaultMapWindowIsLegacy) { QDepthmapView *child = new QDepthmapView(*doc, mSettings); mdiArea->addSubWindow(child); return child; } else { GLView *child = new GLView(*doc, mSettings); mdiArea->addSubWindow(child); return child; } } MapView *MainWindow::activeMapView() { QWidget *p = 0; if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) { p = qobject_cast(activeSubWindow->widget()); if(p) return (MapView *)p; if(!p) { p = qobject_cast(activeSubWindow->widget()); if(p) return (MapView *)(((QPlotView*)p)->pDoc->m_view[1]); } if(!p) { p = qobject_cast(activeSubWindow->widget()); if(p) return (MapView *)(((TableView*)p)->pDoc->m_view[1]); } if(!p) { p = qobject_cast(activeSubWindow->widget()); if(p) return (MapView *)(((Q3DView*)p)->pDoc->m_view[1]); } } current_view_type = 0; return 0; } QGraphDoc *MainWindow::activeMapDoc() { QWidget *p = 0; if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) { p = qobject_cast(activeSubWindow->widget()); if(p) return ((MapView *)p)->getGraphDoc(); p = qobject_cast(activeSubWindow->widget()); if(p) return ((QPlotView *)p)->pDoc; p = qobject_cast(activeSubWindow->widget()); if(p) return ((TableView *)p)->pDoc; p = qobject_cast(activeSubWindow->widget()); if(p) return ((Q3DView *)p)->pDoc; } return 0; } QMdiSubWindow *MainWindow::findMapView(const QString &fileName) { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { MapView *mdiChild = qobject_cast(window->widget()); if (mdiChild && mdiChild->getCurrentFile() == canonicalFilePath) return window; } return 0; } void MainWindow::OnWindowMap() { MapView* m_p = activeMapView(); if(m_p) { if(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_MAP]) return setActiveSubWindow(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_MAP]); QDepthmapView *child = new QDepthmapView(*m_p->getGraphDoc(), mSettings); mdiArea->addSubWindow(child); child->show(); } } void MainWindow::OnViewTable() { MapView* m_p = activeMapView(); if(m_p) { if(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_TABLE]) return setActiveSubWindow(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_TABLE]); TableView *child = new TableView(mSettings, this, m_p->getGraphDoc()); child->pDoc = m_p->getGraphDoc(); mdiArea->addSubWindow(child); child->show(); } } void MainWindow::OnWindow3dView() { MapView* m_p = activeMapView(); if(m_p) { if(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_3D]) return setActiveSubWindow(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_3D]); Q3DView *child = new Q3DView(this, m_p->getGraphDoc()); child->pDoc = m_p->getGraphDoc(); mdiArea->addSubWindow(child); child->show(); } } void MainWindow::OnWindowGLView() { MapView* m_p = activeMapView(); if(m_p) { if(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_MAP_GL]) return setActiveSubWindow(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_MAP_GL]); GLView *child = new GLView(*m_p->getGraphDoc(), mSettings); mdiArea->addSubWindow(child); child->show(); } } void MainWindow::OnViewScatterplot() { MapView* m_p = activeMapView(); if(m_p) { if(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_SCATTER]) return setActiveSubWindow(m_p->getGraphDoc()->m_view[QGraphDoc::VIEW_SCATTER]); QPlotView *child = new QPlotView; child->pDoc = m_p->getGraphDoc(); child->m_parent = this; mdiArea->addSubWindow(child); child->show(); } } void MainWindow::update3DToolbar() { updateActiveWindows(); } void MainWindow::updateActiveWindows() { current_view_type = 0; QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow(); if(!activeSubWindow) { editToolBar->hide(); thirdViewToolBar->hide(); plotToolBar->hide(); return; } QWidget* p = qobject_cast(activeSubWindow->widget()); if(p) { editToolBar->hide(); thirdViewToolBar->hide(); plotToolBar->show(); current_view_type = QGraphDoc::VIEW_SCATTER; OnFocusGraph(((QPlotView*)p)->pDoc, QGraphDoc::CONTROLS_LOADALL); RedoPlotViewMenu(((QPlotView*)p)->pDoc); if(((QPlotView*)p)->m_view_monochrome) toggleColor->setChecked(true); else toggleColor->setChecked(false); if(((QPlotView*)p)->m_view_origin) toggleOrg->setChecked(true); else toggleOrg->setChecked(false); if(((QPlotView*)p)->m_view_trend_line) viewTrend->setChecked(true); else viewTrend->setChecked(false); if(((QPlotView*)p)->m_view_equation) yx->setChecked(true); else yx->setChecked(false); if(((QPlotView*)p)->m_view_rsquared) Rtwo->setChecked(true); else Rtwo->setChecked(false); } else if(qobject_cast(activeSubWindow->widget())) { editToolBar->hide(); thirdViewToolBar->hide(); plotToolBar->hide(); current_view_type = QGraphDoc::VIEW_TABLE; QGraphDoc* m_p = activeMapDoc(); OnFocusGraph(m_p, QGraphDoc::CONTROLS_LOADALL); m_p->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_FOCUS ); return; } else if((p = qobject_cast(activeSubWindow->widget()))) { editToolBar->hide(); plotToolBar->hide(); thirdViewToolBar->show(); QGraphDoc* pDoc = activeMapDoc(); Q3DView *ptr = (Q3DView *)p; if(ptr->m_animating) toolsAgentsPlayAct->setChecked(true); else toolsAgentsPlayAct->setChecked(0); if(!ptr->m_animating) toolsAgentsPauseAct->setChecked(true); else toolsAgentsPauseAct->setChecked(0); if(ptr->m_mouse_mode == ID_3D_PAN) thirdPanAct->setChecked(true); else thirdPanAct->setChecked(0); if(ptr->m_mouse_mode == ID_3D_ROT) thirdRotAct->setChecked(true); else thirdRotAct->setChecked(0); if(ptr->m_mouse_mode == ID_3D_ZOOM) thirdZoomAct->setChecked(true); else thirdZoomAct->setChecked(0); if(ptr->m_mouse_mode == ID_3D_PLAY_LOOP) playLoopAct->setChecked(true); else playLoopAct->setChecked(0); if(ptr->m_fill) thirdFilledAct->setChecked(true); else thirdFilledAct->setChecked(0); if (pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessedPoints()) toolsImportTracesAct->setEnabled(true); else toolsImportTracesAct->setEnabled(false); if (!pDoc->m_meta_graph || !pDoc->m_meta_graph->viewingProcessedPoints()) { if (ptr->m_mouse_mode == ID_ADD_AGENT) ptr->m_mouse_mode = ID_3D_ROT; addAgentAct->setEnabled(false); } else { addAgentAct->setEnabled(true); if (ptr->m_mouse_mode == ID_ADD_AGENT) addAgentAct->setChecked(1); else addAgentAct->setChecked(0); } if (ptr->m_mannequins.size()) { toolsAgentsPlayAct->setEnabled(true); toolsAgentsPauseAct->setEnabled(true); toolsAgentsStopAct->setEnabled(true); if (((Q3DView *)p)->m_animating) toolsAgentsPlayAct->setChecked(true); else toolsAgentsPlayAct->setChecked(false); } else { toolsAgentsPlayAct->setChecked(false); toolsAgentsPlayAct->setEnabled(false); toolsAgentsPauseAct->setEnabled(false); toolsAgentsStopAct->setEnabled(false); } if (ptr->m_mannequins.size()) { toolsAgentsPauseAct->setEnabled(true); if (!ptr->m_animating) { toolsAgentsPauseAct->setChecked(true); } else { toolsAgentsPauseAct->setChecked(false); } } else { toolsAgentsPauseAct->setChecked(false); toolsAgentsPauseAct->setEnabled(false); } if (ptr->m_mannequins.size()) { toolsAgentsStopAct->setEnabled(true); } else { toolsAgentsStopAct->setEnabled(false); } if (ptr->m_drawtrails) { agentTrailsAct->setChecked(1); } else { agentTrailsAct->setChecked(0); } if (ptr->m_fill) { thirdFilledAct->setChecked(1); } else { thirdFilledAct->setChecked(0); } current_view_type = QGraphDoc::VIEW_3D; return; } else if((p = qobject_cast(activeSubWindow->widget()))) { editToolBar->show(); thirdViewToolBar->hide(); plotToolBar->hide(); current_view_type = QGraphDoc::VIEW_MAP; QWidget* v = qobject_cast(activeSubWindow->widget()); if(v) current_view_type = QGraphDoc::VIEW_MAP_GL; switch(m_selected_mapbar_item) { case ID_MAPBAR_ITEM_SELECT: SelectButton->setChecked(true); activeMapView()->OnEditSelect(); break; case ID_MAPBAR_ITEM_MOVE: DragButton->setChecked(true); activeMapView()->OnViewPan(); break; case ID_MAPBAR_ITEM_ZOOM_IN: zoomToolButton->setIcon(QIcon(":/images/win/b-5-3.png")); zoomToolButton->setChecked(true); zoomInAct->setChecked(true); activeMapView()->OnViewZoomIn(); break; case ID_MAPBAR_ITEM_ZOOM_OUT: zoomToolButton->setIcon(QIcon(":/images/win/b-5-4.png")); zoomToolButton->setChecked(true); zoomOutAct->setChecked(true); activeMapView()->OnViewZoomOut(); break; case ID_MAPBAR_ITEM_FILL: fillColorToolButton->setChecked(true); activeMapView()->OnEditFill(); break; case ID_MAPBAR_ITEM_SEMIFILL: fillColorToolButton->setChecked(true); activeMapView()->OnEditSemiFill(); break; case ID_MAPBAR_ITEM_AUGMENT_FILL: // AV TV fillColorToolButton->setChecked(true); activeMapView()->OnEditAugmentFill(); break; case ID_MAPBAR_ITEM_PENCIL: SelectPenButton->setChecked(true); activeMapView()->OnEditPencil(); break; case ID_MAPBAR_ITEM_LINETOOL: lineToolButton->setIcon(QIcon(":/images/win/b-5-10.png")); lineToolButton->setChecked(true); SelectLineAct->setChecked(true); activeMapView()->OnEditLineTool(); break; case ID_MAPBAR_ITEM_POLYGON: lineToolButton->setIcon(QIcon(":/images/win/b-5-11.png")); lineToolButton->setChecked(true); SelectPolyLineAct->setChecked(true); activeMapView()->OnEditPolygonTool(); break; case ID_MAPBAR_ITEM_ISOVIST: newisoToolButton->setIcon(QIcon(":/images/win/b-5-12.png")); newisoToolButton->setChecked(true); MakeIosAct->setChecked(true); activeMapView()->OnModeIsovist(); break; case ID_MAPBAR_ITEM_HALFISOVIST: newisoToolButton->setIcon(QIcon(":/images/win/b-5-13.png")); newisoToolButton->setChecked(true); PartialMakeIosAct->setChecked(true); activeMapView()->OnModeTargetedIsovist(); break; case ID_MAPBAR_ITEM_AL2: AxialMapButton->setChecked(true); activeMapView()->OnModeSeedAxial(); break; case ID_MAPBAR_ITEM_JOIN: JoinToolButton->setIcon(QIcon(":/images/win/b-5-16.png")); JoinToolButton->setChecked(true); JoinAct->setChecked(true); activeMapView()->OnModeJoin(); break; case ID_MAPBAR_ITEM_UNJOIN: JoinToolButton->setIcon(QIcon(":/images/win/b-5-17.png")); JoinToolButton->setChecked(true); JoinUnlinkAct->setChecked(true); activeMapView()->OnModeUnjoin(); break; default: SelectButton->setChecked(true); SelectButton->setChecked(false); activeMapView()->OnEditSelect(); break; } QGraphDoc* m_p = activeMapDoc(); OnFocusGraph(m_p, QGraphDoc::CONTROLS_LOADALL); m_p->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_FOCUS ); } } void MainWindow::updateGLWindows(bool datasetChanged, bool recentreView) { QList windows = mdiArea->subWindowList(); for (int i = 0; i < windows.size(); ++i) { GLView *child = qobject_cast(windows.at(i)->widget()); if(!child) continue; if(datasetChanged) child->notifyDatasetChanged(); if(recentreView) child->matchViewToCurrentMetaGraph(); } } void MainWindow::setActiveSubWindow(QWidget *win) { if (!win) return; foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { if(window->widget() == win) { mdiArea->setActiveSubWindow(window); return; } } QString t = QString(TITLE_BASE); setWindowTitle(t+" "+windowTitle()); } /////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// static bool in_FocusGraph; int MainWindow::OnFocusGraph(QGraphDoc* pDoc, int lParam) { in_FocusGraph = true; updateToolbar(); x_coord->clear(); y_coord->clear(); // Replacement for m_linelayer_chooser is my tree ctrl: if (lParam == QGraphDoc::CONTROLS_DESTROYALL && pDoc == m_treeDoc) { // Lost graph delete pDoc; m_treeDoc = NULL; m_topgraph = NULL; m_backgraph = NULL; m_attrWindow->clear(); m_indexWidget->clear(); } else if (lParam == QGraphDoc::CONTROLS_LOADALL && pDoc != m_treeDoc) { // [Possible] change of window (sent on focus) m_treeDoc = pDoc; m_topgraph = NULL; m_backgraph = NULL; MakeTree(); } else if (lParam == QGraphDoc::CONTROLS_LOADGRAPH && pDoc == m_treeDoc) { // Force update if match current window m_topgraph = NULL; m_backgraph = NULL; m_attrWindow->clear(); m_indexWidget->clear(); ClearGraphTree(); MakeGraphTree(); // also make drawing tree as this overrides layer visible status sometimes: MakeDrawingTree(); } else if (lParam == QGraphDoc::CONTROLS_RELOADGRAPH && pDoc == m_treeDoc) { // Force reload of graph tree if match current window m_topgraph = NULL; m_backgraph = NULL; m_attrWindow->clear(); m_indexWidget->clear(); ClearGraphTree(); MakeTree(); } else if (lParam == QGraphDoc::CONTROLS_LOADDRAWING && pDoc == m_treeDoc) { // Force update if match current window m_backgraph = NULL; m_attrWindow->clear(); m_indexWidget->clear(); ClearGraphTree(); MakeGraphTree(); MakeDrawingTree(); } else if (lParam == QGraphDoc::CONTROLS_LOADATTRIBUTES && pDoc == m_treeDoc) { // Force update if match current window MakeAttributeList(); } else if (lParam == QGraphDoc::CONTROLS_CHANGEATTRIBUTE && pDoc == m_treeDoc) { // Force update if match current window SetAttributeChecks(); } else if (lParam == QGraphDoc::CONTROLS_LOADCONVERT && pDoc == m_treeDoc) { m_topgraph = NULL; m_backgraph = NULL; m_attrWindow->clear(); m_indexWidget->clear(); ClearGraphTree(); MakeGraphTree(); // conversions typically turn off drawing layers: SetDrawingTreeChecks(); } if (m_treeDoc == NULL) { // tree.EnableWindow(FALSE); // Stop some strange auto scroll property: // SetTreeStyle(TVS_NOSCROLL, TRUE); } else { // tree.EnableWindow(TRUE); // Stop some strange auto scroll property: // SetTreeStyle(TVS_NOSCROLL, FALSE); } m_wndColourScale.OnFocusGraph(pDoc, lParam); in_FocusGraph = false; return 0; } void MainWindow::MakeTree() { m_indexWidget->clear(); m_treegraphmap.clear(); m_treedrawingmap.clear(); for (int i = 0; i < 5; i++) m_treeroots[i] = NULL; MetaGraph *graph = m_treeDoc->m_meta_graph; if (!graph) return; int state = graph->getState(); int viewclass = graph->getViewClass(); MakeGraphTree(); MakeDrawingTree(); } void MainWindow::OnSelchangingList() { if(in_FocusGraph) return; int row = -1; row = m_attrWindow->currentRow(); if(row > -1 && m_treeDoc){ MetaGraph *graph = m_treeDoc->m_meta_graph; if (graph->viewingProcessed()) { graph->setDisplayedAttribute(row - 1); } m_treeDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_FOCUS ); SetAttributeChecks(); OnFocusGraph(m_treeDoc, QGraphDoc::CONTROLS_CHANGEATTRIBUTE); // Bug Test TV } // this *does* work here (but only if they click on a valid attribute): } void MainWindow::OnSelchangingTree(QTreeWidgetItem* hItem, int col) { if(in_FocusGraph) return; MetaGraph *graph = m_treeDoc->m_meta_graph; bool update = false; // look it up in the table to see what to do: auto iter = m_treegraphmap.find(hItem); if (iter != m_treegraphmap.end()) { ItemTreeEntry entry = iter->second; bool remenu = false; if (entry.m_cat != -1) { if (entry.m_subcat == -1 && m_indexWidget->isMapColumn(col)) { switch (entry.m_type) { case 0: if (graph->getViewClass() & MetaGraph::VIEWVGA) { if (graph->getDisplayedPointMapRef() == entry.m_cat) { graph->setViewClass(MetaGraph::SHOWHIDEVGA); } else { graph->setDisplayedPointMapRef(entry.m_cat); } } else { graph->setDisplayedPointMapRef(entry.m_cat); graph->setViewClass(MetaGraph::SHOWVGATOP); } remenu = true; break; case 1: if (graph->getViewClass() & MetaGraph::VIEWAXIAL) { if (graph->getDisplayedShapeGraphRef() == entry.m_cat) { graph->setViewClass(MetaGraph::SHOWHIDEAXIAL); } else { graph->setDisplayedShapeGraphRef(entry.m_cat); } } else { graph->setDisplayedShapeGraphRef(entry.m_cat); graph->setViewClass(MetaGraph::SHOWAXIALTOP); } remenu = true; break; case 2: if (graph->getViewClass() & MetaGraph::VIEWDATA) { if (graph->getDisplayedDataMapRef() == entry.m_cat) { graph->setViewClass(MetaGraph::SHOWHIDESHAPE); } else { graph->setDisplayedDataMapRef(entry.m_cat); } } else { graph->setDisplayedDataMapRef(entry.m_cat); graph->setViewClass(MetaGraph::SHOWSHAPETOP); } remenu = true; break; case 4: // slightly different for this one break; } if (remenu) { SetGraphTreeChecks(); m_treeDoc->SetRemenuFlag(QGraphDoc::VIEW_ALL, true); OnFocusGraph(m_treeDoc, QGraphDoc::CONTROLS_CHANGEATTRIBUTE); } m_treeDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_TABLE ); } else if (entry.m_subcat == -1 && m_indexWidget->isEditableColumn(col)) { // hit editable box if (entry.m_type == 1) { int type = graph->getShapeGraphs()[entry.m_cat]->getMapType(); if (type != ShapeMap::SEGMENTMAP && type != ShapeMap::ALLLINEMAP) { graph->getShapeGraphs()[entry.m_cat]->setEditable(m_indexWidget->isItemSetEditable(hItem)); update = true; } } if (entry.m_type == 2) { graph->getDataMaps()[entry.m_cat].setEditable(m_indexWidget->isItemSetEditable(hItem)); update = true; } if (update) { // Depending on if the map is displayed you may have to redraw -- I'm just going to redraw *anyway* // (it may be worth switching it to topmost when they do click here) OnFocusGraph(m_treeDoc, QGraphDoc::CONTROLS_CHANGEATTRIBUTE); } } else { // They've clicked on the displayed layers if (entry.m_type == 1) { update = true; graph->getShapeGraphs()[entry.m_cat]->setLayerVisible(entry.m_subcat, m_indexWidget->isItemSetVisible(hItem)); } else if (entry.m_type == 2) { update = true; graph->getDataMaps()[entry.m_cat].setLayerVisible(entry.m_subcat, m_indexWidget->isItemSetVisible(hItem)); } if (update) { m_treeDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_TABLE ); OnFocusGraph(m_treeDoc, QGraphDoc::CONTROLS_CHANGEATTRIBUTE); } } } } else { auto iter = m_treedrawingmap.find(hItem); if (iter != m_treedrawingmap.end()) { ItemTreeEntry entry = iter->second; if (entry.m_subcat != -1) { if (graph->getLineLayer(entry.m_cat,entry.m_subcat).isShown()) { graph->getLineLayer(entry.m_cat,entry.m_subcat).setShow(false); graph->redoPointMapBlockLines(); graph->resetBSPtree(); } else { graph->getLineLayer(entry.m_cat,entry.m_subcat).setShow(true); graph->redoPointMapBlockLines(); graph->resetBSPtree(); } } m_treeDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_LINESET ); } } } void MainWindow::SetGraphTreeChecks() { in_FocusGraph = true; MetaGraph *graph = m_treeDoc->m_meta_graph; int viewclass = graph->getViewClass(); for (auto item: m_treegraphmap) { QTreeWidgetItem* key = item.first; ItemTreeEntry entry = item.second; int checkstyle = 7; if (entry.m_cat != -1) { if (entry.m_subcat == -1) { // this is the main type box hit switch (entry.m_type) { case 0: if (viewclass & MetaGraph::VIEWVGA && graph->getDisplayedPointMapRef() == entry.m_cat) { checkstyle = 5; m_topgraph = key; } else if (viewclass & MetaGraph::VIEWBACKVGA && graph->getDisplayedPointMapRef() == entry.m_cat) { checkstyle = 6; m_backgraph = key; } break; case 1: if (viewclass & MetaGraph::VIEWAXIAL && graph->getDisplayedShapeGraphRef() == entry.m_cat) { checkstyle = 5; m_topgraph = key; } else if (viewclass & MetaGraph::VIEWBACKAXIAL && graph->getDisplayedShapeGraphRef() == entry.m_cat) { checkstyle = 6; m_backgraph = key; } break; case 2: if (viewclass & MetaGraph::VIEWDATA && graph->getDisplayedDataMapRef() == entry.m_cat) { checkstyle = 5; m_topgraph = key; } else if (viewclass & MetaGraph::VIEWBACKDATA && graph->getDisplayedDataMapRef() == entry.m_cat) { checkstyle = 6; m_backgraph = key; } break; } if(checkstyle == 5) m_indexWidget->setItemVisibility(key, Qt::Checked); else if(checkstyle == 6) m_indexWidget->setItemVisibility(key, Qt::PartiallyChecked); else if(checkstyle == 7) m_indexWidget->setItemVisibility(key, Qt::Unchecked); // the editable box int editable = MetaGraph::NOT_EDITABLE; switch (entry.m_type) { case 0: if (graph->getPointMaps()[entry.m_cat].isProcessed()) { editable = MetaGraph::NOT_EDITABLE; } else { editable = MetaGraph::EDITABLE_ON; } break; case 1: { int type = graph->getShapeGraphs()[entry.m_cat]->getMapType(); if (type == ShapeMap::SEGMENTMAP || type == ShapeMap::ALLLINEMAP) { editable = MetaGraph::NOT_EDITABLE; } else { editable = graph->getShapeGraphs()[entry.m_cat]->isEditable() ? MetaGraph::EDITABLE_ON : MetaGraph::EDITABLE_OFF; } } break; case 2: editable = graph->getDataMaps()[entry.m_cat].isEditable() ? MetaGraph::EDITABLE_ON : MetaGraph::EDITABLE_OFF; break; } switch (editable) { case MetaGraph::NOT_EDITABLE: m_indexWidget->setItemReadOnly(key); break; case MetaGraph::EDITABLE_OFF: m_indexWidget->setItemEditability(key, Qt::Unchecked); break; case MetaGraph::EDITABLE_ON: m_indexWidget->setItemEditability(key, Qt::Checked); break; } } else { // the displayed layers (note that VGA graphs (type 0) // do not currently have layers supported bool show = false; if (entry.m_type == 1) { show = graph->getShapeGraphs()[entry.m_cat]->isLayerVisible(entry.m_subcat); } else if (entry.m_type == 2) { show = graph->getDataMaps()[entry.m_cat].isLayerVisible(entry.m_subcat); } if (show) { m_indexWidget->setItemVisibility(key, Qt::Checked); } else { m_indexWidget->setItemVisibility(key, Qt::Unchecked); } } } } MakeAttributeList(); in_FocusGraph = false; } void MainWindow::SetDrawingTreeChecks() { MetaGraph *graph = m_treeDoc->m_meta_graph; int viewclass = graph->getViewClass(); for (auto iter: m_treedrawingmap) { ItemTreeEntry entry = iter.second; if (entry.m_subcat != -1) { if (graph->getLineLayer(entry.m_cat,entry.m_subcat).isShown()) { iter.first->setIcon(0, m_tree_icon[12]); } else { iter.first->setIcon(0, m_tree_icon[13]); } } } } // clear the graph tree (not the drawing tree) but also clear the attribute list void MainWindow::ClearGraphTree() { m_attribute_locked.clear(); for (int i = 2; i >= 0; i--) { if (m_treeroots[i]) { m_treeroots[i] = NULL; } } m_treegraphmap.clear(); } void MainWindow::MakeGraphTree() { MetaGraph *graph = m_treeDoc->m_meta_graph; int state = graph->getState(); if (state & MetaGraph::POINTMAPS) { if (!m_treeroots[0]) { QTreeWidgetItem* hItem = m_indexWidget->addNewItem(tr("Visibility Graphs")); hItem->setIcon(0, m_tree_icon[0]); ItemTreeEntry entry(0,-1,-1); m_treegraphmap[hItem] = entry; m_treeroots[0] = hItem; } int i = 0; for (auto& pointmap: m_treeDoc->m_meta_graph->getPointMaps()) { QString name = QString(pointmap.getName().c_str()); QTreeWidgetItem* hItem = m_indexWidget->addNewItem(name, m_treeroots[0]); m_indexWidget->setItemVisibility(hItem, Qt::Unchecked); m_indexWidget->setItemEditability(hItem, Qt::Unchecked); ItemTreeEntry entry(0,(short)i,-1); m_treegraphmap.insert(std::make_pair(hItem,entry)); i++; } } else if (m_treeroots[0]) { m_treeroots[0]->removeChild(m_treeroots[0]); auto iter = m_treegraphmap.find(m_treeroots[0]); if(iter != m_treegraphmap.end()) { m_treegraphmap.erase(iter); } m_treeroots[0] = NULL; } if (state & MetaGraph::SHAPEGRAPHS) { if (!m_treeroots[1]) { QTreeWidgetItem* hItem = m_indexWidget->addNewItem(tr("Shape Graphs")); hItem->setIcon(0, m_tree_icon[1]); ItemTreeEntry entry(1,-1,-1); m_treegraphmap[hItem] = entry; m_treeroots[1] = hItem; } for (size_t i = 0; i < m_treeDoc->m_meta_graph->getShapeGraphs().size(); i++) { QString name = QString(m_treeDoc->m_meta_graph->getShapeGraphs()[i]->getName().c_str()); QTreeWidgetItem* hItem = m_indexWidget->addNewItem(name, m_treeroots[1]); m_indexWidget->setItemVisibility(hItem, Qt::Unchecked); m_indexWidget->setItemEditability(hItem, Qt::Unchecked); ItemTreeEntry entry(1,(short)i,-1); m_treegraphmap.insert(std::make_pair(hItem,entry)); LayerManagerImpl& layers = m_treeDoc->m_meta_graph->getShapeGraphs()[i]->getLayers(); if(layers.getNumLayers() > 1) { for (int j = 0; j < layers.getNumLayers(); j++) { QString name = QString(layers.getLayerName(j).c_str()); QTreeWidgetItem* hNewItem = m_indexWidget->addNewItem(name, hItem); ItemTreeEntry entry(1,(short)i,j); m_treegraphmap[hNewItem] = entry; } } } } else if (m_treeroots[1]) { m_treeroots[1]->removeChild(m_treeroots[1]); auto iter = m_treegraphmap.find(m_treeroots[1]); if(iter != m_treegraphmap.end()) { m_treegraphmap.erase(iter); } m_treeroots[1] = NULL; } if (state & MetaGraph::DATAMAPS) { if (!m_treeroots[2]) { QTreeWidgetItem* hItem = m_indexWidget->addNewItem(tr("Data Maps")); hItem->setIcon(0, m_tree_icon[2]); ItemTreeEntry entry(2,-1,-1); m_treegraphmap[hItem] = entry; m_treeroots[2] = hItem; } for (size_t i = 0; i < m_treeDoc->m_meta_graph->getDataMaps().size(); i++) { QString name = QString(m_treeDoc->m_meta_graph->getDataMaps()[i].getName().c_str()); QTreeWidgetItem* hItem = m_indexWidget->addNewItem(name, m_treeroots[2]); m_indexWidget->setItemVisibility(hItem, Qt::Unchecked); m_indexWidget->setItemEditability(hItem, Qt::Unchecked); ItemTreeEntry entry(2,(short)i,-1); m_treegraphmap[hItem] = entry; LayerManagerImpl layers = m_treeDoc->m_meta_graph->getDataMaps()[i].getLayers(); if(layers.getNumLayers() > 1) { for (int j = 0; j < layers.getNumLayers(); j++) { QString name = QString(layers.getLayerName(j).c_str()); QTreeWidgetItem* hNewItem = m_indexWidget->addNewItem(name, hItem); m_indexWidget->setItemVisibility(hNewItem, Qt::Unchecked); ItemTreeEntry entry(2,(short)i,j); m_treegraphmap.insert(std::make_pair(hNewItem,entry)); } } } } else if (m_treeroots[2]) { m_treeroots[2]->removeChild(m_treeroots[2]); auto iter = m_treegraphmap.find(m_treeroots[2]); if(iter != m_treegraphmap.end()) { m_treegraphmap.erase(iter); } m_treeroots[2] = NULL; } SetGraphTreeChecks(); } void MainWindow::MakeDrawingTree() { MetaGraph *graph = m_treeDoc->m_meta_graph; int state = graph->getState(); if (state & MetaGraph::LINEDATA) { if (m_treeroots[4]) { m_treeroots[4] = NULL; m_treedrawingmap.clear(); } // we'll do all of these if it works... QTreeWidgetItem* root = m_indexWidget->addNewItem(tr("Drawing Layers")); root->setIcon(0, m_tree_icon[4]); ItemTreeEntry entry(4,0,-1); m_treedrawingmap.insert(std::make_pair(root,entry)); m_treeroots[4] = root; for (int i = 0; i < m_treeDoc->m_meta_graph->getLineFileCount(); i++) { QTreeWidgetItem* subroot = m_indexWidget->addNewItem(QString(m_treeDoc->m_meta_graph->getLineFileName(i).c_str()), m_treeroots[4]); subroot->setIcon(0, m_tree_icon[8]); ItemTreeEntry entry(4,i,-1); m_treedrawingmap.insert(std::make_pair(subroot,entry)); for (int j = 0; j < m_treeDoc->m_meta_graph->getLineLayerCount(i); j++) { QString name(m_treeDoc->m_meta_graph->getLineLayer(i,j).getName().c_str()); QTreeWidgetItem* hItem = m_indexWidget->addNewItem(name, subroot); if (m_treeDoc->m_meta_graph->getLineLayer(i,j).isShown()) { m_indexWidget->setItemVisibility(hItem, Qt::Checked); } else { m_indexWidget->setItemVisibility(hItem, Qt::Unchecked); } ItemTreeEntry entry(4,i,j); m_treedrawingmap.insert(std::make_pair(hItem,entry)); } } } } void MainWindow::MakeAttributeList() { MetaGraph *graph = m_treeDoc->m_meta_graph; if (graph == NULL) { return; } auto lock = graph->getLockDeferred(); if (lock.try_lock()) { // just doing this the simple way to start off with // (when you add new attributes, list is cleared and re m_attribute_locked.clear(); m_attrWindow->clear(); int cx = 0; QString name; if (graph->viewingProcessed()) { const AttributeTable& table = graph->getAttributeTable(); m_attrWindow->addItem(tr("Ref Number")); m_attribute_locked.push_back(true); for (int i = 0; i < table.getNumColumns(); i++) { name = QString(table.getColumnName(i).c_str()); m_attrWindow->addItem(name); m_attribute_locked.push_back(table.getColumn(i).isLocked()); //} } } } SetAttributeChecks(); } void MainWindow::SetAttributeChecks() { MetaGraph *graph = m_treeDoc->m_meta_graph; if (graph == NULL) return; QListWidgetItem * it; if (graph->viewingProcessed()) { int image, displayed_attribute = graph->getDisplayedAttribute(); for (int i = 0; ; i++) { it = m_attrWindow->item(i); if(!it) break; if ((i-1) == displayed_attribute) { if (!m_attribute_locked[i]) { image = 9; } else { image = 17; } } else { if (!m_attribute_locked[i]) { image = 10; } else { image = 18; } } it->setIcon(m_tree_icon[image]); } } } void MainWindow::chooseAttributeOnIndex(int attributeIdx) { SetAttributeChecks(); m_attrWindow->setCurrentRow(attributeIdx); } void MainWindow::OninvertColor() { activeMapDoc()->OnSwapColours(); } void MainWindow::OnzoomTo() { activeMapView()->OnViewZoomsel(); } void MainWindow::SelectButtonTriggered() { m_selected_mapbar_item = ID_MAPBAR_ITEM_SELECT; activeMapView()->OnEditSelect(); } void MainWindow::DragButtonTriggered() { m_selected_mapbar_item = ID_MAPBAR_ITEM_MOVE; activeMapView()->OnViewPan(); } void MainWindow::SelectPenTriggered() { m_selected_mapbar_item = ID_MAPBAR_ITEM_PENCIL; activeMapView()->OnEditPencil(); } void MainWindow::AxialMapTriggered() { m_selected_mapbar_item = ID_MAPBAR_ITEM_AL2; activeMapView()->OnModeSeedAxial(); } void MainWindow::StepDepthTriggered() { activeMapDoc()->OnToolsPD(); } void MainWindow::zoomButtonTriggered() { int id = zoomInAct->data().value(); if(id == ID_MAPBAR_ITEM_ZOOM_IN) { m_selected_mapbar_item = ID_MAPBAR_ITEM_ZOOM_IN; activeMapView()->OnViewZoomIn(); } else { m_selected_mapbar_item = ID_MAPBAR_ITEM_ZOOM_OUT; activeMapView()->OnViewZoomOut(); } } void MainWindow::FillButtonTriggered() { int id;// = qVariantValue(STDFillColorAct->data()); if( qobject_cast(sender()) ) { // Not sure // Hack TV QAction* temp = qobject_cast(sender()); id = temp->data().value(); delete temp; } else { id = STDFillColorAct->data().value(); } if(id == ID_MAPBAR_ITEM_FILL) { m_selected_mapbar_item = ID_MAPBAR_ITEM_FILL; activeMapView()->OnEditFill(); } else if (id == ID_MAPBAR_ITEM_SEMIFILL) // AV TV { m_selected_mapbar_item = ID_MAPBAR_ITEM_SEMIFILL; activeMapView()->OnEditSemiFill(); } else { m_selected_mapbar_item = ID_MAPBAR_ITEM_AUGMENT_FILL; activeMapView()->OnEditAugmentFill(); // AV TV } } void MainWindow::LineButtonTriggered() { int id = SelectLineAct->data().value(); if(id == ID_MAPBAR_ITEM_LINETOOL) { m_selected_mapbar_item = ID_MAPBAR_ITEM_LINETOOL; activeMapView()->OnEditLineTool(); } else { m_selected_mapbar_item = ID_MAPBAR_ITEM_POLYGON; activeMapView()->OnEditPolygonTool(); } } void MainWindow::isoButtonTriggered() { int id = MakeIosAct->data().value(); if(id == ID_MAPBAR_ITEM_ISOVIST) { m_selected_mapbar_item = ID_MAPBAR_ITEM_ISOVIST; activeMapView()->OnModeIsovist(); } else { m_selected_mapbar_item = ID_MAPBAR_ITEM_HALFISOVIST; activeMapView()->OnModeTargetedIsovist(); } } void MainWindow::joinButtonTriggered() { int id = JoinAct->data().value(); if(id == ID_MAPBAR_ITEM_JOIN) { m_selected_mapbar_item = ID_MAPBAR_ITEM_JOIN; activeMapView()->OnModeJoin(); } else { m_selected_mapbar_item = ID_MAPBAR_ITEM_UNJOIN; activeMapView()->OnModeUnjoin(); } } void MainWindow::zoomModeTriggered() { zoomInAct = qobject_cast(sender()); if(zoomInAct->data() == ID_MAPBAR_ITEM_ZOOM_IN) zoomToolButton->setIcon(QIcon(":/images/win/b-5-3.png")); else zoomToolButton->setIcon(QIcon(":/images/win/b-5-4.png")); zoomToolButton->setChecked(1); zoomButtonTriggered(); } void MainWindow::FillModeTriggered() { fillColorToolButton->setChecked(1); FillButtonTriggered(); } void MainWindow::LineModeTriggered() { SelectLineAct = qobject_cast(sender()); if(SelectLineAct->data() == ID_MAPBAR_ITEM_LINETOOL) lineToolButton->setIcon(QIcon(":/images/win/b-5-10.png")); else lineToolButton->setIcon(QIcon(":/images/win/b-5-11.png")); lineToolButton->setChecked(1); LineButtonTriggered(); } void MainWindow::isoModeTriggered() { MakeIosAct = qobject_cast(sender()); if(MakeIosAct->data() == ID_MAPBAR_ITEM_ISOVIST) newisoToolButton->setIcon(QIcon(":/images/win/b-5-12.png")); else newisoToolButton->setIcon(QIcon(":/images/win/b-5-13.png")); newisoToolButton->setChecked(1); isoButtonTriggered(); } void MainWindow::joinTriggered() { JoinAct = qobject_cast(sender()); if(JoinAct->data() == ID_MAPBAR_ITEM_JOIN) JoinToolButton->setIcon(QIcon(":/images/win/b-5-16.png")); else JoinToolButton->setIcon(QIcon(":/images/win/b-5-17.png")); JoinToolButton->setChecked(1); joinButtonTriggered(); } void MainWindow::OnFileProperties() { QGraphDoc* gd = activeMapView()->getGraphDoc(); gd->OnFileProperties(); } // PlotView message void MainWindow::OntoggleColor() { QGraphDoc* gd = activeMapDoc(); if(((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])) ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->OnViewColor(); } void MainWindow::OntoggleOrg() { QGraphDoc* gd = activeMapDoc(); if(((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])) ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->OnViewOrigin(); } void MainWindow::OnviewTrend() { QGraphDoc* gd = activeMapDoc(); if(((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])) ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->OnViewTrendLine(); } void MainWindow::OnYX() { QGraphDoc* gd = activeMapDoc(); if(((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])) ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->OnViewEquation(); } void MainWindow::OnRtwo() { QGraphDoc* gd = activeMapDoc(); if(((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])) ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->OnViewRsquared(); } void MainWindow::OnToolsImportTraces() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnToolsImportTraces(); } void MainWindow::OnAddAgent() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnAddAgent(); } void MainWindow::OnToolsAgentsPlay() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnToolsAgentsPlay(); } void MainWindow::OnToolsAgentsPause() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnToolsAgentsPause(); } void MainWindow::OnToolsAgentsStop() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnToolsAgentsStop(); updateActiveWindows(); } void MainWindow::OnAgentTrails() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnAgentTrails(); } void MainWindow::On3dRot() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->On3dRot(); } void MainWindow::On3dPan() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->On3dPan(); } void MainWindow::On3dZoom() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->On3dZoom(); } void MainWindow::OnPlayLoop() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->OnPlayLoop(); } void MainWindow::On3dFilled() { QGraphDoc* gd = activeMapDoc(); if(((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])) ((Q3DView*)gd->m_view[QGraphDoc::VIEW_3D])->On3dFilled(); } /////////////////////////////////////// void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); g_info_curr = new QLabel; g_info_curr->setText(" "); statusBar()->addPermanentWidget(g_info_curr); g_size = new QLabel; g_size->setText(" "); statusBar()->addPermanentWidget(g_size); g_pos_curr = new QLabel; g_pos_curr->setText(" "); statusBar()->addPermanentWidget(g_pos_curr); } void MainWindow::readSettings() { auto settings = mSettings.getTransaction(); QPoint pos = settings->readSetting(SettingTag::position, QPoint(200, 200)).toPoint(); QSize size = settings->readSetting(SettingTag::size, QSize(400, 400)).toSize(); m_foreground = settings->readSetting(SettingTag::foregroundColour, qRgb(128,255,128)).toInt(); m_background = settings->readSetting(SettingTag::backgroundColour, qRgb(0,0,0)).toInt(); m_simpleVersion = settings->readSetting(SettingTag::simpleVersion, true).toBool(); m_defaultMapWindowIsLegacy = settings->readSetting(SettingTag::legacyMapWindow, false).toBool(); if (settings->readSetting(SettingTag::mwMaximised, true).toBool()) { setWindowState(Qt::WindowMaximized); } else{ move(pos); resize(size); } } void MainWindow::writeSettings() { auto settings = mSettings.getTransaction(); settings->writeSetting(SettingTag::position, pos()); settings->writeSetting(SettingTag::size, size()); settings->writeSetting(SettingTag::mwMaximised, windowState() == Qt::WindowMaximized); } void MainWindow::setCurrentFile(const QString &fileName) { auto settings = mSettings.getTransaction(); QStringList files = settings->readSetting(SettingTag::recentFileList).toStringList(); files.removeAll(fileName); files.prepend(fileName); while (files.size() > MaxRecentFiles) files.removeLast(); settings->writeSetting(SettingTag::recentFileList, files); updateRecentFileActions(files); } void MainWindow::updateRecentFileActions(const QStringList &files) { int numRecentFiles = qMin(files.size(), MaxRecentFiles); for (int i = 0; i < numRecentFiles; ++i) { QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); recentFileActs[i]->setText(text); recentFileActs[i]->setData(files[i]); recentFileActs[i]->setVisible(true); } for (int j = numRecentFiles; j < MaxRecentFiles; ++j) recentFileActs[j]->setVisible(false); separatorAct->setVisible(numRecentFiles > 0); } QString MainWindow::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } void MainWindow::openRecentFile() { QAction *action = qobject_cast(sender()); if (action) { QMdiSubWindow *existing = findMapView(action->data().toString()); if (existing) { mdiArea->setActiveSubWindow(existing); return; } MapView *child = createMapView(); QByteArray ba = action->data().toString().toUtf8(); // quick fix for weird chars (russian filename bug report) char *file = ba.data(); // quick fix for weird chars (russian filename bug report) if(child->getGraphDoc()->OnOpenDocument(file)) // quick fix for weird chars (russian filename bug report) { child->setCurrentFile(action->data().toString()); child->postLoadFile(); setCurrentFile(action->data().toString()); statusBar()->showMessage(tr("File loaded"), 2000); child->show(); OnFocusGraph(child->getGraphDoc(), QGraphDoc::CONTROLS_LOADALL); } else child->close(); } } void MainWindow::RedoPlotViewMenu(QGraphDoc* pDoc) { if(!pDoc->m_view[QGraphDoc::VIEW_SCATTER]) return; in_FocusGraph = true; // this will be used to distinguish between viewing VGA and axial maps int view_class = pDoc->m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWAXIAL | MetaGraph::VIEWDATA); int curr_j = 0; { auto lock = pDoc->m_meta_graph->getLockDeferred(); if (lock.try_lock()) { m_view_map_entries.clear(); if (view_class == MetaGraph::VIEWVGA) { PointMap& map = pDoc->m_meta_graph->getDisplayedPointMap(); const AttributeTable& table = map.getAttributeTable(); m_view_map_entries.insert(std::make_pair(0, "Ref Number")); for (int i = 0; i < table.getNumColumns(); i++) { m_view_map_entries.insert(std::make_pair(i+1, table.getColumnName(i))); if (map.getDisplayedAttribute() == i) { curr_j = i + 1; } } } else if (view_class == MetaGraph::VIEWAXIAL) { // using attribute tables is very, very simple... const ShapeGraph& map = pDoc->m_meta_graph->getDisplayedShapeGraph(); const AttributeTable& table = map.getAttributeTable(); m_view_map_entries.insert(std::make_pair(0, "Ref Number")); curr_j = 0; for (int i = 0; i < table.getNumColumns(); i++) { m_view_map_entries.insert(std::make_pair(i+1, table.getColumnName(i))); if (map.getDisplayedAttribute() == i) { curr_j = i + 1; } } } else if (view_class == MetaGraph::VIEWDATA) { // using attribute tables is very, very simple... const ShapeMap& map = pDoc->m_meta_graph->getDisplayedDataMap(); const AttributeTable& table = map.getAttributeTable(); m_view_map_entries.insert(std::make_pair(0, "Ref Number")); curr_j = 0; for (int i = 0; i < table.getNumColumns(); i++) { m_view_map_entries.insert(std::make_pair(i+1, table.getColumnName(i))); if (map.getDisplayedAttribute() == i) { curr_j = i + 1; } } } } } int t, cur_sel = 0; x_coord->clear(); y_coord->clear(); int i = 0; for (auto view_map_entry: m_view_map_entries) { if (curr_j == view_map_entry.first) cur_sel = i; x_coord->addItem( QString(view_map_entry.second.c_str()) ); y_coord->addItem( QString(view_map_entry.second.c_str()) ); i++; } t = ((QPlotView*)pDoc->m_view[QGraphDoc::VIEW_SCATTER])->curr_y; if(t != -1) cur_sel = t; ((QPlotView*)pDoc->m_view[QGraphDoc::VIEW_SCATTER])->SetAxis(1, cur_sel - 1, true); y_coord->setCurrentIndex(cur_sel); t = ((QPlotView*)pDoc->m_view[QGraphDoc::VIEW_SCATTER])->curr_x; if(t != -1) cur_sel = t; ((QPlotView*)pDoc->m_view[QGraphDoc::VIEW_SCATTER])->SetAxis(0, cur_sel - 1, true); x_coord->setCurrentIndex(cur_sel); in_FocusGraph = false; } void MainWindow::OnSelchangeViewSelector_X(const QString &string) { if(in_FocusGraph) return; int i = x_coord->currentIndex(); QGraphDoc* gd = activeMapDoc(); ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->SetAxis(0, /*m_view_selection*/i - 1, true); ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->curr_x = i; // note: this is only attached to a scatter view, and changing the attribute only // affects the scatter view, so only send draw to the map: gd->SetRedrawFlag(QGraphDoc::VIEW_SCATTER, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_COLUMN ); } void MainWindow::OnSelchangeViewSelector_Y(const QString &string) { if(in_FocusGraph) return; int i = y_coord->currentIndex(); QGraphDoc* gd = activeMapDoc(); ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->SetAxis(1, i - 1, true); ((QPlotView*)gd->m_view[QGraphDoc::VIEW_SCATTER])->curr_y = i; // note: this is only attached to a scatter view, and changing the attribute only // affects the scatter view, so only send draw to the map: gd->SetRedrawFlag(QGraphDoc::VIEW_SCATTER, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_COLUMN ); } void MainWindow::updateViewMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { RecentAct->setEnabled(0); showGridAct->setEnabled(0); attributeSummaryAct->setEnabled(0); return; } RecentAct->setEnabled(true); showGridAct->setEnabled(true); if(m_p->m_meta_graph->m_showgrid) showGridAct->setChecked(true); else showGridAct->setChecked(false); attributeSummaryAct->setEnabled(true); if (!m_p->m_communicator && m_p->m_meta_graph && !m_p->m_meta_graph->viewingNone()) attributeSummaryAct->setEnabled(true); else attributeSummaryAct->setEnabled(0); } void MainWindow::updateVisibilitySubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { SetGridAct->setEnabled(0); makeVisibilityGraphAct->setEnabled(0); unmakeVisibilityGraphAct->setEnabled(0); importVGALinksAct->setEnabled(0); makeIsovistPathAct->setEnabled(0); runVisibilityGraphAnalysisAct->setEnabled(0); convertDataMapLinesAct->setEnabled(0); return; } if (m_p->m_meta_graph->getState() & MetaGraph::LINEDATA || m_p->m_meta_graph->viewingUnprocessedPoints()) SetGridAct->setEnabled(true); else SetGridAct->setEnabled(0); if (m_p->m_meta_graph->viewingUnprocessedPoints()) { makeVisibilityGraphAct->setEnabled(true); unmakeVisibilityGraphAct->setEnabled(false); } else { makeVisibilityGraphAct->setEnabled(false); unmakeVisibilityGraphAct->setEnabled(true); } int state = m_p->m_meta_graph->getState(); if (state & MetaGraph::LINEDATA) makeIsovistPathAct->setEnabled(true); else makeIsovistPathAct->setEnabled(0); if (m_p->m_meta_graph->viewingProcessedPoints()) { importVGALinksAct->setEnabled(true); runVisibilityGraphAnalysisAct->setEnabled(true); } else { importVGALinksAct->setEnabled(0); runVisibilityGraphAnalysisAct->setEnabled(0); } if ( !m_p->m_communicator && m_p->m_meta_graph->viewingProcessedShapes() && (m_p->m_meta_graph->getState() & MetaGraph::POINTMAPS) && m_p->m_meta_graph->getDisplayedPointMap().isProcessed()) convertDataMapLinesAct->setEnabled(true); else convertDataMapLinesAct->setEnabled(0); } void MainWindow::updateStepDepthSubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { visibilityStepAct->setEnabled(0); metricStepAct->setEnabled(0); angularStepAct->setEnabled(0); return; } if (m_p->m_meta_graph->viewingProcessed() && m_p->m_meta_graph->isSelected()) visibilityStepAct->setEnabled(true); else visibilityStepAct->setEnabled(0); if ((m_p->m_meta_graph->viewingProcessedPoints() || (m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap())) && m_p->m_meta_graph->isSelected()) metricStepAct->setEnabled(true); else metricStepAct->setEnabled(0); if (m_p->m_meta_graph->viewingProcessedPoints() && m_p->m_meta_graph->isSelected()) angularStepAct->setEnabled(true); else angularStepAct->setEnabled(0); } void MainWindow::updateAgentToolsSubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { runAgentAnalysisAct->setEnabled(0); loadAgentProgramAct->setEnabled(0); return; } if (m_p->m_meta_graph && m_p->m_meta_graph->viewingProcessedPoints() && !m_p->m_communicator) runAgentAnalysisAct->setEnabled(true); else runAgentAnalysisAct->setEnabled(0); if(current_view_type == QGraphDoc::VIEW_3D) loadAgentProgramAct->setEnabled(true); else loadAgentProgramAct->setEnabled(0); } void MainWindow::updateSegmentSubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { runAngularSegmentAnalysisAct->setEnabled(0); runTopologicalOrMetricAnalysisAct->setEnabled(0); return; } if (m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) runAngularSegmentAnalysisAct->setEnabled(true); else runAngularSegmentAnalysisAct->setEnabled(0); if (m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) runTopologicalOrMetricAnalysisAct->setEnabled(true); else runTopologicalOrMetricAnalysisAct->setEnabled(0); } void MainWindow::updateSegmentStepDepthSubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { segmentAngularStepAct->setEnabled(0); topologicalStepAct->setEnabled(0); segmentMetricStepAct->setEnabled(0); return; } if (m_p->m_meta_graph->viewingProcessed() && m_p->m_meta_graph->isSelected()) segmentAngularStepAct->setEnabled(true); else segmentAngularStepAct->setEnabled(0); if (m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap() && m_p->m_meta_graph->isSelected()) topologicalStepAct->setEnabled(true); else topologicalStepAct->setEnabled(0); if ((m_p->m_meta_graph->viewingProcessedPoints() || (m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap())) && m_p->m_meta_graph->isSelected()) segmentMetricStepAct->setEnabled(true); else segmentMetricStepAct->setEnabled(0); } void MainWindow::updateAxialSubMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { runGraphAnaysisAct->setEnabled(0); stepDepthAct->setEnabled(0); reduceToFewestLineMapAct->setEnabled(0); convertDataMapPointsAct->setEnabled(0); loadUnlinksFromFileAct->setEnabled(0); return; } int state = m_p->m_meta_graph->getState(); // non-segment maps only if (state & MetaGraph::SHAPEGRAPHS && !m_p->m_communicator && !m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) runGraphAnaysisAct->setEnabled(true); else runGraphAnaysisAct->setEnabled(0); if (m_p->m_meta_graph->viewingProcessed() && m_p->m_meta_graph->isSelected()) stepDepthAct->setEnabled(true); else stepDepthAct->setEnabled(0); state = m_p->m_meta_graph->getState(); if (state & MetaGraph::SHAPEGRAPHS && !m_p->m_communicator && m_p->m_meta_graph->getDisplayedShapeGraph().isAllLineMap()) reduceToFewestLineMapAct->setEnabled(true); else reduceToFewestLineMapAct->setEnabled(0); if ( !m_p->m_communicator && m_p->m_meta_graph && m_p->m_meta_graph->viewingProcessedLines() && m_p->m_meta_graph->getDisplayedShapeGraph().getMapType() == ShapeMap::AXIALMAP) convertDataMapPointsAct->setEnabled(true); else convertDataMapPointsAct->setEnabled(0); if ( !m_p->m_communicator && m_p->m_meta_graph && m_p->m_meta_graph->viewingProcessedLines() && !m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) loadUnlinksFromFileAct->setEnabled(true); else loadUnlinksFromFileAct->setEnabled(0); } void MainWindow::updateAttributesMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { addColumAct->setEnabled(0); updateColumAct->setEnabled(0); renameColumnAct->setEnabled(0); removeColumAct->setEnabled(0); pushValueAct->setEnabled(0); columnPropertiesAct->setEnabled(0); return; } if (!m_p->m_communicator && m_p->m_meta_graph->viewingProcessed()) { addColumAct->setEnabled(true); columnPropertiesAct->setEnabled(true); int col = m_p->m_meta_graph->getDisplayedAttribute(); if (col == -1 || col == -2 || m_p->m_meta_graph->isAttributeLocked(col)) { renameColumnAct->setEnabled(0); updateColumAct->setEnabled(0); removeColumAct->setEnabled(0); pushValueAct->setEnabled(0); } else { renameColumnAct->setEnabled(true); updateColumAct->setEnabled(true); removeColumAct->setEnabled(true); pushValueAct->setEnabled(true); } } else { addColumAct->setEnabled(0); updateColumAct->setEnabled(0); renameColumnAct->setEnabled(0); removeColumAct->setEnabled(0); pushValueAct->setEnabled(0); columnPropertiesAct->setEnabled(0); } } void MainWindow::updateMapMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { mapNewAct->setEnabled(0); deleteAct->setEnabled(0); convertActiveMapAct->setEnabled(0); convertDrawingMapAct->setEnabled(0); convertMapShapesAct->setEnabled(0); importAct->setEnabled(0); exportAct->setEnabled(0); exportGeometryAct->setEnabled(false); exportLinksAct->setEnabled(0); exportAxialConnectionsDotAct->setEnabled(0); exportAxialConnectionsPairAct->setEnabled(0); exportSegmentConnectionsPairAct->setEnabled(0); return; } mapNewAct->setEnabled(true); importAct->setEnabled(true); if (!m_p->m_meta_graph->viewingNone() && !m_p->m_communicator) deleteAct->setEnabled(true); else deleteAct->setEnabled(0); if (!m_p->m_communicator && (m_p->m_meta_graph->viewingProcessedLines() || m_p->m_meta_graph->viewingProcessedShapes())) convertActiveMapAct->setEnabled(true); else convertActiveMapAct->setEnabled(0); if (!m_p->m_communicator && (m_p->m_meta_graph->getState() & MetaGraph::LINEDATA) == MetaGraph::LINEDATA) convertDrawingMapAct->setEnabled(true); else convertDrawingMapAct->setEnabled(0); if (m_p->m_meta_graph && m_p->m_meta_graph->viewingShapes()) convertMapShapesAct->setEnabled(true); else convertMapShapesAct->setEnabled(0); if (!m_p->m_meta_graph->viewingNone() && !m_p->m_communicator) { exportAct->setEnabled(true); exportGeometryAct->setEnabled(true); exportLinksAct->setEnabled(true); exportAxialConnectionsDotAct->setEnabled(true); exportAxialConnectionsPairAct->setEnabled(true); exportSegmentConnectionsPairAct->setEnabled(true); } else { exportAct->setEnabled(0); exportGeometryAct->setEnabled(false); exportLinksAct->setEnabled(0); exportAxialConnectionsDotAct->setEnabled(0); exportAxialConnectionsPairAct->setEnabled(0); exportSegmentConnectionsPairAct->setEnabled(0); } } void MainWindow::updateEditMenu() { QGraphDoc* m_p = activeMapDoc(); if(!m_p) { copyDataAct->setEnabled(0); undoAct->setEnabled(0); copyScreenAct->setEnabled(0); exportScreenAct->setEnabled(0); clearAct->setEnabled(0); selectByQueryAct->setEnabled(0); //zoomToSelectionAct->setEnabled(0); selectionToLayerAct->setEnabled(0); return; } copyScreenAct->setEnabled(true); exportScreenAct->setEnabled(true); if(m_p->m_meta_graph->isEditable()) clearAct->setEnabled(true); else clearAct->setEnabled(0); if (m_p->m_meta_graph->canUndo()) undoAct->setEnabled(true); else undoAct->setEnabled(0); if (m_p->m_meta_graph && !m_p->m_communicator && m_p->m_meta_graph->viewingProcessed()) selectByQueryAct->setEnabled(true); else selectByQueryAct->setEnabled(0); if(m_p->m_meta_graph->isSelected()) { //zoomToSelectionAct->setEnabled(true); selectionToLayerAct->setEnabled(true); } else { //zoomToSelectionAct->setEnabled(0); selectionToLayerAct->setEnabled(0); } } void MainWindow::updateFileMenu() { if(mdiArea->activeSubWindow()) { closeAct->setEnabled( true ); saveAct->setEnabled( true ); saveAsAct->setEnabled( true ); propertiesAct->setEnabled( true ); if(current_view_type == QGraphDoc::VIEW_3D) { printAct->setEnabled( 0 ); printPreviewAct->setEnabled( 0 ); } else { printAct->setEnabled( true ); printPreviewAct->setEnabled( true ); } } else { closeAct->setEnabled( 0 ); saveAct->setEnabled( 0 ); saveAsAct->setEnabled( 0 ); propertiesAct->setEnabled( 0 ); printAct->setEnabled( 0 ); printPreviewAct->setEnabled( 0 ); } } void MainWindow::updateWindowMenu() { QGraphDoc* m_p = activeMapDoc(); windowMenu->clear(); windowMenu->addAction(mapAct); if(m_p && m_p->m_view[QGraphDoc::VIEW_MAP]) mapAct->setChecked(true); else mapAct->setChecked(false); windowMenu->addAction(scatterPlotAct); if(m_p && m_p->m_view[QGraphDoc::VIEW_SCATTER]) scatterPlotAct->setChecked(true); else scatterPlotAct->setChecked(false); windowMenu->addAction(tableAct); if(m_p && m_p->m_view[QGraphDoc::VIEW_TABLE]) tableAct->setChecked(true); else tableAct->setChecked(false); windowMenu->addAction(thirdDViewAct); if(m_p && m_p->m_view[QGraphDoc::VIEW_3D]) thirdDViewAct->setChecked(true); else thirdDViewAct->setChecked(false); windowMenu->addAction(glViewAct); if(m_p && m_p->m_view[QGraphDoc::VIEW_MAP_GL]) glViewAct->setChecked(true); else glViewAct->setChecked(false); windowMenu->addSeparator(); windowMenu->addAction(colourRangeAct); windowMenu->addSeparator(); windowMenu->addAction(cascadeAct); windowMenu->addAction(tileAct); windowMenu->addAction(arrangeIconsAct); windowMenu->addAction(separatorAct); if(!m_p) { mapAct->setEnabled(0); scatterPlotAct->setEnabled(0); tableAct->setEnabled(0); thirdDViewAct->setEnabled(0); glViewAct->setEnabled(0); } else { thirdDViewAct->setEnabled(true); mapAct->setEnabled(true); glViewAct->setEnabled(true); if (m_p->m_meta_graph && m_p->m_meta_graph->viewingProcessed()) { tableAct->setEnabled(true); scatterPlotAct->setEnabled(true); } else { tableAct->setEnabled(0); scatterPlotAct->setEnabled(0); } } QList windows = mdiArea->subWindowList(); int find_count = 1; for (int i = 0; i < windows.size(); ++i) { MapView *child = qobject_cast(windows.at(i)->widget()); if(!child) continue; QString text; text = tr("&%1 %2").arg(find_count++).arg(child->windowTitle()); QAction *action = windowMenu->addAction(text); action->setCheckable(true); action ->setChecked(child == activeMapView()); connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); windowMapper->setMapping(action, windows.at(i)->widget()); } } void MainWindow::UpdateStatus(QString s1, QString s2, QString s3) { g_info_curr->setText(s1); g_info_curr->update(); g_size->setText(s2); g_size->update(); g_pos_curr->setText(s3); g_pos_curr->update(); } void MainWindow::updateToolbar() { importAct->setEnabled(0); saveAct->setEnabled(0); addColumAct->setEnabled(0); updateColumAct->setEnabled(0); removeColumAct->setEnabled(0); pushValueAct->setEnabled(0); invertColorAct->setEnabled(0); SelectButton->setEnabled(0); DragButton->setEnabled(0); zoomToolButton->setEnabled(0); zoomToAct->setEnabled(0); RecentAct->setEnabled(0); SetGridAct->setEnabled(0); fillColorToolButton->setEnabled(0); SelectPenButton->setEnabled(0); lineToolButton->setEnabled(0); newisoToolButton->setEnabled(0); AxialMapButton->setEnabled(0); StepDepthButton->setEnabled(0); JoinToolButton->setEnabled(0); attr_del_button->setEnabled(0); attr_add_button->setEnabled(0); QGraphDoc* m_p = activeMapDoc(); MapView* tmpView = activeMapView(); if(m_p) { importAct->setEnabled(true); saveAct->setEnabled(true); if(m_p->m_meta_graph->getDisplayedMapRef() != -1) addColumAct->setEnabled(true); SelectButton->setEnabled(true); DragButton->setEnabled(true); RecentAct->setEnabled(true); if(m_p->m_meta_graph->isSelected()) zoomToAct->setEnabled(true); if (m_p->m_meta_graph->isShown()) // zoom bug VGA // TV zoomToolButton->setEnabled(true); if (m_p->m_meta_graph->viewingProcessed()) zoomToolButton->setEnabled(true); if (m_p->m_meta_graph->getState() & MetaGraph::LINEDATA || m_p->m_meta_graph->viewingUnprocessedPoints()) SetGridAct->setEnabled(true); if (m_p->m_meta_graph->viewingUnprocessedPoints()) { fillColorToolButton->setEnabled(true); SelectPenButton->setEnabled(true); } else { if (tmpView) { if (m_selected_mapbar_item == ID_MAPBAR_ITEM_FILL || m_selected_mapbar_item == ID_MAPBAR_ITEM_SEMIFILL || m_selected_mapbar_item == ID_MAPBAR_ITEM_PENCIL) { tmpView->OnEditSelect(); SelectButton->setChecked(true); } } } int type = m_p->m_meta_graph->getDisplayedMapType(); if ((type == ShapeMap::DATAMAP && m_p->m_meta_graph->getDisplayedDataMap().isEditable()) || ((type == ShapeMap::AXIALMAP || type == ShapeMap::CONVEXMAP || type == ShapeMap::PESHMAP) && m_p->m_meta_graph->getDisplayedShapeGraph().isEditable())) lineToolButton->setEnabled(true); else { if (tmpView) { if (m_selected_mapbar_item == ID_MAPBAR_ITEM_LINETOOL || m_selected_mapbar_item == ID_MAPBAR_ITEM_POLYGON) { tmpView->OnEditSelect(); SelectButton->setChecked(true); } } } type = m_p->m_meta_graph->getState(); if (!(~type & MetaGraph::LINEDATA)) newisoToolButton->setEnabled(true); else { if (tmpView) { if (m_selected_mapbar_item == ID_MAPBAR_ITEM_ISOVIST || m_selected_mapbar_item == ID_MAPBAR_ITEM_HALFISOVIST) { tmpView->OnEditSelect(); SelectButton->setChecked(true); } } } if (( ( (m_p->m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) && (m_p->m_meta_graph->getDisplayedPointMap().getFilledPointCount() > 1)) || (((m_p->m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) && (m_p->m_meta_graph->getState() & MetaGraph::SHAPEGRAPHS)) && (!m_p->m_meta_graph->getDisplayedShapeGraph().isSegmentMap()) ) )) JoinToolButton->setEnabled(true); else { if (tmpView) { if (m_selected_mapbar_item == ID_MAPBAR_ITEM_JOIN || m_selected_mapbar_item == ID_MAPBAR_ITEM_UNJOIN) { tmpView->OnEditSelect(); SelectButton->setChecked(true); } } } type = m_p->m_meta_graph->getState(); if (!(~type & MetaGraph::LINEDATA)) AxialMapButton->setEnabled(true); else { if (tmpView) { if (m_selected_mapbar_item == ID_MAPBAR_ITEM_AL2) { tmpView->OnEditSelect(); SelectButton->setChecked(true); } } } if (m_p->m_meta_graph->viewingProcessed() && m_p->m_meta_graph->isSelected()) StepDepthButton->setEnabled(true); if (!m_p->m_communicator && m_p->m_meta_graph->viewingProcessed()) { int col = m_p->m_meta_graph->getDisplayedAttribute(); if (!(col == -1 || col == -2 || m_p->m_meta_graph->isAttributeLocked(col))) { renameColumnAct->setEnabled(true); updateColumAct->setEnabled(true); removeColumAct->setEnabled(true); pushValueAct->setEnabled(true); invertColorAct->setEnabled(true); attr_del_button->setEnabled(true); attr_add_button->setEnabled(true); } } } } /////////////////////////////////////////////////////////////////////////////////// void MainWindow::createActions() { newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); newAct->setShortcut(tr("Ctrl+N")); newAct->setStatusTip(tr("Create a new graph workspace\nNew Workspace")); connect(newAct, SIGNAL(triggered()), this, SLOT(OnFileNew())); openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); openAct->setStatusTip(tr("Change the printing options\nPage Setup")); connect(openAct, SIGNAL(triggered()), this, SLOT(OnFileOpen())); closeAct = new QAction(tr("&Close"), this); closeAct->setStatusTip(tr("Close the active graph workspace\nClose Workspace")); connect(closeAct, SIGNAL(triggered()), this, SLOT(OnFileClose())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); saveAct->setShortcut(tr("Ctrl+S")); saveAct->setStatusTip(tr("Save the active graph workspace\nSave workspace")); connect(saveAct, SIGNAL(triggered()), this, SLOT(OnFileSave())); saveAsAct = new QAction(tr("Save &As..."), this); saveAsAct->setStatusTip(tr("Save the active graph workspace with a new name\nSave Workspace As")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(OnFileSaveAs())); propertiesAct = new QAction(tr("Properties..."), this); propertiesAct->setStatusTip(tr("Edit graph workspace properties\nWorkspace Properties")); connect(propertiesAct, SIGNAL(triggered()), this, SLOT(OnFileProperties())); printAct = new QAction(tr("&Print..."), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setStatusTip(tr("Print the active graph workspace\nPrint Workspace")); connect(printAct, SIGNAL(triggered()), this, SLOT(OnFilePrint())); printPreviewAct = new QAction(tr("Print Pre&view"), this); printPreviewAct->setStatusTip(tr("Display full pages\nPrint Preview")); connect(printPreviewAct, SIGNAL(triggered()), this, SLOT(OnFilePrintPreview())); printSetupAct = new QAction(tr("P&rint Setup..."), this); printSetupAct->setStatusTip(tr("Change the printer and printing options\nPrint Setup")); connect(printSetupAct, SIGNAL(triggered()), this, SLOT(OnFilePrintSetup())); for (int i = 0; i < MaxRecentFiles; ++i) { recentFileActs[i] = new QAction(this); recentFileActs[i]->setVisible(false); connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); } exitAct = new QAction(tr("E&xit"), this); exitAct->setStatusTip(tr("Quit the application; prompts to save documents\nExit")); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); //Edit Menu Actions undoAct = new QAction(tr("&Undo"), this); undoAct->setShortcut(tr("Ctrl+Z")); undoAct->setStatusTip(tr("Undo the last action\nUndo")); connect(undoAct, SIGNAL(triggered()), this, SLOT(OnEditUndo())); copyDataAct = new QAction(tr("Copy &Data"), this); connect(copyDataAct, SIGNAL(triggered()), this, SLOT(OnEditCopyData())); copyScreenAct = new QAction(tr("Copy &Screen"), this); copyScreenAct->setShortcut(tr("Ctrl+C")); copyScreenAct->setStatusTip(tr("Copy the screen contents to clipboard\nCopy Screen")); connect(copyScreenAct, SIGNAL(triggered()), this, SLOT(OnEditCopy())); exportScreenAct = new QAction(tr("&Export Screen..."), this); exportScreenAct->setStatusTip(tr("Export the screen as an Encapsulated Postscript file\nExport Screen")); connect(exportScreenAct, SIGNAL(triggered()), this, SLOT(OnEditSave())); clearAct = new QAction(tr("&Clear"), this); clearAct->setShortcut(tr("Del")); clearAct->setShortcutContext(Qt::ApplicationShortcut); clearAct->setStatusTip(tr("Erase the selection\nErase")); connect(clearAct, SIGNAL(triggered()), this, SLOT(OnEditClear())); selectByQueryAct = new QAction(tr("Select by &Query"), this); selectByQueryAct->setShortcut(tr("Ctrl+Q")); connect(selectByQueryAct, SIGNAL(triggered()), this, SLOT(OnEditQuery())); //zoomToSelectionAct = new QAction(tr("&Zoom to Selection"), this); //zoomToSelectionAct->setStatusTip(tr("Zoom in around current selection\nZoom to Selection")); //connect(zoomToSelectionAct, SIGNAL(triggered()), this, SLOT(OnViewZoomsel())); selectionToLayerAct = new QAction(tr("Selection to &Layer..."), this); selectionToLayerAct->setStatusTip(tr("Convert the current selection to a new map layer")); connect(selectionToLayerAct, SIGNAL(triggered()), this, SLOT(OnEditSelectToLayer())); //Map Menu Actions mapNewAct = new QAction(tr("&New..."), this); mapNewAct->setStatusTip(tr("Create a new map")); connect(mapNewAct, SIGNAL(triggered()), this, SLOT(OnLayerNew())); deleteAct = new QAction(tr("&Delete..."), this); deleteAct->setStatusTip(tr("Delete the active map")); connect(deleteAct, SIGNAL(triggered()), this, SLOT(OnLayerDelete())); convertActiveMapAct = new QAction(tr("&Convert Active Map..."), this); convertActiveMapAct->setStatusTip(tr("Create a new map from the active map")); connect(convertActiveMapAct, SIGNAL(triggered()), this, SLOT(OnLayerConvert())); convertDrawingMapAct = new QAction(tr("Convert Drawing &Map..."), this); convertDrawingMapAct->setStatusTip(tr("Create a new map from the displayed drawing maps")); connect(convertDrawingMapAct, SIGNAL(triggered()), this, SLOT(OnLayerConvertDrawing())); convertMapShapesAct = new QAction(tr("Convert Map &Shapes..."), this); convertMapShapesAct->setStatusTip(tr("Convert shapes to other shapes within the current map")); connect(convertMapShapesAct, SIGNAL(triggered()), this, SLOT(OnConvertMapShapes())); importAct = new QAction(QIcon(":/images/down.png"), tr("&Import..."), this); importAct->setShortcut(tr("Ctrl+I")); importAct->setStatusTip(tr("Import a DXF or points file\nImport Map")); connect(importAct, SIGNAL(triggered()), this, SLOT(OnFileImport())); exportAct = new QAction(tr("&Export map..."), this); exportAct->setShortcut(tr("Ctrl+E")); exportAct->setStatusTip(tr("Export the active map")); connect(exportAct, SIGNAL(triggered()), this, SLOT(OnFileExport())); exportGeometryAct = new QAction(tr("&Export map geometry..."), this); exportGeometryAct->setStatusTip(tr("Export the geometry of the active map")); connect(exportGeometryAct, SIGNAL(triggered()), this, SLOT(OnFileExportMapGeometry())); exportLinksAct = new QAction(tr("&Export links..."), this); exportLinksAct->setStatusTip(tr("Export the links of the active map")); connect(exportLinksAct, SIGNAL(triggered()), this, SLOT(OnFileExportLinks())); exportAxialConnectionsPairAct = new QAction(tr("&Axial Connections as CSV..."), this); exportAxialConnectionsPairAct->setStatusTip(tr("Export a list of line-line intersections")); connect(exportAxialConnectionsPairAct, SIGNAL(triggered()), this, SLOT(OnAxialConnectionsExportAsPairCSV())); exportAxialConnectionsDotAct = new QAction(tr("&Axial Connections as Dot..."), this); exportAxialConnectionsDotAct->setStatusTip(tr("Export a list of line-line intersections")); connect(exportAxialConnectionsDotAct, SIGNAL(triggered()), this, SLOT(OnAxialConnectionsExportAsDot())); exportSegmentConnectionsPairAct = new QAction(tr("&Segment Connections as CSV..."), this); exportSegmentConnectionsPairAct->setStatusTip(tr("Export a list of line-line intersections and weights")); connect(exportSegmentConnectionsPairAct, SIGNAL(triggered()), this, SLOT(OnSegmentConnectionsExportAsPairCSV())); exportPointmapConnectionsPairAct = new QAction(tr("Visibility Graph Connections as CSV..."), this); exportPointmapConnectionsPairAct->setStatusTip(tr("Export connections between cells in a visibility graph as an adjacency list")); connect(exportPointmapConnectionsPairAct, SIGNAL(triggered()), this, SLOT(OnPointmapExportConnectionsAsCSV())); //Attributes Menu Actions renameColumnAct = new QAction(tr("&Rename Column..."), this); renameColumnAct->setStatusTip(tr("Rename the currently displayed attribute")); connect(renameColumnAct, SIGNAL(triggered()), this, SLOT(OnRenameColumn())); columnPropertiesAct = new QAction(tr("Column &Properties..."), this); columnPropertiesAct->setStatusTip(tr("Summary statistics for the active attribute")); connect(columnPropertiesAct, SIGNAL(triggered()), this, SLOT(OnColumnProperties())); //Tools Menu Actions makeVisibilityGraphAct = new QAction(tr("Make &Visibility Graph..."), this); connect(makeVisibilityGraphAct, SIGNAL(triggered()), this, SLOT(OnToolsMakeGraph())); unmakeVisibilityGraphAct = new QAction(tr("Unmake &Visibility Graph..."), this); connect(unmakeVisibilityGraphAct, SIGNAL(triggered()), this, SLOT(OnToolsUnmakeGraph())); importVGALinksAct = new QAction(tr("Import VGA links from file..."), this); connect(importVGALinksAct, SIGNAL(triggered()), this, SLOT(OnToolsImportVGALinks())); generateIsovistsAct = new QAction(tr("Generate isovists from file..."), this); connect(generateIsovistsAct, SIGNAL(triggered()), this, SLOT(OnToolsGenerateIsovistsFromFile())); makeIsovistPathAct = new QAction(tr("Make &Isovist Path..."), this); connect(makeIsovistPathAct, SIGNAL(triggered()), this, SLOT(OnToolsIsovistpath())); runVisibilityGraphAnalysisAct = new QAction(tr("&Run Visibility Graph Analysis..."), this); connect(runVisibilityGraphAnalysisAct, SIGNAL(triggered()), this, SLOT(OnToolsRun())); visibilityStepAct = new QAction(tr("&Visibility Step"), this); visibilityStepAct->setStatusTip(tr("Step depth from current selection\nStep Depth")); connect(visibilityStepAct, SIGNAL(triggered()), this, SLOT(OnToolsPD())); metricStepAct = new QAction(tr("&Metric Step"), this); metricStepAct->setStatusTip(tr("Distance from current selection\nMetric Depth")); connect(metricStepAct, SIGNAL(triggered()), this, SLOT(OnToolsMPD())); angularStepAct = new QAction(tr("&Angular Step"), this); angularStepAct->setStatusTip(tr("Angular distance from current selection\nAngular Depth")); connect(angularStepAct, SIGNAL(triggered()), this, SLOT(OnToolsAPD())); convertDataMapLinesAct = new QAction(tr("Convert Data Map Lines to Merge Points"), this); convertDataMapLinesAct->setStatusTip(tr("Convert displayed data map lines to merge points for current visibility graph")); connect(convertDataMapLinesAct, SIGNAL(triggered()), this, SLOT(OnToolsPointConvShapeMap())); runAgentAnalysisAct = new QAction(tr("&Run Agent Analysis"), this); connect(runAgentAnalysisAct, SIGNAL(triggered()), this, SLOT(OnToolsAgentRun())); loadAgentProgramAct = new QAction(tr("&Load Agent Program"), this); connect(loadAgentProgramAct, SIGNAL(triggered()), this, SLOT(OnToolsAgentLoadProgram())); runGraphAnaysisAct = new QAction(tr("&Run Graph Analysis..."), this); runGraphAnaysisAct->setStatusTip(tr("Analyse currently displayed axial line map\nAxial analysis")); connect(runGraphAnaysisAct, SIGNAL(triggered()), this, SLOT(OnToolsRunAxa())); stepDepthAct = new QAction(tr("Step &Depth"), this); stepDepthAct->setShortcut(tr("Ctrl+D")); stepDepthAct->setStatusTip(tr("Step depth from current selection\nStep Depth")); connect(stepDepthAct, SIGNAL(triggered()), this, SLOT(OnToolsPD())); reduceToFewestLineMapAct = new QAction(tr("Reduce to &Fewest Line Map..."), this); connect(reduceToFewestLineMapAct, SIGNAL(triggered()), this, SLOT(OnToolsMakeFewestLineMap())); convertDataMapPointsAct = new QAction(tr("Convert Data Map Points to Unlinks"), this); convertDataMapPointsAct->setStatusTip(tr("Convert displayed data map points to unlinks for current axial map")); connect(convertDataMapPointsAct, SIGNAL(triggered()), this, SLOT(OnToolsAxialConvShapeMap())); loadUnlinksFromFileAct = new QAction(tr("Load Unlinks from File..."), this); connect(loadUnlinksFromFileAct, SIGNAL(triggered()), this, SLOT(OnToolsLineLoadUnlinks())); runAngularSegmentAnalysisAct = new QAction(tr("&Run Angular Segment Analysis..."), this); connect(runAngularSegmentAnalysisAct, SIGNAL(triggered()), this, SLOT(OnToolsRunSeg())); runTopologicalOrMetricAnalysisAct = new QAction(tr("Run &Topological or Metric Analysis..."), this); connect(runTopologicalOrMetricAnalysisAct, SIGNAL(triggered()), this, SLOT(OnToolsTopomet())); segmentAngularStepAct = new QAction(tr("&Angular Step"), this); segmentAngularStepAct->setShortcut(tr("Ctrl+D")); segmentAngularStepAct->setStatusTip(tr("Step depth from current selection\nStep Depth")); connect(segmentAngularStepAct, SIGNAL(triggered()), this, SLOT(OnToolsPD())); topologicalStepAct = new QAction(tr("&Topological Step"), this); connect(topologicalStepAct, SIGNAL(triggered()), this, SLOT(OnToolsTPD())); segmentMetricStepAct = new QAction(tr("&Metric Step"), this); connect(segmentMetricStepAct, SIGNAL(triggered()), this, SLOT(OnToolsMPD())); optionsAct = new QAction(tr("Options..."), this); connect(optionsAct, SIGNAL(triggered()), this, SLOT(OnToolsOptions())); //View Menu Actions showGridAct = new QAction(tr("Show &Grid"), this); showGridAct->setStatusTip(tr("Display grid")); showGridAct->setCheckable(true); connect(showGridAct, SIGNAL(triggered()), this, SLOT(OnViewShowGrid())); attributeSummaryAct = new QAction(tr("&Attribute Summary..."), this); attributeSummaryAct->setStatusTip(tr("Show summarised attribute information for selected points")); connect(attributeSummaryAct, SIGNAL(triggered()), this, SLOT(OnViewSummary())); //Window Menu Actions mapAct = new QAction(tr("&Map"), this); mapAct->setCheckable(true); connect(mapAct, SIGNAL(triggered()), this, SLOT(OnWindowMap())); scatterPlotAct = new QAction(tr("&Scatter Plot"), this); scatterPlotAct->setCheckable(true); connect(scatterPlotAct, SIGNAL(triggered()), this, SLOT(OnViewScatterplot())); tableAct = new QAction(tr("&Table"), this); tableAct->setCheckable(true); connect(tableAct, SIGNAL(triggered()), this, SLOT(OnViewTable())); thirdDViewAct = new QAction(tr("&3D View"), this); thirdDViewAct->setCheckable(true); connect(thirdDViewAct, SIGNAL(triggered()), this, SLOT(OnWindow3dView())); glViewAct = new QAction(tr("Map (Open&GL)"), this); glViewAct->setCheckable(true); connect(glViewAct, SIGNAL(triggered()), this, SLOT(OnWindowGLView())); colourRangeAct = new QAction(tr("&Colour Range"), this); connect(colourRangeAct, SIGNAL(triggered()), this, SLOT(OnViewColourRange())); cascadeAct = new QAction(tr("C&ascade"), this); cascadeAct->setStatusTip(tr("Arrange windows so they overlap\nCascade Windows")); connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); tileAct = new QAction(tr("T&ile"), this); tileAct->setStatusTip(tr("Arrange windows as non-overlapping tiles\nTile Windows")); connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); arrangeIconsAct = new QAction(tr("A&rrange Icons"), this); arrangeIconsAct->setStatusTip(tr("Arrange icons at the bottom of the window\nArrange Icons")); // connect(arrangeIconsAct, SIGNAL(triggered()), mdiArea, SLOT(arrangeSubWindows())); //Help Menu Actions onlineBugsAct = new QAction(tr("Submit Problems/Ideas"), this); onlineBugsAct->setStatusTip(tr("View or Submit Problems and Ideas online")); connect(onlineBugsAct, SIGNAL(triggered()), this, SLOT(OnHelpBugs())); onlineHandbookAct = new QAction(tr("Get the PDF &Handbook"), this); onlineHandbookAct->setStatusTip(tr("View the Original Depthmap Researchers' Handbook")); connect(onlineHandbookAct, SIGNAL(triggered()), this, SLOT(OnHelpManual())); onlineTutorialsAct = new QAction(tr("Online &Tutorials"), this); onlineTutorialsAct->setStatusTip(tr("View the Original Depthmap tutorials online")); connect(onlineTutorialsAct, SIGNAL(triggered()), this, SLOT(OnHelpTutorials())); onlineScriptingManualAct = new QAction(tr("Online &Scripting Manual"), this); onlineScriptingManualAct->setStatusTip(tr("See the Original SalaScript web page")); connect(onlineScriptingManualAct, SIGNAL(triggered()), this, SLOT(OnHelpSalaManual())); aboutDepthMapAct = new QAction(tr("About &depthmapX..."), this); aboutDepthMapAct->setStatusTip(tr("Display program information, version number and copyright\nAbout")); connect(aboutDepthMapAct, SIGNAL(triggered()), this, SLOT(OnAppAbout())); // ToolBar actions invertColorAct = new QAction(QIcon(":/images/win/b-5-18.png"), tr("Invert Colour Range"), this); invertColorAct->setStatusTip(tr("Invert the colour range\nInvert Colour Range")); connect(invertColorAct, SIGNAL(triggered()), this, SLOT(OninvertColor())); addColumAct = new QAction(QIcon(":/images/win/b-5-19.png"), tr("&Add Column"), this); addColumAct->setStatusTip(tr("Add column to the active map\nAdd Column")); connect(addColumAct, SIGNAL(triggered()), this, SLOT(OnAddColumn())); updateColumAct = new QAction(QIcon(":/images/win/b-5-20.png"), tr("&Update Column"), this); updateColumAct->setStatusTip(tr("Replace column contents using a SalaScript command\nUpdate Column")); connect(updateColumAct, SIGNAL(triggered()), this, SLOT(OnUpdateColumn())); removeColumAct = new QAction(QIcon(":/images/win/b-5-21.png"), tr("&Remove Column"), this); removeColumAct->setStatusTip(tr("Remove column from the active map\nRemove column")); connect(removeColumAct, SIGNAL(triggered()), this, SLOT(OnRemoveColumn())); pushValueAct = new QAction(QIcon(":/images/win/b-5-22.png"), tr("&Push Values"), this); pushValueAct->setStatusTip(tr("Push values from active map to another map\npushValue")); connect(pushValueAct, SIGNAL(triggered()), this, SLOT(OnPushToLayer())); zoomToAct = new QAction(QIcon(":/images/win/b-5-5.png"), tr("Zoom to Selection"), this); zoomToAct->setStatusTip(tr("Zoom in on current selected items\nZoom to Selection")); connect(zoomToAct, SIGNAL(triggered()), this, SLOT(OnzoomTo())); RecentAct = new QAction(QIcon(":/images/win/b-5-6.png"), tr("&Recentre View"), this); RecentAct->setStatusTip(tr("Fit map to window\nRecentre")); connect(RecentAct, SIGNAL(triggered()), this, SLOT(OnViewCentreView())); SetGridAct = new QAction(QIcon(":/images/win/b-5-7.png"), tr("Set Grid"), this); SetGridAct->setStatusTip(tr("Overlay grid on plan\nSet Grid")); connect(SetGridAct, SIGNAL(triggered()), this, SLOT(OnEditGrid())); toggleColor = new QAction(QIcon(":/images/win/b-7-1.png"), tr("Toggle Colour"), this); toggleColor->setCheckable(1); toggleColor->setStatusTip(tr("Toggle colour display on and off\nToggle Colour")); connect(toggleColor, SIGNAL(triggered()), this, SLOT(OntoggleColor())); toggleOrg = new QAction(QIcon(":/images/win/b-7-2.png"), tr("Toggle origin on/off"), this); toggleOrg->setCheckable(1); toggleOrg->setStatusTip(tr("Toggle graph intersect at origin of X, Y values\nToggle origin on/off")); connect(toggleOrg, SIGNAL(triggered()), this, SLOT(OntoggleOrg())); viewTrend = new QAction(QIcon(":/images/win/b-7-3.png"), tr("View trend line"), this); viewTrend->setCheckable(1); viewTrend->setStatusTip(tr("Show regression line\nView trend line")); connect(viewTrend, SIGNAL(triggered()), this, SLOT(OnviewTrend())); yx = new QAction(QIcon(":/images/win/b-7-4.png"), tr(""), this); yx->setCheckable(1); yx->setStatusTip(tr("")); connect(yx, SIGNAL(triggered()), this, SLOT(OnYX())); Rtwo = new QAction(QIcon(":/images/win/b-7-5.png"), tr(""), this); Rtwo->setCheckable(1); Rtwo->setStatusTip(tr("")); connect(Rtwo, SIGNAL(triggered()), this, SLOT(OnRtwo())); /////////////////////////////////////////////////////////// //Popup toolbar { zoomToolButton = new QToolButton; zoomToolButton->setPopupMode(QToolButton::MenuButtonPopup); QMenu *zoomMenu = new QMenu; zoomInAct = new QAction(tr("Zoom in"), this); zoomInAct->setStatusTip(tr("Zoom into or out of (using Alt-key) view of map\nZoom In")); zoomInAct->setCheckable(1); zoomInAct->setChecked(1); zoomInAct->setData(ID_MAPBAR_ITEM_ZOOM_IN); connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomModeTriggered())); zoomMenu->addAction(zoomInAct); zoomOutAct = new QAction(tr("Zoom out"), this); zoomOutAct->setStatusTip(tr("Zoom out of or into (using Alt-key) view of map\nZoom Out")); zoomOutAct->setCheckable(1); zoomOutAct->setData(ID_MAPBAR_ITEM_ZOOM_OUT); connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomModeTriggered())); zoomMenu->addAction(zoomOutAct); zoomMenu->setDefaultAction(zoomInAct); zoomToolButton->setMenu(zoomMenu); zoomToolButton->setIcon(QIcon(":/images/win/b-5-3.png")); zoomToolButton->setCheckable(1); connect(zoomToolButton, SIGNAL(clicked()), this, SLOT(zoomButtonTriggered())); QActionGroup* tGroup = new QActionGroup(this); tGroup->addAction(zoomInAct); tGroup->addAction(zoomOutAct); } { fillColorToolButton = new QToolButton; fillColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); QMenu *fillColorMenu = new QMenu; STDFillColorAct = new QAction(tr("Standard Fill"), this); STDFillColorAct->setStatusTip(tr("Standard Fill grid spaces with points\nFill")); STDFillColorAct->setCheckable(1); STDFillColorAct->setChecked(1); STDFillColorAct->setData(ID_MAPBAR_ITEM_FILL); connect(STDFillColorAct, SIGNAL(triggered()), this, SLOT(FillModeTriggered())); ContextFillColorAct = new QAction(tr("Context Fill"), this); ContextFillColorAct->setStatusTip(tr("Context Fill grid spaces with points\nFill")); ContextFillColorAct->setCheckable(1); ContextFillColorAct->setData(ID_MAPBAR_ITEM_SEMIFILL); connect(ContextFillColorAct, SIGNAL(triggered()), this, SLOT(FillModeTriggered())); // AV test - TV AugmentFillColorAct = new QAction(tr("Augmented Fill"), this); AugmentFillColorAct->setStatusTip(tr("Augmented Fill grid spaces with points\nFill")); AugmentFillColorAct->setCheckable(1); AugmentFillColorAct->setData(ID_MAPBAR_ITEM_AUGMENT_FILL); //connect(AugmentFillColorAct, SIGNAL(triggered()), this, SLOT(FillModeTriggered())); fillColorMenu->addAction(STDFillColorAct); fillColorMenu->addAction(ContextFillColorAct); //fillColorMenu->addAction(AugmentFillColorAct); // AV TV fillColorMenu->setDefaultAction(STDFillColorAct); fillColorToolButton->setMenu(fillColorMenu); fillColorToolButton->setIcon(QIcon(":/images/win/b-5-8.png")); fillColorToolButton->setCheckable(1); connect(fillColorToolButton, SIGNAL(clicked()), this, SLOT(FillButtonTriggered())); QActionGroup* tGroup = new QActionGroup(this); tGroup->addAction(STDFillColorAct); tGroup->addAction(ContextFillColorAct); tGroup->addAction(AugmentFillColorAct); // AV TV } { lineToolButton = new QToolButton; lineToolButton->setPopupMode(QToolButton::MenuButtonPopup); QMenu *lineToolMenu = new QMenu; SelectLineAct = new QAction(tr("Line"), this); SelectLineAct->setStatusTip(tr("Draw a new line\nLine")); SelectLineAct->setCheckable(1); SelectLineAct->setChecked(1); SelectLineAct->setData(ID_MAPBAR_ITEM_LINETOOL); connect(SelectLineAct, SIGNAL(triggered()), this, SLOT(LineModeTriggered())); SelectPolyLineAct = new QAction(tr("Polygon"), this); SelectPolyLineAct->setStatusTip(tr("Draw a new polygon\nPolygon")); SelectPolyLineAct->setCheckable(1); SelectPolyLineAct->setData(ID_MAPBAR_ITEM_POLYGON); connect(SelectPolyLineAct, SIGNAL(triggered()), this, SLOT(LineModeTriggered())); lineToolMenu->addAction(SelectLineAct); lineToolMenu->addAction(SelectPolyLineAct); lineToolMenu->setDefaultAction(SelectLineAct); lineToolButton->setMenu(lineToolMenu); lineToolButton->setIcon(QIcon(":/images/win/b-5-10.png")); lineToolButton->setCheckable(1); connect(lineToolButton, SIGNAL(clicked()), this, SLOT(LineButtonTriggered())); QActionGroup* tGroup = new QActionGroup(this); tGroup->addAction(SelectLineAct); tGroup->addAction(SelectPolyLineAct); } { newisoToolButton = new QToolButton; newisoToolButton->setPopupMode(QToolButton::MenuButtonPopup); QMenu *isoToolMenu = new QMenu; MakeIosAct = new QAction(tr("Isovisit"), this); MakeIosAct->setStatusTip(tr("Make a new isovist\nIsovist")); MakeIosAct->setCheckable(1); MakeIosAct->setChecked(1); MakeIosAct->setData(ID_MAPBAR_ITEM_ISOVIST); connect(MakeIosAct, SIGNAL(triggered()), this, SLOT(isoModeTriggered())); PartialMakeIosAct = new QAction(tr("Partial isovisist"), this); PartialMakeIosAct->setStatusTip(tr("Make a new partial isovist\nPartial Isovist")); PartialMakeIosAct->setCheckable(1); PartialMakeIosAct->setData(ID_MAPBAR_ITEM_HALFISOVIST); connect(PartialMakeIosAct, SIGNAL(triggered()), this, SLOT(isoModeTriggered())); isoToolMenu->addAction(MakeIosAct); isoToolMenu->addAction(PartialMakeIosAct); isoToolMenu->setDefaultAction(MakeIosAct); newisoToolButton->setMenu(isoToolMenu); newisoToolButton->setIcon(QIcon(":/images/win/b-5-12.png")); newisoToolButton->setCheckable(1); connect(newisoToolButton, SIGNAL(clicked()), this, SLOT(isoButtonTriggered())); QActionGroup* tGroup = new QActionGroup(this); tGroup->addAction(MakeIosAct); tGroup->addAction(PartialMakeIosAct); } { JoinToolButton = new QToolButton; JoinToolButton->setPopupMode(QToolButton::MenuButtonPopup); QMenu *joinToolMenu = new QMenu; JoinAct = new QAction(tr("Link"), this); JoinAct->setStatusTip(tr("merge points together\nLink")); JoinAct->setCheckable(1); JoinAct->setChecked(1); JoinAct->setData(ID_MAPBAR_ITEM_JOIN); connect(JoinAct, SIGNAL(triggered()), this, SLOT(joinTriggered())); JoinUnlinkAct = new QAction(tr("unLink"), this); JoinUnlinkAct->setStatusTip(tr("unmerge points\nUnlink")); JoinUnlinkAct->setCheckable(1); JoinUnlinkAct->setData(ID_MAPBAR_ITEM_UNJOIN); connect(JoinUnlinkAct, SIGNAL(triggered()), this, SLOT(joinTriggered())); joinToolMenu->addAction(JoinAct); joinToolMenu->addAction(JoinUnlinkAct); joinToolMenu->setDefaultAction(JoinAct); JoinToolButton->setMenu(joinToolMenu); JoinToolButton->setIcon(QIcon(":/images/win/b-5-16.png")); JoinToolButton->setCheckable(1); connect(JoinToolButton, SIGNAL(clicked()), this, SLOT(joinButtonTriggered())); QActionGroup* tGroup = new QActionGroup(this); tGroup->addAction(JoinAct); tGroup->addAction(JoinUnlinkAct); } SelectButton = new QToolButton; SelectButton->setStatusTip(tr("Select a grid point\nSelect")); SelectButton->setIcon(QIcon(":/images/win/b-5-1.png")); SelectButton->setCheckable(1); connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectButtonTriggered())); DragButton = new QToolButton; DragButton->setStatusTip(tr("Click and drag to move map\nDrag")); DragButton->setIcon(QIcon(":/images/win/b-5-2.png")); DragButton->setCheckable(1); connect(DragButton, SIGNAL(clicked()), this, SLOT(DragButtonTriggered())); SelectPenButton = new QToolButton; SelectPenButton->setStatusTip(tr("Fill grid spaces individually (or click on a filled space to clear)\nPencil")); SelectPenButton->setIcon(QIcon(":/images/win/b-5-9.png")); SelectPenButton->setCheckable(1); connect(SelectPenButton, SIGNAL(clicked()), this, SLOT(SelectPenTriggered())); AxialMapButton = new QToolButton; AxialMapButton->setStatusTip(tr("Construct all line axial map from a seed point\nAxial Map")); AxialMapButton->setIcon(QIcon(":/images/win/b-5-14.png")); AxialMapButton->setCheckable(1); connect(AxialMapButton, SIGNAL(clicked()), this, SLOT(AxialMapTriggered())); StepDepthButton = new QToolButton; StepDepthButton->setStatusTip(tr("Step depth from current selection\nStep Depth")); StepDepthButton->setIcon(QIcon(":/images/win/b-5-15.png")); StepDepthButton->setCheckable(1); connect(StepDepthButton, SIGNAL(clicked()), this, SLOT(StepDepthTriggered())); QButtonGroup* pointerTypeGroup = new QButtonGroup; pointerTypeGroup->addButton(JoinToolButton, ID_MAPBAR_JOIN_ITEMS); pointerTypeGroup->addButton(zoomToolButton, ID_MAPBAR_ZOOM_ITEMS); pointerTypeGroup->addButton(fillColorToolButton, ID_MAPBAR_FILL_ITEMS); pointerTypeGroup->addButton(lineToolButton, ID_MAPBAR_DRAW_ITEMS); pointerTypeGroup->addButton(newisoToolButton, ID_MAPBAR_ISOVIST_ITEMS); pointerTypeGroup->addButton(SelectButton, ID_MAPBAR_ITEM_SELECT); pointerTypeGroup->addButton(DragButton, ID_MAPBAR_ITEM_MOVE); pointerTypeGroup->addButton(SelectPenButton, ID_MAPBAR_ITEM_PENCIL); pointerTypeGroup->addButton(AxialMapButton, ID_MAPBAR_ITEM_AL2); pointerTypeGroup->addButton(StepDepthButton, ID_MAPBAR_ITEM_PD); { toolsImportTracesAct = new QAction(QIcon(":/images/win/b-4-1.png"), tr("Import Traces"), this); toolsImportTracesAct->setStatusTip(tr("Import agent traces from a file\nImport Traces")); connect(toolsImportTracesAct, SIGNAL(triggered()), this, SLOT(OnToolsImportTraces())); addAgentAct = new QAction(QIcon(":/images/win/b-4-2.png"), tr("Add Agent"), this); addAgentAct->setCheckable(1); connect(addAgentAct, SIGNAL(triggered()), this, SLOT(OnAddAgent())); QActionGroup *tGroup = new QActionGroup(this); tGroup->addAction(toolsImportTracesAct); tGroup->addAction(addAgentAct); } { toolsAgentsPlayAct = new QAction(QIcon(":/images/win/b-4-3.png"), tr("Agents Play"), this); toolsAgentsPlayAct->setCheckable(1); connect(toolsAgentsPlayAct, SIGNAL(triggered()), this, SLOT(OnToolsAgentsPlay())); toolsAgentsPauseAct = new QAction(QIcon(":/images/win/b-4-4.png"), tr("Agents Pause"), this); toolsAgentsPauseAct->setCheckable(1); connect(toolsAgentsPauseAct, SIGNAL(triggered()), this, SLOT(OnToolsAgentsPause())); toolsAgentsStopAct = new QAction(QIcon(":/images/win/b-4-5.png"), tr("Agents Stop"), this); connect(toolsAgentsStopAct, SIGNAL(triggered()), this, SLOT(OnToolsAgentsStop())); QActionGroup *tGroup = new QActionGroup(this); tGroup->addAction(toolsAgentsPlayAct); tGroup->addAction(toolsAgentsPauseAct); tGroup->addAction(toolsAgentsStopAct); } agentTrailsAct = new QAction(QIcon(":/images/win/b-4-6.png"), tr("Agent Trails"), this); agentTrailsAct->setCheckable(1); connect(agentTrailsAct, SIGNAL(triggered()), this, SLOT(OnAgentTrails())); { thirdRotAct = new QAction(QIcon(":/images/win/b-4-7.png"), tr("3D Rot"), this); thirdRotAct->setCheckable(1); connect(thirdRotAct, SIGNAL(triggered()), this, SLOT(On3dRot())); thirdPanAct = new QAction(QIcon(":/images/win/b-4-8.png"), tr("3D Pan"), this); thirdPanAct->setCheckable(1); connect(thirdPanAct, SIGNAL(triggered()), this, SLOT(On3dPan())); thirdZoomAct = new QAction(QIcon(":/images/win/b-4-9.png"), tr("3D Zoom"), this); thirdZoomAct->setCheckable(1); connect(thirdZoomAct, SIGNAL(triggered()), this, SLOT(On3dZoom())); playLoopAct = new QAction(QIcon(":/images/win/b-4-10.png"), tr("Play Loop"), this); playLoopAct->setCheckable(1); connect(playLoopAct, SIGNAL(triggered()), this, SLOT(OnPlayLoop())); QActionGroup *tGroup = new QActionGroup(this); tGroup->addAction(thirdRotAct); tGroup->addAction(thirdPanAct); tGroup->addAction(thirdZoomAct); tGroup->addAction(playLoopAct); tGroup->addAction(addAgentAct); } thirdFilledAct = new QAction(QIcon(":/images/win/b-4-11.png"), tr("3D Filled"), this); thirdFilledAct->setCheckable(1); connect(thirdFilledAct, SIGNAL(triggered()), this, SLOT(On3dFilled())); } void MainWindow::createMenus() { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(closeAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addSeparator(); fileMenu->addAction(propertiesAct); fileMenu->addSeparator(); fileMenu->addAction(printAct); fileMenu->addAction(printPreviewAct); fileMenu->addAction(printSetupAct); separatorAct = fileMenu->addSeparator(); for (int i = 0; i < MaxRecentFiles; ++i) fileMenu->addAction(recentFileActs[i]); fileMenu->addSeparator(); fileMenu->addAction(exitAct); updateRecentFileActions(mSettings.readSetting(SettingTag::recentFileList).toStringList()); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(undoAct); editMenu->addSeparator(); editMenu->addAction(copyDataAct); editMenu->addAction(copyScreenAct); editMenu->addAction(exportScreenAct); editMenu->addSeparator(); editMenu->addAction(clearAct); editMenu->addSeparator(); editMenu->addAction(selectByQueryAct); //editMenu->addAction(zoomToSelectionAct); editMenu->addAction(selectionToLayerAct); mapMenu = menuBar()->addMenu(tr("&Map")); mapMenu->addAction(mapNewAct); mapMenu->addAction(deleteAct); mapMenu->addSeparator(); mapMenu->addAction(convertActiveMapAct); mapMenu->addAction(convertDrawingMapAct); mapMenu->addAction(convertMapShapesAct); mapMenu->addSeparator(); mapMenu->addAction(importAct); exportSubMenu = mapMenu->addMenu(tr("&Export")); exportSubMenu->addAction(exportAct); exportSubMenu->addAction(exportGeometryAct); exportSubMenu->addAction(exportLinksAct); exportSubMenu->addAction(exportAxialConnectionsDotAct); exportSubMenu->addAction(exportAxialConnectionsPairAct); exportSubMenu->addAction(exportSegmentConnectionsPairAct); exportSubMenu->addAction(exportPointmapConnectionsPairAct); attributesMenu = menuBar()->addMenu(tr("&Attributes")); attributesMenu->addAction(addColumAct); attributesMenu->addSeparator(); attributesMenu->addAction(renameColumnAct); attributesMenu->addAction(updateColumAct); attributesMenu->addAction(removeColumAct); attributesMenu->addAction(columnPropertiesAct); attributesMenu->addSeparator(); attributesMenu->addAction(pushValueAct); toolsMenu = menuBar()->addMenu(tr("&Tools")); visibilitySubMenu = toolsMenu->addMenu(tr("&Visibility")); visibilitySubMenu->addAction(SetGridAct); visibilitySubMenu->addAction(makeVisibilityGraphAct); visibilitySubMenu->addAction(unmakeVisibilityGraphAct); visibilitySubMenu->addAction(importVGALinksAct); visibilitySubMenu->addAction(generateIsovistsAct); visibilitySubMenu->addAction(makeIsovistPathAct); visibilitySubMenu->addSeparator(); visibilitySubMenu->addAction(runVisibilityGraphAnalysisAct); stepDepthSubMenu = visibilitySubMenu->addMenu(tr("Step &Depth")); stepDepthSubMenu->addAction(visibilityStepAct); stepDepthSubMenu->addAction(metricStepAct); stepDepthSubMenu->addAction(angularStepAct); visibilitySubMenu->addSeparator(); visibilitySubMenu->addAction(convertDataMapLinesAct); agentToolsSubMenu = toolsMenu->addMenu(tr("&Agent Tools")); agentToolsSubMenu->addAction(runAgentAnalysisAct); agentToolsSubMenu->addAction(loadAgentProgramAct); axialSubMenu = toolsMenu->addMenu(tr("A&xial / Convex / Pesh")); axialSubMenu->addAction(runGraphAnaysisAct); axialSubMenu->addAction(stepDepthAct); axialSubMenu->addSeparator(); axialSubMenu->addAction(reduceToFewestLineMapAct); axialSubMenu->addSeparator(); axialSubMenu->addAction(convertDataMapPointsAct); axialSubMenu->addAction(loadUnlinksFromFileAct); segmentSubMenu = toolsMenu->addMenu(tr("&Segment")); segmentSubMenu->addAction(runAngularSegmentAnalysisAct); segmentSubMenu->addAction(runTopologicalOrMetricAnalysisAct); segmentStepDepthSubMenu = segmentSubMenu->addMenu(tr("Step &Depth")); segmentStepDepthSubMenu->addAction(segmentAngularStepAct); segmentStepDepthSubMenu->addAction(topologicalStepAct); segmentStepDepthSubMenu->addAction(segmentMetricStepAct); toolsMenu->addSeparator(); toolsMenu->addAction(optionsAct); viewMenu = menuBar()->addMenu(tr("&View")); viewMenu->addAction(RecentAct); viewMenu->addAction(showGridAct); viewMenu->addAction(attributeSummaryAct); windowMenu = menuBar()->addMenu(tr("&Window")); windowMenu->addAction(mapAct); windowMenu->addAction(scatterPlotAct); windowMenu->addAction(tableAct); windowMenu->addAction(thirdDViewAct); windowMenu->addAction(glViewAct); windowMenu->addSeparator(); windowMenu->addAction(colourRangeAct); windowMenu->addSeparator(); windowMenu->addAction(cascadeAct); windowMenu->addAction(tileAct); windowMenu->addAction(arrangeIconsAct); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(onlineBugsAct); helpMenu->addAction(onlineHandbookAct); helpMenu->addAction(onlineTutorialsAct); helpMenu->addAction(onlineScriptingManualAct); helpMenu->addSeparator(); helpMenu->addAction(aboutDepthMapAct); for(auto &&mainWindowModule: mainWindowPluginRegistry.getModules()) { mainWindowModule->createMenus(this); } connect(viewMenu, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu())); connect(visibilitySubMenu, SIGNAL(aboutToShow()), this, SLOT(updateVisibilitySubMenu())); connect(stepDepthSubMenu, SIGNAL(aboutToShow()), this, SLOT(updateStepDepthSubMenu())); connect(agentToolsSubMenu, SIGNAL(aboutToShow()), this, SLOT(updateAgentToolsSubMenu())); connect(segmentSubMenu, SIGNAL(aboutToShow()), this, SLOT(updateSegmentSubMenu())); connect(segmentStepDepthSubMenu, SIGNAL(aboutToShow()), this, SLOT(updateSegmentStepDepthSubMenu())); connect(axialSubMenu, SIGNAL(aboutToShow()), this, SLOT(updateAxialSubMenu())); connect(attributesMenu, SIGNAL(aboutToShow()), this, SLOT(updateAttributesMenu())); connect(mapMenu, SIGNAL(aboutToShow()), this, SLOT(updateMapMenu())); connect(editMenu, SIGNAL(aboutToShow()), this, SLOT(updateEditMenu())); connect(fileMenu, SIGNAL(aboutToShow()), this, SLOT(updateFileMenu())); connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); } void MainWindow::createToolBars() { fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); fileToolBar->addAction(importAct); fileToolBar->addAction(saveAct); fileToolBar->addSeparator(); fileToolBar->addAction(addColumAct); fileToolBar->addAction(updateColumAct); fileToolBar->addAction(removeColumAct); fileToolBar->addAction(pushValueAct); fileToolBar->addSeparator(); fileToolBar->addAction(invertColorAct); fileToolBar->setIconSize(QSize(16,16)); fileToolBar->setMovable(0); editToolBar = addToolBar(tr("Edit")); editToolBar->addWidget(SelectButton); editToolBar->addWidget(DragButton); editToolBar->addWidget(zoomToolButton); editToolBar->addSeparator(); //editToolBar->addAction(zoomToAct); editToolBar->addAction(RecentAct); editToolBar->addSeparator(); editToolBar->addAction(SetGridAct); editToolBar->addWidget(fillColorToolButton); editToolBar->addWidget(SelectPenButton); editToolBar->addWidget(lineToolButton); editToolBar->addSeparator(); editToolBar->addWidget(newisoToolButton); editToolBar->addWidget(AxialMapButton); editToolBar->addWidget(StepDepthButton); editToolBar->addWidget(JoinToolButton); editToolBar->setIconSize(QSize(16,16)); editToolBar->setMovable(0); x_coord = new QComboBox(this); x_coord->setMinimumContentsLength(20); y_coord = new QComboBox(this); y_coord->setMinimumContentsLength(20); connect(x_coord, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(OnSelchangeViewSelector_X(const QString &))); connect(y_coord, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(OnSelchangeViewSelector_Y(const QString &))); QAction* xx = new QAction(tr("X = "), this); xx->setEnabled(0); QAction* yy = new QAction(tr("Y = "), this); yy->setEnabled(0); plotToolBar = addToolBar(tr("PlotEdit")); plotToolBar->addAction(xx); plotToolBar->addWidget(x_coord); plotToolBar->addSeparator(); plotToolBar->addAction(yy); plotToolBar->addWidget(y_coord); plotToolBar->addSeparator(); plotToolBar->addAction(toggleColor); plotToolBar->addAction(toggleOrg); plotToolBar->addAction(viewTrend); plotToolBar->addAction(yx); plotToolBar->addAction(Rtwo); plotToolBar->setIconSize(QSize(16,16)); plotToolBar->setMovable(0); thirdViewToolBar = addToolBar(tr("3DView")); thirdViewToolBar->addAction(toolsImportTracesAct); thirdViewToolBar->addAction(addAgentAct); thirdViewToolBar->addSeparator(); thirdViewToolBar->addAction(toolsAgentsPlayAct); thirdViewToolBar->addAction(toolsAgentsPauseAct); thirdViewToolBar->addAction(toolsAgentsStopAct); thirdViewToolBar->addSeparator(); thirdViewToolBar->addAction(agentTrailsAct); thirdViewToolBar->addSeparator(); thirdViewToolBar->addAction(thirdRotAct); thirdViewToolBar->addAction(thirdPanAct); thirdViewToolBar->addAction(thirdZoomAct); thirdViewToolBar->addAction(playLoopAct); thirdViewToolBar->addSeparator(); thirdViewToolBar->addAction(thirdFilledAct); thirdViewToolBar->setIconSize(QSize(16,16)); thirdViewToolBar->setMovable(0); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-1.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-2.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-3.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-4.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-5.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-6.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-7.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-8.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-9.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-10.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-11.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-12.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-13.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-14.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-15.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-16.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-17.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-18.png"))); m_tree_icon.push_back(QIcon(tr(":/images/win/b-1-19.png"))); } ================================================ FILE: depthmapX/mainwindow.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef MAINWINDOW_H #define MAINWINDOW_H #include "depthmapX/indexWidget.h" #include "depthmapX/treeWindow.h" #include "depthmapX/GraphDoc.h" #include "depthmapX/compatibilitydefines.h" #include "depthmapX/settings.h" #include "depthmapX/mainwindowmoduleregistry.hpp" #include "depthmapX/dialogs/ColourScaleDlg.h" #include "depthmapX/views/glview/glview.h" #include "version.h" #include #include #include class ItemTreeEntry { public: ItemTreeEntry() { m_type = -1; m_cat = -1; m_subcat = -1; } ItemTreeEntry(char t, short c, short sc) { m_type = t; m_cat = c; m_subcat = sc; } char m_type; short m_cat; short m_subcat; }; class QDepthmapView; class QGraphDoc; QT_BEGIN_NAMESPACE class QAction; class QMenu; class QMdiArea; class QMdiSubWindow; class QSignalMapper; class QToolButton; QT_END_NAMESPACE const int MaxRecentFiles = 5; enum { FOCUSGRAPH = 1001, AllTransactionsDone = 1002 }; class QmyEvent : public QEvent { public: void* wparam; int lparam; QmyEvent(Type type, void* wp, int lp); }; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(const QString &fileToLoad, Settings &settings); // Graph analysis options QString m_formula_cache; Options m_options; QRgb m_foreground; QRgb m_background; MainWindowModuleRegistry mainWindowPluginRegistry; QGraphDoc *activeMapDoc(); bool m_simpleVersion; // bool that replaces compile defines void RedoPlotViewMenu(QGraphDoc* pDoc); void updateToolbar(); void update3DToolbar(); void showContextMenu(QPoint &point); void UpdateStatus(QString s1, QString s2, QString s3); void updateGLWindows(bool datasetChanged, bool recentreView); void loadFile(QString fileName); void chooseAttributeOnIndex(int attributeIdx); protected: QGraphDoc* m_treeDoc; void closeEvent(QCloseEvent *event); bool eventFilter(QObject *object, QEvent *e); virtual void actionEvent( QActionEvent * event ); private slots: void updateActiveWindows(); void updateSubWindowTitles(QString newTitle); void updateWindowMenu(); void setActiveSubWindow(QWidget *window); void OnSelchangingTree(QTreeWidgetItem* item, int col); void OnSelchangingList(); void OnFileNew(); void OnFileImport(); void OnFileOpen(); void OnFileClose(); void OnFileSave(); void OnFileSaveAs(); void OnFileProperties(); void OnFilePrint(); void OnFilePrintPreview(); void OnFilePrintSetup(); void OnEditUndo(); void OnEditCopyData(); void OnEditCopy(); void OnEditSave(); void OnEditClear(); void OnEditQuery(); void OnViewZoomsel(); void OnEditSelectToLayer(); void OnAppAbout(); void OnLayerNew(); void OnLayerDelete(); void OnLayerConvert(); void OnLayerConvertDrawing(); void OnConvertMapShapes(); void OnFileExport(); void OnFileExportMapGeometry(); void OnFileExportLinks(); void OnAxialConnectionsExportAsDot(); void OnAxialConnectionsExportAsPairCSV(); void OnSegmentConnectionsExportAsPairCSV(); void OnPointmapExportConnectionsAsCSV(); void OnAddColumn(); void OnRenameColumn(); void OnUpdateColumn(); void OnRemoveColumn(); void OnColumnProperties(); void OnPushToLayer(); void OnToolsMakeGraph(); void OnToolsUnmakeGraph(); void OnToolsImportVGALinks(); void OnToolsGenerateIsovistsFromFile(); void OnToolsIsovistpath(); void OnToolsAgentLoadProgram(); void OnToolsRunAxa(); void OnToolsPD(); void OnToolsAPD(); void OnToolsMakeFewestLineMap(); void OnToolsAxialConvShapeMap(); void OnToolsLineLoadUnlinks(); void OnToolsRunSeg(); void OnToolsTopomet(); void OnToolsTPD(); void OnToolsMPD(); void OnToolsPointConvShapeMap(); void OnToolsOptions(); void OnViewCentreView(); void OnViewShowGrid(); void OnViewSummary(); void OnViewColourRange(); void OnHelpBugs(); void OnHelpManual(); void OnHelpTutorials(); void OnHelpSalaManual(); void OnEditGrid(); void OnWindowMap(); void OnViewTable(); void OnWindow3dView(); void OnWindowGLView(); void OnViewScatterplot(); void OnToolsRun(); void OnToolsAgentRun(); // MapView message void zoomModeTriggered(); void FillModeTriggered(); void LineModeTriggered(); void isoModeTriggered(); void joinTriggered(); void zoomButtonTriggered(); void FillButtonTriggered(); void LineButtonTriggered(); void isoButtonTriggered(); void joinButtonTriggered(); void openRecentFile(); void StepDepthTriggered(); void AxialMapTriggered(); void SelectPenTriggered(); void DragButtonTriggered(); void SelectButtonTriggered(); void OnSelchangeViewSelector_X(const QString &string); void OnSelchangeViewSelector_Y(const QString &string); void OninvertColor(); void OnzoomTo(); // PlotView message void OntoggleColor(); void OntoggleOrg(); void OnviewTrend(); void OnYX(); void OnRtwo(); //Menu Update slots void updateViewMenu(); void updateAttributesMenu(); void updateMapMenu(); void updateEditMenu(); void updateFileMenu(); void updateVisibilitySubMenu(); void updateStepDepthSubMenu(); void updateSegmentStepDepthSubMenu(); void updateAgentToolsSubMenu(); void updateSegmentSubMenu(); void updateAxialSubMenu(); //3D View ToolBar slots void OnToolsImportTraces(); void OnAddAgent(); void OnToolsAgentsPlay(); void OnToolsAgentsPause(); void OnToolsAgentsStop(); void OnAgentTrails(); void On3dRot(); void On3dPan(); void On3dZoom(); void OnPlayLoop(); void On3dFilled(); private: int OnFocusGraph(QGraphDoc* pDoc, int lParam); void setCurrentFile(const QString &fileName); void updateRecentFileActions(const QStringList &files); QString strippedName(const QString &fullFileName); void createActions(); void createMenus(); void createToolBars(); void createStatusBar(); // Settings Files Settings &mSettings; void readSettings(); void writeSettings(); bool m_defaultMapWindowIsLegacy; QWidget * setupAttributesListWidget(); MapView *createMapView(); MapView *activeMapView(); QMdiSubWindow *findMapView(const QString &fileName); ////////////////////////////////////////////////////// // treeContorl QVector m_tree_icon; std::map m_view_map_entries; std::vector m_attribute_locked; std::map m_treegraphmap; std::map m_treedrawingmap; QTreeWidgetItem* m_topgraph; QTreeWidgetItem* m_backgraph; QTreeWidgetItem* m_treeroots[5]; void MakeTree(); void MakeGraphTree(); void MakeDrawingTree(); void ClearGraphTree(); void MakeAttributeList(); void SetAttributeChecks(); void SetDrawingTreeChecks(); void SetGraphTreeChecks(); //////////////////////////////////////////////////////////// QMdiArea *mdiArea; QSignalMapper *windowMapper; IndexWidget* m_indexWidget; AttribWindow* m_attrWindow; CColourScaleDlg m_wndColourScale; QLabel *g_size; QLabel *g_pos_curr; QLabel *g_info_curr; QMenu *fileMenu; QMenu *editMenu; QMenu *mapMenu; QMenu *exportSubMenu; QMenu *attributesMenu; QMenu *toolsMenu; QMenu *visibilitySubMenu; QMenu *stepDepthSubMenu; QMenu *agentToolsSubMenu; QMenu *axialSubMenu; QMenu *segmentSubMenu; QMenu *segmentStepDepthSubMenu; QMenu *viewMenu; QMenu *windowMenu; QMenu *helpMenu; QToolBar *fileToolBar; QToolBar *editToolBar; QToolBar *plotToolBar; QToolBar *thirdViewToolBar; QToolButton *fillColorToolButton; QToolButton *zoomToolButton; QToolButton *lineToolButton; QToolButton *newisoToolButton; QToolButton *JoinToolButton; QToolButton *SelectButton; QToolButton *DragButton; QToolButton *SelectPenButton; QToolButton *AxialMapButton; QToolButton *StepDepthButton; QToolButton *attr_add_button; QToolButton *attr_del_button; //File Menu Actions QAction *newAct; QAction *openAct; QAction *closeAct; QAction *saveAct; QAction *saveAsAct; QAction *propertiesAct; QAction *printAct; QAction *printPreviewAct; QAction *printSetupAct; QAction *recentFileActs[MaxRecentFiles]; QAction *separatorAct; QAction *exitAct; //Edit Menu Actions QAction *undoAct; QAction *copyDataAct; QAction *copyScreenAct; QAction *exportScreenAct; QAction *clearAct; QAction *selectByQueryAct; QAction *selectionToLayerAct; //Map Menu Actions QAction *mapNewAct; QAction *deleteAct; QAction *convertActiveMapAct; QAction *convertDrawingMapAct; QAction *convertMapShapesAct; QAction *importAct; QAction *exportAct; QAction *exportGeometryAct; QAction *exportLinksAct; QAction *exportAxialConnectionsDotAct; QAction *exportAxialConnectionsPairAct; QAction *exportSegmentConnectionsPairAct; QAction *exportPointmapConnectionsPairAct; //Attributes Menu Actions QAction *renameColumnAct; QAction *columnPropertiesAct; //Tools Menu Actions QAction *makeVisibilityGraphAct; QAction *unmakeVisibilityGraphAct; QAction *importVGALinksAct; QAction *generateIsovistsAct; QAction *makeIsovistPathAct; QAction *runVisibilityGraphAnalysisAct; QAction *visibilityStepAct; QAction *metricStepAct; QAction *angularStepAct; QAction *convertDataMapLinesAct; QAction *runAgentAnalysisAct; QAction *loadAgentProgramAct; QAction *runGraphAnaysisAct; QAction *stepDepthAct; QAction *reduceToFewestLineMapAct; QAction *convertDataMapPointsAct; QAction *loadUnlinksFromFileAct; QAction *runAngularSegmentAnalysisAct; QAction *runTopologicalOrMetricAnalysisAct; QAction *segmentAngularStepAct; QAction *topologicalStepAct; QAction *segmentMetricStepAct; QAction *optionsAct; //View Menu Actions QAction *showGridAct; QAction *attributeSummaryAct; //Window Menu Actions QAction *mapAct; QAction *scatterPlotAct; QAction *tableAct; QAction *thirdDViewAct; QAction *glViewAct; QAction *colourRangeAct; QAction *cascadeAct; QAction *tileAct; QAction *arrangeIconsAct; //Help Menu Actions QAction *onlineBugsAct; QAction *onlineHandbookAct; QAction *onlineTutorialsAct; QAction *onlineScriptingManualAct; QAction *aboutDepthMapAct; //depthmapX Contorl QAction *addColumAct; QAction *updateColumAct; QAction *removeColumAct; QAction *pushValueAct; QAction *invertColorAct; QAction *zoomInAct; QAction *zoomOutAct; QAction *zoomToAct; QAction *RecentAct; QAction *SetGridAct; QAction *STDFillColorAct; QAction *ContextFillColorAct; QAction *AugmentFillColorAct; // AV test - TV QAction *SelectLineAct; QAction *SelectPolyLineAct; QAction *MakeIosAct; QAction *PartialMakeIosAct; QAction *JoinAct; QAction *JoinUnlinkAct; //PlotMap control QComboBox *x_coord; QComboBox *y_coord; QAction *toggleColor; QAction *toggleOrg; QAction *viewTrend; QAction *yx; QAction *Rtwo; //3D View ToolBar QAction *toolsImportTracesAct; QAction *addAgentAct; QAction *toolsAgentsPlayAct; QAction *toolsAgentsPauseAct; QAction *toolsAgentsStopAct; QAction *agentTrailsAct; QAction *thirdRotAct; QAction *thirdPanAct; QAction *thirdZoomAct; QAction *playLoopAct; QAction *thirdFilledAct; int m_selected_mapbar_item = -1; enum { ID_MAPBAR_ZOOM_ITEMS = 2, ID_MAPBAR_FILL_ITEMS = 8, ID_MAPBAR_DRAW_ITEMS = 10, ID_MAPBAR_ISOVIST_ITEMS = 12, ID_MAPBAR_JOIN_ITEMS = 15 }; enum { ID_MAPBAR_ITEM_SELECT = 0, ID_MAPBAR_ITEM_MOVE = 1, ID_MAPBAR_ITEM_ZOOM_IN = 2, ID_MAPBAR_ITEM_ZOOM_OUT = 3, ID_MAPBAR_ITEM_FILL = 7, ID_MAPBAR_ITEM_SEMIFILL = 8, ID_MAPBAR_ITEM_PENCIL = 9, ID_MAPBAR_ITEM_LINETOOL = 10, ID_MAPBAR_ITEM_POLYGON = 11, ID_MAPBAR_ITEM_ISOVIST = 12, ID_MAPBAR_ITEM_HALFISOVIST = 13, ID_MAPBAR_ITEM_AL2 = 14, ID_MAPBAR_ITEM_PD = 15, ID_MAPBAR_ITEM_JOIN = 16, ID_MAPBAR_ITEM_UNJOIN = 17, ID_MAPBAR_ITEM_AUGMENT_FILL = 18 // AV test - TV }; }; #endif ================================================ FILE: depthmapX/mainwindowfactory.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mainwindowfactory.h" #include "mainwindow.h" #include "dialogs/licenseagreement.h" #include namespace MainWindowFactory{ std::unique_ptr getMainWindow(const QString& fileToLoad, Settings &settings) { return std::unique_ptr(new MainWindow(fileToLoad, settings)); } std::unique_ptr getLicenseDialog() { return std::unique_ptr(new LicenseAgreement); } } ================================================ FILE: depthmapX/mainwindowfactory.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef MAINWINDOWFACTORY_H #define MAINWINDOWFACTORY_H #include #include #include class Settings; namespace MainWindowFactory{ std::unique_ptr getMainWindow(const QString &fileToLoad, Settings &settings); std::unique_ptr getLicenseDialog(); } #endif // MAINWINDOWFACTORY_H ================================================ FILE: depthmapX/mainwindowhelpers.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "depthmapX/mainwindowhelpers.h" #include "depthmapX/mainwindow.h" QMenu *MainWindowHelpers::getOrAddRootMenu(MainWindow *mainWindow, QString menuTitle) { QMenuBar *menuBar = mainWindow->menuBar(); QMenu *menu = nullptr; foreach (QAction *action, menuBar->actions()) { if (action->menu()) { QMenu *childMenu = action->menu(); if (childMenu != nullptr && childMenu->title() == menuTitle) { menu = childMenu; } } } if (menu == nullptr) { menu = menuBar->addMenu(menuTitle); } return menu; } QMenu *MainWindowHelpers::getOrAddMenu(QMenu *parent, QString menuTitle) { QMenu *menu = nullptr; foreach (QAction *action, parent->actions()) { if (action->menu()) { QMenu *childMenu = action->menu(); if (childMenu != nullptr && childMenu->title() == menuTitle) { menu = childMenu; } } } if (menu == nullptr) { menu = parent->addMenu(menuTitle); } return menu; } ================================================ FILE: depthmapX/mainwindowhelpers.h ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "mainwindow.h" #include namespace MainWindowHelpers { QMenu *getOrAddRootMenu(MainWindow *mainWindow, QString menuTitle); QMenu *getOrAddMenu(QMenu *parent, QString menuTitle); } // namespace MainWindowHelpers ================================================ FILE: depthmapX/mainwindowmodulefactory.cpp ================================================ // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mainwindowpluginfactory.hpp" MainWindowPluginFactory::PluginMap *MainWindowPluginFactory::map = NULL; ================================================ FILE: depthmapX/mainwindowmoduleregistry.cpp ================================================ // Copyright (C) 2017, Christian Sailer // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mainwindowmoduleregistry.hpp" #include "modules/segmentshortestpaths/gui/segmentpathsmainwindow.h" void MainWindowModuleRegistry::populateModules() { // Register any main window modules here REGISTER_MAIN_WINDOW_MODULE(SegmentPathsMainWindow); // ********* } ================================================ FILE: depthmapX/mainwindowmoduleregistry.hpp ================================================ // Copyright (C) 2017, Christian Sailer // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imainwindowmodule.h" #include "imainwindowmodulefactory.h" #include #include class MainWindowModuleRegistry : public IMainWindowModuleFactory { public: MainWindowModuleRegistry() { populateModules(); } const MainWindowModuleVec &getModules() const { return m_availableModules; } private: void populateModules(); MainWindowModuleVec m_availableModules; }; #define REGISTER_MAIN_WINDOW_MODULE(module) \ m_availableModules.push_back(std::unique_ptr(new module)); ================================================ FILE: depthmapX/make_version_header.bat ================================================ @echo off del version_defs.h echo // Copyright (C) 2018 Christian Sailer >> version_defs.h echo // This program is free software: you can redistribute it and/or modify >> version_defs.h echo // it under the terms of the GNU General Public License as published by >> version_defs.h echo // the Free Software Foundation, either version 3 of the License, or >> version_defs.h echo // (at your option) any later version. >> version_defs.h echo. >> version_defs.h echo // This program is distributed in the hope that it will be useful, >> version_defs.h echo // but WITHOUT ANY WARRANTY; without even the implied warranty of >> version_defs.h echo // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> version_defs.h echo // GNU General Public License for more details. >> version_defs.h echo. >> version_defs.h echo // You should have received a copy of the GNU General Public License >> version_defs.h echo|set /p="// along with this program. If not, see ." >> version_defs.h echo. >> version_defs.h echo. >> version_defs.h echo // This file is autogenerated - do not modify it directly! >> version_defs.h echo. >> version_defs.h echo #pragma once >> version_defs.h echo. >> version_defs.h :: Get date in correct form (YYYY/MM/DD). for /f "skip=1" %%x in ('wmic os get localdatetime') do if not defined MyDate set MyDate=%%x for /f %%x in ('wmic path win32_localtime get /format:list ^| findstr "="') do set %%x set fmonth=00%Month% set fday=00%Day% set today=%Year%/%fmonth:~-2%/%fday:~-2% echo #ifndef APP_DATE >> version_defs.h echo #define APP_DATE "%today%" >> version_defs.h echo #endif >> version_defs.h echo. >> version_defs.h for /f "delims=" %%A in ('git rev-parse --abbrev-ref HEAD') do set "mybranch=%%A" echo #ifndef APP_GIT_BRANCH >> version_defs.h echo #define APP_GIT_BRANCH "%mybranch%" >> version_defs.h echo #endif >> version_defs.h echo. >> version_defs.h for /f "delims=" %%A in ('git log "--pretty=format:%%h" -n 1') do set "mycommit=%%A" echo #ifndef APP_GIT_COMMIT >> version_defs.h echo #define APP_GIT_COMMIT "%mycommit%" >> version_defs.h echo #endif >> version_defs.h ================================================ FILE: depthmapX/make_version_header.sh ================================================ rm version_defs.h printf "// Copyright (C) 2018 Christian Sailer\n" >> version_defs.h printf "// This program is free software: you can redistribute it and/or modify\n" >> version_defs.h printf "// it under the terms of the GNU General Public License as published by\n" >> version_defs.h printf "// the Free Software Foundation, either version 3 of the License, or\n" >> version_defs.h printf "// (at your option) any later version.\n\n" >> version_defs.h printf "// This program is distributed in the hope that it will be useful,\n" >> version_defs.h printf "// but WITHOUT ANY WARRANTY\; without even the implied warranty of\n" >> version_defs.h printf "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" >> version_defs.h printf "// GNU General Public License for more details.\n\n" >> version_defs.h printf "// You should have received a copy of the GNU General Public License\n" >> version_defs.h printf "// along with this program. If not, see .\n\n" >> version_defs.h printf "// This file is autogenerated - do not modify it directly!\n\n" >> version_defs.h printf "#pragma once\n\n" >> version_defs.h printf "#ifndef APP_DATE\n" >> version_defs.h printf "#define APP_DATE \"`date +%Y/%m/%d`\"\n" >> version_defs.h printf "#endif\n\n" >> version_defs.h printf "#ifndef APP_GIT_BRANCH\n" >> version_defs.h printf "#define APP_GIT_BRANCH \"`git rev-parse --abbrev-ref HEAD`\"\n" >> version_defs.h printf "#endif\n\n" >> version_defs.h printf "#ifndef APP_GIT_COMMIT\n" >> version_defs.h printf "#define APP_GIT_COMMIT \"`git log --pretty=format:'%h' -n 1`\"\n" >> version_defs.h printf "#endif\n" >> version_defs.h ================================================ FILE: depthmapX/mdichild.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include "mdichild.h" MdiChild::MdiChild() { setAttribute(Qt::WA_DeleteOnClose); isUntitled = true; } void MdiChild::newFile() { static int sequenceNumber = 1; isUntitled = true; curFile = tr("document%1.txt").arg(sequenceNumber++); setWindowTitle(curFile + "[*]"); connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified())); } bool MdiChild::loadFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("MDI"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); setCurrentFile(fileName); connect(document(), SIGNAL(contentsChanged()), this, SLOT(documentWasModified())); return true; } bool MdiChild::save() { if (isUntitled) { return saveAs(); } else { return saveFile(curFile); } } bool MdiChild::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), curFile); if (fileName.isEmpty()) return false; return saveFile(fileName); } bool MdiChild::saveFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::WriteOnly | QFile::Text)) { QMessageBox::warning(this, tr("MDI"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } QTextStream out(&file); QApplication::setOverrideCursor(Qt::WaitCursor); out << toPlainText(); QApplication::restoreOverrideCursor(); setCurrentFile(fileName); return true; } QString MdiChild::userFriendlyCurrentFile() { return strippedName(curFile); } void MdiChild::closeEvent(QCloseEvent *event) { if (maybeSave()) { event->accept(); } else { event->ignore(); } } void MdiChild::documentWasModified() { setWindowModified(document()->isModified()); } bool MdiChild::maybeSave() { if (document()->isModified()) { QMessageBox::StandardButton ret; ret = QMessageBox::warning(this, tr("MDI"), tr("'%1' has been modified.\n" "Do you want to save your changes?") .arg(userFriendlyCurrentFile()), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (ret == QMessageBox::Save) return save(); else if (ret == QMessageBox::Cancel) return false; } return true; } void MdiChild::setCurrentFile(const QString &fileName) { curFile = QFileInfo(fileName).canonicalFilePath(); isUntitled = false; document()->setModified(false); setWindowModified(false); setWindowTitle(userFriendlyCurrentFile() + "[*]"); } QString MdiChild::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } ================================================ FILE: depthmapX/mdichild.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef MDICHILD_H #define MDICHILD_H #include class MdiChild : public QTextEdit { Q_OBJECT public: MdiChild(); void newFile(); bool loadFile(const QString &fileName); bool save(); bool saveAs(); bool saveFile(const QString &fileName); QString userFriendlyCurrentFile(); QString currentFile() { return curFile; } protected: void closeEvent(QCloseEvent *event); private slots: void documentWasModified(); private: bool maybeSave(); void setCurrentFile(const QString &fileName); QString strippedName(const QString &fullFileName); QString curFile; bool isUntitled; }; #endif ================================================ FILE: depthmapX/qrc_mdi.cpp ================================================ /**************************************************************************** ** Resource object code ** ** Created: Sat Mar 10 09:32:20 2012 ** by: The Resource Compiler for Qt version 4.8.0 ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include static const unsigned char qt_resource_data[] = { // /work/depthmap/depthmap/images/new.png 0x0,0x0,0x3,0x54, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xd6,0xd8,0xd4,0x4f,0x58,0x32, 0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65, 0x0,0x41,0x64,0x6f,0x62,0x65,0x20,0x49,0x6d,0x61,0x67,0x65,0x52,0x65,0x61,0x64, 0x79,0x71,0xc9,0x65,0x3c,0x0,0x0,0x2,0xe6,0x49,0x44,0x41,0x54,0x58,0xc3,0xd5, 0x97,0xcd,0x4e,0x13,0x61,0x14,0x86,0xeb,0x35,0x94,0x95,0x7b,0x71,0xe1,0xd2,0xc4, 0xe0,0x5,0xb8,0xe2,0xe,0x5c,0xb8,0xf4,0x2,0x5c,0xb1,0x30,0xea,0x5,0x18,0x96, 0x26,0x62,0x58,0xb8,0xb0,0x91,0x58,0x20,0xd1,0x9d,0xbf,0x89,0xa4,0x14,0xb1,0x52, 0xa4,0x48,0x45,0x94,0xfe,0xd0,0x2,0x43,0xff,0xa6,0x9d,0x19,0xa6,0x65,0x80,0xe3, 0x79,0x7b,0xfa,0x85,0x51,0x4a,0x82,0xc9,0x21,0x86,0x49,0xde,0x9c,0x33,0xa7,0xf3, 0xcd,0xfb,0x9c,0xf3,0x4d,0x9b,0x4e,0x84,0x88,0x22,0xff,0x53,0x91,0x73,0x1,0xc0, 0xc7,0xd5,0x90,0x6e,0xff,0xa5,0xfb,0xac,0xc7,0x3d,0x3d,0x64,0xd,0xa9,0x2,0xf0, 0x31,0x32,0x3c,0x3c,0xbc,0x6a,0x34,0x3a,0x3a,0xba,0x19,0x56,0x3c,0x1e,0xaf,0x26, 0x93,0xc9,0x56,0x3a,0x9d,0x76,0x13,0x89,0x44,0x6b,0x60,0x60,0x20,0xcd,0x6b,0x6e, 0x68,0x2,0xa4,0x38,0xd2,0xe1,0xe1,0x71,0x99,0xba,0xef,0xb7,0xc9,0xb2,0x2c,0xda, 0xdf,0xdf,0x27,0x86,0xf1,0x78,0xcd,0x18,0xeb,0x8a,0x1a,0x40,0x3f,0xf3,0xb0,0x1c, 0xc7,0xa5,0x4c,0x66,0xb9,0xb,0x14,0x4,0x1,0xc5,0x62,0xb1,0x3a,0xaf,0x7b,0x70, 0x1a,0x88,0x53,0x1,0x1c,0x1c,0x10,0x77,0x77,0xb2,0x6c,0xdb,0xa1,0xf9,0xf9,0xcf, 0x64,0xe,0xd7,0x75,0xe9,0xf9,0xc4,0x44,0x17,0x42,0x5,0x0,0x26,0x7b,0xc1,0xc9, 0xaa,0x37,0x1c,0x4a,0xce,0xcd,0x53,0xf8,0x70,0x5d,0xf,0x8b,0x17,0x54,0x0,0x82, 0x10,0x40,0x67,0x4f,0x14,0xce,0xed,0xa6,0x47,0x1f,0x67,0x66,0xe9,0xf5,0x9b,0xb7, 0x14,0x9f,0x9c,0xa4,0xa9,0xa9,0x69,0x7a,0xf7,0xfe,0x3,0x45,0xa3,0xd1,0x65,0x5e, 0x7f,0x41,0x5,0xc0,0xef,0x10,0xed,0xb6,0x25,0x86,0x85,0x9a,0xe3,0x5,0x94,0x5d, 0xcd,0xd1,0xe4,0xf4,0x2b,0x7a,0x32,0xfe,0x94,0x9e,0xc5,0x5e,0xd0,0x4c,0x62,0xe, 0x8b,0x17,0x55,0x0,0xda,0x81,0x18,0xf5,0x13,0x20,0x3c,0xff,0x90,0x6a,0xcd,0x36, 0x15,0x37,0xab,0x94,0x2f,0x6e,0x53,0x89,0x63,0x8d,0xb7,0x85,0xd7,0x7e,0x51,0x1, 0xf0,0x79,0xcc,0xcd,0x5d,0x1e,0xb5,0xc7,0x7b,0xdb,0xee,0x9f,0x3b,0xbe,0xe4,0x88, 0x5d,0xb8,0xbd,0xee,0xe2,0x94,0xca,0x33,0xe0,0x75,0xe4,0xc6,0x75,0x57,0x62,0xd8, 0x10,0x39,0xea,0xe6,0x33,0x44,0xd4,0x1,0xa7,0x6,0xe0,0xf4,0x3a,0xad,0x39,0x22, 0x98,0x98,0x68,0x72,0x80,0x98,0x6b,0x50,0x53,0x9d,0x0,0x0,0x2a,0x2d,0xb9,0x31, 0xe2,0x4e,0x53,0x8c,0x10,0xd,0x4,0xf2,0x6d,0xfb,0x28,0xb6,0x7c,0x45,0x0,0x9b, 0x3b,0xdb,0x6a,0xfc,0x69,0x8e,0x3c,0x6c,0x88,0x1a,0xae,0x39,0x13,0x80,0x3a,0x8f, 0xb7,0x54,0x23,0x2a,0xd7,0xc5,0x4,0x6,0x6,0x0,0x35,0x28,0x9c,0x17,0xab,0xbc, 0x25,0xbb,0xca,0x13,0xc0,0x4d,0x61,0xe,0x15,0x2a,0x72,0x6e,0xcc,0x7e,0x5a,0x2, 0x68,0x6a,0xdd,0xad,0xf1,0x94,0x27,0x0,0x53,0xdc,0x1c,0x71,0x6d,0x5b,0x40,0x60, 0x9a,0xab,0x1c,0x75,0x9e,0xeb,0x81,0x41,0x15,0x47,0x11,0xc0,0x6a,0x89,0x31,0xc, 0xd6,0x77,0x4,0x20,0xc,0x64,0x26,0x62,0xb6,0x69,0x75,0x8b,0xa8,0xaa,0x9,0x50, 0xb6,0xc5,0xbc,0xd0,0x3,0xf8,0xbe,0x29,0x63,0x87,0x29,0x60,0xc,0x18,0x84,0x1c, 0x0,0x5b,0x4d,0x45,0x0,0x74,0x3,0x53,0x98,0xad,0x94,0xc5,0x1c,0xe7,0x46,0xe6, 0x1c,0x0,0xc8,0x71,0x5d,0xa9,0xa1,0x8,0x80,0xfd,0xfc,0x56,0x12,0x73,0x33,0x1, 0x8,0x35,0x18,0x42,0xe8,0xda,0x7c,0x8e,0x29,0xa8,0x4e,0x0,0x5b,0x0,0x3,0xc8, 0x98,0x67,0x36,0x4,0x0,0x32,0xe6,0x85,0xde,0xf8,0x17,0xb,0xfc,0x2c,0xd8,0x8a, 0x0,0x18,0x67,0x3a,0x4f,0xb4,0x54,0x14,0x23,0x98,0x2,0x0,0x2,0xc,0x3e,0xfb, 0xc5,0x53,0x28,0xf0,0x43,0xb8,0x66,0x49,0xf7,0x6b,0xf9,0x52,0x87,0xd7,0xbe,0x54, 0x1,0xc8,0x55,0x8f,0xba,0x4e,0xad,0x4b,0xe,0x90,0xaf,0x85,0xde,0xb7,0xc2,0x92, 0x3d,0x4f,0xa6,0xb3,0xde,0xa3,0xb1,0x71,0xeb,0xda,0xd0,0xf5,0x15,0x98,0xb3,0x6e, 0xa9,0x0,0x6c,0x34,0xa4,0x6b,0x18,0xff,0xe0,0x11,0x7f,0x5a,0x17,0x53,0xd4,0x13, 0xb,0x59,0x6f,0xe4,0xee,0xbd,0xe2,0xa5,0xc1,0xcb,0x4b,0x7c,0x6d,0x8c,0x75,0x87, 0x35,0xa8,0xfa,0xb7,0x1c,0xdd,0x65,0xd9,0x3c,0x8f,0x1f,0x19,0xfe,0x9e,0xcf,0x1e, 0x37,0xbd,0xc9,0xba,0x78,0x26,0x6f,0x46,0x0,0x68,0xf2,0xff,0x81,0x99,0x94,0x9e, 0xe9,0x3f,0xbf,0x19,0x1,0x42,0xd3,0xf4,0xfc,0xbd,0x9c,0x9e,0xa5,0x7e,0x3,0x51, 0x6c,0x25,0xa1,0x92,0x95,0xa,0x77,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/down.png 0x0,0x0,0x2,0x52, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x16,0x0,0x0,0x0,0x16,0x8,0x6,0x0,0x0,0x0,0xc4,0xb4,0x6c,0x3b, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xd6,0xd8,0xd4,0x4f,0x58,0x32, 0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65, 0x0,0x41,0x64,0x6f,0x62,0x65,0x20,0x49,0x6d,0x61,0x67,0x65,0x52,0x65,0x61,0x64, 0x79,0x71,0xc9,0x65,0x3c,0x0,0x0,0x1,0xe4,0x49,0x44,0x41,0x54,0x38,0x8d,0xbd, 0xd4,0xcf,0x4f,0xd3,0x60,0x1c,0xc7,0xf1,0xb5,0x5b,0x69,0x3b,0x37,0xcc,0x96,0x68, 0x42,0xa6,0x82,0x98,0xa1,0x1c,0x38,0x98,0xe0,0xcd,0x8b,0x28,0xa4,0x12,0xa3,0x19, 0x48,0x48,0x20,0x1a,0x6e,0x1a,0x16,0xe5,0xc4,0xc5,0x18,0x42,0x23,0x3a,0xa2,0xc6, 0x18,0x63,0xc6,0x8f,0x39,0x6,0x54,0xb3,0xf2,0x40,0x3c,0x29,0x97,0x72,0xf1,0x2f, 0xfb,0xf0,0x7d,0x6a,0x4b,0xea,0xb6,0x67,0x3c,0x90,0xe0,0x93,0xbc,0x8f,0x7d,0xf5, 0xc9,0xd3,0x6f,0x9f,0x18,0x80,0xd8,0x59,0x74,0x26,0xe8,0xff,0x87,0x69,0x95,0x29, 0x48,0xb4,0x46,0x25,0x28,0x45,0x16,0x46,0xfd,0xcf,0xb,0x6c,0x78,0x4f,0x85,0x2d, 0xd5,0x6f,0x85,0x78,0x9a,0xe3,0xd2,0xf0,0xa6,0xf7,0x4,0xcb,0x6c,0x50,0xd8,0x33, 0xfb,0x7a,0x8,0x77,0x51,0x86,0x34,0xbc,0xe5,0x4d,0xe1,0x3d,0xbb,0x29,0xec,0xb9, 0x9d,0xf,0xe1,0x5e,0xea,0x9c,0x34,0xec,0x78,0x93,0xf8,0xc8,0x6,0x84,0xcd,0xda, 0xbd,0x21,0xdc,0xc7,0x8f,0x43,0x1a,0xfe,0xe1,0x3d,0xc6,0x27,0xd6,0x2f,0xac,0x68, 0x77,0x9f,0xe,0x76,0xbd,0x2,0xbe,0xb0,0xbc,0xb0,0x39,0xfb,0x92,0x1c,0x4c,0x4b, 0xa3,0x56,0xc2,0x51,0xda,0x3d,0x78,0x84,0xaf,0xac,0x47,0x58,0xa9,0x72,0x39,0x3a, 0x76,0xbf,0xa9,0x51,0x2a,0x1e,0x8e,0x5e,0x14,0x9e,0xb3,0x1e,0x76,0xe1,0xe7,0xc1, 0x3,0xbf,0xfa,0xfe,0x6d,0xac,0xb2,0x9c,0xb0,0xb2,0x9b,0xc3,0xda,0xee,0x15,0x54, 0xf6,0xae,0x62,0xa6,0x98,0xe1,0xc0,0x2f,0x3e,0x1d,0x94,0xda,0x8,0xeb,0xd4,0xfa, 0x90,0x65,0x62,0xd5,0xbd,0x88,0x75,0xd6,0xbe,0xcf,0xb5,0xb,0x98,0x5f,0xcc,0x60, 0xb4,0x90,0x44,0x2a,0xad,0x72,0x60,0x3a,0x98,0xe9,0x78,0x23,0xac,0x50,0x29,0xaa, 0x76,0xd7,0x32,0x50,0x71,0xb3,0xa8,0xb2,0xe6,0xbe,0xed,0x64,0xb1,0xe2,0x64,0xb0, 0xb0,0xdc,0x89,0x3b,0x23,0x6,0x34,0x4d,0xe1,0xf,0x17,0xa9,0x1c,0x95,0x6c,0xda, 0x71,0x80,0xf3,0xdf,0x33,0x4b,0x39,0xf7,0xac,0xe,0x6c,0xb8,0x69,0x6c,0xb2,0x7f, 0x2b,0xd7,0x52,0x58,0x78,0x97,0xc4,0xd8,0xa4,0xe,0xdd,0xf0,0xd1,0x19,0x2a,0x1f, 0x3c,0xd7,0xd1,0x74,0xc6,0xad,0xf0,0x61,0x2b,0x81,0x2d,0xd7,0x84,0xc3,0xfe,0x56, 0x75,0x4c,0xd8,0x25,0x1d,0x43,0xc3,0x9,0x98,0xa6,0x8f,0xbe,0x6e,0x85,0xb6,0x1b, 0xb7,0x23,0x7c,0xc4,0x52,0xf1,0x7d,0x47,0x43,0x75,0x5b,0x43,0xe9,0x43,0x2,0xe3, 0x13,0x2a,0x14,0x25,0x16,0xdd,0x69,0xa6,0x11,0x6d,0x7b,0x6d,0x46,0x71,0xeb,0xbe, 0x82,0x37,0x6f,0x55,0x14,0xc6,0x14,0xfa,0x50,0x3e,0xfa,0x4a,0xb4,0x53,0xa9,0xfb, 0x38,0xc0,0xf9,0x25,0xb3,0x6d,0x18,0x31,0xe8,0xba,0x8f,0xbe,0x3c,0xe,0x3d,0x16, 0x8e,0xe0,0x7c,0x5a,0xae,0x51,0x37,0x82,0x17,0x9d,0x6f,0x87,0x4a,0xc1,0x1,0x1e, 0xf,0x20,0x23,0x98,0xf7,0x96,0x97,0xfb,0x89,0xe1,0xd3,0x74,0x8,0x56,0x10,0xa, 0xb,0xb1,0xaa,0xe0,0x42,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/save.png 0x0,0x0,0x4,0xa3, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xd6,0xd8,0xd4,0x4f,0x58,0x32, 0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65, 0x0,0x41,0x64,0x6f,0x62,0x65,0x20,0x49,0x6d,0x61,0x67,0x65,0x52,0x65,0x61,0x64, 0x79,0x71,0xc9,0x65,0x3c,0x0,0x0,0x4,0x35,0x49,0x44,0x41,0x54,0x58,0xc3,0xe5, 0x97,0xcd,0x8f,0x54,0x45,0x14,0xc5,0x7f,0xb7,0xea,0xd6,0x7b,0xaf,0xdb,0x6e,0xc7, 0xf9,0x40,0x9d,0x89,0x46,0x4d,0x34,0x99,0x44,0x8d,0x1a,0x48,0x98,0xc4,0x8c,0x1f, 0x1b,0xfe,0x2,0x4c,0x5c,0xf1,0x7,0x18,0x16,0x2e,0x4d,0x5c,0x6b,0x58,0xc3,0x8e, 0xc4,0x8d,0x1b,0x17,0xce,0x82,0x68,0x74,0x41,0x5c,0x18,0xd,0xe2,0xc4,0xc6,0x0, 0x3d,0x60,0x50,0x51,0x19,0x60,0x2,0xa2,0xe,0xc,0x83,0xd3,0xfd,0x5e,0xf7,0x94, 0x8b,0xaa,0xee,0xf9,0x60,0xe6,0xd,0x84,0x51,0x16,0x56,0x52,0xa9,0xce,0x7b,0xb7, 0xeb,0x9e,0x3a,0xf7,0xd4,0xa9,0x7a,0xea,0xbd,0xe7,0x7e,0x36,0xe5,0x3e,0xb7,0x3e, 0x80,0x5d,0xbb,0x76,0xbd,0x3,0xec,0xfd,0x8f,0xf2,0x4e,0x35,0x1a,0x8d,0x3,0xeb, 0x19,0xd8,0xbb,0xef,0xbd,0xa3,0x3b,0x1f,0x1f,0x76,0x0,0x9c,0x3c,0x3a,0xcf,0xcc, 0x97,0x37,0x58,0x9c,0xef,0xdc,0x53,0xa6,0xda,0xa0,0xf2,0xdc,0x6b,0x3,0xbc,0xb8, 0x67,0x10,0x80,0x8b,0x7f,0x16,0x7c,0xf8,0xee,0x1e,0x80,0xdb,0x0,0x70,0xfc,0xec, 0x1c,0xdf,0x3f,0x30,0x4,0x78,0x2e,0xfd,0xb8,0xc0,0xfe,0xb7,0xce,0x6f,0xcb,0x72, 0xf,0x1d,0x79,0x9a,0xb,0x23,0x96,0xd3,0x9f,0x1f,0x64,0xfc,0xd5,0x7d,0x9b,0x6b, 0x40,0x45,0xb0,0x16,0x40,0x78,0x70,0x2c,0x23,0xcb,0xb2,0x6d,0x1,0x30,0x30,0x96, 0x61,0x8d,0x50,0x1b,0x7c,0x14,0x23,0x25,0x22,0x14,0x2b,0xd8,0x18,0x91,0xd5,0x95, 0x73,0xe7,0xce,0x83,0x2a,0xb8,0x4,0xd2,0x14,0xb2,0xc,0xd2,0x2c,0x8c,0x49,0xa, 0x49,0x12,0xde,0x77,0x3a,0x90,0xe7,0x90,0xb7,0xa1,0xd5,0x82,0x76,0x2b,0x8e,0x6d, 0x28,0x72,0xb2,0xfa,0x38,0xd6,0xa,0xe3,0xaf,0xbc,0x49,0x6b,0xf1,0xfa,0xe6,0x0, 0xac,0x15,0xac,0x15,0x4,0xb0,0x46,0xd8,0xbd,0x7b,0xe7,0x16,0x6b,0xeb,0x86,0xae, 0x80,0x5a,0xa8,0x56,0x81,0xea,0x6d,0x51,0x8d,0xaf,0x4,0xb5,0x82,0xf7,0xa0,0xa6, 0x84,0x1,0x67,0x5,0x35,0x82,0x8,0xa8,0xa,0x95,0x2c,0xc3,0x23,0x20,0x1e,0x8, 0xc0,0xf0,0x1e,0x2f,0x2,0xde,0x23,0x12,0x26,0x15,0x7c,0x88,0x23,0xc4,0x21,0x1e, 0x3c,0x21,0x5e,0x40,0x4d,0x58,0x18,0x40,0xd7,0x4a,0x89,0x6,0xac,0xa0,0xda,0x63, 0x0,0x9a,0x33,0xbf,0x5,0x8a,0x53,0x7,0x69,0x2,0x95,0x4,0xb2,0x34,0xf6,0x4, 0x12,0x7,0x4e,0xa1,0xe8,0x40,0x5e,0x40,0x2b,0x8f,0xbd,0x5,0x4b,0x39,0xb4,0x73, 0xc8,0xb,0x54,0x87,0x71,0x3d,0x0,0x2a,0xe5,0x25,0x70,0x31,0x40,0xd5,0x30,0x39, 0xf9,0xd2,0xd6,0xa,0xf3,0x3e,0xd0,0xaf,0x16,0xaa,0x1b,0x8b,0xf6,0xd8,0x27,0x61, 0x61,0xbd,0x1c,0x25,0x25,0x20,0x0,0xf0,0x81,0x8d,0x34,0x4d,0xa3,0x3a,0xc3,0xb3, 0x98,0x11,0x89,0x6c,0x7,0xda,0x63,0x9,0x56,0x98,0x5f,0x29,0x46,0xfc,0x61,0xcd, 0x72,0x7f,0x61,0x1d,0x2d,0xd1,0x80,0x3a,0x9,0x54,0x49,0x18,0x4f,0x34,0x2f,0xe0, 0x9d,0x85,0xc4,0x21,0x89,0xc3,0x67,0x9,0x92,0x69,0xd8,0x11,0x89,0xe2,0x13,0x87, 0x58,0x8b,0xef,0x76,0x91,0xbc,0x80,0xbc,0x3,0xed,0x2,0xdf,0x6a,0x23,0xed,0x2, 0xf2,0x2,0x9f,0x77,0x50,0x1d,0x45,0xd5,0x20,0x78,0x3a,0xeb,0x54,0x78,0x9b,0x6, 0x9c,0x33,0x78,0xf,0x3,0x8f,0x24,0xbc,0xfe,0xf2,0xf3,0x77,0x68,0xe8,0x36,0x68, 0xa4,0xbe,0xf1,0xeb,0xc6,0xfc,0xdf,0xb1,0x4,0x52,0x5e,0x82,0x44,0x4d,0x5f,0x84, 0x8f,0xd,0xa5,0x38,0xe7,0xb6,0xc5,0x88,0x9e,0x18,0x4b,0xb9,0x76,0xb3,0x3,0x8, 0x9d,0x52,0x11,0xaa,0x90,0xb8,0x50,0xef,0x5a,0xc5,0x30,0x7d,0xb1,0xcb,0x40,0xc5, 0xb0,0xe,0xf4,0x26,0xad,0x57,0xf9,0x55,0x2e,0xe1,0xe1,0xc6,0xd2,0x32,0xf5,0xcc, 0x70,0x7d,0xc9,0x84,0x2d,0xe9,0x4a,0x19,0x10,0x9c,0x1a,0xc0,0x73,0xe5,0x66,0x97, 0x2b,0x37,0xbb,0xac,0x51,0x57,0x3f,0xd7,0xaa,0x64,0x7e,0xc5,0x27,0xa2,0x29,0xac, 0x5,0x15,0xc3,0x9c,0xb,0xb5,0x77,0xa6,0x6c,0x17,0xa8,0xc1,0xa9,0x20,0xc8,0x1a, 0x35,0xaf,0x9b,0x35,0x1a,0x8f,0x59,0x31,0x9e,0xfe,0x7b,0xe9,0xef,0x14,0x0,0xf1, 0x82,0xef,0x9b,0x58,0x30,0x2b,0x57,0x56,0x2,0x55,0x21,0xd1,0x90,0xfc,0xe7,0x53, 0xdf,0xf2,0xeb,0x99,0x13,0x2c,0x2d,0xde,0xb8,0xa7,0xfa,0x57,0x6a,0x3,0x3c,0xf5, 0xec,0x4e,0x9e,0x79,0x61,0x2,0xf,0xa8,0x33,0x5b,0x31,0x10,0x3,0x7c,0x87,0xf7, 0xf7,0xbf,0xc1,0xc2,0xc2,0x2,0xb7,0x6e,0xdd,0xa2,0x28,0xa,0x44,0x4,0x6b,0x2d, 0xd6,0x5a,0x54,0x15,0x55,0xc5,0x39,0x87,0xaa,0x62,0xad,0xc5,0x98,0xf0,0xdf,0xe5, 0xe5,0x65,0xf2,0x3c,0xef,0xf7,0x23,0xcd,0xf9,0xb8,0xf2,0x2d,0x18,0x70,0x56,0x50, 0x17,0x18,0xdc,0x31,0x3a,0xb6,0x72,0x4f,0x38,0x7e,0x9c,0xe9,0xe9,0x69,0x8c,0x31, 0x78,0xef,0x99,0x98,0x98,0x60,0x72,0x72,0xf2,0x8e,0x59,0xd8,0x31,0x3a,0xd6,0xdf, 0x86,0xae,0xd4,0x9,0x55,0x70,0x36,0xac,0xa2,0x56,0xaf,0xf7,0x6b,0x39,0x33,0x33, 0xc3,0xd0,0xd0,0x10,0xd6,0x5a,0xbc,0xf7,0x34,0x9b,0xcd,0xbb,0x2,0x50,0xab,0xd7, 0x70,0xd1,0x88,0xb4,0xd4,0x88,0x14,0x9c,0xb,0x27,0x5c,0xa0,0x2a,0x0,0xa8,0x56, 0xab,0x64,0x59,0xd6,0xa7,0xb8,0x37,0xde,0x69,0x73,0x1a,0xa9,0x17,0x41,0x4b,0xad, 0x38,0x1e,0xc7,0xbd,0x23,0xb4,0xd7,0x8c,0x31,0x88,0x44,0xdf,0x8f,0x3a,0xb8,0xab, 0x9b,0xaf,0x35,0xa8,0xd,0xf3,0xf6,0x18,0x2e,0x3d,0x8e,0x83,0x29,0x6d,0xe3,0xd5, 0xdb,0x12,0xa9,0xf7,0xe5,0x56,0x6c,0xad,0xf4,0x91,0xe,0x8e,0xc,0xc3,0xf2,0xef, 0xdb,0x2,0xe0,0xa1,0x91,0x61,0xd4,0xc2,0xb5,0x2b,0x97,0x59,0x9c,0xbf,0xbe,0x5, 0x3,0x36,0xf8,0xc0,0x60,0xad,0x2,0xb,0xdb,0xc3,0xc0,0x50,0xad,0xc2,0xec,0xc5, 0x4b,0x9c,0xfd,0xee,0x1b,0xce,0x9f,0x9c,0x9e,0x3,0xa6,0x36,0x4,0x60,0x24,0x5e, 0x4a,0x5,0x12,0xb,0xed,0x91,0x27,0xa9,0x3d,0xc,0x6f,0x1f,0x38,0xc8,0x66,0xc7, 0x81,0x27,0x3a,0xf1,0x2a,0xe7,0x35,0x1e,0x32,0x81,0x14,0x28,0xba,0x70,0xf9,0xea, 0x55,0xce,0x34,0x8e,0xd1,0xfc,0xfa,0x8b,0xb9,0xd9,0x1f,0x4e,0x1d,0x2,0xe,0x6f, 0x8,0xe0,0xb3,0x8f,0x3e,0xe0,0xa7,0xd3,0x27,0x57,0x99,0xe9,0xda,0xa3,0x86,0x55, 0xe6,0xbb,0x1e,0x4,0x1b,0x3c,0x5f,0x1d,0x6f,0x7c,0x77,0xee,0x8f,0xd9,0x5f,0xe, 0x1,0x87,0x1b,0x8d,0xc6,0x5f,0x1b,0x1,0x98,0x9a,0xfe,0xf4,0xe3,0x7f,0xf5,0x73, 0x6c,0x7d,0xf2,0x35,0x0,0xe2,0xb7,0xda,0x81,0xff,0xdd,0xd7,0xf1,0x3f,0x4d,0xf0, 0x4b,0xb9,0xe8,0x46,0x89,0xaf,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/paste.png 0x0,0x0,0x6,0x6d, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x6,0x34,0x49,0x44,0x41,0x54,0x78,0x5e,0xad,0x97,0x5b,0x6c,0x54,0xc7, 0x1d,0xc6,0x7f,0x73,0xce,0xd9,0x8b,0xbd,0xf6,0xfa,0x16,0xa0,0xbe,0x0,0xe,0xb2, 0x69,0x63,0x24,0x42,0x4a,0x21,0x22,0xa1,0x2d,0x95,0x62,0xa5,0x2f,0xee,0x4b,0x68, 0x2b,0x95,0xa6,0x55,0xa5,0xc6,0x60,0x55,0xaa,0xda,0xb4,0xaa,0xfa,0x56,0x9,0x55, 0xca,0x3,0x94,0x27,0xda,0x7,0x84,0x14,0x29,0xad,0xc4,0x8b,0xa5,0x52,0x83,0x79, 0x8,0xc5,0x18,0x39,0xe,0x69,0xd3,0x84,0x9a,0x9b,0x63,0x6a,0xec,0xb2,0x4,0x1b, 0x3b,0xbb,0xf6,0x7a,0x8f,0xbd,0xbb,0xde,0xb3,0x67,0xa6,0xc3,0x68,0x85,0xe5,0x72, 0x6c,0x88,0xc9,0x27,0x7d,0xfa,0x9f,0x9d,0x87,0xfd,0x7e,0xf3,0x9f,0x99,0x73,0x11, 0x4a,0x29,0x82,0x24,0x84,0x78,0x5,0x78,0x9e,0xc7,0x6b,0x48,0x29,0xf5,0x77,0xd6, 0x28,0x27,0x20,0xb8,0x43,0xbb,0x1,0x68,0x97,0x52,0xbe,0xc6,0x63,0x64,0x59,0xd6, 0x7,0x1a,0xf6,0xbb,0x40,0xb7,0x6,0x39,0xff,0x14,0x0,0x26,0xfc,0xb7,0xed,0xf5, 0xe2,0x60,0x5d,0x44,0x44,0x6e,0xce,0x89,0x8a,0x2b,0x57,0xae,0x50,0x5d,0x53,0x8d, 0x40,0x0,0xa0,0x50,0x8,0x65,0x28,0x41,0x29,0x66,0xd3,0x69,0x5e,0xa9,0x17,0x2f, 0xbc,0xb4,0x4e,0x6c,0x3b,0xf1,0x1f,0xb9,0x47,0x83,0x7c,0x5b,0x43,0x4c,0x3c,0x4d, 0x7,0xf6,0xff,0x60,0x8b,0xdd,0x2c,0x25,0xf8,0x4a,0x32,0x3c,0x3c,0x4c,0x65,0x65, 0x25,0x2b,0xc9,0x75,0x5d,0x1e,0xc0,0x6e,0xa9,0xb0,0x22,0x1b,0xa2,0x2a,0x72,0x3f, 0xa7,0xea,0x81,0xb5,0x3,0x8,0x2d,0x5,0x48,0xa1,0xd,0xf4,0x5d,0xbc,0x48,0x2e, 0x97,0xc3,0x2f,0x16,0x51,0x4a,0x91,0xcf,0xe7,0x59,0x5c,0x5c,0xa4,0x50,0x28,0x50, 0xd4,0x63,0xb5,0xb5,0xb5,0x94,0x1,0x58,0x80,0xf8,0x82,0xf6,0x80,0x1,0x0,0x36, 0x44,0x5,0x1f,0xf,0xbc,0x4b,0x3e,0x3b,0x8f,0x85,0x44,0x95,0x32,0xe2,0xb6,0xc4, 0xb6,0x4,0x21,0x21,0x70,0x3e,0x53,0x6c,0x8c,0x3b,0x80,0x44,0x2a,0x4,0xf0,0x9c, 0x10,0x2,0xe0,0xcb,0x40,0x5,0x50,0xf,0x34,0x60,0xc4,0x48,0x69,0x9f,0x24,0x2, 0x1,0x4e,0x9c,0x38,0x21,0x0,0x81,0x5,0xd2,0x87,0x96,0x96,0x67,0x9,0x65,0x6d, 0x14,0xe5,0x28,0xa5,0xb4,0x41,0x8,0x58,0x57,0x19,0x25,0xe2,0xd8,0x44,0x42,0x16, 0xc3,0x13,0x73,0x5c,0xbc,0x3d,0x41,0xf7,0x58,0x8e,0x5c,0x24,0xbe,0xa9,0xbd,0x7d, 0xf7,0xef,0x2d,0xcb,0x5a,0xdc,0xb1,0x63,0x47,0x59,0x55,0x55,0x95,0xd3,0xd8,0xd8, 0x18,0x7e,0xe0,0x86,0x86,0x86,0xd0,0xa5,0x4b,0x97,0xdc,0xae,0xae,0xae,0x8,0xf0, 0xd6,0xaa,0x1d,0x0,0x13,0x44,0x55,0x2c,0xc2,0x73,0xd5,0x31,0xf2,0x9e,0x4f,0xa1, 0x28,0x91,0x4a,0x61,0x9,0x41,0xd8,0xb1,0x88,0x86,0x6c,0xe6,0x72,0x5,0x12,0xa2, 0x8e,0x3f,0x9f,0xff,0x2b,0xd,0x4d,0x1b,0x1,0x22,0xc0,0x66,0x96,0x84,0xef,0xfb, 0x78,0x9e,0x47,0x75,0x75,0xb5,0x9e,0x50,0x4b,0xf4,0xea,0xd5,0xab,0x87,0x84,0x10, 0x28,0xa5,0xde,0x5a,0x11,0xc0,0xb2,0x41,0x0,0xb6,0x2d,0x90,0xda,0xb6,0x14,0x38, 0x8,0xa4,0x12,0x58,0xc2,0x8c,0x1b,0x8f,0x4c,0xb9,0xec,0x7b,0xf5,0x3b,0xd4,0x37, 0x36,0x11,0x7c,0x2f,0xc1,0x84,0x67,0x32,0x19,0xca,0xcb,0xcb,0xcd,0x66,0x3e,0x76, 0xec,0xd8,0x26,0xbd,0x7f,0xe,0x2e,0x41,0x2c,0x1,0xd0,0xd9,0xd9,0xa9,0xe,0x1d, 0x3a,0xa4,0x6c,0x21,0x8,0x59,0x10,0xb6,0x2d,0x1c,0xc7,0xc6,0x42,0x50,0xb4,0xcd, 0x1a,0x1b,0x0,0xc7,0xb2,0x88,0x38,0x96,0xae,0x2,0x60,0x59,0x78,0x10,0xc0,0xdc, 0xdc,0x1c,0x35,0x35,0x35,0x6,0x20,0x1a,0x8d,0x72,0xe4,0xc8,0x91,0xcd,0xc0,0x3, 0x88,0x1b,0x1a,0xa2,0xc7,0x62,0xb9,0xb0,0x6d,0x74,0x30,0x66,0x8d,0xcb,0x23,0x36, 0xb1,0xa8,0xa3,0xc7,0x2c,0x32,0x8b,0x1e,0x93,0x99,0x1c,0x63,0xa9,0x79,0xee,0xcc, 0x2e,0xe8,0xdf,0x45,0x72,0xf9,0x3c,0xab,0xc8,0x2c,0x41,0x36,0x9b,0x35,0xa7,0x66, 0xe9,0xff,0x6d,0xe,0x1c,0x38,0xb0,0x1e,0xe8,0x0,0x58,0x6,0xa0,0xb4,0x74,0x16, 0x8e,0xd,0xe1,0x90,0xc0,0x53,0x8a,0xb1,0xa4,0xcb,0x8d,0x8c,0x83,0xd3,0xb2,0x97, 0xa6,0x7d,0xaf,0xb3,0xb5,0xe3,0x17,0xac,0xdb,0xfb,0x3a,0xd,0x2f,0xb4,0x73,0xfb, 0xce,0x24,0xfd,0xfd,0xfd,0x24,0x93,0x49,0x94,0x52,0xe6,0xfa,0xf8,0xf1,0xe3,0xe8, 0xba,0xac,0x33,0xe7,0xce,0x9d,0xe3,0xe8,0xd1,0xa3,0x1c,0x3e,0x7c,0x98,0xde,0xde, 0x5e,0x12,0x89,0x84,0x4,0x2c,0xa1,0x15,0xdc,0x1,0xed,0xff,0xce,0xe6,0xf8,0xe7, 0x94,0x4f,0x6b,0xc7,0xcf,0xf8,0xe6,0x2f,0xdf,0x26,0xf6,0xf5,0x37,0x99,0x7c,0xa6, 0x83,0x6b,0xfe,0x2e,0xae,0xf1,0x2d,0x64,0x6b,0x17,0xad,0x7b,0x7f,0x4e,0x5e,0x56, 0x73,0xfa,0x6f,0x67,0xd1,0x77,0x4d,0xee,0xdc,0x9d,0xe2,0x1b,0xaf,0x76,0x72,0xfd, 0xfa,0x75,0x3,0xa0,0x67,0x6b,0xd6,0x3f,0x16,0x8b,0x99,0xeb,0x78,0x3c,0x8e,0xe3, 0x38,0x25,0x38,0x4,0xc0,0x23,0x0,0x96,0x25,0x98,0xca,0x41,0x3a,0xde,0xca,0xfe, 0xdf,0xbd,0x4d,0xd5,0xae,0xd7,0x28,0x84,0x62,0x8,0xdb,0x42,0x59,0x82,0x6c,0x41, 0x72,0x7f,0x66,0x91,0x4f,0xee,0x66,0x18,0xb8,0xea,0x72,0xfa,0x1f,0x61,0x64,0xd5, 0x5e,0xae,0x8f,0xdc,0x67,0x32,0xd7,0xc6,0x85,0xf,0xee,0x9b,0x0,0xed,0x87,0xa1, 0xcd,0xcd,0xcd,0xb4,0xb5,0xb5,0x19,0x37,0x35,0x35,0xa1,0xa1,0x14,0x20,0x83,0x1f, 0x46,0x16,0xdc,0x71,0x15,0xdf,0xff,0xe9,0x6f,0xa8,0x6c,0xd8,0x48,0xe2,0xec,0x3b, 0x4c,0x8f,0x5e,0xc3,0x89,0x94,0xb1,0xb5,0x79,0x7,0x9b,0x5b,0xb6,0xf3,0x49,0x79, 0x25,0x63,0x9,0x97,0xcf,0x66,0xf2,0xdc,0x9d,0xce,0x32,0xa1,0xed,0x88,0xd,0x4c, 0x27,0xe7,0xd8,0xb7,0x2b,0xca,0xfa,0x25,0x0,0x33,0x7b,0x3d,0x6b,0xea,0xea,0xea, 0x0,0xcc,0x75,0x2a,0x95,0x32,0x0,0x4a,0x2b,0x10,0xa0,0xb9,0x5a,0x70,0xe1,0x9d, 0x63,0x28,0x2c,0xca,0xe6,0xc6,0xd9,0x10,0x8f,0x52,0x94,0x92,0x7b,0xc3,0x7d,0x24, 0x65,0x5,0xdb,0xda,0x7f,0x4c,0x4d,0xdb,0xcb,0x7c,0x3c,0x9c,0x66,0xd2,0x5f,0xc0, 0xcd,0x78,0x2c,0xcc,0x6b,0x2f,0x78,0x20,0x0,0xb5,0x74,0x3a,0x42,0xa1,0x90,0x9, 0x2d,0xdd,0xea,0x1f,0x8e,0x1,0x2a,0xf8,0x3e,0x60,0xc1,0xc6,0xb8,0xa0,0x50,0x1c, 0x23,0x1c,0x8b,0x53,0xb7,0xa5,0x96,0x92,0x78,0x76,0x7d,0x5,0xe9,0xac,0xc7,0x68, 0xff,0x9f,0x98,0xae,0xbc,0x4c,0xcb,0xf6,0x83,0xb8,0xb,0x61,0xbc,0x82,0xa4,0x58, 0x94,0x78,0xda,0x21,0xc7,0x42,0x2d,0xaa,0x80,0xe3,0x69,0xa0,0x96,0xd5,0x15,0x1, 0x0,0xd6,0xc7,0x43,0x84,0xca,0x23,0xfc,0xbf,0x6a,0x63,0x21,0x9e,0xa9,0xc,0x73, 0xe1,0xdf,0x83,0xec,0xd9,0xf9,0x13,0xca,0xa3,0xe,0xb9,0x32,0x47,0x3,0x28,0x3, 0x61,0x6b,0x0,0x16,0x4b,0x21,0xa5,0x1c,0x25,0x30,0x2a,0x15,0xa4,0x5c,0x5,0x40, 0x58,0xa5,0x2a,0xcc,0xf5,0x23,0xfa,0x70,0x6c,0x86,0xf1,0x59,0x8f,0xef,0xfd,0xfa, 0x8f,0xdc,0xca,0xd4,0xe0,0x44,0x5c,0xa2,0x11,0x1b,0xcf,0x93,0x14,0x3d,0x7,0xd3, 0x1,0xa5,0x90,0x52,0xf2,0x50,0x6a,0x59,0x1,0x56,0x5,0x10,0x8,0x4c,0xd,0x4, 0x18,0x9d,0x76,0xf9,0xd5,0x5f,0x86,0x18,0xbd,0xb7,0x80,0x3d,0x93,0x67,0xd3,0xba, 0x32,0xf2,0x79,0x5f,0xbb,0x68,0xea,0xce,0xaf,0xd4,0x70,0xf9,0xdd,0xe0,0x25,0x0, 0x9e,0x78,0x9,0x4c,0xb8,0x10,0x3c,0xa2,0xd6,0x2f,0x55,0xf2,0x87,0x1f,0x3e,0xcf, 0xf5,0x4f,0x33,0x44,0x1b,0xb7,0xb1,0xf3,0xc5,0x97,0x59,0x12,0x5c,0x4e,0x60,0x8e, 0xdb,0x53,0x1,0x28,0xc0,0x12,0x25,0x0,0x6d,0xd4,0x52,0x7d,0xb1,0xb5,0x96,0xdd, 0x5b,0xe2,0x74,0xbf,0x97,0xa5,0x6a,0xf7,0x57,0xf9,0xd1,0x1b,0x6f,0x10,0xa0,0xb5, 0x3,0x98,0xb5,0x37,0xd5,0xd8,0x8,0x1,0xd2,0xcb,0x53,0x70,0x53,0x78,0xf3,0x33, 0x14,0xb3,0x69,0xa,0x19,0x1f,0x25,0xfd,0xd5,0x82,0xd6,0x8,0xf0,0xf0,0x29,0xe7, 0xe3,0xe7,0x33,0x14,0xe6,0x75,0xa8,0xe,0xd6,0x0,0xcb,0xf7,0x89,0x10,0xc1,0x33, 0x7d,0xfa,0xd7,0x72,0x8c,0xb2,0x13,0x37,0x3,0xc7,0x1,0xb2,0x1e,0xfe,0xad,0x94, 0xcc,0x6f,0xf7,0x44,0x54,0x3,0xd8,0x5f,0x70,0x7,0x8,0x92,0x9,0xfd,0xd7,0x3d, 0x3f,0xfd,0x7e,0x42,0xa6,0xcf,0xdf,0xf6,0xef,0x2,0xee,0x76,0x3b,0xfc,0x92,0x6, 0xa8,0xe3,0x73,0xca,0x75,0x5d,0x1f,0x70,0x57,0xed,0x0,0x40,0x32,0xab,0xa,0x1f, 0x7e,0x2a,0xd3,0xbd,0xb7,0xfc,0xd4,0xcd,0x69,0x39,0x5,0xf4,0x3,0x97,0x74,0x68, 0xbf,0x10,0xa2,0xd3,0xb6,0xed,0xaf,0x7d,0x9e,0x25,0x58,0x58,0x58,0xf0,0x7,0x6, 0x6,0xd2,0x27,0x4f,0x9e,0x9c,0x6,0xba,0x83,0x0,0x3e,0x1a,0x49,0xca,0xad,0xe3, 0xb3,0x2a,0xd7,0x3b,0xe2,0xa7,0x6e,0x4c,0xcb,0xd1,0x52,0xe8,0x59,0x1d,0x74,0x8b, 0x0,0x3d,0x9,0xc0,0xd0,0xd0,0x90,0xdb,0xd3,0xd3,0x93,0xd2,0x4e,0xcf,0xce,0xce, 0x9e,0x2e,0xbd,0x1d,0xdf,0x8,0x2,0xe8,0xee,0xea,0x29,0x0,0x8c,0x4,0x84,0x6, 0x85,0xaf,0x8,0x30,0x35,0x35,0x55,0xd0,0x2f,0x22,0xa9,0x53,0xa7,0x4e,0x25,0xc7, 0xc7,0xc7,0x2f,0x3,0x67,0x81,0x7e,0x1d,0xec,0xae,0xb8,0x9,0x4b,0xdf,0x76,0xda, 0x4f,0x26,0x85,0x1,0x40,0x8,0x40,0x61,0x5a,0xfc,0xde,0xe0,0x60,0xba,0xbb,0xbb, 0x3b,0xa5,0xdf,0x8a,0xcc,0x24,0xd0,0x5e,0xed,0x73,0xcd,0x61,0xed,0x9a,0x77,0x33, 0x6e,0x11,0x60,0x70,0xf0,0xfd,0x74,0x5f,0x5f,0x5f,0xfa,0xcc,0x99,0x33,0xa6,0xc5, 0xa5,0xd0,0x8f,0x78,0x2,0x89,0xb5,0x9e,0x63,0x21,0x44,0x18,0x78,0x13,0xd8,0x4f, 0x69,0x73,0x6,0xb4,0xf8,0xb1,0xfa,0x1f,0xbd,0xfa,0x2a,0x5f,0xf2,0xd8,0x15,0x9d, 0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/open.png 0x0,0x0,0x8,0x19, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xd6,0xd8,0xd4,0x4f,0x58,0x32, 0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x53,0x6f,0x66,0x74,0x77,0x61,0x72,0x65, 0x0,0x41,0x64,0x6f,0x62,0x65,0x20,0x49,0x6d,0x61,0x67,0x65,0x52,0x65,0x61,0x64, 0x79,0x71,0xc9,0x65,0x3c,0x0,0x0,0x7,0xab,0x49,0x44,0x41,0x54,0x58,0xc3,0xad, 0x57,0x5b,0x50,0x93,0x67,0x1a,0xf6,0xca,0xce,0xec,0xcc,0xf6,0x62,0x2f,0xbc,0xd9, 0xe9,0xce,0xec,0x6e,0xbd,0xda,0xd9,0x9b,0xb5,0xce,0xba,0x3b,0x7b,0xb0,0xad,0xcc, 0x7a,0xb1,0xce,0xce,0x3a,0xb3,0x76,0x54,0x70,0x75,0xdb,0xe2,0x81,0xd6,0xb6,0x54, 0x4,0xbb,0xa5,0x20,0x6d,0xc1,0x82,0x6,0x8,0x7,0x51,0x42,0x80,0x80,0x80,0x2, 0x21,0x81,0x10,0x92,0x40,0x48,0x10,0x73,0x24,0x21,0x67,0x72,0x80,0x4,0x42,0x20, 0x9c,0x9,0x47,0xb5,0x54,0x78,0xf6,0xfb,0x7e,0x13,0x16,0x30,0x58,0x8b,0x7d,0x67, 0x9e,0xf9,0x2f,0x92,0xfc,0xcf,0xfb,0x3e,0xcf,0xfb,0xbe,0xdf,0x97,0x5d,0x0,0x76, 0xfd,0x98,0x20,0xf1,0xb,0x82,0x14,0x2,0x3,0xc1,0x75,0x82,0x3,0xcf,0xfd,0xfe, 0x8f,0x48,0xbc,0x9b,0x20,0xe1,0x57,0xaf,0xef,0xb5,0x2a,0x8c,0xd6,0x65,0xdb,0x2, 0x60,0x19,0x1e,0x5b,0x9,0x27,0xf1,0x33,0xfa,0x19,0x81,0x22,0xfc,0xdc,0x3e,0x76, 0x48,0x7e,0x8a,0xa0,0xb9,0xb6,0x59,0x1c,0x32,0xcf,0xad,0x42,0x39,0xfe,0x1d,0x44, 0xf6,0x51,0xd8,0xc7,0xe6,0xe8,0x87,0x86,0x3d,0x7b,0xf6,0x58,0x53,0x52,0xae,0x2c, 0xca,0x3a,0x3a,0x10,0x4e,0xe2,0xe5,0x49,0xc3,0xc4,0x31,0x4,0xb7,0x3e,0x49,0xf9, 0x2c,0x60,0x9b,0x5d,0x59,0x53,0x4d,0x3,0x4d,0xb6,0x11,0x34,0xeb,0xfb,0x20,0x31, 0x79,0x60,0x19,0x9d,0xc5,0xbb,0xef,0xbe,0x3f,0xc5,0xab,0xbe,0x83,0xf1,0x89,0x29, 0x4c,0x4f,0xcf,0xae,0x92,0xef,0xd7,0xbc,0x74,0x2,0x11,0x9f,0xf,0xbe,0x1d,0xe3, 0xb2,0x4,0x43,0x4f,0xb4,0x33,0x40,0x8b,0x7b,0x6,0xcd,0x3d,0x2e,0x34,0xeb,0xec, 0xa8,0x57,0xf6,0x20,0x87,0x53,0x85,0x32,0x5e,0x35,0x43,0xbc,0xb0,0xf4,0x90,0x81, 0xc1,0x60,0x5c,0x26,0xbf,0x4b,0x7c,0xe1,0x4,0x48,0x1c,0x24,0x38,0x41,0xfd,0xdd, 0xea,0x73,0x27,0xf1,0xb9,0x27,0x4,0x48,0x87,0x97,0xc1,0xd7,0xbb,0x20,0x22,0x55, 0x37,0xdc,0x37,0xa2,0xb8,0x4e,0x88,0x2c,0x56,0x3e,0xcc,0x56,0xdb,0x3a,0x71,0x4, 0x2c,0x16,0x6b,0x2c,0xfc,0xce,0xe7,0x27,0x10,0x91,0x36,0x93,0x95,0x3f,0x46,0x7d, 0xa5,0xfe,0x12,0xc4,0x6f,0xf4,0x59,0x31,0xb6,0x2,0x7e,0xef,0x20,0x5a,0x7b,0x9c, 0xe0,0x3f,0x30,0xa1,0x4c,0x28,0x43,0x46,0xe,0x1b,0xb2,0xe,0xf9,0x26,0xd2,0xf9, 0xc5,0x65,0xcc,0x2d,0x2c,0x21,0x34,0xbf,0x88,0xbd,0x7b,0xf7,0x5a,0xc9,0x3b,0x7e, 0xba,0x6d,0x2,0x24,0x7e,0x43,0x90,0x46,0x3d,0x35,0x13,0x69,0x75,0xb3,0x80,0xd2, 0x3f,0xf,0xcb,0xc4,0xe2,0x9a,0x50,0xa1,0x5a,0xb4,0x6c,0xf1,0x59,0xa0,0xb6,0xa0, 0xa6,0x5d,0x8d,0x2f,0xb2,0x73,0x71,0xb7,0x9e,0xff,0xc,0x31,0x25,0x9d,0x9,0xcd, 0x63,0x62,0x6a,0x6,0x83,0x43,0x81,0x27,0xe4,0xdd,0xbc,0x2d,0xd3,0xb0,0x3b,0x92, 0x3,0x33,0x26,0xd4,0x53,0xb5,0xd3,0xfb,0x58,0x4f,0x88,0xc5,0x3,0x21,0x88,0x2c, 0x43,0x50,0xba,0x46,0xd0,0xed,0x9,0x42,0xe5,0x9b,0x42,0x9b,0x73,0xfc,0xa9,0xcf, 0x5a,0x1b,0xee,0x2a,0x74,0xc8,0xbc,0xc9,0x45,0x9,0xa7,0x6c,0x93,0xcf,0x9b,0x88, 0x27,0xa7,0x11,0x18,0x1d,0xc3,0x80,0x6f,0x8,0xa2,0xd6,0xd6,0x25,0xc2,0x51,0xdb, 0x28,0x12,0x87,0xc6,0x1f,0xaf,0x82,0x2f,0x62,0x94,0x4d,0x89,0x24,0x90,0x22,0xea, 0x52,0x2d,0x9a,0x42,0xab,0xe8,0x18,0x79,0x4,0xa1,0xc5,0xcf,0x10,0x53,0x74,0xf6, 0xd,0xa3,0xd3,0xe1,0x87,0xd4,0x3c,0x80,0x16,0xbd,0x3,0xd,0x5d,0x6,0x14,0xd5, 0xa,0x90,0x91,0x95,0xd,0x2f,0x79,0xf1,0xc6,0xaa,0xa9,0xd4,0xb3,0x73,0xb,0x4c, 0xc5,0x94,0xd8,0xdd,0xef,0x85,0xc9,0x62,0x5,0xb7,0xbc,0x12,0xa5,0xe5,0x95,0x4b, 0x13,0xf3,0xcb,0xab,0x23,0xf,0x1,0x37,0xd9,0x11,0xe6,0xd9,0x15,0x84,0x97,0x15, 0x13,0x6,0xcb,0x3c,0xd0,0x68,0xf2,0xa3,0xdd,0xee,0x5f,0x27,0x96,0x3b,0x86,0x20, 0xb3,0x78,0xd7,0x7d,0xe6,0x8,0xa4,0xf8,0x3c,0x33,0x1b,0x2a,0x8d,0x36,0xaa,0xdc, 0x53,0x33,0x21,0x8c,0x8e,0x8d,0x33,0x15,0xd3,0x26,0xe4,0x37,0x9,0xf1,0xc1,0xc5, 0x8f,0x51,0x73,0xaf,0x1,0xbe,0x65,0x60,0xfc,0x11,0xa0,0x23,0x13,0x23,0xf2,0xce, 0xa1,0xbe,0x5d,0xb9,0xb8,0x51,0x1,0x83,0x81,0x74,0x74,0x4d,0xa7,0x1e,0xa,0x67, 0x80,0xa9,0xb8,0xdd,0xea,0x83,0xd8,0xe8,0x42,0x93,0xca,0xcc,0xf8,0x7c,0xe5,0xcb, 0x2c,0x88,0xda,0x24,0x51,0x89,0xa7,0x67,0xe7,0x18,0x1b,0x86,0x86,0x47,0x60,0x77, 0x38,0x49,0x82,0x3a,0x24,0x7c,0xf8,0x21,0xae,0xb3,0xb,0xe1,0x99,0x5c,0x80,0x6f, 0x9,0xd0,0x90,0xde,0xe1,0xf,0x2c,0x81,0xab,0x1f,0xc4,0x7d,0xef,0x4,0xdd,0x7, 0x1d,0x61,0xeb,0xff,0x9f,0xc0,0x1d,0xb9,0x16,0x1d,0xf6,0x21,0x48,0xcc,0xfd,0x4f, 0x7d,0xee,0xd4,0x22,0x9d,0x55,0x84,0xaa,0x9a,0xba,0x4d,0x3e,0x47,0xe4,0x8e,0xf8, 0x3c,0x3c,0x12,0x84,0xd3,0xdd,0xf,0xbd,0xc1,0x88,0xc2,0xe2,0x62,0x9c,0x7e,0x2f, 0x1e,0x3d,0x3,0x1,0xf4,0x2f,0x2,0x83,0x84,0xbc,0xc5,0xff,0x2d,0xee,0x3a,0x43, 0x28,0x51,0x91,0xf7,0xf6,0x5,0xf1,0x4e,0xdc,0xbf,0x7d,0x84,0x33,0x69,0xe3,0x20, 0x18,0xf4,0x33,0xab,0xe0,0xc9,0x54,0x68,0x35,0x38,0xd1,0xd8,0xdd,0xb,0x9e,0x58, 0x89,0xac,0x5c,0xf6,0x33,0x3e,0x47,0xaa,0x9e,0x9c,0x9e,0x65,0xe4,0xee,0xf7,0xe, 0xa2,0xd7,0x6c,0x41,0x43,0x3,0x1f,0x27,0x62,0xe3,0x20,0xe9,0xd6,0xc0,0x45,0xcf, 0x1,0x52,0x90,0x24,0xb8,0x86,0xb2,0x9e,0x0,0x6e,0xb4,0xdb,0x50,0xd1,0x1b,0x44, 0x85,0xce,0x8b,0x4a,0x7e,0xb,0x6d,0xbe,0x9b,0x5b,0x27,0xd1,0xa0,0x99,0xf8,0x16, 0x65,0x22,0x5,0xee,0x29,0xf4,0x28,0x13,0xc8,0x90,0x78,0x35,0xb,0x1a,0xad,0x3e, 0xaa,0xdc,0x63,0x13,0x93,0xf0,0xd,0xd,0xc3,0x66,0xef,0x83,0xb4,0x5d,0x8e,0xc4, 0x4b,0x97,0x90,0xc3,0xca,0xc3,0xd4,0x63,0xc0,0x4e,0x7a,0x49,0x31,0x4e,0xfa,0x89, 0x94,0x7f,0x5b,0x3b,0x84,0x7c,0x85,0x13,0x25,0x6a,0x1f,0x4a,0xd5,0x3,0xe8,0xf2, 0x30,0xa3,0x28,0x22,0xf8,0xf9,0x33,0x9,0x74,0x8f,0x2e,0xa1,0xa8,0xbe,0x15,0xa5, 0x7c,0x9,0xb2,0x4a,0x2a,0xf0,0xcf,0xe3,0x71,0x51,0xe5,0xf6,0x7,0x46,0xd1,0xe7, 0xf2,0x40,0xab,0x37,0x20,0xfd,0x6a,0x6,0x92,0xbf,0x48,0x83,0xcd,0x37,0x2,0x27, 0xa9,0xda,0x40,0x1a,0x4c,0xe0,0x7b,0x88,0x52,0x9d,0x1f,0x45,0xdd,0xfd,0xc,0x71, 0x41,0x97,0x1b,0xc5,0xdd,0x1e,0x88,0x9c,0x41,0xfc,0xf9,0xcd,0xb7,0x5d,0x84,0xeb, 0x6c,0xb4,0x43,0xd0,0x28,0xf7,0x4e,0x23,0xa7,0xfc,0x1e,0xb2,0x4b,0xab,0xf1,0x51, 0xea,0x57,0x48,0xfe,0x6f,0xea,0xfa,0x58,0x51,0xb9,0x47,0x82,0xe3,0xf0,0xc,0xf8, 0x60,0x34,0x99,0x51,0xc9,0xab,0xc2,0xfb,0x67,0xcf,0x41,0xfe,0x40,0x3,0x3f,0xe9, 0x6e,0xb2,0x8d,0x19,0xb9,0x6f,0x69,0x6,0x19,0xd2,0x9b,0x2a,0x2f,0x72,0xe5,0xe, 0xe4,0x75,0xf6,0xa1,0xf0,0xbe,0x1b,0x1c,0x95,0x1b,0xf9,0x9c,0xca,0x29,0xc2,0x53, 0xb8,0xdd,0x29,0xdc,0x2b,0x76,0x4,0x90,0x51,0xc8,0xc5,0x95,0x6b,0x79,0x38,0x11, 0x9f,0x80,0x9b,0xb7,0x6e,0x33,0x63,0x15,0x91,0xdb,0x6a,0x73,0x40,0x22,0x6d,0xc7, 0x85,0x84,0xf,0x50,0x74,0xbb,0xc,0xf3,0x2b,0x80,0x9f,0x34,0x58,0xf7,0x24,0x20, 0x1c,0x7c,0x84,0x4a,0xd3,0x18,0x38,0xfa,0x61,0x86,0x9c,0x56,0xfd,0x55,0xb3,0x1e, 0xac,0xe,0x3b,0xb8,0x3a,0x1f,0xd9,0x21,0x1e,0x7a,0x2f,0xe0,0x13,0xbc,0xba,0x5d, 0x2,0x26,0xbe,0xc1,0x83,0x94,0x6f,0xd8,0x38,0x9f,0x9c,0x8a,0x3,0x7f,0x3d,0x4, 0x63,0xaf,0x99,0xe9,0x6e,0x2a,0xb7,0x46,0xd7,0x83,0xa4,0xcb,0xc9,0x48,0xff,0x3a, 0x8b,0x8c,0xd5,0x3c,0x53,0xb5,0x71,0xf6,0xa9,0xdc,0x35,0xf6,0x69,0x5c,0x97,0x59, 0x19,0xd9,0xbf,0x6e,0x21,0xa7,0xa0,0xd4,0x82,0x74,0xbe,0x1a,0x57,0x9b,0x34,0x60, 0xc9,0xcc,0x10,0xbb,0x82,0xf8,0xe5,0xaf,0x5f,0xa7,0x67,0xc0,0x3b,0xe1,0x75,0x1f, 0x35,0xcc,0x35,0xdd,0x66,0x7c,0x94,0x96,0x85,0xb8,0x73,0x17,0xf1,0x97,0x43,0x31, 0x4c,0xd5,0x74,0x99,0xf0,0xaa,0xaa,0x71,0xfa,0xf4,0x19,0x68,0xcc,0xe,0x8c,0x92, 0x2d,0x36,0x14,0x1e,0xab,0x5a,0xc7,0xc,0x78,0xe6,0x71,0x70,0xd,0x23,0x4c,0xa3, 0x65,0x8a,0xc,0x8c,0xec,0xb4,0xfa,0x9c,0xb6,0x5e,0x94,0x74,0x39,0xd0,0x66,0xf7, 0xaf,0x1e,0x3d,0x11,0x4b,0x47,0x2e,0x6f,0xc3,0x79,0x13,0x35,0x2c,0x5c,0x99,0x1a, 0xf1,0x97,0x3e,0xc7,0xd1,0xd8,0x33,0xf8,0x38,0x31,0x9,0x86,0x5e,0x13,0x1a,0x9b, 0x4,0xf8,0xdd,0x1b,0xfb,0x51,0x4f,0xd4,0xf1,0x90,0x99,0xee,0x9a,0x0,0xaa,0xad, 0x93,0x60,0x2b,0x5d,0xc,0x39,0xf5,0xbc,0xf0,0xbe,0x67,0xbd,0xea,0xcc,0x16,0x3d, 0x4a,0x55,0x1e,0x8,0x6d,0x1,0x94,0xd4,0xf1,0x43,0xe1,0x65,0x53,0x40,0xf0,0xca, 0xf7,0x25,0x60,0x2b,0x6e,0x6a,0xc7,0xa9,0x84,0x44,0xc4,0x1c,0x39,0x8a,0xdc,0x7c, 0x36,0x5a,0x5a,0xc5,0x38,0x14,0x13,0x83,0x2f,0x39,0x35,0xc8,0x14,0x6a,0x98,0xe6, 0xa2,0xd5,0xd2,0x27,0xf5,0x9a,0x7a,0x4c,0x13,0xa1,0x49,0x64,0xb7,0x99,0x90,0xdb, 0x6e,0x46,0xb9,0xda,0x8d,0x6,0xa5,0x76,0x39,0x2c,0x39,0x3d,0xf9,0x4e,0x13,0xec, 0xd9,0x72,0xd4,0x47,0xd,0x3b,0xab,0x46,0x88,0x63,0xff,0x39,0x8f,0xdf,0xee,0xfb, 0x3d,0x1a,0xf9,0x2,0x9c,0xbf,0x90,0x80,0x93,0xf1,0x17,0x70,0xa3,0xad,0x7,0x19, 0xc4,0x4f,0x4a,0x14,0xe9,0x6e,0xba,0x58,0xa8,0xef,0x2c,0xfa,0x94,0x98,0x50,0x28, 0xb7,0x40,0xe9,0xe,0x3c,0xf9,0x57,0xec,0x29,0x2a,0x77,0x2d,0xc1,0x67,0x4,0xfb, 0xb6,0xb9,0xe4,0x44,0x8d,0xbe,0xcc,0xb2,0x5a,0xfc,0xe3,0xe4,0x19,0x1c,0x3c,0xf4, 0x37,0xb0,0x72,0xf3,0xb0,0xef,0xc0,0x1f,0x50,0x20,0xd1,0x21,0x89,0x27,0x65,0x2a, 0xa6,0x4b,0x85,0x3e,0xbf,0x21,0xd5,0x46,0xe4,0x2e,0x90,0x5b,0x21,0xb0,0xc,0xae, 0xe5,0xdc,0xe2,0xd2,0x11,0x13,0x13,0xe4,0x87,0x6f,0x3c,0xaf,0x3c,0xe7,0x96,0x15, 0x35,0x9c,0x69,0x45,0xe5,0xf8,0xfb,0xb1,0x58,0x1c,0x3f,0x19,0x87,0x37,0xf6,0xef, 0xc7,0x8d,0x3a,0x11,0x92,0xab,0xa4,0xc,0x21,0xed,0x70,0xea,0x35,0x55,0x21,0x8b, 0x34,0x5b,0xc9,0x3,0x37,0x2a,0x34,0x6e,0xd4,0x49,0x3a,0x17,0xc3,0x72,0x73,0x8, 0x8e,0x6d,0x95,0xfb,0x87,0x24,0xe0,0x4a,0x65,0x73,0x70,0xe4,0xf8,0x29,0x1c,0x3e, 0x7c,0x98,0x8c,0x63,0x2e,0x32,0x5,0x2a,0x5c,0x22,0xd5,0xd3,0x5d,0x7e,0x4d,0xdc, 0xb,0x36,0xe9,0x74,0x76,0xa7,0x1d,0x77,0x8c,0xe4,0x88,0xb6,0xf9,0x9e,0x84,0xb7, 0x1a,0x95,0xfb,0x22,0xbd,0x49,0xfd,0x80,0xb,0x6d,0xf4,0x4,0x32,0x4a,0x78,0x4c, 0xf,0x9c,0x4b,0x49,0xc3,0xb5,0xa6,0x2e,0x7c,0xc2,0x6d,0x65,0x36,0x59,0xf1,0x83, 0x1,0x5c,0x97,0x9a,0xc1,0x51,0x7b,0x20,0xf3,0x4,0xd7,0xce,0x25,0x26,0x5,0x36, 0xc8,0xfd,0xc7,0x9d,0xc8,0x1d,0xd5,0x82,0xdc,0x1a,0x1,0xce,0x5e,0x4e,0x45,0x81, 0x58,0x85,0x78,0xf6,0x5d,0x5c,0xa9,0x55,0x90,0xaa,0xfb,0xc0,0x96,0xdb,0x50,0xad, 0x75,0xe3,0xae,0x54,0x41,0x2f,0x10,0xca,0xd,0x72,0xbf,0xba,0xd3,0x6a,0xa3,0x5, 0xb7,0xa2,0x51,0xf8,0x1d,0xaf,0x43,0x8d,0x4f,0xb9,0x2d,0x88,0xcb,0xe6,0xe1,0x9a, 0x48,0x8f,0xaa,0x1e,0x2f,0x9a,0x35,0xe6,0xc7,0x7f,0x7a,0xf3,0x2d,0x57,0x78,0xac, 0xa8,0xdc,0xaf,0xbd,0xac,0xdc,0xd1,0xe2,0x8,0xdd,0x5,0x5c,0x75,0x1f,0xde,0xcb, 0xaf,0x45,0xb9,0x76,0x0,0x32,0x67,0x60,0xf5,0xc2,0xa7,0x97,0xa9,0xdc,0xf7,0x8, 0xd2,0xa9,0xdc,0x3b,0xf8,0x3,0xf3,0xc2,0xf1,0x13,0x82,0xca,0x1c,0xee,0x9d,0x50, 0xb,0x39,0x94,0xb8,0xd,0xc2,0xc8,0x16,0xa3,0x17,0x87,0xc3,0x2f,0x22,0xf7,0xe, 0xff,0xda,0x6d,0x8a,0xdd,0x61,0x99,0xd5,0x1b,0xb6,0xd8,0x6b,0xbb,0x5e,0x32,0xbe, 0x2f,0x89,0xff,0x1,0x66,0xb9,0x5f,0xfc,0x11,0x80,0x3d,0xcf,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00006.png 0x0,0x0,0x1,0x93, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0, 0x2,0x68,0xc0,0x1d,0x0,0x10,0x40,0x2c,0x14,0xea,0x27,0x54,0x8c,0x32,0x12,0x32, 0x0,0x20,0x80,0x28,0x71,0xc0,0x7f,0x46,0x46,0xfc,0xe6,0xff,0x87,0x94,0xf3,0x78, 0x15,0x1,0x4,0x10,0xb,0x25,0x96,0x13,0xaa,0x47,0xa0,0x6a,0xf0,0x3a,0x2,0x20, 0x80,0x98,0x68,0x61,0x39,0xa1,0x90,0x41,0x6,0x0,0x1,0xc4,0x44,0xb,0xcb,0x49, 0xa9,0x61,0x1,0x2,0x88,0x69,0x20,0x2d,0x7,0x1,0x80,0x0,0x62,0xa2,0x95,0xe5, 0x48,0x7c,0xbc,0xf1,0x1,0x10,0x40,0x4c,0x3,0x69,0x39,0x8,0x0,0x4,0x10,0xb, 0xb1,0x59,0x8d,0xd8,0x84,0x45,0x8a,0xe5,0x20,0x0,0x10,0x40,0x44,0x65,0x43,0x62, 0xb2,0x1b,0x39,0x96,0x83,0x0,0x40,0x0,0x51,0xad,0x28,0x26,0xc7,0x72,0x10,0x0, 0x8,0x20,0x16,0x62,0xd,0x27,0x32,0x94,0x18,0x49,0x75,0x38,0x40,0x0,0xb1,0x50, 0x1a,0xfc,0xa4,0x94,0xfb,0xd8,0x0,0x40,0x0,0xb1,0xd0,0xc2,0x50,0x52,0x0,0x40, 0x0,0xd,0x78,0x75,0xc,0x10,0x40,0x3,0xee,0x0,0x80,0x0,0x1a,0x70,0x7,0x0, 0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0, 0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0,0x2,0xc,0x0,0x1f,0xc5, 0x4a,0x53,0x9b,0x40,0x18,0xd3,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00007.png 0x0,0x0,0x1,0xbb, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x31,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0x10,0xc9,0xe,0x60,0x64,0x64,0xfc,0xf,0xc2,0x84, 0xd4,0xe0,0xe3,0x23,0x3,0x80,0x0,0x62,0x22,0xd5,0x72,0x50,0xa2,0x5,0x61,0x5c, 0x86,0xc2,0xd4,0xc0,0xe4,0xd1,0xf9,0xe8,0x0,0x20,0x80,0xa8,0x1e,0x5,0x40,0xcb, 0x80,0x76,0x31,0xc2,0x1d,0x9,0xa5,0xc1,0xe2,0xd8,0xd4,0x3,0x4,0x10,0x4d,0xd2, 0x0,0x9a,0x23,0x70,0x5a,0xe,0x2,0x0,0x1,0x44,0x13,0x7,0xa0,0xf9,0x1c,0x6f, 0x1a,0x0,0x8,0x20,0x26,0x4a,0x2d,0x42,0x4f,0x94,0xe8,0xc1,0x4e,0xc8,0x11,0x0, 0x1,0xc4,0x42,0x61,0x50,0xc3,0x2c,0x65,0x40,0x73,0x4,0x3c,0xd8,0xa1,0x8e,0xf8, 0x8f,0x2b,0x1a,0x0,0x2,0x88,0x89,0x5a,0x59,0xf,0x96,0x3b,0xb0,0x65,0x3d,0x7c, 0x69,0x0,0x20,0x80,0x98,0x48,0xc9,0x7a,0xa4,0x84,0xc,0xa1,0xb8,0x87,0x1,0x80, 0x0,0x1a,0xf0,0x92,0x10,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0xc4,0x44,0x4e,0xa2, 0x23,0x96,0x4d,0xc,0x0,0x8,0xa0,0x1,0xf,0x1,0x80,0x0,0x1a,0x70,0x7,0x0, 0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0xc4,0x44,0x44,0xc2, 0x3,0x17,0xa7,0xb4,0x2,0x0,0x1,0xc4,0x44,0x64,0xea,0x27,0xd9,0x11,0x84,0x6a, 0x41,0x18,0x0,0x8,0x20,0x46,0x52,0xb2,0xd,0x31,0x25,0x1b,0x31,0xc5,0x2f,0x32, 0x0,0x8,0xa0,0x1,0x4f,0x3,0x0,0x1,0xc4,0x38,0xd0,0xfd,0x2,0x80,0x0,0x1a, 0xf0,0x10,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0,0x2,0x68, 0xc0,0x1d,0x0,0x10,0x40,0x3,0xee,0x0,0x80,0x0,0x1a,0x70,0x7,0x0,0x4,0xd0, 0x80,0x3b,0x0,0x20,0xc0,0x0,0xbb,0x7f,0x8c,0x33,0xe4,0xfc,0xec,0x2c,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/icon-1-2.png 0x0,0x0,0x1,0x19, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x8f,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0xc4,0xc1,0x83,0x7,0x49,0x36,0xc5,0xde,0xde, 0x9e,0x11,0x44,0x3,0x4,0x10,0xb,0x4c,0xe0,0xc0,0x81,0x3,0x70,0x49,0x7,0x7, 0x7,0xc,0xbe,0x83,0xbd,0x3d,0x9c,0x7f,0xe0,0xe0,0x41,0x38,0x1b,0x20,0x80,0x98, 0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0xc4,0x8,0xa,0x44,0x4a,0xc2, 0x0,0x20,0x80,0x70,0x86,0x1,0xba,0x9f,0xd1,0xe5,0x61,0x0,0x20,0x80,0x28,0xf6, 0x2,0x40,0x0,0x51,0x6c,0x0,0x40,0x0,0x51,0x1c,0x6,0x0,0x1,0x4,0xf,0x3, 0x42,0x7e,0xc6,0x15,0x6,0x0,0x1,0x44,0xb1,0x17,0x0,0x2,0x88,0x62,0x3,0x0, 0x2,0x88,0xe2,0x30,0x0,0x8,0x20,0x46,0x4a,0x73,0x23,0x40,0x0,0x51,0xec,0x5, 0x80,0x0,0x3,0x0,0xad,0x72,0x3a,0x15,0x1f,0xe8,0xcd,0x47,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00008.png 0x0,0x0,0x0,0xc7, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x79,0x49,0x44,0x41,0x54,0x38,0x8d,0x9d, 0x92,0x4b,0x12,0xc0,0x20,0x8,0x43,0x13,0xc7,0xfb,0x5f,0x99,0x2e,0xfa,0x19,0x94, 0x60,0x51,0x76,0xd4,0xf0,0x12,0xb1,0x44,0x2c,0x9b,0x7a,0xa,0x8d,0x3c,0x34,0x0, 0x30,0x1b,0xe7,0x49,0x2a,0x6d,0x0,0xd8,0x3c,0x18,0x84,0x37,0x28,0x40,0x5a,0x26, 0x76,0xce,0xcb,0x6a,0x15,0xf7,0x27,0x22,0x10,0xf7,0x83,0x2e,0x62,0x86,0x7e,0x65, 0x20,0xaf,0xb0,0x53,0x43,0x82,0xd7,0xa9,0xe2,0xec,0x13,0xb0,0xb2,0xb0,0xec,0x15, 0x7a,0x94,0xd6,0x9c,0x3f,0xb0,0x9f,0x53,0xc3,0x22,0x1d,0xd3,0xc6,0x83,0x84,0xc6, 0xc4,0xb7,0xf5,0x7f,0xfe,0x3,0xd7,0x4b,0xd9,0x85,0x9c,0x0,0x66,0xc8,0x71,0x19, 0x0,0x5c,0xfb,0x35,0x27,0x1e,0x97,0x58,0x7e,0x9,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/icon-1-3.png 0x0,0x0,0x1,0x87, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xfd,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x70,0x49,0x1c,0x3c,0x78,0x90,0x28,0x93,0x1,0x2, 0x88,0x1,0xe4,0x2,0x74,0x7c,0xe0,0xc0,0x81,0xff,0xc4,0x2,0x80,0x0,0x62,0xc1, 0x66,0xb3,0xbd,0xbd,0x3d,0x98,0xdd,0xd8,0xd8,0x8,0x17,0xaf,0xaf,0xaf,0x47,0x51, 0x7,0x93,0x3,0x8,0x20,0x26,0x42,0x9a,0x1d,0x1c,0x1c,0xc0,0x9a,0x91,0xd,0x43, 0x96,0x3,0x8,0x20,0x16,0x6c,0x9a,0x91,0x1,0xd0,0x3b,0x70,0x36,0x23,0x54,0x63, 0x3,0x92,0x1c,0x40,0x0,0x31,0xe1,0xd3,0xdc,0x80,0x66,0xc8,0x7f,0xa0,0x4b,0xfe, 0x43,0xbd,0x2,0x93,0x3,0x8,0x20,0x26,0x7c,0x9a,0x1b,0x90,0xf8,0xb0,0x30,0x0, 0xb9,0x2,0xe4,0x74,0x98,0x1c,0x40,0x0,0x31,0xfe,0x87,0x26,0x4,0x64,0x3f,0x36, 0x40,0x6d,0x43,0x6,0x20,0x8d,0x7,0x80,0x1a,0xd1,0x2d,0x3,0x8,0x20,0x16,0xf4, 0x40,0x1,0x2b,0x40,0x32,0xc,0xe8,0x42,0x6,0x7,0xa0,0x17,0x40,0x9a,0x61,0x7c, 0x64,0x0,0x10,0x40,0x8c,0xd,0xd,0xd,0x28,0x9,0x6,0x66,0x8,0xc8,0x50,0x98, 0x4b,0x40,0x9a,0x80,0x62,0x8c,0xd8,0xd2,0x11,0x40,0x0,0xb1,0xe0,0xb,0x75,0x42, 0x9a,0x41,0x0,0x20,0x80,0x98,0xb0,0x9,0x22,0x1b,0x42,0x8,0x0,0x4,0x10,0x13, 0x7a,0xa,0x43,0xe,0x75,0x42,0xb6,0x83,0x0,0x40,0x0,0x31,0x61,0x4b,0xa6,0xb8, 0xc,0xc5,0x6,0x0,0x2,0x88,0x1,0x57,0x26,0x81,0x66,0x28,0x6,0x42,0x18,0x20, 0xc0,0x0,0x14,0xdf,0xdc,0x6c,0x9,0x64,0xf5,0x51,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00009.png 0x0,0x0,0x0,0xb6, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x68,0x49,0x44,0x41,0x54,0x38,0x8d,0xcd, 0x52,0x41,0xe,0x80,0x30,0xc,0x2,0xe3,0xff,0xbf,0x8c,0x7,0x63,0xe2,0x5a,0xec, 0xea,0xbc,0xc8,0x6d,0x2b,0xd0,0x76,0x83,0xc8,0x50,0x38,0xd3,0x70,0x6c,0x51,0x0, 0x20,0x8d,0x7a,0x92,0x8e,0x9b,0xc,0x14,0x85,0x89,0x78,0x1a,0x25,0x93,0xad,0x54, 0x35,0xc0,0x4e,0xf7,0x6a,0x8a,0xdd,0x10,0x12,0xaa,0x6,0x9f,0x57,0x18,0x26,0xe8, 0xae,0x72,0xc7,0x3f,0x7e,0xe1,0xc2,0x2c,0x48,0x4e,0x63,0xd3,0xf5,0x14,0x65,0x99, 0xbb,0x3a,0xe7,0x13,0x73,0xff,0x28,0x6f,0x4d,0x56,0xc,0xa2,0xc9,0x32,0x4,0x0, 0x7,0xc6,0x58,0x21,0x14,0x85,0xdf,0x14,0x1b,0x0,0x0,0x0,0x0,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/icon-1-4.png 0x0,0x0,0x1,0x5b, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd1,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x3c,0x70,0xe0,0xc0, 0x7f,0x6,0xa,0x0,0x40,0x0,0xb1,0x80,0x8,0x7b,0x7b,0x7b,0xb2,0xd,0x0,0x8, 0x20,0x16,0x64,0x4e,0x63,0x63,0x23,0x9c,0x5d,0x5f,0x5f,0x8f,0xa1,0x18,0x9b,0x3c, 0x40,0x0,0x31,0xa1,0x4b,0x3a,0x38,0x38,0x80,0x25,0x91,0x15,0xe3,0x93,0x7,0x8, 0x20,0x16,0x74,0x5b,0x80,0x61,0x2,0x67,0x33,0x22,0x19,0xd2,0x80,0x45,0x1e,0x4, 0x0,0x2,0x88,0x5,0x9b,0xbf,0x60,0x8a,0xfe,0x23,0x79,0x3,0xd9,0x45,0xc8,0x86, 0x0,0x4,0x10,0x13,0x2e,0x3f,0xa3,0xf3,0x1b,0xd0,0x2c,0x81,0xc9,0x3,0x4,0x10, 0xc8,0xb4,0xff,0xc8,0x80,0xa1,0xa1,0xe1,0x3f,0x3a,0xc0,0x26,0x6,0x3,0x0,0x1, 0xc4,0x44,0x28,0x9a,0x40,0xe1,0xf0,0x1f,0x4b,0x8c,0xc0,0x0,0x40,0x0,0xb1,0x10, 0xa3,0xf9,0xe0,0xc1,0x83,0x38,0xd5,0x0,0x4,0x10,0x46,0x3a,0x68,0x40,0xa2,0x91, 0x6d,0x6,0x26,0x36,0x46,0x6c,0x6,0x0,0x4,0x10,0xb,0xb6,0x78,0x6,0xa7,0x4c, 0xb4,0x74,0x80,0xb,0x0,0x4,0x10,0xde,0x74,0x40,0xc,0x0,0x8,0x20,0x26,0x7c, 0xe9,0x80,0x18,0x0,0x10,0x40,0x44,0xa7,0x3,0x5c,0x0,0x20,0x80,0x58,0xc8,0xd1, 0x84,0xc,0x0,0x2,0xc,0x0,0x20,0xbf,0x7e,0xb2,0x45,0xde,0x1f,0x48,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/icon-1-5.png 0x0,0x0,0x1,0x24, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x9a,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0xe,0x1e,0x3c,0x48,0xb6,0x9,0xf6,0xf6,0xf6,0x8c, 0x0,0x1,0xc4,0x2,0x62,0x1c,0x38,0x70,0x0,0xab,0x2,0x7,0x7,0x7,0xbc,0x72, 0x20,0x0,0x10,0x40,0x4c,0xc,0x14,0x2,0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0x62, 0x4,0x3a,0x91,0xa2,0x30,0x0,0x8,0x20,0x16,0x88,0x7f,0xb0,0xfb,0xf3,0xc0,0x1, 0x7,0x6,0x7b,0x7,0x7b,0xac,0x72,0x7,0xf,0x1c,0x4,0xd3,0x0,0x1,0x44,0xb1, 0x17,0x0,0x2,0x88,0x62,0x3,0x0,0x2,0x88,0x5,0xe6,0x54,0x5c,0x0,0xe6,0x54, 0x5c,0x0,0x20,0x80,0x20,0x6,0xe0,0x8,0x3,0x7,0xa0,0xc1,0xf8,0xc2,0x7,0x4, 0x0,0x2,0x88,0x62,0x2f,0x0,0x4,0x10,0xc5,0x6,0x0,0x4,0x10,0xc5,0xe9,0x0, 0x20,0x80,0x18,0x29,0xcd,0x8d,0x0,0x1,0x44,0xb1,0x17,0x0,0x2,0xc,0x0,0xb, 0x95,0x28,0x1d,0x48,0xe7,0x5c,0xd0,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/icon-1-1.png 0x0,0x0,0x1,0x1, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x77,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xcf,0xc0,0x0, 0x44,0x68,0x0,0x53,0x4,0xc,0x18,0xb1,0x48,0x0,0x4,0x10,0x13,0x3,0x85,0x0, 0x20,0x80,0x28,0x36,0x0,0x20,0x80,0x28,0x36,0x0,0x20,0x80,0x28,0x36,0x0,0x20, 0x80,0x28,0x36,0x0,0x20,0x80,0x40,0x1,0xfb,0x1f,0x33,0x12,0xfe,0x33,0x12,0x6b, 0x0,0x40,0x0,0x51,0xec,0x2,0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0xa2,0xd8,0x0, 0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0x62,0xc1,0x1a,0x35, 0x8c,0xd8,0x73,0xc3,0xff,0xff,0xc,0x18,0xb1,0x3,0x10,0x40,0x14,0xbb,0x0,0x20, 0x80,0x28,0x36,0x0,0x20,0x80,0x28,0x36,0x0,0x20,0xc0,0x0,0xb7,0xb3,0xb,0x1b, 0x26,0xf4,0x39,0x27,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00001.png 0x0,0x0,0x1,0xc7, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x3d,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x34,0xe0,0xe,0x0,0x8,0x20,0x16,0x32,0xf5,0x21,0xe7,0x5d,0x46,0x4a,0x1c, 0x0,0x10,0x40,0xe4,0x38,0xe0,0x3f,0x23,0x23,0xc2,0xce,0xff,0x90,0x82,0x84,0x6c, 0x47,0x0,0x4,0x10,0xb,0x39,0x96,0x23,0x17,0x5e,0x50,0x3e,0xd9,0x8e,0x0,0x8, 0x20,0x8a,0xd2,0x0,0x72,0x48,0x90,0xb,0x0,0x2,0x88,0x89,0x12,0xcb,0x61,0x21, 0x1,0x75,0x8,0x59,0x65,0x3a,0x40,0x0,0x31,0x51,0x6a,0x39,0x34,0x1d,0x20,0x3b, 0x82,0x24,0x87,0x0,0x4,0x10,0x59,0xe,0xc0,0x56,0x81,0xc1,0x1c,0x41,0x6a,0x68, 0x0,0x4,0x10,0x13,0x25,0x9,0x10,0x97,0xc3,0x48,0x71,0x4,0x40,0x0,0x31,0x51, 0x62,0x39,0x4c,0xc,0x2d,0x5b,0x92,0xe4,0x8,0x80,0x0,0x62,0xa2,0xc4,0xe7,0x30, 0xcb,0x29,0x69,0x53,0x0,0x4,0x10,0xc5,0x45,0x31,0xb6,0x50,0x21,0x5,0x0,0x4, 0x10,0x31,0xe,0x60,0x44,0xf,0x66,0x62,0x73,0x7,0x31,0x0,0x20,0x80,0x88,0xd, 0x1,0x82,0x8e,0x20,0x37,0x2a,0x0,0x2,0x88,0x94,0x28,0xc0,0xe9,0x8,0x24,0xcb, 0x49,0x2e,0x1a,0x1,0x2,0x88,0xd4,0x34,0x80,0xe1,0x8,0x4a,0x2c,0x7,0x1,0x80, 0x0,0x22,0xa7,0x36,0x4,0x39,0x2,0x5e,0x23,0xe2,0xb2,0x9c,0x58,0x47,0x1,0x4, 0x10,0x23,0x5,0x59,0xe8,0x3f,0x8e,0xf6,0xc0,0x7f,0x52,0xda,0x9,0x0,0x1,0xc4, 0x42,0x41,0xe,0x64,0x24,0x51,0x1c,0x2b,0x0,0x8,0xa0,0x1,0x6f,0x92,0x1,0x4, 0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0,0x8, 0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0,0x2,0x68,0xc0,0x1d,0x0,0x10, 0x60,0x0,0xae,0xad,0x6b,0x42,0x91,0x5,0x45,0xf9,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00002.png 0x0,0x0,0x1,0x94, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xa,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0x51,0xcb,0x1,0xff, 0xa1,0x98,0x64,0x0,0x10,0x40,0xd4,0x70,0xc0,0x7f,0x46,0x46,0x46,0x6,0x10,0x26, 0xc7,0x11,0x0,0x1,0xc4,0x44,0xd,0xcb,0x41,0xa5,0x29,0x8,0x93,0xe3,0x8,0x80, 0x0,0x62,0xa2,0x86,0xe5,0x70,0x1,0x32,0x1c,0x1,0x10,0x40,0x14,0x47,0x1,0xd4, 0x42,0xb2,0x1,0x40,0x0,0x31,0x51,0x31,0xe8,0x19,0x90,0x42,0x84,0x68,0x57,0x1, 0x4,0x10,0x55,0x72,0x1,0xcc,0x11,0xa4,0x5a,0xe,0x2,0x0,0x1,0xc4,0x44,0x8d, 0xb8,0xa7,0x4,0x0,0x4,0x10,0x55,0x42,0x80,0x5c,0xdf,0x83,0x0,0x40,0x0,0x31, 0xd,0xa4,0xef,0x41,0x0,0x20,0x80,0x98,0x6,0xd2,0xf7,0x20,0x0,0x10,0x40,0x4c, 0x3,0x91,0xf5,0x90,0x1,0x40,0x0,0xb1,0x50,0x9a,0xff,0x29,0xf1,0x3d,0x8,0x0, 0x4,0x10,0x13,0xa5,0xd9,0x8f,0x12,0xcb,0x41,0x0,0x20,0x80,0x98,0x6,0xd2,0x72, 0x10,0x0,0x8,0x20,0xa6,0x81,0xb4,0x1c,0x4,0x0,0x2,0x88,0x69,0x20,0x2d,0x7, 0x1,0x80,0x0,0x22,0x35,0x11,0x52,0x2f,0xf9,0x43,0x1,0x40,0x0,0xd,0x78,0x93, 0xc,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77, 0x0,0x40,0x0,0xd,0xb8,0x3,0x0,0x2,0x68,0xc0,0x1d,0x0,0x10,0x60,0x0,0xcd, 0x37,0x44,0x3d,0xf6,0xaf,0xb8,0x50,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00003.png 0x0,0x0,0x1,0x86, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xfc,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0, 0x2,0x68,0xc0,0x1d,0x0,0x10,0x40,0x2c,0x34,0x30,0x13,0xb9,0x68,0x65,0x24,0xa4, 0x18,0x20,0x80,0xa8,0xed,0x80,0xff,0x8c,0x8c,0x8,0x3b,0xff,0x43,0xca,0x79,0xbc, 0x8e,0x0,0x8,0x20,0x26,0x5a,0x59,0x4e,0x2c,0x0,0x8,0xa0,0x1,0x4f,0x3,0x0, 0x1,0xc4,0x44,0x4d,0xdf,0x23,0xd7,0xac,0x50,0x36,0xc1,0x20,0x1,0x8,0x20,0x16, 0x6a,0x5a,0x8e,0xe6,0x8,0xa2,0xe2,0x3,0x20,0x80,0x58,0x68,0x60,0x39,0x49,0x9, 0x1,0x20,0x80,0x98,0x6,0xd2,0x72,0x10,0x0,0x8,0x20,0xa6,0x81,0xb4,0x1c,0x4, 0x0,0x2,0x88,0x69,0x20,0x2d,0x7,0x1,0x80,0x0,0x62,0x1a,0x48,0xcb,0x41,0x0, 0x20,0x80,0x98,0x6,0xd2,0x72,0x10,0x0,0x8,0x20,0xa6,0x81,0xb4,0x1c,0x4,0x0, 0x2,0x88,0xa4,0x28,0xa0,0xb6,0xe5,0x20,0x0,0x10,0x40,0x44,0x97,0x3,0xa4,0x16, 0x30,0xc4,0x2,0x80,0x0,0x22,0xd6,0x1,0x54,0xb5,0x14,0x19,0x0,0x4,0xd0,0x80, 0x57,0x46,0x0,0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd, 0xb8,0x3,0x0,0x2,0x68,0xc0,0x1d,0x0,0x10,0x40,0x3,0xee,0x0,0x80,0x0,0x3, 0x0,0x74,0x64,0x4f,0x47,0x9a,0x77,0x62,0xbf,0x0,0x0,0x0,0x0,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00004.png 0x0,0x0,0x1,0xb6, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x2c,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x44,0x92,0x3,0x18,0x19,0x19,0xff,0x83,0x30,0x35,0x1d,0x0,0x10,0x40,0x2c, 0xa4,0x58,0xe,0xcb,0xb2,0x50,0x36,0x23,0xba,0x3c,0x8c,0x8d,0x2e,0x87,0xf,0x0, 0x4,0x10,0x55,0xa2,0x0,0xe6,0x38,0x18,0x46,0xf,0x25,0x7c,0xa1,0x6,0x10,0x40, 0x2c,0xd4,0xb2,0x1c,0x48,0x33,0x20,0x85,0x0,0x3c,0x94,0x8,0x45,0x19,0x40,0x0, 0xb1,0x50,0xcb,0x72,0xe4,0x60,0x47,0x12,0xc7,0x70,0x1c,0x3a,0x0,0x8,0x20,0x26, 0x4a,0x2c,0x87,0xd2,0x18,0x71,0xe,0xf5,0x39,0x3,0x31,0xc5,0x3c,0x40,0x0,0x91, 0x1d,0x2,0x48,0x9,0x12,0x23,0x1,0x22,0x27,0x58,0x42,0x0,0x20,0x80,0x58,0x88, 0xf5,0x29,0xa9,0x8e,0xc1,0x17,0xec,0xc8,0x0,0x20,0x80,0x58,0x48,0xc8,0x7a,0x24, 0x87,0xc,0x31,0xd9,0x11,0x20,0x80,0x6,0xbc,0x24,0x4,0x8,0xa0,0x1,0x77,0x0, 0x40,0x0,0x31,0x91,0x9a,0xe8,0x88,0x65,0x13,0xb,0x0,0x2,0x68,0xc0,0x43,0x0, 0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0, 0x40,0x0,0x31,0x11,0x48,0x78,0x8c,0xc4,0xe6,0x7f,0x72,0x1,0x40,0x0,0x31,0x11, 0x91,0xfa,0x49,0x76,0x4,0xb1,0x85,0x10,0x8,0x0,0x4,0x10,0x23,0xb1,0x59,0x87, 0x94,0x96,0x10,0x29,0xd,0x12,0x80,0x0,0x1a,0xf0,0x34,0x0,0x10,0x40,0x8c,0x3, 0xdd,0x33,0x2,0x8,0xa0,0x1,0xf,0x1,0x80,0x0,0x1a,0x70,0x7,0x0,0x4,0xd0, 0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0,0x8,0x30, 0x0,0x5f,0x54,0x7b,0x41,0xcf,0x3f,0x72,0xbe,0x0,0x0,0x0,0x0,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/cur/cur00005.png 0x0,0x0,0x1,0xc3, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x20,0x0,0x0,0x0,0x20,0x8,0x6,0x0,0x0,0x0,0x73,0x7a,0x7a,0xf4, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x39,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0xc3,0x40,0x2,0x80,0x0,0x62,0x62,0x18,0x60,0x0,0x10,0x40,0x3,0xee,0x0,0x80, 0x0,0x1a,0x70,0x7,0x0,0x4,0xd0,0x80,0x3b,0x0,0x20,0x80,0x6,0xdc,0x1,0x0, 0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0,0x40,0x0,0xd,0xb8,0x3,0x0, 0x2,0x68,0xc0,0x1d,0x0,0x10,0x40,0x2c,0x84,0x14,0x30,0x32,0x32,0x62,0x2d,0x2a, 0x81,0x25,0x28,0x23,0x29,0x6a,0x70,0x1,0x80,0x0,0x62,0x21,0xc6,0x95,0xc8,0xc5, 0x35,0xd0,0x32,0xc,0x83,0x41,0x7c,0x90,0x23,0xd0,0xd5,0x11,0x3,0x0,0x2,0x88, 0xa4,0x28,0xc0,0x66,0x39,0x9a,0x23,0x48,0x8e,0x2,0x80,0x0,0x62,0x22,0xd1,0x72, 0x9c,0xc1,0xd,0xb,0x1,0x52,0x1d,0x1,0x10,0x40,0x4c,0xa4,0xf8,0x1c,0x97,0x23, 0x90,0x2d,0x27,0x35,0x24,0x0,0x2,0x88,0x89,0xc8,0x34,0xc0,0x88,0x1c,0xcc,0xc8, 0x8e,0x40,0xb7,0x9c,0xd8,0xc4,0x7,0x3,0x0,0x1,0xc4,0x48,0x4e,0x7b,0x0,0x6a, 0x29,0x23,0x2e,0x3e,0x29,0x0,0x20,0x80,0x18,0x7,0xba,0x41,0x2,0x10,0x40,0x64, 0x15,0x44,0xd8,0xd2,0x0,0xb9,0xe,0x0,0x8,0x20,0x26,0x72,0x2c,0xc3,0x91,0x6, 0xc8,0x72,0x14,0x40,0x0,0x31,0x91,0xe2,0x63,0x5c,0x9,0xe,0x5b,0xc2,0x24,0x36, 0x4,0x0,0x2,0x88,0xd8,0x5c,0x80,0xd5,0x72,0xf4,0x42,0x8,0x59,0x1d,0xb1,0x0, 0x20,0x80,0x88,0x4e,0x3,0xb8,0x2c,0xc7,0xe6,0x8,0x52,0x0,0x40,0x0,0x91,0x94, 0x8,0x89,0x29,0x9,0x49,0x5,0x0,0x1,0xc4,0x42,0x6c,0x49,0x48,0xa8,0x1c,0x20, 0xa5,0x2,0x42,0x6,0x0,0x1,0x34,0xe0,0xe5,0x0,0x40,0x0,0xd,0x78,0x83,0x4, 0x20,0x80,0x6,0xdc,0x1,0x0,0x1,0x34,0xe0,0xe,0x0,0x8,0xa0,0x1,0x77,0x0, 0x40,0x0,0xd,0xb8,0x3,0x0,0x2,0x68,0xc0,0x1d,0x0,0x10,0x60,0x0,0x52,0x4, 0xa4,0x47,0x89,0x78,0x1c,0xe3,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-5.png 0x0,0x0,0x1,0x4d, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc3,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8c,0x8c,0x8c,0x70,0xd3,0x80,0x6,0x33, 0x12,0x63,0x0,0x40,0x0,0x31,0x21,0x6b,0xfe,0xcf,0x80,0x80,0xc8,0x86,0xe1,0x3, 0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20,0x26,0x64,0x27,0x33,0x32,0x30,0x32, 0x34,0x2,0x21,0x88,0x46,0xf2,0xc2,0x7f,0x7c,0x18,0x20,0x80,0x58,0x90,0xbd,0xd0, 0xc0,0xd0,0x0,0x66,0xc3,0xe8,0xc6,0xc6,0xc6,0xff,0xf5,0xf5,0xf5,0x20,0x1a,0xab, 0xed,0x20,0x39,0x80,0x0,0x62,0x41,0xf,0x3c,0x1c,0xa,0x31,0x2,0x14,0x64,0x38, 0x88,0x6,0x8,0x20,0x26,0x70,0xe0,0x11,0x19,0xe2,0xd8,0x0,0x40,0x0,0xb1,0x20, 0x6b,0x86,0x39,0x1d,0x6c,0x2b,0x10,0x12,0x3,0x0,0x2,0x88,0x9,0x3d,0xde,0x49, 0x75,0xd,0x40,0x0,0x51,0x1c,0x8d,0x0,0x1,0xc4,0x84,0x2d,0x15,0x92,0x2,0x0, 0x2,0x88,0x89,0x12,0xcd,0x20,0x0,0x10,0x40,0x2c,0xd8,0xfc,0x4d,0x4a,0x38,0x0, 0x4,0x10,0xb,0x91,0xea,0xfe,0x63,0x4b,0x44,0x20,0x0,0x10,0x40,0x4,0xd,0xc0, 0x95,0xa,0x61,0x9,0xc,0x20,0xc0,0x0,0x18,0xc6,0x49,0x9b,0x6d,0x5f,0x0,0xf4, 0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-4.png 0x0,0x0,0x1,0x51, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc7,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x88,0x51,0xd4,0xc8,0xc8,0x88,0xd5,0x96,0xfa,0xff, 0xff,0x19,0x1,0x2,0x88,0x89,0x81,0x42,0x0,0x10,0x40,0x14,0x1b,0x0,0x10,0x40, 0x18,0x5e,0x60,0xc4,0xe1,0x5c,0x18,0x68,0x40,0xe3,0x3,0x4,0x10,0x86,0x1,0xc0, 0x40,0x65,0x4,0x19,0x82,0x2d,0x70,0x81,0xe2,0x18,0x62,0x0,0x1,0x84,0xd5,0xb, 0xd,0xd,0xd,0x58,0x15,0x63,0x3,0x0,0x1,0xc4,0x4,0x73,0x76,0x63,0x63,0x23, 0xd8,0x4a,0x10,0xd,0x32,0x80,0xd8,0xe8,0x5,0x8,0x20,0xb0,0x42,0xa0,0x86,0xff, 0x10,0xd7,0xff,0x87,0xa,0x61,0x7,0x30,0x35,0xc8,0x18,0x20,0x80,0x10,0xc,0xa0, 0x24,0xc8,0x20,0x6c,0x86,0xc0,0xf8,0xd8,0xc,0x0,0x8,0x20,0x38,0x3,0xd9,0x15, 0xc8,0x86,0xc0,0xc,0x6,0xd1,0xd8,0xc,0x0,0x8,0x20,0x54,0xe,0x92,0x2b,0x70, 0xf1,0xd1,0xd,0x0,0x8,0x20,0x14,0xe,0xba,0x2b,0x88,0xc1,0x0,0x1,0x84,0x29, 0x80,0x66,0x2b,0x21,0xc,0x10,0x40,0x8c,0xe8,0xd1,0x5,0x4b,0x89,0xa0,0x4,0x45, 0x4c,0x2c,0x2,0x4,0x10,0x23,0xa5,0xd9,0x19,0x20,0xc0,0x0,0xda,0x7f,0x29,0xad, 0xde,0x4,0x3f,0x86,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-9.png 0x0,0x0,0x1,0x57, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xcd,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x82,0xcc,0x69,0x6c, 0x6c,0x7c,0x88,0xcc,0xaf,0xaf,0xaf,0x97,0x27,0x64,0x0,0x40,0x0,0x31,0x80,0xbc, 0x0,0xc2,0xd,0xd,0xd,0xf,0x21,0xcc,0xff,0x50,0xa1,0xff,0xf,0x21,0x62,0xff, 0x19,0xf0,0x61,0x80,0x0,0x62,0x4,0x11,0x20,0x9b,0xeb,0xeb,0x1b,0xe4,0x18,0x18, 0x40,0xe1,0xc1,0xc8,0x80,0x44,0x3f,0x2,0xca,0x61,0xb5,0x18,0xe6,0x3a,0x80,0x0, 0x82,0xd9,0xfe,0x1f,0x3f,0x40,0x71,0xd9,0x7f,0x90,0xcb,0x80,0x7a,0xc1,0xae,0x3, 0x8,0x20,0xa4,0x40,0x64,0xc4,0x43,0xa3,0xbb,0x8c,0x41,0xe,0x8a,0x19,0x0,0x2, 0x8,0xc9,0x80,0xff,0x38,0x14,0x63,0xa3,0x11,0x0,0x20,0x80,0xd0,0x5c,0x40,0xac, 0x21,0x8,0x0,0x10,0x40,0x14,0xbb,0x0,0x20,0x80,0x28,0x76,0x1,0x40,0x0,0x51, 0xec,0x2,0x80,0x0,0x82,0xa7,0x3,0x28,0x5f,0x8e,0xd8,0x24,0xc,0x8c,0x4a,0x50, 0x9c,0x32,0x2,0x4,0x10,0x23,0x2c,0x33,0x31,0x32,0x32,0x3e,0x24,0x35,0x1f,0x0, 0xf5,0xca,0x3,0x4,0x10,0x23,0xa5,0xb9,0x11,0x20,0x80,0x28,0xce,0x8d,0x0,0x1, 0x6,0x0,0xa3,0x54,0xad,0x53,0x19,0x46,0x2,0xbd,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-19.png 0x0,0x0,0x1,0x50, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc6,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x48,0x51,0xcc,0xc8,0xc0,0xf8,0x1f,0x84,0x91,0xc5, 0x0,0x2,0x88,0x68,0x3,0x18,0x1b,0x19,0xb1,0x3a,0x15,0x20,0x80,0x58,0xc0,0x92, 0x8c,0x8c,0x38,0xfd,0x1,0xf4,0x22,0x23,0x3e,0x83,0x1,0x2,0x88,0x11,0x14,0x6, 0x20,0x3,0x70,0x84,0x5,0x23,0xba,0x93,0xd1,0x1,0x40,0x0,0x31,0xa1,0xaa,0x66, 0x84,0x63,0x30,0xb7,0x91,0x91,0x60,0x8,0x3,0x4,0x10,0xb,0x9a,0x73,0x31,0x55, 0x34,0x22,0xb1,0xeb,0x51,0xc5,0xfe,0xd7,0xff,0x67,0x4,0x8,0x20,0x98,0xa6,0xff, 0x50,0x3f,0xc0,0x31,0x88,0x8b,0x8c,0x19,0x1a,0x80,0xe2,0x50,0x88,0x2c,0xe,0x10, 0x40,0xf8,0x5c,0xf0,0x1f,0x25,0x6,0x71,0x0,0x80,0x0,0xc2,0x19,0x6,0x68,0xe1, 0x1,0x77,0x3a,0xd0,0x5e,0x14,0xc3,0x0,0x2,0x88,0x50,0x2c,0x10,0x74,0x1,0x40, 0x0,0xb1,0xa0,0xbb,0x0,0x77,0x72,0x0,0x5b,0x84,0x91,0x2e,0x0,0x2,0x88,0x70, 0x2c,0x10,0x0,0x0,0x1,0x44,0xac,0xb,0x70,0x1a,0xe,0x10,0x40,0x14,0xbb,0x0, 0x20,0x80,0x58,0x88,0xb1,0x1d,0x1f,0x0,0x8,0x30,0x0,0xed,0x42,0x5e,0x17,0x5f, 0xdd,0xc2,0x9a,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-7-5.png 0x0,0x0,0x2,0x5d, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xd3,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x85,0x81,0x81,0x1,0x84,0x59,0x81,0x98,0x1d,0x4a,0x33,0x33,0x40,0xc0,0x3f,0x20, 0xfe,0xb,0xc5,0xff,0xd1,0x30,0x48,0xec,0xf,0x40,0x0,0xb1,0x40,0x15,0x83,0x34, 0x72,0x2,0x31,0x37,0x10,0x73,0xa0,0x19,0xf0,0x7,0xc9,0x10,0x64,0x43,0x7f,0x1, 0xf1,0x4f,0x80,0x0,0x2,0x19,0xc0,0x6,0xd5,0xc4,0xb,0xc4,0xfc,0x40,0xcc,0x5, 0x75,0x5,0x3,0x54,0xe1,0x6f,0x24,0x1b,0xff,0x43,0xd,0x0,0x69,0xfe,0x6,0xc4, 0x4c,0x0,0x1,0x4,0x33,0x0,0x64,0x33,0x7f,0xbf,0xb7,0xdd,0x69,0x6,0x2c,0x0, 0xe8,0xcd,0x50,0xa8,0x46,0x26,0xa0,0x9a,0xd5,0x50,0x31,0x6b,0x20,0xf5,0x1e,0x20, 0x80,0x60,0x5e,0x0,0x19,0xc2,0x9,0x14,0xc,0x3,0x2a,0x58,0x5,0xa4,0x53,0x91, 0x5c,0xf0,0x17,0xa4,0x9,0x28,0x96,0x2,0xa4,0xe7,0x40,0xe5,0xbe,0x2,0xd9,0x47, 0x81,0x6c,0x63,0x80,0x0,0x62,0x82,0x6a,0x6,0x87,0x1,0x54,0x73,0x6,0xd4,0x4b, 0xec,0x50,0x39,0x98,0x77,0xd8,0x80,0x72,0xb9,0x20,0x1a,0xa8,0x6e,0x19,0x90,0xed, 0xd,0xb2,0x1c,0x20,0x80,0x90,0x63,0x80,0x3,0xaa,0x90,0x1d,0x2a,0xf6,0xf,0x8a, 0x19,0xa1,0xe2,0xe0,0xd0,0x7,0x6a,0x9e,0xa,0xd4,0x1c,0xf,0x13,0x3,0x8,0x20, 0x98,0x17,0x58,0xa1,0xb6,0x31,0x20,0x45,0x23,0x38,0xb0,0x80,0x1a,0x66,0x3,0x35, 0x24,0x43,0x35,0xcf,0x3,0x29,0x0,0xd2,0xb,0xa1,0xe1,0x60,0x4,0x10,0x40,0x30, 0x17,0xc0,0x30,0x48,0xb2,0x7,0x2d,0x0,0x23,0x41,0xd1,0x5,0xc2,0x40,0xb6,0x3b, 0x34,0x5c,0x40,0xfc,0xaf,0x40,0xfc,0x11,0x20,0x80,0x58,0xa0,0xd1,0xc6,0xe,0xd4, 0xb8,0x1c,0xa8,0x20,0x7,0x6a,0x10,0x28,0xb4,0xfb,0x80,0xfc,0x44,0x24,0xc5,0x5f, 0x80,0xf8,0x3b,0x34,0x5d,0x80,0xa2,0xf1,0x7,0x88,0xf,0x10,0x40,0x2c,0x68,0x1, 0xf5,0x13,0x1a,0xef,0x30,0x7f,0xff,0x80,0x2a,0xfe,0xe,0x8d,0xf7,0xcf,0x48,0x6a, 0xc0,0x6,0x1,0x4,0x10,0x13,0xd4,0xbf,0x30,0xd,0x20,0x5b,0x3e,0x81,0x9c,0x6, 0xb4,0x3d,0x1c,0xe4,0x2a,0xa8,0x6,0x64,0x43,0xbe,0x40,0x31,0xc8,0x55,0x3f,0x1, 0x2,0x8,0xe4,0x2,0x46,0xa0,0xc2,0xad,0x40,0xd,0xfe,0x50,0x93,0xff,0x42,0x3, 0x10,0x6,0xbe,0xc1,0xc2,0x0,0x8a,0xbf,0x43,0xd5,0x81,0xd5,0x0,0x4,0x10,0x23, 0x34,0x7a,0x60,0x1,0x66,0x5,0xb5,0xd,0x96,0xee,0x41,0x86,0x9f,0x83,0xca,0x29, 0x40,0x6d,0xfe,0x86,0xac,0x6,0x20,0x80,0x18,0x81,0x12,0x5a,0xd0,0x70,0xf8,0x87, 0xe4,0x3f,0x98,0x1,0x30,0xef,0xfd,0x85,0xda,0xfc,0x3,0x8a,0xe1,0x2e,0x0,0x8, 0x20,0x16,0xa8,0x9f,0x59,0x90,0x32,0xce,0x1f,0x24,0x57,0x31,0x23,0xb9,0xf2,0x17, 0x92,0x46,0xb8,0xab,0x1,0x2,0xc,0x0,0x7a,0xaf,0xc0,0x76,0x61,0x4a,0xa9,0x1b, 0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-4.png 0x0,0x0,0x2,0x4e, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xc4,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x48, 0x8a,0x81,0x81,0x41,0x4,0x88,0x25,0x81,0x58,0x2,0xca,0xe6,0x61,0x80,0x80,0x2f, 0x40,0xfc,0x6,0x88,0x5f,0x0,0xf1,0x73,0x28,0xfb,0x33,0x10,0x7f,0x7,0xe2,0x3f, 0x20,0x5,0x0,0x1,0xc4,0x2,0xd5,0xa0,0x8,0xc4,0x6a,0x40,0xac,0xd4,0xef,0x6d, 0x97,0xc1,0x80,0x4,0x80,0x16,0xcc,0x0,0x52,0xf7,0x80,0x98,0x3,0x2a,0xf4,0x17, 0x9,0xff,0x7,0x8,0x20,0x26,0xa8,0xcd,0x6a,0xfc,0xa7,0xf7,0x75,0x81,0x34,0xff, 0xff,0xff,0x9f,0x1,0x19,0x83,0xc4,0x40,0x72,0x50,0xb,0x40,0x6a,0xf9,0x81,0x98, 0xd,0x88,0x41,0x7a,0x19,0x0,0x2,0x88,0x5,0xea,0x6c,0xa5,0x86,0x86,0x6,0xb0, 0x6,0x74,0x0,0x12,0x63,0x64,0x64,0x4,0xba,0xc4,0x49,0x9,0xc8,0x7d,0x5,0xc4, 0x6f,0x81,0xf8,0x23,0x10,0x7f,0x3,0xb9,0x2,0x20,0x80,0x40,0xa6,0x88,0xc0,0x6c, 0xc6,0x5,0x60,0x2e,0x81,0x7a,0x97,0x17,0x88,0xd9,0x61,0x2e,0x0,0x8,0x20,0x16, 0xa4,0x0,0x3,0xdb,0x84,0xcb,0x0,0x28,0x0,0x39,0x9f,0x13,0x88,0x59,0x61,0x6, 0x0,0x4,0x10,0x13,0x3,0x69,0x80,0x13,0x1a,0x98,0x20,0x3,0x98,0x41,0x2,0x0, 0x1,0xc4,0x2,0x8d,0x2a,0x74,0x9b,0x70,0x1,0x36,0xa8,0xf3,0xd9,0xa0,0x7a,0x99, 0x1,0x2,0x8,0xe4,0x82,0x37,0xa0,0xa8,0xc2,0xe5,0x7c,0x98,0xd7,0x80,0x6a,0xe, 0x40,0x6d,0xe6,0x82,0x7a,0x1b,0xe4,0x1a,0x36,0x80,0x0,0x62,0x82,0x26,0x92,0x7b, 0xa0,0x58,0xc0,0x66,0x8,0x4c,0xc,0x18,0x88,0xe,0x50,0xdb,0x41,0xe1,0x20,0x4, 0xc4,0x82,0x40,0xcc,0xd,0x10,0x40,0x4c,0xd0,0x14,0x76,0xeb,0xa3,0xa9,0x53,0x19, 0xcc,0x25,0xc8,0x18,0x6a,0x33,0xcc,0x90,0x24,0xa8,0x46,0x9,0x28,0x16,0x6,0x8, 0x20,0x46,0x1c,0x49,0x19,0x16,0xda,0x6c,0x50,0x67,0xb3,0x43,0x35,0xc3,0x52,0x67, 0x25,0x90,0x7a,0xc,0xc4,0xf,0x0,0x2,0x88,0x9,0x9a,0xb6,0x5f,0x2,0xf1,0x7d, 0x20,0xbe,0xa,0xc4,0xe7,0x80,0xf8,0x4,0x10,0x1f,0x87,0xd2,0x67,0x41,0xe2,0x40, 0x4d,0x2d,0x48,0x2e,0x69,0x7,0x52,0x2,0x20,0xd7,0x0,0x4,0x10,0x13,0x34,0x63, 0x7c,0x86,0xa6,0x32,0x90,0xa9,0x77,0x81,0xf8,0x26,0x10,0x5f,0x83,0x1a,0x78,0x1d, 0xe4,0x45,0x20,0x7e,0x8,0xb5,0x19,0x66,0xc8,0x14,0x90,0x2b,0x1,0x2,0x8,0xe4, 0x5,0x70,0x58,0x41,0xd3,0x4,0x33,0x94,0x86,0xb1,0x59,0xa0,0x5e,0x41,0xf6,0xb7, 0x0,0x54,0x33,0x18,0x0,0x4,0x10,0x2c,0x21,0xfd,0x87,0xe6,0xae,0x5f,0x40,0xfc, 0x3,0x9a,0xce,0x41,0xae,0xfa,0x4,0xc4,0xef,0xa1,0x5e,0x7c,0x2,0xf2,0x33,0xd4, 0x25,0x61,0xd0,0xb0,0x70,0x1,0x8,0x30,0x0,0x10,0x96,0x91,0x99,0x29,0xe6,0xd6, 0x25,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-15.png 0x0,0x0,0x1,0x24, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x9a,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0x11,0x52,0xc8,0xc8,0xc8,0x8,0xc6,0xb8,0x0,0x40,0x0,0xb1,0x10,0xd2,0xdc,0xd0, 0xd0,0x0,0x67,0x63,0xb,0x2f,0x80,0x0,0x62,0x21,0xc2,0x9f,0x38,0x35,0x83,0x0, 0x40,0x0,0x31,0xe1,0xb3,0x9d,0x98,0x18,0x2,0x8,0x20,0xa2,0xc2,0x0,0x9f,0x41, 0x0,0x1,0xc4,0x44,0x89,0xed,0x20,0x0,0x10,0x40,0x4c,0x94,0xd8,0xe,0x2,0x0, 0x1,0x84,0x37,0xc,0x88,0x1,0x0,0x1,0x84,0xd7,0x5,0xc4,0x78,0x3,0x20,0x80, 0x98,0x28,0xd1,0xc,0x2,0x0,0x1,0xc4,0x44,0x89,0x66,0x10,0x0,0x8,0x20,0x16, 0xf4,0xb4,0x4d,0x2a,0x0,0x8,0x20,0x46,0x4a,0xb3,0x33,0x40,0x80,0x1,0x0,0x90, 0xd3,0x2c,0xa6,0x24,0x2b,0x68,0x0,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-9.png 0x0,0x0,0x1,0x3d, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xb3,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x1e,0x0,0x92,0x64,0xc4,0xa7,0x0,0x20,0x80,0x58,0xf0,0x68,0x44,0x67,0x63, 0x35,0x8,0x20,0x80,0x98,0x70,0x18,0xc0,0xd8,0xd8,0xd8,0x8,0x66,0x80,0x68,0x18, 0x1b,0x1b,0x0,0x8,0x20,0x6,0x90,0x17,0xf0,0xe0,0xff,0xd,0xd,0xd,0xff,0xf1, 0xa9,0x1,0x8,0x20,0x26,0x6,0xfc,0x80,0x91,0x80,0x3c,0x3,0x40,0x0,0x31,0x12, 0x8,0x44,0x82,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xc8,0x0,0x82, 0xce,0x3,0x8,0x20,0x82,0x2e,0x0,0xc6,0x0,0x5e,0x43,0x0,0x2,0x88,0x89,0x44, 0x1b,0x31,0xe4,0x1,0x2,0x88,0x9,0x4b,0xa8,0xe3,0x32,0xe4,0x3f,0xb6,0xf4,0x0, 0x10,0x40,0x4c,0x58,0x9c,0x8c,0xcd,0x26,0xb0,0xe6,0xfa,0xfa,0x7a,0x8c,0x68,0x5, 0x8,0x20,0xac,0x89,0x3,0x9a,0x78,0xe0,0x0,0x5f,0x62,0x2,0x8,0x20,0x9c,0x29, 0xc,0x66,0x8,0xa1,0x94,0x8,0x10,0x40,0x78,0x93,0x32,0x21,0xcd,0x20,0xc,0x10, 0x40,0x14,0xa7,0x44,0x80,0x0,0x3,0x0,0x16,0x71,0xe1,0x63,0xc4,0xa9,0xe4,0x72, 0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-2.png 0x0,0x0,0x1,0x5c, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd2,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x0,0xb9,0xa0,0xa1,0xa1,0xe1,0x3f,0x8,0x1c,0x38, 0x70,0x0,0xc4,0xfd,0xf,0xe3,0xc3,0x0,0x48,0x9c,0x1,0x49,0x1c,0x4a,0x83,0xf5, 0x2,0x4,0x10,0xb,0xcc,0xc4,0x83,0x7,0xf,0xa2,0xd8,0x80,0xce,0xc7,0x25,0xe, 0x10,0x40,0x8,0x17,0x30,0x30,0x10,0x8d,0x91,0x5d,0x0,0x10,0x40,0x70,0x17,0x34, 0x36,0x34,0x40,0xfd,0xd6,0x0,0xc,0x93,0x6,0xc,0x9b,0x1b,0x80,0xe2,0xd,0x58, 0xc4,0x1,0x2,0x88,0x5,0x29,0x50,0x50,0x9c,0x7,0xe2,0x63,0x73,0x36,0x48,0x1c, 0x18,0xe8,0x70,0x3e,0x40,0x0,0x31,0x31,0x50,0x8,0x0,0x2,0x88,0x62,0x3,0x0, 0x2,0x8,0x6b,0x2c,0x38,0x38,0x38,0x10,0x1d,0xb,0x0,0x1,0x4,0x8f,0x5,0x58, 0x20,0x83,0x2,0x17,0x6b,0xe0,0x23,0x89,0x23,0xc7,0x2,0x40,0x0,0xc1,0x5d,0xd0, 0xd0,0x80,0x8,0x18,0x64,0x36,0x5c,0xc,0x87,0x38,0x40,0x0,0x51,0x1c,0xb,0x0, 0x1,0xc4,0x8,0x72,0x6,0x25,0x79,0x1,0x20,0x80,0x18,0x29,0xcd,0x8d,0x0,0x1, 0x44,0x71,0x34,0x2,0x4,0x18,0x0,0x6a,0xb7,0xbc,0x8,0xb8,0x1e,0x95,0x1c,0x0, 0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-8.png 0x0,0x0,0x1,0x2a, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa0,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x82,0xcc,0x69,0x6c, 0x6c,0x24,0xd9,0x39,0x0,0x1,0xc4,0x0,0xf2,0x2,0x8,0x37,0x34,0x34,0xc0,0x98, 0x60,0x4c,0x1c,0xff,0x3f,0x3,0x40,0x0,0x51,0xa4,0x19,0x84,0x1,0x2,0x88,0x91, 0xd2,0x40,0x4,0x8,0x20,0x26,0x46,0x46,0x46,0xb2,0x4c,0x80,0xe9,0x3,0x8,0x20, 0xb0,0xb,0xb0,0x19,0x2,0x14,0x67,0x44,0x57,0x8c,0x4d,0x1e,0x20,0x80,0x70,0x7a, 0x1,0xa4,0x9,0xa4,0x8,0x46,0xe3,0x72,0x9,0x40,0x0,0xe1,0xd,0x3,0x42,0x9a, 0x41,0x0,0x20,0x80,0x28,0xe,0x44,0x80,0x0,0x62,0xa1,0x24,0x11,0xd5,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xd6,0x74,0x40,0xc,0x86,0xa5,0x5,0x80,0x0,0xa2,0x48,0x33, 0x8,0x3,0x4,0x10,0xb,0xc4,0xf9,0xd,0xa4,0x3b,0x1d,0xa,0x0,0x2,0x88,0xe2, 0x40,0x4,0x8,0x30,0x0,0x43,0x72,0xed,0xe1,0x2c,0xc5,0x5a,0xfe,0x0,0x0,0x0, 0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-15.png 0x0,0x0,0x1,0x10, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x86,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x40,0x4,0x23,0x23,0xc3,0x7f,0x10,0x6,0xb3,0x19, 0x18,0xff,0x83,0x30,0x44,0x1a,0x44,0x33,0x62,0x88,0x23,0xab,0x7,0x8,0x20,0x26, 0x6,0xa,0x1,0x40,0x0,0x31,0x52,0xea,0x5,0x80,0x0,0x62,0xc2,0xe7,0x6c,0xa0, 0x5b,0xff,0x83,0x31,0x1e,0xef,0x0,0x4,0x10,0xc5,0x5e,0x0,0x8,0x20,0x8a,0xbd, 0x0,0x10,0x40,0x4c,0x78,0x9d,0xd,0xa,0x69,0x68,0x68,0xe3,0xf2,0xe,0x40,0x0, 0x51,0xec,0x5,0x80,0x0,0xa2,0xd8,0xb,0x0,0x1,0x44,0x71,0x2c,0x0,0x4,0x10, 0xc5,0x5e,0x0,0x8,0x20,0x8a,0xbd,0x0,0x10,0x40,0x14,0xe7,0x5,0x80,0x0,0xa2, 0xd8,0xb,0x0,0x1,0x44,0xb1,0x17,0x0,0x2,0xc,0x0,0xb6,0x7a,0x44,0x29,0x87, 0x6d,0x4a,0x3b,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-3.png 0x0,0x0,0x1,0x5c, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd2,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x20,0x14,0xe3,0x7f,0xec,0x34,0xc,0xe0,0x96,0x7, 0x8,0x20,0x46,0x5c,0x2e,0x60,0x64,0x44,0x28,0x2,0xaa,0x61,0xc4,0xe5,0x2,0x80, 0x0,0xc2,0xea,0x2,0x90,0xe6,0xff,0xc,0x8,0x88,0x30,0xc,0xd3,0x5,0x0,0x1, 0x4,0x35,0x0,0x66,0x3,0x6e,0x9b,0x70,0xa9,0x3,0x8,0x20,0xac,0x2e,0x0,0x39, 0x99,0x91,0x81,0x91,0xa1,0x11,0x8,0x41,0x34,0xc2,0xb,0x98,0x2e,0x0,0x8,0x20, 0xac,0x61,0x0,0x72,0x72,0x3,0x43,0x3,0x9c,0xf,0x62,0xe3,0xa,0x7,0x80,0x0, 0x62,0xc2,0x30,0x91,0x91,0xf1,0x3f,0xa1,0x40,0x45,0x56,0xf,0x10,0x40,0x28,0x61, 0x0,0xe,0x3c,0x1c,0x36,0x81,0xbd,0x5,0x37,0x4,0xa1,0x6,0x20,0x80,0x98,0xd0, 0xfd,0x8e,0x37,0x8,0x31,0xc2,0x82,0x81,0x1,0x20,0x80,0x70,0x86,0x1,0x6e,0xcd, 0xa8,0x0,0x20,0x80,0x70,0xc6,0x2,0x36,0x1a,0x5b,0x2c,0x0,0x4,0x10,0xc5,0xe9, 0x0,0x20,0x80,0x70,0xa6,0x44,0xec,0x5e,0xc2,0x74,0x1,0x40,0x0,0x61,0xb8,0x0, 0x7f,0x34,0x62,0xba,0x0,0x20,0x80,0xa0,0x81,0x8,0x93,0x44,0x56,0xc4,0xc0,0x80, 0x9b,0x8f,0x10,0x7,0x8,0x30,0x0,0xae,0x19,0x7b,0xf,0xd3,0xa,0x4a,0xbe,0x0, 0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-16.png 0x0,0x0,0x1,0x24, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x9a,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0x11,0x52,0x78,0xf0,0xe0,0x41,0x30,0xc6,0x5,0x0,0x2,0x88,0x89,0x90,0x66,0x6c, 0x6c,0x64,0x0,0x10,0x40,0x4,0x5d,0x60,0x6f,0x6f,0x8f,0x42,0xa3,0x3,0x80,0x0, 0x62,0xc2,0x67,0x3b,0x2e,0x4d,0xc8,0x0,0x20,0x80,0x88,0xa,0x3,0x7c,0x6,0x1, 0x4,0x10,0x13,0x25,0xb6,0x83,0x0,0x40,0x0,0x31,0x51,0x62,0x3b,0x8,0x0,0x4, 0x10,0x13,0x31,0x31,0x80,0xf,0x0,0x4,0x10,0x13,0x31,0x31,0x80,0xf,0x0,0x4, 0x10,0x13,0x25,0x9a,0x41,0x0,0x20,0x80,0x98,0x28,0xd1,0xc,0x2,0x0,0x1,0xc4, 0x82,0x9e,0xb6,0x49,0x5,0x0,0x1,0xc4,0x48,0x69,0x76,0x6,0x8,0x30,0x0,0x1c, 0xc,0x29,0xa2,0x83,0x80,0x88,0x54,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-2.png 0x0,0x0,0x1,0x72, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xe8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8c,0x8c,0x8c,0x70,0xd3,0x80,0x6,0x33, 0x12,0x63,0x0,0x40,0x0,0x31,0x21,0x6b,0xfe,0xcf,0x80,0x80,0xc8,0x86,0xe1,0x3, 0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20,0x26,0x64,0x27,0x33,0x32,0x30,0x32, 0x34,0x2,0x21,0x88,0xc6,0xe2,0x85,0xff,0x48,0x18,0xe,0x0,0x2,0x8,0xc5,0xb, 0xd,0xc,0xd,0x60,0x36,0x88,0xc6,0xe6,0x85,0xc6,0xc6,0x46,0xc,0x17,0x0,0x4, 0x10,0x13,0x7a,0xe0,0x61,0xb,0x54,0xa0,0x46,0x9c,0xe1,0x1,0x10,0x40,0x4c,0xe0, 0xc0,0xc3,0x12,0xe2,0xd,0xd,0xd,0x44,0xc5,0x4,0x40,0x0,0x81,0x14,0x31,0x40, 0xd3,0x2,0xdc,0x8f,0x30,0xb1,0xff,0x68,0x0,0x68,0x28,0xba,0xd0,0x7f,0x80,0x0, 0x62,0x44,0x4e,0x48,0xc8,0xae,0x1,0x39,0xbb,0xbe,0xbe,0x1e,0xab,0xbf,0x61,0x0, 0x24,0xf,0x10,0x40,0xc,0x48,0xb6,0x31,0x20,0xdb,0x8e,0xcd,0x36,0x6c,0x62,0x0, 0x1,0xc4,0x82,0x2d,0x15,0x62,0xb,0x75,0xb0,0x6d,0x68,0xe2,0x40,0x31,0x46,0x80, 0x0,0xc2,0xe7,0x7f,0x6,0x74,0xd7,0x20,0xb9,0x0,0x2e,0x7,0x10,0x40,0x2c,0xa4, 0xa4,0x7b,0x6c,0x0,0x20,0x80,0x48,0x4a,0xca,0xc8,0xde,0x80,0x1,0x80,0x0,0x22, 0xda,0x0,0x90,0xbf,0xa1,0x7e,0x47,0x71,0x2d,0x40,0x80,0x1,0x0,0x43,0xed,0xd9, 0x1b,0xad,0xe9,0x68,0x40,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-5-8.png 0x0,0x0,0x2,0x60, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xd6,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x99,0x81,0x81,0x81,0x1d,0x88,0x39,0x81,0x98,0x17,0x88,0x5,0x81,0x98,0xb,0x88, 0x59,0x19,0x20,0xe0,0x3b,0x10,0x7f,0x0,0xe2,0x4f,0x40,0xfc,0x5,0xca,0xff,0x3, 0x95,0x63,0x0,0x8,0x20,0x16,0x20,0x6,0x19,0xc0,0x6,0xc4,0xdc,0x40,0x2c,0x2, 0xc4,0xd2,0xfd,0xde,0x76,0x1b,0x60,0xa,0x80,0x16,0x24,0x0,0xa9,0x17,0x40,0xfc, 0xa,0x88,0xdf,0x20,0x19,0xfa,0x17,0x88,0xff,0x3,0x4,0x10,0xb2,0x1,0x3c,0x40, 0x2c,0x4,0xd2,0xc,0xd4,0xd4,0xc,0x64,0xf3,0x83,0xc4,0x81,0xfc,0x5,0x40,0x7e, 0x1,0xd4,0x75,0x9c,0x50,0x97,0x81,0x5c,0xf4,0x3,0x88,0x7f,0x1,0x4,0x10,0xb, 0xd4,0x15,0x1c,0x50,0x5,0x62,0x50,0x1b,0xd4,0x41,0x6c,0xa0,0x66,0x7,0x28,0xdf, 0x18,0xea,0x3a,0x7e,0xa8,0x21,0x20,0x17,0xbd,0x7,0xe2,0xaf,0x0,0x1,0xc4,0x84, 0x64,0x3b,0x48,0x81,0xc,0x54,0x3,0x58,0xf3,0xff,0xff,0xff,0xc1,0x1c,0x20,0x3b, 0x16,0x48,0x59,0x0,0xb1,0x9,0x10,0xeb,0x2,0xb1,0xa,0x10,0x4b,0x1,0xb1,0x0, 0x40,0x0,0xb1,0x40,0x3,0x4c,0x8,0x2a,0xa0,0x8,0xd5,0x0,0xd7,0xc,0x2,0x20, 0x36,0x23,0x23,0xa3,0xb,0x90,0xe9,0x2,0xf4,0xce,0x52,0xa8,0x85,0xa0,0x80,0x67, 0x0,0x8,0x20,0x90,0x1,0x2,0x40,0x2c,0x1,0xc4,0xf2,0x40,0xac,0x4,0xd3,0x80, 0xe,0xa0,0x86,0x80,0xc,0x8f,0x86,0x6,0x6e,0x2d,0x28,0x1c,0x0,0x2,0x8,0xe4, 0x5,0x61,0xa8,0xed,0x4a,0x40,0x49,0x17,0x6c,0x9a,0x91,0xd,0x81,0x1,0xa0,0x5a, 0x50,0x40,0x8b,0x3,0x4,0x10,0x13,0x34,0xde,0x25,0x81,0x2,0x91,0xe8,0x9a,0x41, 0x36,0xc2,0x6c,0xc6,0x66,0x8,0xc8,0xf5,0x0,0x1,0x4,0x32,0x80,0xb,0xa8,0xb9, 0x2,0x9f,0xb3,0x91,0xe5,0x8a,0xb6,0x1d,0x3e,0x80,0xa4,0x84,0x1d,0x20,0x80,0x98, 0x18,0x8,0x0,0x74,0xcd,0x48,0x51,0xb,0x2,0x4c,0x0,0x1,0x4,0x32,0xe0,0xb, 0x30,0x40,0x5a,0x90,0x9d,0x89,0xd,0xc0,0x34,0x3,0xd5,0x22,0xbb,0xe0,0x27,0x40, 0x0,0x81,0xc,0x78,0xb,0xc4,0x4f,0x80,0x12,0x73,0x70,0x19,0x82,0xa4,0x79,0x2f, 0x34,0x15,0xc2,0xc0,0x67,0x80,0x0,0x2,0x19,0xf0,0x1a,0x88,0x1f,0x0,0xf1,0x35, 0xa0,0x82,0x5,0xe8,0x86,0x20,0x69,0x5e,0x8,0xe4,0x5e,0x5,0xe2,0x3b,0x48,0xd2, 0x1f,0x1,0x2,0x8,0x94,0xe,0xde,0x41,0xf3,0x3,0x8,0xff,0x5,0x2a,0xfc,0xc, 0x34,0x24,0x17,0xe4,0x77,0xa0,0xe6,0xcd,0x40,0xcd,0xbe,0x40,0xb1,0x56,0x90,0x62, 0x50,0xd2,0x85,0x66,0x22,0x18,0x78,0x7,0x10,0x40,0x2c,0xd0,0x2c,0xa,0x3,0xbf, 0x41,0xce,0x2,0x6a,0xa8,0x0,0x1a,0xd2,0x1,0x64,0x83,0x34,0x67,0xc3,0xd2,0x3d, 0x34,0x3,0xc1,0x72,0xa9,0x1b,0x48,0x1c,0x20,0xc0,0x0,0x75,0xe3,0xaf,0x3,0x95, 0x9b,0x78,0x44,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-11.png 0x0,0x0,0x0,0xdf, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8e,0x7c,0xfb,0x51,0x93, 0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x25,0x0,0x0,0x80,0x83, 0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60, 0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5,0x46,0x0,0x0,0x0,0x6a, 0x49,0x44,0x41,0x54,0x38,0x4f,0xb5,0x92,0xd1,0xa,0x40,0x21,0x8,0x43,0xeb,0xcf, 0xfd,0xf3,0xca,0x60,0x97,0x8,0xe7,0x15,0x25,0x41,0x7a,0xa9,0xe3,0x9a,0xeb,0x63, 0x55,0xab,0x94,0x2,0x2a,0xd5,0x2a,0x8f,0xb7,0xfa,0x8,0x40,0x44,0x86,0xb6,0x55, 0x61,0x80,0x3e,0xb6,0x20,0x1f,0x0,0x53,0xd8,0x89,0xe9,0x37,0x64,0x3,0xd6,0x12, 0xa8,0x44,0x4b,0xf6,0x9,0x49,0x1,0xce,0xef,0xa4,0x0,0x54,0x81,0xe7,0xc3,0xaf, 0x7,0xea,0x3,0x6b,0x4c,0x74,0xb7,0xc0,0xf2,0x0,0x83,0xd3,0x39,0x80,0x2a,0x3a, 0x20,0x92,0x44,0xef,0x4e,0x28,0x89,0x4f,0x1,0x13,0xe0,0xe0,0x63,0xf8,0x6d,0x51, 0x7b,0x8e,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-1.png 0x0,0x0,0x1,0x39, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xaf,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x84,0x61,0x0,0x23,0x23, 0xe3,0x7f,0x10,0x26,0xd6,0x0,0x80,0x0,0x62,0x0,0x79,0x1,0x86,0x81,0x0,0xce, 0x5,0xb1,0x1b,0x1a,0x1a,0xc0,0x34,0x36,0xc,0x53,0x8,0x10,0x40,0x8c,0xb0,0x30, 0x0,0xd9,0x8a,0x1e,0x1c,0x8c,0x8c,0xc,0xc,0xd8,0xc2,0x8,0xa8,0x16,0x24,0xce, 0x8,0x62,0x3,0x4,0x10,0xc5,0x61,0x0,0x10,0x40,0x4c,0x48,0x5e,0x1,0x19,0x8c, 0x6e,0x3b,0x23,0x21,0x3,0x0,0x2,0x8,0xc5,0x5,0x40,0x3f,0x83,0x35,0xc2,0x34, 0x43,0x3,0x13,0xaf,0x21,0x0,0x1,0x84,0xe2,0x71,0x48,0x38,0xfc,0x47,0xf3,0x2e, 0x86,0x18,0x4a,0x18,0x0,0x4,0x10,0x13,0xe1,0x48,0xc2,0x1f,0xa3,0x0,0x1,0x44, 0x71,0x20,0x2,0x4,0x10,0xc5,0x6,0x0,0x4,0x10,0xb,0xb6,0x38,0x26,0x5,0x0, 0x4,0x10,0x23,0xa5,0x99,0x9,0x20,0x80,0x28,0xf6,0x2,0x40,0x0,0x51,0x6c,0x0, 0x40,0x80,0x1,0x0,0x28,0x50,0x50,0xfb,0x47,0x76,0x6a,0xcb,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-6.png 0x0,0x0,0x1,0x49, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xbf,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0xe1,0x52,0xc0,0xc8,0xc8,0x88,0x17,0xc3,0x0,0x40,0x0,0x31,0xe1,0xd2,0xc,0xa, 0x1a,0x6c,0x18,0x4,0x90,0xc3,0xd,0x20,0x80,0x98,0x70,0x69,0xc6,0x6e,0x30,0x3, 0x43,0x43,0x43,0x3,0x8a,0xb,0x0,0x2,0x88,0x89,0x14,0xcd,0x7,0xe,0x1c,0x0, 0x1b,0x80,0xec,0x2,0x80,0x0,0x62,0x42,0xd6,0xc,0x53,0x88,0xd,0x83,0x34,0x3b, 0x38,0x38,0x60,0xb8,0x0,0x20,0x80,0xe0,0xb1,0x0,0x32,0x15,0x14,0xb2,0x20,0x45, 0xd8,0x0,0x48,0x1c,0x66,0x8,0x4c,0x2d,0x8,0x0,0x4,0x10,0xb,0xba,0xb,0x70, 0x1,0x64,0xcd,0xc8,0x0,0x20,0x80,0x48,0x72,0x1,0xb6,0x54,0xb,0x10,0x40,0x44, 0xbb,0x0,0x57,0x92,0x7,0x8,0x20,0x16,0x42,0xa,0x8,0x1,0x80,0x0,0x62,0x62, 0xa0,0x10,0x0,0x4,0x10,0xb,0x7a,0xda,0x26,0x15,0x0,0x4,0x10,0x23,0xa5,0xd9, 0x19,0x20,0xc0,0x0,0x82,0x44,0x51,0xa,0x1,0xc0,0x7b,0xef,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-10.png 0x0,0x0,0x1,0x34, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xaa,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0xb0,0x9,0x36,0x32,0x32,0x62,0x35,0xb5,0xfe,0xff, 0x7f,0x46,0x74,0x31,0x80,0x0,0x62,0x0,0xb9,0x0,0x19,0x37,0x30,0x30,0x80,0xdc, 0x84,0x15,0x83,0xe5,0xd0,0xd4,0x3,0x4,0x10,0x23,0xcc,0xb,0x30,0x5b,0xeb,0xb1, 0xd8,0x7c,0xf0,0xc0,0x1,0x30,0x6d,0xef,0xe0,0xc0,0xd0,0x88,0xe6,0x1a,0x80,0x0, 0x22,0xca,0x66,0x18,0x3e,0x70,0xe0,0x0,0x86,0x4b,0x0,0x2,0x88,0x68,0xcd,0xb8, 0xc,0x1,0x8,0x20,0x92,0x34,0x63,0x33,0x4,0x20,0x80,0x98,0x18,0x28,0x4,0x0, 0x1,0x44,0x96,0x1,0xa0,0xc0,0x84,0x1,0x80,0x0,0xa2,0xd8,0x5,0x0,0x1,0x44, 0xb1,0x1,0x0,0x1,0x44,0x72,0x2c,0xa0,0x27,0x2a,0x80,0x0,0x22,0x29,0x1d,0x60, 0x4b,0x91,0x0,0x1,0x84,0xe2,0x85,0x46,0x22,0x5c,0x8c,0xae,0x6,0x20,0x80,0x28, 0xce,0xb,0x0,0x1,0xc4,0x88,0x2d,0x3b,0x93,0x92,0x1b,0x1,0x2,0xc,0x0,0x99, 0xa,0x12,0xae,0x7,0xe7,0xff,0x79,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-16.png 0x0,0x0,0x1,0x53, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x82,0x4d,0x90,0x91, 0x91,0x11,0xc3,0x59,0x40,0x97,0x32,0x62,0x53,0xb,0x10,0x40,0x2c,0xe8,0x1a,0x1b, 0x1a,0x1a,0xb0,0x2a,0x6,0xc9,0x61,0x13,0x7,0x8,0x20,0xb8,0x1,0x8d,0x8d,0x8d, 0xff,0x71,0xd9,0x2,0x73,0x1,0x36,0x43,0x0,0x2,0x8,0x24,0xc1,0x0,0xd,0xc8, 0xff,0x30,0x36,0x3a,0x6,0xc9,0x1,0x5d,0xf6,0x1f,0x99,0x86,0xc9,0x1,0x4,0x10, 0x23,0x2c,0x16,0x70,0x39,0x11,0x5b,0xb8,0x20,0xab,0x3,0x8,0x20,0x46,0x52,0xa2, 0x11,0x9b,0x25,0x0,0x1,0xc4,0x48,0x69,0x3a,0x0,0x8,0x20,0x26,0x90,0xa9,0xa0, 0x0,0x44,0xa6,0xb1,0xda,0xde,0xc8,0x8,0xb4,0x1a,0x88,0x91,0x68,0x90,0x38,0x40, 0x0,0x31,0x81,0xa2,0xd,0x4,0x60,0x34,0x4e,0x50,0x8f,0x46,0x43,0x1,0x40,0x0, 0x31,0x11,0xd4,0x8,0x8f,0x67,0xec,0xc2,0x0,0x1,0x44,0xbc,0x1,0xf5,0xd8,0x85, 0x1,0x2,0x8,0x14,0xa2,0x44,0x25,0x5b,0x98,0x9f,0x51,0xd4,0xd5,0xff,0x67,0x4, 0x8,0x20,0x8a,0x63,0x1,0x20,0x80,0x28,0xce,0x8d,0x0,0x1,0x6,0x0,0xab,0xc0, 0x7a,0x77,0xa7,0x68,0x79,0x83,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-7-2.png 0x0,0x0,0x2,0x82, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xf8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0xc8, 0x8c,0x81,0x81,0x81,0x1d,0x88,0xff,0x1,0xf1,0xf,0x20,0xfe,0xe,0xa5,0x7f,0x1, 0xf1,0x5f,0x28,0xfd,0x1b,0x8a,0x61,0x62,0x70,0x0,0x10,0x40,0x2c,0x40,0x2c,0xd3, 0xe7,0x65,0xbb,0x16,0xc4,0x29,0xda,0x76,0x38,0x0,0x48,0x7d,0x5,0xe2,0x2f,0x40, 0xfc,0x13,0x88,0xff,0x0,0xf1,0x37,0x28,0xfe,0xe,0xd5,0x8c,0x62,0x0,0x40,0x0, 0x31,0xf1,0x9f,0xde,0xb7,0x16,0x89,0x2f,0x9,0xc4,0x12,0x50,0x2c,0x5,0x34,0xf8, 0x12,0x90,0x16,0x1,0x62,0x3e,0x20,0xe6,0x0,0x62,0x66,0x6,0x34,0x0,0x10,0x40, 0x4c,0x20,0xa2,0xb1,0xb1,0x11,0x64,0x7b,0x1b,0x90,0x29,0xc,0xc4,0xa2,0x40,0x2c, 0xe,0x34,0x78,0xb,0x54,0x8d,0x10,0x10,0xf3,0x42,0xd,0x60,0x42,0x37,0x0,0x20, 0x80,0x98,0x3e,0x9a,0x3a,0x75,0xd4,0xd7,0xd7,0x33,0x0,0x6d,0xab,0x2,0xf2,0x5, 0x80,0x58,0x10,0xaa,0x9,0x6,0xf8,0x81,0x98,0x1b,0x88,0xd9,0xb0,0x19,0x0,0x10, 0x40,0x20,0x2f,0x54,0x20,0xf1,0xb9,0x80,0x98,0x7,0x6a,0x23,0xc,0xf0,0x42,0xc5, 0xd9,0xb0,0x79,0x1,0x20,0x80,0x58,0x60,0x5e,0x0,0xba,0x64,0x2e,0xd4,0x6,0x36, 0x98,0x38,0x14,0x80,0x5c,0xf5,0x1,0xea,0x5,0x16,0xa8,0x21,0xf0,0x80,0x4,0x8, 0x20,0x16,0xa0,0xc6,0x3e,0xa0,0xf3,0x8b,0x80,0xec,0x64,0x60,0x38,0x2c,0x4,0xd2, 0x8c,0x68,0x4e,0x15,0x83,0xc6,0x2,0x28,0x66,0x3e,0x3,0xf1,0x7f,0x68,0x94,0x82, 0xc,0xf9,0x7,0x10,0x40,0x2c,0x40,0x2f,0x14,0x31,0x78,0xd9,0x22,0xfb,0x97,0x15, 0x8a,0x61,0x40,0x11,0x6a,0xe8,0x7f,0x24,0x2f,0x7d,0x83,0xa6,0x95,0x9f,0x0,0x1, 0xc4,0xec,0xe0,0xe0,0xd0,0x70,0xf0,0xe0,0x41,0x86,0x4d,0xdf,0x98,0xb7,0x3,0x5, 0x38,0x61,0xd1,0xd5,0x9e,0x1a,0xa7,0x0,0x52,0xed,0xae,0x2a,0xaf,0xb5,0xf3,0xf6, 0xa3,0xd7,0x50,0x3,0x18,0xa1,0x86,0xb3,0x41,0x13,0x1f,0x33,0x40,0x0,0x81,0x62, 0x61,0x2a,0x34,0x16,0x3c,0x61,0x7e,0x7,0xb2,0x1d,0x40,0xe1,0x2,0xb,0x1f,0x20, 0xdf,0x1f,0xc8,0x54,0x80,0x62,0x79,0x50,0xe2,0x3,0x45,0x35,0x28,0xda,0x1,0x2, 0x88,0xa1,0xa1,0xa1,0xe1,0x3f,0xc,0x0,0x93,0xf5,0xfe,0xff,0x24,0x2,0x80,0x0, 0x62,0x4,0x19,0x0,0xb2,0x9,0xe8,0x92,0x3,0xc0,0xf0,0x70,0x0,0xb1,0x41,0x2e, 0x2,0xd9,0x8c,0x4e,0x63,0x3,0x0,0x1,0xc4,0x8,0xb4,0xb5,0x15,0x9a,0x88,0x40, 0xa9,0x71,0x27,0xc8,0x6f,0x20,0x83,0x40,0x9a,0x60,0x0,0x28,0xbe,0x19,0x48,0x3d, 0x5,0xe2,0x57,0x40,0xfc,0x6,0x64,0x1f,0x34,0x46,0xde,0x3,0x4,0x10,0x28,0x21, 0x55,0x21,0x19,0x78,0xf,0x84,0x81,0xae,0x59,0x4,0xb3,0x11,0xa8,0x79,0x26,0x90, 0x2,0xe5,0x89,0xeb,0x40,0x7c,0x1b,0x88,0x1f,0x40,0xd,0x7b,0x9,0xc4,0x6f,0x1, 0x2,0x8,0xd9,0xb,0xd9,0x68,0x69,0x80,0x11,0x68,0xf8,0x44,0xa0,0x78,0x2a,0xd4, 0x46,0x10,0xfe,0x4,0xcd,0xad,0xb0,0xac,0xfd,0x13,0x20,0xc0,0x0,0xb5,0x6e,0xdc, 0x2,0x4c,0x1f,0x33,0xba,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-5-1.png 0x0,0x0,0x2,0x48, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xbe,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x8d,0x81,0x81,0x81,0x7,0x88,0x5,0x80,0x58,0x8,0x8a,0x41,0x62,0xbf,0x80,0xf8, 0x13,0x10,0xbf,0x7,0xe2,0x77,0x40,0xfc,0x5,0x2a,0xf6,0x97,0x1,0x9,0x0,0x4, 0x10,0xb,0x10,0x33,0x3,0x31,0x27,0x54,0xa3,0x74,0xbf,0xb7,0xdd,0x6,0x90,0x4, 0xd0,0xe0,0x12,0xa8,0xc6,0x67,0x50,0x35,0xc,0xd8,0xc,0x1,0x8,0x20,0x90,0x1, 0x4c,0x40,0xcc,0xe,0xc4,0xfc,0x40,0x2c,0x5,0x12,0xfc,0xff,0xff,0x3f,0x3,0x23, 0x23,0x63,0xf,0xd0,0x90,0xc9,0x50,0x97,0x31,0x23,0x59,0x8a,0x62,0x8,0x40,0x0, 0xc1,0xc,0x0,0x39,0x99,0x1b,0x88,0x45,0x61,0xaa,0xa0,0x86,0xe4,0x2,0xd,0x59, 0x2,0x55,0xc3,0x80,0xcd,0x10,0x80,0x0,0x2,0x19,0xc0,0x8,0xb5,0x81,0x3,0x88, 0xf9,0x90,0x55,0x41,0xd,0x89,0x1,0x1a,0xc2,0xc8,0x80,0x9,0xc0,0x86,0x0,0x4, 0x10,0xcc,0x0,0x90,0xd,0xac,0xd0,0xb0,0x60,0xc0,0x62,0x48,0x34,0xd0,0x90,0x1f, 0x40,0xee,0x77,0x20,0xfe,0x6,0xc4,0x3f,0xa0,0x2e,0xf8,0x3,0x10,0x40,0xe8,0x4e, 0x63,0xc2,0x62,0x13,0xd8,0x10,0x60,0xe0,0x26,0x3,0x99,0x72,0x40,0x2c,0x6,0xc4, 0xbc,0xd0,0x70,0x63,0x2,0x8,0x20,0x74,0xd,0xff,0x19,0x70,0x0,0xa8,0x21,0xe5, 0xd0,0xd8,0xe2,0x86,0x86,0x1b,0x33,0x40,0x0,0x21,0x1b,0x0,0xa,0xd5,0xdf,0xd8, 0x34,0x3,0xbd,0x0,0xc6,0x20,0x0,0x34,0x64,0x3a,0xd4,0xab,0xe0,0x8,0x0,0x8, 0x20,0x16,0xa8,0xad,0x7f,0xa1,0x7e,0xfa,0x82,0xae,0x11,0x64,0x33,0x34,0x5d,0x1c, 0x0,0x52,0x6f,0x81,0xf8,0x4,0x54,0xf,0x8,0xff,0x3,0x8,0x20,0x26,0x28,0xe3, 0xf,0x34,0x70,0xde,0x21,0x6b,0x46,0x73,0xbe,0x3,0x34,0xb6,0x58,0x91,0xa2,0x9f, 0x11,0x20,0x80,0x40,0x8c,0x7f,0x48,0xc9,0xf6,0x5,0x4c,0x33,0xd4,0x46,0x10,0xdb, 0x1,0xe6,0xa,0x28,0x60,0x46,0x4a,0xc1,0x4c,0x0,0x1,0xc4,0x4,0x35,0x0,0x14, 0x2d,0x1f,0xa1,0xc9,0x16,0xa4,0xb9,0x16,0x48,0xdd,0x84,0x46,0x1b,0xb2,0x2b,0x2, 0x90,0xc,0x1,0xa7,0x4e,0x80,0x0,0x62,0x81,0xfa,0x1f,0x64,0xc0,0x7,0x10,0x1b, 0xa8,0xd9,0x16,0x48,0xb,0x3,0xf1,0x6b,0x90,0x9f,0x81,0xfc,0xb7,0xa0,0xc4,0x84, 0xe4,0x8a,0x5f,0x48,0xb1,0xc5,0x8,0x10,0x40,0x30,0x3,0x7e,0x42,0x5,0x7f,0x23, 0x19,0xf6,0x11,0x1a,0x2e,0xdf,0xd0,0x12,0x55,0x27,0xd0,0x50,0x2f,0x58,0x2,0x4, 0x8,0x20,0x58,0x18,0xfc,0x46,0x8a,0x9,0x90,0xb3,0x3f,0x43,0x35,0x82,0xf8,0xdf, 0x80,0x1a,0xb2,0x80,0x1a,0xa7,0x41,0xbd,0x17,0x9,0xd,0x2f,0x90,0xa5,0x7f,0x1, 0x2,0xc,0x0,0xcd,0x4d,0xa1,0x48,0xe6,0xd0,0x2,0x83,0x0,0x0,0x0,0x0,0x49, 0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-11.png 0x0,0x0,0x1,0x29, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x9f,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x2,0x63,0x30,0x32, 0x32,0x82,0x9d,0x2,0x74,0x11,0x23,0xba,0x22,0x98,0x1c,0x3a,0x0,0xa9,0x5,0x8, 0x20,0x16,0x64,0x81,0x86,0x86,0x6,0xb0,0x62,0x64,0x43,0x40,0x7c,0x90,0x38,0x3a, 0x80,0x89,0x1,0x4,0x10,0x13,0x36,0x9,0x98,0x8d,0xb8,0x34,0x23,0x3,0x80,0x0, 0xc2,0x1a,0x6,0x30,0x43,0x8,0x69,0x6,0x1,0x80,0x0,0xc2,0x19,0x88,0xc4,0x68, 0x6,0x1,0x80,0x0,0xa2,0x38,0x16,0x0,0x2,0x88,0x62,0x3,0x0,0x2,0x88,0x62, 0x3,0x0,0x2,0x88,0x85,0x90,0xbf,0x9,0x85,0x5,0x40,0x0,0xb1,0x20,0x27,0xa, 0x62,0x13,0x10,0x32,0x0,0x8,0x20,0x8a,0xbd,0x0,0x10,0x40,0x14,0x1b,0x0,0x10, 0x40,0x8c,0xf8,0x72,0x23,0x21,0x2f,0x80,0xbc,0xd,0x10,0x40,0x8c,0x94,0x66,0x67, 0x80,0x0,0x3,0x0,0xc5,0x1b,0x30,0x25,0xf6,0x14,0xfa,0x83,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-7.png 0x0,0x0,0x1,0x57, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xcd,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x2,0x22,0x1a,0x19, 0x19,0x51,0x9c,0x51,0xf,0x74,0x15,0x63,0x23,0x23,0x4e,0x4d,0xff,0xeb,0xff,0x83, 0xf4,0x80,0xd4,0x31,0x2,0x4,0x10,0xb,0x4c,0x3,0xc,0x80,0x24,0x48,0x1,0x0, 0x1,0x4,0x71,0x1,0x92,0x6d,0x30,0xc3,0x40,0xb6,0x80,0x0,0xba,0x4b,0x60,0xb6, 0xc3,0x0,0x40,0x0,0xb1,0x60,0x33,0x95,0x91,0xb1,0x11,0xa1,0x81,0x40,0x20,0x3, 0x4,0x10,0xb,0x21,0x27,0x22,0x1b,0x6,0x31,0xb0,0x1e,0xc5,0xcb,0x0,0x1,0x84, 0x12,0xb,0xf5,0x40,0xe7,0xa1,0x6b,0xc0,0x6a,0x28,0xd0,0x5b,0x30,0xaf,0x1,0x4, 0x10,0x49,0xd1,0x8,0xb2,0x1d,0x3d,0x4c,0x0,0x2,0x88,0xe2,0x74,0x0,0x10,0x40, 0x4c,0xa4,0x3a,0x1f,0x1d,0x0,0x4,0x10,0x13,0x4c,0x33,0xcc,0x89,0x20,0x4c,0xa, 0x0,0x8,0x20,0x16,0x58,0xa0,0x20,0xc7,0x2f,0xae,0xa8,0xc3,0x96,0x3a,0x1,0x2, 0x88,0x11,0xaa,0xf8,0x3f,0xa1,0x14,0x58,0x8f,0xdd,0x50,0x46,0x80,0x0,0x62,0x21, 0xc5,0xb9,0x8d,0x68,0x2e,0x0,0x79,0x1d,0x20,0x80,0x18,0x29,0xcd,0xce,0x0,0x1, 0x6,0x0,0xda,0xa7,0x46,0xa0,0xe5,0xcc,0x7c,0x78,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-12.png 0x0,0x0,0x1,0x4f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0x94,0x1,0x8d,0x8d,0x8d,0xf,0x41,0x18,0x9b,0x1c,0x40,0x0,0x11,0xed,0x2, 0x7,0x7,0x7,0x6,0x6c,0x86,0x0,0x4,0x10,0x23,0x2c,0x10,0x71,0xd9,0x80,0x64, 0x80,0x1c,0x90,0x7a,0x74,0xe0,0xc0,0x1,0x86,0xfa,0xfa,0x7a,0x79,0x98,0x38,0x40, 0x0,0x81,0xd,0x60,0x64,0x64,0x7c,0xd8,0xd0,0xd0,0x0,0x53,0x44,0x8,0xa0,0x18, 0x2,0x10,0x40,0x30,0x2f,0xc8,0x41,0x31,0x31,0x40,0xe,0x68,0xd1,0x33,0xa0,0x8b, 0x8f,0x83,0x38,0x0,0x1,0xc4,0x42,0x46,0xc0,0x83,0x5c,0x20,0x5,0x73,0x1,0x40, 0x0,0xa1,0x18,0x0,0x72,0x1a,0xbe,0x40,0xc4,0x16,0x6,0x0,0x1,0x4,0xf,0x3, 0x7c,0x56,0x2,0xc3,0x7,0xe4,0x6c,0xc,0xcd,0x20,0x0,0x10,0x40,0x60,0x17,0x0, 0xd,0x91,0xc7,0xa5,0x19,0x6a,0x38,0x56,0xcd,0x20,0x0,0x10,0x40,0x8c,0x84,0xf2, 0x2,0xcc,0x75,0xb8,0x2c,0x1,0x8,0x20,0x46,0x4a,0x33,0x13,0x40,0x0,0x51,0x9c, 0x17,0x0,0x2,0x88,0x62,0x3,0x0,0x2,0xc,0x0,0x29,0x1f,0x4f,0x99,0xac,0x7f, 0x99,0x8b,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-6.png 0x0,0x0,0x1,0x4b, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc1,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x42,0xac,0x42,0x46, 0x46,0x46,0xb8,0x53,0x81,0xae,0x66,0x84,0xb1,0x1,0x2,0x88,0x85,0x58,0xcd,0xd, 0xd,0xd,0x28,0x7c,0x98,0x21,0x0,0x1,0x44,0xb1,0x17,0x0,0x2,0x8,0xe4,0x1c, 0xa2,0x30,0xc8,0xe5,0x40,0x57,0xfc,0x87,0xf8,0x0,0x21,0xe,0x10,0x40,0x4c,0xa4, 0x7a,0x1,0x44,0x23,0x87,0x7,0x40,0x0,0x31,0x91,0x12,0x78,0xd8,0xc4,0x1,0x2, 0x88,0x89,0x90,0x66,0xe4,0x10,0x47,0xf3,0x3a,0x23,0x48,0x1e,0x20,0x80,0x50,0xd, 0x60,0x64,0xf8,0xf,0xc6,0x58,0xa2,0xb,0x97,0x21,0x0,0x1,0xc4,0x8,0x4f,0x89, 0x20,0x8d,0x20,0xed,0xe8,0x6c,0x1c,0xde,0x80,0x19,0xe,0x10,0x40,0x4c,0xd8,0x34, 0x80,0xd9,0x58,0x5c,0x82,0x4e,0x83,0x0,0x40,0x0,0xe1,0xe,0x3,0x98,0x21,0x48, 0x6,0x61,0x3,0x0,0x1,0x84,0x3f,0x16,0x20,0xda,0x19,0xd1,0xbd,0x80,0xcc,0x7, 0x8,0x20,0x26,0x6c,0x4e,0x26,0x25,0x1a,0x1,0x2,0x88,0x11,0x25,0x3b,0xa3,0x87, 0x5,0x11,0x0,0x20,0xc0,0x0,0xb6,0x9,0x77,0xf5,0x1c,0x6d,0x6d,0xca,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-5.png 0x0,0x0,0x1,0x46, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xbc,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8d,0x8d,0x8d,0x24,0x9b,0x6,0x10,0x40, 0xc,0x20,0x17,0x80,0x70,0x43,0x43,0x3,0xc8,0x2d,0x70,0xc,0xe2,0x33,0x20,0x41, 0x30,0x1f,0x21,0xd,0xe6,0x83,0xf4,0x1,0x4,0x10,0x45,0x9a,0x41,0x18,0x20,0x80, 0x18,0x29,0xd,0x3,0x80,0x0,0x62,0xc1,0x26,0xc8,0xc8,0xc8,0xf8,0x1f,0x87,0x77, 0x19,0xd1,0xc5,0x0,0x2,0x88,0x5,0x5f,0xd8,0xa0,0x19,0x8a,0x55,0x1d,0x40,0x0, 0xb1,0x10,0x63,0x33,0xba,0x3c,0xb2,0x4b,0x0,0x2,0x88,0x9,0x9b,0x13,0xb1,0x85, 0xb,0x4c,0xc,0xdd,0x1b,0x0,0x1,0xc4,0x84,0xcd,0x9f,0xd8,0x9c,0xb,0x12,0xc3, 0x16,0x6,0x0,0x1,0xc4,0x84,0x2b,0xb0,0x90,0xd,0xc1,0xa5,0x19,0x4,0x0,0x2, 0x8,0x6f,0x34,0x62,0xf3,0x33,0x3a,0x0,0x8,0x20,0x14,0x3,0xc8,0x49,0xca,0x0, 0x1,0x84,0x92,0x94,0x19,0x48,0x84,0x20,0x3d,0x0,0x1,0x44,0x91,0x66,0x90,0x5e, 0x80,0x0,0x62,0x84,0xa4,0x73,0xd2,0x41,0x7d,0x7d,0x3d,0x38,0x5c,0x0,0x2,0xc, 0x0,0xca,0x6,0xcc,0x8f,0xd8,0x78,0x33,0x9c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-20.png 0x0,0x0,0x1,0x74, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xea,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0x94,0x1,0x8d,0x8d,0x8d,0xf,0x41,0x18,0x9b,0x1c,0x40,0x0,0x11,0xed,0x2, 0x7,0x7,0x7,0x6,0x6c,0x86,0x0,0x4,0x10,0x23,0x2c,0x10,0x71,0xd9,0x80,0x64, 0x80,0x1c,0x90,0x7a,0x74,0xe0,0xc0,0x1,0x86,0xfa,0xfa,0x7a,0x79,0x98,0x38,0x40, 0x0,0x81,0xd,0x60,0x64,0x64,0x7c,0xd8,0xd0,0xd0,0x0,0x53,0x44,0x8,0xa0,0x18, 0x2,0x10,0x40,0x30,0x2f,0xc8,0x41,0x31,0x31,0x40,0xe,0x68,0xd1,0x33,0xa0,0x8b, 0x8f,0x83,0x38,0x0,0x1,0x84,0x12,0x6,0x20,0x93,0x89,0x74,0x81,0x14,0xd0,0x5, 0x96,0x20,0xe,0x40,0x0,0xb1,0xa0,0x7,0x14,0x2e,0x43,0x40,0x72,0xd8,0xc2,0x0, 0x20,0x80,0x18,0xa0,0x81,0xf8,0x1f,0x28,0xf1,0x1f,0x99,0x46,0xc6,0xc0,0xf0,0x1, 0x89,0x83,0xc2,0xe9,0x21,0x48,0x3d,0x32,0x6,0x8,0x20,0x98,0xb,0x1e,0x81,0x8, 0xa0,0x2,0x39,0x74,0xaf,0xe0,0xb4,0x19,0xa,0x0,0x2,0x8,0x6e,0x12,0x10,0x3c, 0x4,0xd9,0x2,0xa2,0xa1,0xec,0xff,0xc8,0x7c,0x74,0x9b,0x61,0x18,0x20,0x80,0x18, 0x91,0x33,0x13,0x28,0x3a,0x81,0x7c,0x79,0x10,0x8d,0x64,0x81,0x3c,0xbe,0x10,0x5, 0x8,0x20,0x46,0x4a,0x73,0x23,0x40,0x0,0x51,0x9c,0x99,0x0,0x2,0xc,0x0,0x5, 0x68,0x96,0x69,0xa6,0xd0,0x96,0xe5,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-12.png 0x0,0x0,0x1,0x63, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0xd0,0x5,0x1a,0x1b,0x1b,0x71,0x9a,0x58,0x5f,0x5f, 0xcf,0x88,0x2e,0x6,0x10,0x40,0x2c,0xd8,0x15,0x36,0x30,0x60,0x1a,0xdc,0x80,0xd5, 0x50,0x80,0x0,0x62,0x0,0x79,0x1,0x1d,0x37,0x34,0x34,0xa0,0x8,0x41,0xf8,0xff, 0xb1,0xaa,0x5,0x8,0x20,0x26,0x90,0x93,0xf1,0x39,0x1b,0x1b,0x40,0xd6,0x3,0x10, 0x40,0x70,0xdb,0x40,0x34,0xb2,0x4d,0xc8,0xe2,0xc8,0x62,0xe8,0xe2,0x0,0x1,0xc4, 0x82,0xee,0xef,0xc6,0x46,0x86,0xff,0xb8,0x2,0x16,0x5b,0xd8,0x0,0x4,0x10,0xb, 0xae,0x0,0x44,0xe,0x34,0x6c,0x1a,0x61,0x0,0x20,0x80,0x98,0x70,0x47,0x59,0x3, 0x41,0xcd,0x20,0x0,0x10,0x40,0x2c,0xf8,0xa2,0xb,0xa4,0x99,0x90,0x4b,0x0,0x2, 0x88,0x9,0x59,0x23,0x8,0xc3,0x12,0xb,0xba,0xb,0x40,0xe2,0x30,0x35,0xc8,0x0, 0x20,0x80,0x18,0x70,0x85,0x3e,0x22,0xa4,0x19,0xf0,0xc4,0xc6,0x7f,0x6,0x80,0x0, 0x22,0x22,0x1,0xe1,0x4f,0x50,0x0,0x1,0x44,0x30,0xf5,0x11,0x32,0x4,0x20,0x80, 0x98,0x60,0xf1,0x4c,0x28,0xb4,0x51,0x3,0x16,0x91,0x72,0x1,0x2,0x88,0x5,0x57, 0x66,0x41,0x4,0x26,0x28,0xf0,0x18,0x70,0x26,0x75,0x80,0x0,0x3,0x0,0x21,0xe7, 0x26,0xee,0xd8,0xba,0x71,0x79,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-5.png 0x0,0x0,0x1,0x6b, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xe1,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0xc4,0x2,0x63,0x30,0x32,0x32,0xe2,0xf5,0xb,0xd0,0xab,0x8c,0xd8,0xc4,0x1,0x2, 0x88,0x5,0x55,0x11,0x76,0xcd,0x8c,0x8c,0xb8,0xd,0x6,0x8,0x20,0x16,0xc2,0x8e, 0xfc,0xcf,0x88,0x2f,0x9c,0x1,0x2,0x88,0x85,0x90,0x66,0x64,0xaf,0x61,0xf3,0x6, 0x40,0x0,0x31,0x11,0xd2,0xc,0x8a,0x66,0x90,0xb,0x40,0x34,0xb6,0x70,0x2,0x8, 0x20,0x26,0x42,0x9a,0x81,0x21,0xc0,0xd0,0xd8,0xd8,0x0,0xe,0xa,0x6c,0x86,0x0, 0x4,0x10,0x3,0xc4,0x86,0xff,0xc8,0xcc,0xff,0xa8,0x7c,0x88,0x23,0x1a,0x1a,0x1a, 0xfe,0x43,0x25,0xfe,0x23,0x29,0x64,0x0,0x8,0x20,0x46,0x58,0x4a,0x44,0xf7,0x2b, 0xb2,0xb,0x80,0x22,0x70,0x1a,0x28,0x8e,0x12,0x16,0x0,0x1,0xc4,0x88,0x2f,0x29, 0x23,0xc,0x81,0x80,0xc6,0xc6,0x46,0x30,0x5d,0x5f,0x5f,0xf,0x37,0x0,0x20,0x80, 0x98,0x8,0x25,0x1e,0x90,0x8d,0x30,0xc,0x2,0x40,0xaf,0x80,0xc,0x82,0x9b,0xa, 0x10,0x40,0x4,0xd3,0x1,0x96,0xa8,0x3,0x85,0x7,0x98,0x6,0xb9,0x4,0x20,0x80, 0x58,0x48,0x4d,0xfb,0x50,0xe7,0xc3,0xd,0x1,0x8,0x20,0xe4,0xa0,0x27,0x9,0x43, 0x63,0x85,0x1,0x20,0xc0,0x0,0xfc,0x35,0xaf,0x40,0x1e,0xc7,0x29,0xf8,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-20.png 0x0,0x0,0x1,0x62, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x48,0xd5,0xc0,0xc8,0xc0,0x80,0x62,0x23,0x40,0x0, 0x31,0x91,0x63,0x2b,0xb2,0x21,0x0,0x1,0x4,0x64,0x33,0xe0,0xf4,0x3,0xd0,0x7b, 0x8c,0x8c,0xf8,0xe4,0x81,0x66,0x1,0x4,0x10,0xb,0x54,0x21,0x56,0x8b,0x18,0x1b, 0x1b,0x31,0x25,0xea,0xeb,0x21,0x74,0x63,0x23,0x98,0xd,0x10,0x40,0x50,0xfd,0x60, 0x13,0x30,0x30,0x48,0x18,0x86,0xc1,0x44,0x43,0xc3,0x7f,0x18,0xd,0x13,0x7,0x8, 0x20,0x16,0x24,0xe7,0x12,0x17,0x70,0x40,0x9b,0xff,0xd7,0xd7,0x33,0xc2,0xb8,0x0, 0x1,0x84,0xd3,0x5,0x60,0x21,0x98,0x8d,0x38,0x30,0x88,0x2,0x8,0x20,0x46,0xb8, 0x62,0xac,0x16,0x3,0x9,0x50,0x38,0x20,0xfb,0x1b,0x66,0x2b,0xd4,0x15,0x0,0x1, 0x84,0x37,0xc,0x30,0x5c,0x82,0xe4,0x77,0x18,0x6,0x8,0x20,0xb8,0x1,0x4,0x0, 0x3,0x36,0xcd,0x20,0xc,0x10,0x40,0x70,0x2f,0x30,0x32,0x32,0x32,0xe0,0x49,0xf, 0x70,0x2f,0xa1,0x3,0x80,0x0,0x22,0x2a,0x16,0x20,0x89,0x82,0x11,0x64,0x11,0x86, 0x21,0x0,0x1,0xc4,0x82,0xa4,0x80,0x90,0xb,0xb0,0x2,0x80,0x0,0x22,0xda,0x5, 0xb8,0x0,0x40,0x0,0xb1,0x10,0xb2,0x9d,0x10,0x0,0x8,0x30,0x0,0x96,0x23,0xd6, 0x74,0x60,0x41,0x14,0x4d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-1-3.png 0x0,0x0,0x1,0x2f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x0,0xb9,0xa0,0xa1,0xa1,0xe1,0x3f,0x21,0x0,0x52, 0x3,0x56,0xc,0x65,0x43,0x99,0xc,0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20, 0x16,0x52,0x14,0x37,0x34,0x36,0x62,0x88,0x1,0x4,0x10,0x49,0x2e,0x68,0xa8,0x6f, 0x0,0x63,0x64,0x0,0x10,0x40,0x14,0x7b,0x1,0x20,0x80,0x48,0xf4,0x42,0x3,0x86, 0x18,0x40,0x0,0x91,0xe8,0x85,0x7a,0x30,0x46,0x6,0x0,0x1,0x44,0xb1,0x17,0x0, 0x2,0x8,0xee,0x85,0x46,0x2c,0x21,0x4c,0x4c,0x2c,0x0,0x4,0x10,0x3c,0x21,0x21, 0x27,0x12,0x6,0x28,0xc4,0x10,0x67,0xf8,0xf,0xc6,0xc8,0x9,0x9,0x20,0x80,0x28, 0xf6,0x2,0x40,0x0,0x31,0x82,0x4c,0xa1,0x24,0x2f,0x0,0x4,0x10,0x23,0xa5,0xb9, 0x11,0x20,0x80,0x28,0xf6,0x2,0x40,0x80,0x1,0x0,0x6f,0x6b,0x7c,0xc7,0x78,0xc6, 0x61,0xbb,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-4.png 0x0,0x0,0x1,0x30, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa6,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0xc4,0x8,0xc,0x1,0xcc,0x40,0xf8,0xff,0x9f,0x11,0xbf, 0x2e,0xa0,0x36,0xa8,0x1a,0x80,0x0,0x62,0x81,0x2b,0x46,0x12,0x24,0x5,0x0,0x4, 0x10,0x13,0x4e,0x1b,0x40,0x18,0x1b,0x1f,0x8d,0x6,0x8,0x20,0x26,0x9c,0xce,0x3, 0x61,0x98,0x46,0x28,0xbf,0xb1,0xb1,0x11,0xe1,0x4a,0x28,0xd,0x10,0x40,0x8c,0xf0, 0x74,0x0,0x53,0x88,0x6c,0x33,0xb2,0xf7,0xd0,0xf9,0x50,0x36,0x40,0x0,0xb1,0x60, 0xf5,0x2,0x54,0x12,0x6c,0x23,0x10,0xd4,0xe3,0x9,0x27,0x80,0x0,0x62,0x0,0xb9, 0x0,0x8c,0x41,0xda,0x90,0xd9,0x78,0xf8,0xd,0xd,0xd,0x70,0x3e,0x40,0x0,0x31, 0x52,0x9a,0x94,0x1,0x2,0x88,0xe2,0x84,0x4,0x10,0x40,0x14,0x1b,0x0,0x10,0x40, 0x14,0x1b,0x0,0x10,0x40,0x14,0x1b,0x0,0x10,0x60,0x0,0xf6,0xa2,0x6b,0xee,0x31, 0x8b,0xeb,0x9a,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-17.png 0x0,0x0,0x1,0x64, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xda,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x9c,0xd7,0xd0,0xc0,0x50,0x4f,0xa4,0x6b,0x1a,0x19,0x19, 0xc1,0xea,0x41,0x0,0x20,0x80,0x98,0xe0,0xa6,0x1,0x35,0x83,0x25,0xd0,0xc0,0xc1, 0x83,0x7,0xc1,0x18,0x59,0x33,0xb2,0x45,0x0,0x1,0xc4,0x84,0xe2,0x24,0x34,0x43, 0x90,0x35,0x82,0xd8,0xe8,0x9a,0x41,0x0,0x20,0x80,0x98,0x30,0xfc,0x85,0x66,0x88, 0xbd,0xbd,0x3d,0x98,0x3e,0xe0,0xe0,0x80,0xd5,0x8b,0x0,0x1,0xc4,0x82,0x35,0x70, 0xa0,0x86,0xc0,0x34,0xe0,0xd2,0xc,0x2,0x0,0x1,0xc4,0x82,0x2b,0xa0,0x1c,0xe, 0x1c,0x80,0xbb,0x4,0x5f,0xe0,0x2,0x4,0x10,0x13,0x36,0x41,0x90,0x7f,0x61,0x4e, 0x27,0x4,0x0,0x2,0x88,0x9,0x5f,0x54,0x81,0x5c,0x81,0x2b,0x76,0x60,0x0,0x20, 0x80,0xb0,0x1a,0x0,0xf2,0x33,0x48,0x33,0xa1,0x28,0x6,0x1,0x80,0x0,0x62,0xc2, 0x65,0x33,0x72,0xc,0xe0,0x33,0x4,0x20,0x80,0x98,0xd0,0x35,0xc3,0x2,0xc,0x5b, 0x18,0x60,0x33,0x4,0x20,0x80,0x98,0x88,0xd5,0x8c,0xcb,0x10,0x80,0x0,0x62,0x4, 0xe5,0x46,0x4a,0x32,0x13,0x40,0x0,0x31,0x52,0x9a,0x9d,0x1,0x2,0xc,0x0,0xfa, 0xe0,0x62,0x5a,0x6d,0xf7,0xca,0x68,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-3.png 0x0,0x0,0x1,0x61, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd7,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8c,0x8c,0x8c,0x70,0xd3,0x80,0x6,0x33, 0x12,0x63,0x0,0x40,0x0,0x31,0x21,0x6b,0xfe,0xcf,0x80,0x80,0xc8,0x86,0xe1,0x3, 0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20,0x26,0x64,0x27,0x33,0x32,0x30,0x32, 0x34,0x2,0x21,0x88,0xc6,0xe2,0x5,0xac,0x2e,0x2,0x8,0x20,0x14,0x2f,0x34,0x30, 0x34,0x80,0xd9,0x20,0x1a,0xd9,0xb,0x8d,0x8d,0x8d,0xff,0x71,0x19,0x2,0x10,0x40, 0x4c,0xe8,0x81,0x87,0x2b,0x50,0xa1,0x6,0x61,0x18,0x2,0x10,0x40,0x4c,0xe0,0xc0, 0xc3,0x11,0xe2,0xe8,0xe2,0xf5,0xf5,0xf5,0x8c,0xe8,0x86,0x0,0x4,0x10,0x48,0x11, 0x3,0x34,0x2d,0xfc,0x47,0xc7,0x30,0xb9,0x86,0x86,0x86,0xff,0x50,0x80,0xc1,0x7, 0x8,0x20,0x26,0x74,0xdb,0xd0,0x69,0x6c,0x0,0xd9,0x25,0x0,0x1,0x44,0x76,0x34, 0x2,0xd,0x1,0x87,0x9,0x40,0x0,0x31,0xe1,0xa,0x30,0x2,0x9,0xe9,0x3f,0x48, 0x33,0xc8,0x25,0x0,0x1,0x44,0x52,0x2c,0xa0,0x6b,0x6,0x71,0x0,0x2,0x88,0x5, 0x9b,0x7f,0xf1,0xf8,0x1f,0x45,0x33,0x8,0x0,0x4,0x10,0x49,0x61,0x80,0xae,0x19, 0x4,0x0,0x2,0x88,0x89,0x12,0xcd,0x20,0x0,0x10,0x60,0x0,0xe3,0x27,0x81,0x3, 0x20,0x43,0x31,0xe7,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-9.png 0x0,0x0,0x2,0x62, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xd8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x1,0x8,0x98,0x81,0x98,0xd,0x88,0xb9,0x80,0x98,0x1b,0x8a,0x39,0x18,0x20,0xe0, 0x7,0x10,0x7f,0x85,0xe2,0x6f,0x40,0xfc,0xb,0x88,0xff,0x42,0xe5,0x18,0x0,0x2, 0x88,0x5,0x88,0x19,0xa1,0x34,0x48,0xb3,0x20,0x10,0x8b,0x1,0xb1,0x30,0x10,0xf3, 0x40,0xd5,0x7c,0x1,0xe2,0xb7,0x40,0xfc,0xa,0xca,0xff,0x7,0xc5,0xff,0x41,0x1c, 0x80,0x0,0x2,0x69,0x64,0x2,0x62,0x56,0xa8,0xad,0x20,0xcd,0x8a,0x40,0x2c,0xdf, 0xef,0x6d,0xd7,0xa,0x52,0x0,0x74,0x61,0x3d,0x90,0x7a,0xc,0x55,0x3,0xd2,0xf8, 0x7,0xea,0x2,0x10,0xcd,0x0,0x10,0x40,0x4c,0x48,0x2e,0xe0,0x86,0xda,0xc,0xd6, 0xfc,0xff,0xff,0x7f,0x6,0x10,0x6,0xb2,0x1b,0x81,0x62,0xda,0x40,0xac,0x0,0xc4, 0xa2,0x50,0x75,0x6c,0x50,0x7d,0xc,0x0,0x1,0x84,0x6c,0x0,0xc8,0xcf,0x7c,0xfc, 0xa7,0xf7,0xb5,0x36,0x34,0x34,0xc0,0xbc,0x8,0x33,0xa4,0x18,0xc8,0x54,0x5,0x62, 0x29,0xa8,0x37,0x39,0xa0,0xe1,0xc6,0x0,0x10,0x40,0x4c,0xc,0xa8,0x80,0x19,0x8d, 0xcf,0xc0,0xc8,0xc8,0x8,0x63,0x2a,0x3,0xb1,0xc,0x10,0xb,0x21,0xbb,0x2,0x20, 0x80,0x98,0xa0,0x81,0xf1,0x7,0x1a,0xba,0xdf,0x3e,0x9a,0x3a,0xf5,0xc2,0x5c,0x0, 0xd2,0x8c,0xe4,0x95,0x8,0xa0,0x90,0x1c,0x34,0x9c,0x78,0xa1,0x6,0x30,0x1,0x4, 0x10,0xb2,0x1,0xa0,0x68,0xfa,0x0,0xa,0x6d,0x60,0xc0,0x6d,0x86,0x69,0x46,0x3, 0xd2,0x40,0x2c,0x2,0x35,0x80,0x1d,0xe4,0x62,0x80,0x0,0x62,0x82,0x86,0xec,0x6f, 0x68,0x1c,0x83,0xa2,0xeb,0x19,0x10,0x3f,0x40,0xd7,0x9,0x75,0x45,0x24,0xd4,0xb, 0x7c,0xb0,0x70,0x0,0x8,0x20,0x74,0x17,0xbc,0x3,0xe2,0x27,0x40,0x7c,0xf,0xe8, 0x8a,0x55,0x48,0xfe,0x47,0x6,0xa0,0xf4,0xc1,0x9,0xf3,0x2,0x40,0x0,0xb1,0x40, 0x5,0x41,0xf1,0xfa,0x13,0x88,0x3f,0x3,0xf1,0x6b,0x20,0x7e,0x8,0x8d,0x32,0x6c, 0x80,0x19,0x1a,0x6b,0xe0,0x34,0x4,0x10,0x40,0xc8,0xb1,0xf0,0x17,0x9a,0x6c,0xdf, 0x43,0xbd,0x71,0x7,0xe8,0x8a,0x69,0x30,0x57,0x20,0xb9,0xe6,0x7,0xd4,0xdb,0x60, 0x0,0x10,0x40,0xc8,0x6,0xfc,0x87,0xc6,0xc4,0x57,0xa8,0x2b,0x40,0xe1,0x70,0x3, 0x68,0xc8,0x24,0x34,0xaf,0x7c,0x80,0x1a,0x2,0xce,0xf,0x0,0x1,0x84,0x9e,0xe, 0x60,0xae,0xf8,0x8,0x75,0xc5,0x2d,0x20,0xbe,0xc,0x34,0xa4,0xa,0x49,0xcd,0x4b, 0x20,0xfe,0x4,0xb5,0xec,0x1f,0x40,0x0,0xa1,0x1b,0x0,0xb,0xd0,0x6f,0xd0,0x0, 0x7d,0xc,0x35,0xe4,0x1a,0xd0,0x90,0x48,0xa8,0x9a,0xe7,0x50,0xb,0xc0,0x5e,0x1, 0x8,0x20,0x16,0x2c,0x81,0xf4,0x17,0x6a,0xfa,0x17,0x28,0xff,0x3b,0xd4,0x30,0xe, 0xa0,0x21,0xa6,0xd0,0x80,0xfe,0x2,0xf3,0x6,0x40,0x80,0x1,0x0,0xcb,0x7b,0x92, 0x92,0x74,0x98,0x65,0xe6,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-2-2.png 0x0,0x0,0x1,0x35, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xab,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0xc4,0x42,0x48,0x1,0x23,0x23,0x23,0xd6,0x40,0x2,0x86, 0x1d,0x23,0x88,0x6,0x8,0x20,0x46,0x7c,0x81,0x8,0xd2,0x8c,0x4d,0x1e,0x28,0xe, 0x37,0x4,0x20,0x80,0x98,0xc8,0xd1,0xdc,0xd0,0xd0,0x0,0xe7,0x3,0x4,0x10,0x13, 0x25,0x9a,0x41,0x0,0x20,0x80,0x98,0xc8,0xd1,0xc,0xa2,0x61,0x61,0x0,0x10,0x40, 0x4c,0x94,0x68,0x6,0x1,0x80,0x0,0x62,0x41,0xf,0x6d,0x58,0x0,0x21,0x3,0x5c, 0x9a,0x41,0x0,0x20,0x80,0x58,0xd0,0xa2,0x6,0x6c,0x6,0x88,0x9,0xa3,0x61,0x6, 0x62,0xd3,0xc,0x2,0x0,0x1,0x4,0x8f,0x46,0xa8,0xf3,0x51,0x34,0x43,0x84,0x21, 0x2e,0xc3,0xa6,0x19,0x4,0x0,0x2,0x88,0x5,0x47,0xa2,0x41,0xa1,0x71,0x69,0x6, 0x1,0x80,0x0,0x62,0xa4,0x34,0x37,0x2,0x4,0x10,0xc5,0x79,0x1,0x20,0xc0,0x0, 0x7e,0xfc,0x56,0x9c,0x4c,0xe5,0xd4,0xef,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-7.png 0x0,0x0,0x1,0x54, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xca,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0xe1,0x52,0xc0,0xc8,0xc8,0x88,0x17,0xc3,0x0,0x40,0x0,0xb1,0xe0,0xd2,0x7c,0xe0, 0xc0,0x1,0xac,0x6,0x3b,0x38,0x38,0x30,0x80,0xc2,0xd,0xe6,0x2,0x80,0x0,0x62, 0x22,0x55,0x73,0x43,0x43,0x3,0x8a,0xb,0x0,0x2,0x88,0x89,0x34,0x9b,0x19,0xc0, 0x6,0x20,0xc7,0x1c,0x40,0x0,0xb1,0x20,0x6b,0x86,0x29,0xc4,0x6,0x40,0x7a,0x40, 0x4a,0x60,0x2e,0x0,0xd1,0x20,0x0,0x10,0x40,0x4c,0x8,0x5,0xff,0xa1,0xa6,0x33, 0x60,0xc5,0x20,0xcd,0x20,0xd7,0xa1,0xbb,0x0,0x20,0x80,0x30,0x5c,0x0,0x35,0x18, 0x3,0x80,0x34,0xc3,0x2,0x10,0x19,0x0,0x4,0x10,0xb,0xb2,0xb,0x40,0x21,0x8b, 0xcb,0xb,0xd8,0x34,0x83,0x0,0x40,0x0,0x61,0xb8,0x0,0x17,0xc0,0x95,0xe4,0x1, 0x2,0x88,0x85,0x90,0x2,0x42,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4, 0x82,0x9e,0xb6,0x49,0x5,0x0,0x1,0xc4,0x48,0x69,0x76,0x6,0x8,0x30,0x0,0x3e, 0x20,0x57,0x3d,0x6b,0xb0,0x24,0x78,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-11.png 0x0,0x0,0x1,0x2c, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa2,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb6,0x1,0x8c,0x8c, 0x8c,0x60,0xa7,0x3,0x4,0x10,0x13,0xb2,0x0,0x4c,0x10,0x46,0xe3,0xd3,0xc,0x4, 0x8c,0x20,0x36,0x40,0x0,0xc1,0xd,0x80,0x9,0x90,0xa,0x0,0x2,0x88,0x5,0xd9, 0x46,0x90,0x21,0xc8,0xa6,0x23,0xbb,0x4,0x59,0xc,0xd9,0x32,0x80,0x0,0x62,0x42, 0xd6,0x8c,0xcd,0x8f,0x84,0x0,0x40,0x0,0x81,0x34,0x91,0x1c,0x8f,0xc8,0x96,0x1, 0x4,0x10,0x13,0x4c,0x0,0x26,0x88,0xcc,0xc6,0xc5,0x47,0x76,0x25,0x40,0x0,0x61, 0xb8,0x0,0x5f,0x60,0xc2,0xfc,0x8f,0xec,0x3d,0x80,0x0,0x2,0x89,0x60,0x4,0xc, 0xa1,0xb8,0x47,0xe,0x50,0x80,0x0,0x62,0xa4,0x24,0x29,0x83,0xc,0x0,0x8,0x20, 0x46,0x4a,0xf3,0x2,0x40,0x0,0x51,0x9c,0x17,0x0,0x2,0x88,0x62,0x3,0x0,0x2, 0x88,0x62,0x3,0x0,0x2,0xc,0x0,0x5c,0x96,0x59,0xd,0x4d,0x49,0x91,0x82,0x0, 0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-17.png 0x0,0x0,0x1,0x51, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc7,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0xc4,0x82,0x4d,0x90,0x91, 0x91,0x11,0xc3,0x59,0x40,0x97,0x32,0x62,0x53,0xb,0x10,0x40,0x2c,0xe8,0x1a,0x1b, 0x1a,0x1a,0xb0,0x2a,0x6,0xc9,0x61,0x13,0x7,0x8,0x20,0xb8,0x1,0x8d,0x8d,0x8d, 0xff,0x71,0xd9,0x2,0x73,0x1,0x36,0x43,0x0,0x2,0x8,0x24,0xc1,0x0,0xd,0xc8, 0xff,0x30,0x36,0x3a,0x6,0xc9,0x1,0x5d,0xf6,0x1f,0x99,0x86,0xc9,0x1,0x4,0x10, 0x23,0x2c,0x16,0x70,0x39,0x11,0x5b,0xb8,0x20,0xab,0x3,0x8,0x20,0x46,0x52,0xa2, 0x11,0x9b,0x25,0x0,0x1,0xc4,0x48,0x69,0x3a,0x0,0x8,0x20,0x26,0x90,0xa9,0xa0, 0x0,0x44,0xa6,0xb1,0x29,0x6c,0x4,0x89,0x83,0xd4,0x20,0xd3,0x40,0x0,0x10,0x40, 0x4c,0xa0,0x68,0x3,0x1,0x18,0x8d,0xb,0xd4,0xa3,0xd1,0x30,0x0,0x10,0x40,0x4c, 0x84,0x34,0xc2,0x5d,0x80,0x43,0x1c,0x20,0x80,0x88,0x36,0xa0,0x1e,0x87,0x38,0x40, 0x0,0x81,0x42,0x94,0xa8,0x64,0xdb,0x88,0x25,0x6c,0xea,0x81,0xea,0x0,0x2,0x88, 0xe2,0x58,0x0,0x8,0x20,0x8a,0x73,0x23,0x40,0x80,0x1,0x0,0xaf,0x3c,0x7a,0x77, 0xa1,0xed,0xed,0x66,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-7-3.png 0x0,0x0,0x1,0xc4, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x3a,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x1,0xf,0x60,0x6,0x62,0x56,0x20,0xe6,0x82,0x62,0xe,0x28,0xff,0x3f,0x10,0x7f, 0x3,0x61,0x80,0x0,0x62,0x22,0x52,0x33,0x3f,0x10,0xb,0x3,0xb1,0x18,0x10,0x8b, 0xf4,0x79,0xd9,0x5e,0x7,0xd2,0x3c,0x20,0x3,0x1,0x2,0x88,0x89,0x4,0xcd,0xa2, 0x50,0xcd,0x87,0x1a,0x1b,0x1b,0x41,0x6a,0xd8,0x41,0xea,0x0,0x2,0x88,0x89,0x4, 0xcd,0xc2,0x40,0xcd,0x1b,0x41,0x9a,0x3f,0x9a,0x3a,0x79,0x40,0xd5,0xfe,0x3,0x8, 0x20,0x26,0x22,0x35,0xb,0x2,0x35,0xaf,0x80,0x6a,0xe,0x1,0xf2,0x7f,0x2,0xf1, 0xf,0x10,0xd,0x10,0x40,0x4c,0x44,0x6a,0x5e,0xa,0xd5,0x1c,0x9,0xe4,0x7f,0x1, 0xe2,0x4f,0x40,0xfc,0x15,0x88,0x7f,0x1,0x4,0x10,0x13,0x9,0x9a,0xa3,0x81,0xfc, 0x8f,0x40,0xfc,0x16,0x88,0xdf,0x43,0xd,0xfa,0x1,0x10,0x40,0x4c,0x24,0x68,0x6, 0x69,0x7a,0xd,0x35,0xe0,0x23,0x34,0x1a,0x7f,0x3,0x4,0x10,0x13,0x25,0x9a,0x81, 0xf8,0x2f,0x40,0x0,0x31,0x41,0x13,0x7,0x28,0x4e,0x5,0xa1,0x6,0xf0,0x13,0xab, 0x19,0xe4,0x77,0x80,0x0,0x2,0x19,0xc0,0x6,0xc4,0xdc,0x40,0xcc,0x7,0x32,0x8, 0xa8,0x79,0x39,0xb1,0x9a,0x41,0x0,0x20,0x80,0x58,0xa0,0x9,0x2,0xe4,0xa,0x76, 0xa0,0xe6,0x35,0x50,0xcd,0x11,0xd0,0x90,0xc6,0xab,0x19,0x4,0x0,0x2,0x88,0x5, 0xea,0xa,0x6,0xa0,0xe6,0x1d,0x50,0xcd,0xfe,0x50,0xc5,0x1f,0x8,0x69,0x6,0x1, 0x80,0x0,0x62,0x81,0xa,0xfe,0x84,0x6a,0xb6,0x83,0xf2,0xbf,0x42,0x5d,0x80,0x57, 0x33,0x8,0x0,0x4,0x10,0xb,0x34,0x45,0x31,0x1,0x35,0x6b,0x2,0x69,0x46,0xa8, 0xe2,0x1f,0xb0,0xdc,0x86,0x4f,0x33,0x8,0x0,0x4,0x10,0xb,0x34,0x59,0x82,0xb2, 0xe7,0x2f,0x28,0xfd,0x7,0xca,0xfe,0x4d,0x48,0x33,0x8,0x0,0x4,0x18,0x0,0x8e, 0x4,0x90,0x75,0xbc,0x65,0x14,0x5c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-2.png 0x0,0x0,0x1,0xe9, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x5f,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x48, 0x80,0x81,0x81,0x81,0x1b,0x88,0xf9,0x81,0x58,0x0,0x8a,0x79,0x81,0x98,0x7,0x88, 0x39,0x18,0x20,0xe0,0x7,0x10,0x7f,0x5,0xe2,0x77,0x40,0xfc,0x1a,0x4a,0x7f,0x1, 0xe2,0xef,0x0,0x1,0xc4,0x2,0xd5,0x2c,0xc,0xc4,0x92,0x40,0x2c,0x3,0xa5,0x41, 0x7c,0xc1,0x7e,0x6f,0xbb,0x78,0x90,0x6e,0xa0,0x25,0xb,0x81,0xd4,0x47,0x20,0x7e, 0x1,0xc4,0x8f,0x80,0xf8,0x9,0x10,0xbf,0x1,0x19,0x4,0x10,0x40,0x2c,0x50,0xdb, 0xc4,0x80,0x58,0x19,0xa8,0x61,0x2a,0x54,0xc3,0x1,0x20,0xdb,0xe1,0xff,0xff,0xff, 0x60,0xeb,0x19,0x19,0x19,0xe3,0xa1,0x2e,0x1,0xc9,0x4d,0x6,0x19,0xe,0x35,0x88, 0x1d,0x20,0x80,0x40,0x6,0xf0,0x1,0xb1,0x4,0x48,0x33,0x92,0x6,0x7,0x6,0x34, 0x80,0x24,0x97,0xb,0x34,0x64,0x1,0xd4,0x62,0x56,0x80,0x0,0x62,0x82,0xfa,0x59, 0x9c,0x81,0x34,0xa0,0x0,0xb4,0xb0,0xd,0x48,0xab,0x1,0x4,0x10,0x23,0xd0,0xb4, 0x8,0x20,0xc3,0x8,0x88,0x4d,0xd1,0x9c,0xcd,0x80,0x8b,0xd,0x73,0x11,0x88,0xd, 0x10,0x40,0x4c,0x48,0x1,0x48,0x34,0x80,0x19,0x6,0x2,0x0,0x1,0x4,0xa,0x94, 0x7a,0x90,0x18,0x8,0x3,0xd9,0xfb,0x21,0xf2,0xb8,0x1,0xb2,0x3c,0x88,0xd,0x10, 0x40,0x8c,0x50,0x1,0xc,0xe7,0x11,0x3,0x40,0xea,0x1,0x2,0x88,0x9,0xa7,0xd3, 0x88,0xd0,0xc,0x74,0xf1,0x6,0x80,0x0,0x62,0x2,0x12,0x9d,0x30,0x9b,0x49,0x35, 0x4,0x94,0x2a,0x1,0x2,0x8,0xe4,0x82,0x57,0x40,0x43,0xd6,0x22,0x1b,0x42,0x2, 0x78,0x9,0x10,0x40,0x20,0x3,0x9e,0x1,0xf1,0x3d,0x52,0x74,0x41,0x9d,0xbf,0x1c, 0xc8,0x7c,0xe,0x10,0x40,0x4c,0xd0,0x24,0x79,0xb,0x28,0x30,0x83,0x44,0x57,0x3c, 0x4,0xe5,0xd,0x80,0x0,0x62,0x82,0x66,0x90,0xbb,0x40,0x7c,0x5,0x68,0xc8,0x2c, 0x42,0x86,0x40,0x6d,0x9f,0x5,0x64,0x3e,0x0,0x79,0x1f,0x20,0x80,0x98,0xa0,0xb9, 0xc,0xe4,0x8d,0x5b,0x40,0x7c,0x1e,0x28,0xd9,0x4f,0x84,0x4b,0xae,0x43,0x5d,0xf0, 0x6,0x20,0xc0,0x0,0x52,0xe3,0xa2,0xc4,0x8a,0x6d,0xfc,0x1,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-8.png 0x0,0x0,0x1,0x2d, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa3,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x84,0xd7,0x80,0x46,0x46, 0x46,0x82,0xce,0x3,0x8,0x20,0x26,0x64,0xc5,0xc8,0x1a,0x60,0x6c,0x74,0x31,0x74, 0x43,0x1,0x2,0x8,0xa7,0xb,0xea,0xff,0xff,0x67,0x44,0xa6,0x71,0x1,0x80,0x0, 0x62,0x0,0x5,0x22,0x32,0x6e,0x60,0x0,0x51,0xf8,0xd9,0xc8,0x18,0x20,0x80,0x18, 0xb0,0x9,0xc2,0x14,0xa3,0xd3,0xd8,0x30,0x40,0x0,0x31,0xe0,0xb3,0x81,0x18,0x31, 0x80,0x0,0x62,0x4,0x11,0xb8,0x42,0x1b,0xe4,0x7f,0x7c,0x72,0x20,0x1a,0x20,0x80, 0x28,0x76,0x1,0x40,0x0,0x51,0x1c,0x6,0x0,0x1,0x44,0x71,0x2c,0x0,0x4,0x10, 0xb,0x7a,0xc2,0xc1,0x15,0xef,0xc8,0xe1,0x81,0xac,0x6,0x20,0x80,0x98,0x8,0x25, 0x63,0x42,0xc9,0x19,0x20,0x80,0x18,0x70,0xf9,0x8d,0x90,0xdf,0x61,0x18,0x20,0x80, 0x18,0x29,0xcd,0xce,0x0,0x1,0x6,0x0,0x13,0xc1,0x60,0x7a,0x5b,0x22,0x14,0x67, 0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-13.png 0x0,0x0,0x1,0x52, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0x31,0x50,0x8,0x0,0x2,0x88,0x5,0x97,0x4,0x23,0x23,0x23,0xa,0x1f,0x57,0x58, 0x1,0x4,0x10,0xb,0x2e,0x8d,0xd,0xd,0xd,0x58,0xc5,0xd1,0xd,0x2,0x8,0x20, 0x26,0x74,0x45,0x20,0x5,0x30,0xcd,0x20,0x1a,0x99,0xd,0x92,0x43,0x77,0x19,0x40, 0x0,0x31,0xa1,0x6b,0x3e,0x78,0xf0,0x20,0x86,0xb,0x60,0x6c,0x90,0x1c,0xba,0x21, 0x0,0x1,0x84,0x33,0x10,0xf,0x1c,0x38,0xc0,0x40,0x4c,0x1a,0x1,0x8,0x20,0x26, 0xe4,0x40,0x2,0x99,0x6c,0x6f,0x6f,0xf,0x37,0x0,0xdd,0x35,0x20,0x39,0x98,0x4b, 0x61,0x0,0x20,0x80,0x98,0xd0,0x43,0x1a,0xa4,0x0,0xa6,0x1,0x64,0x8,0x72,0x18, 0xa0,0x6b,0x6,0x1,0x80,0x0,0xc2,0x88,0x5,0x98,0x2,0x62,0xa3,0x11,0x20,0x80, 0x70,0xa6,0x3,0x62,0xf3,0x8,0x40,0x0,0x51,0x9c,0x12,0x1,0x2,0x88,0x5,0x3d, 0x6d,0x93,0xa,0x0,0x2,0x88,0x91,0xd2,0xec,0xc,0x10,0x60,0x0,0x9c,0x22,0x58, 0x27,0x89,0xcf,0x42,0x16,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-4-7.png 0x0,0x0,0x1,0x65, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xdb,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x8,0xc8,0xff,0x87,0x62,0x9c,0x0,0x20,0x80,0xf0, 0x19,0xf0,0xff,0xe0,0xc1,0x83,0xc,0x20,0xdc,0xd8,0xd8,0x88,0xd3,0x10,0x80,0x0, 0x62,0xc2,0xa7,0x19,0x6,0x1c,0x1c,0x1c,0x70,0x1a,0x2,0x10,0x40,0x2c,0xb8,0x4c, 0x3e,0x70,0xe0,0x0,0x51,0x61,0x0,0x10,0x40,0x8c,0xc8,0x81,0x8,0xb3,0xa5,0xbe, 0xbe,0x9e,0x1,0xd9,0x5,0xc8,0x6,0x2,0xe5,0x18,0x91,0xc5,0x1,0x2,0x8,0x6c, 0x0,0x4c,0x23,0xc8,0xa9,0xf6,0xf6,0xf6,0x18,0x9a,0xb1,0xb9,0xa,0x66,0x10,0x40, 0x0,0x81,0xbc,0xf0,0x1f,0xa4,0x91,0x58,0x80,0xa4,0x16,0x64,0x29,0x23,0x40,0x0, 0x31,0x31,0x50,0x8,0x0,0x2,0x8,0x64,0x0,0x23,0xc8,0xd9,0xa4,0x0,0xa8,0x7a, 0xb0,0x17,0x0,0x2,0x8,0x39,0x10,0x51,0xa2,0x9,0x3d,0x1c,0xd0,0x2c,0x81,0x7, 0x24,0x40,0x0,0x31,0x80,0xc,0xc0,0x82,0x31,0x40,0x43,0x43,0xc3,0x7f,0x6c,0x6a, 0x1,0x2,0x8,0x67,0x3a,0xc0,0x15,0x13,0xe8,0x0,0x20,0x80,0x70,0x5,0x22,0x4a, 0xb8,0x80,0xa2,0xf,0x3d,0xfe,0x61,0x0,0x20,0x80,0x18,0x9,0xe4,0xc6,0xff,0x18, 0x7e,0x46,0x3,0x0,0x1,0xc4,0x42,0x28,0xa5,0x12,0xf2,0x2,0x40,0x80,0x1,0x0, 0x52,0xe3,0x7a,0xe4,0xee,0x8e,0x19,0xe1,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-6.png 0x0,0x0,0x1,0x53, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0xb0,0x9,0x32,0x32,0x32,0xc2,0x4d,0x5,0x5a,0xc0, 0x88,0xcf,0x0,0x80,0x0,0x62,0xc1,0xa6,0x19,0x59,0x13,0x3a,0x1f,0x1d,0x0,0x4, 0x10,0x13,0x3e,0xd3,0x91,0x5d,0x82,0xb,0x0,0x4,0x10,0x13,0x3e,0xcd,0xd,0xd, 0xd,0x4,0xd,0x2,0x8,0x20,0x90,0x1f,0x51,0x30,0xc8,0xdb,0x20,0xc,0xd4,0xc, 0x72,0xfa,0x7f,0x48,0x30,0x40,0x68,0x28,0x1b,0x45,0x3d,0x40,0x0,0x61,0x35,0x0, 0xa6,0x19,0x44,0xa3,0x1b,0x86,0x6e,0x10,0x40,0x0,0xe1,0xd5,0x8c,0xec,0x2,0x5c, 0x86,0x0,0x4,0x10,0x31,0x9a,0x19,0x70,0x19,0x2,0x62,0x2,0x4,0x10,0x4e,0xcd, 0xb8,0x5c,0x0,0xf3,0x16,0xcc,0x0,0x80,0x0,0x62,0xc0,0x66,0x3,0x3e,0x1a,0xdd, 0xb,0x0,0x1,0x84,0xe2,0x5,0x62,0x34,0x23,0xc7,0x14,0x88,0xd,0x10,0x40,0x18, 0x81,0x48,0x48,0x33,0xba,0x1,0x0,0x1,0x84,0x35,0x1a,0xf1,0x69,0x46,0x37,0x0, 0x20,0x80,0x30,0xc,0x40,0x37,0x4,0x6b,0xe2,0x41,0x32,0x0,0x20,0x80,0x58,0x70, 0xa4,0x4e,0x46,0x58,0xf2,0xc5,0x95,0x91,0x60,0xe2,0x0,0x1,0x6,0x0,0x7c,0x5b, 0xb5,0x34,0x9c,0xc8,0x30,0x39,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-12.png 0x0,0x0,0x1,0xb, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x81,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0xc4,0x82,0xc2,0x63,0x64,0x44,0xd,0x90,0xff,0xff,0x19, 0xf1,0x8a,0x3,0x1,0x40,0x0,0xb1,0x60,0x18,0x89,0x24,0x9,0xd6,0x8,0xe3,0x23, 0x8b,0x23,0x1,0x80,0x0,0xa2,0xd8,0xb,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0xc4, 0x42,0xb4,0x4a,0xe4,0x70,0x40,0xf2,0xe,0x40,0x0,0x11,0x6f,0x0,0x8e,0x30,0x0, 0x8,0x20,0x8a,0xbd,0x0,0x10,0x40,0x14,0x1b,0x0,0x10,0x40,0x2c,0xc4,0xfa,0x15, 0x97,0x38,0x40,0x0,0x31,0x52,0x9a,0x99,0x0,0x2,0x88,0x62,0x2f,0x0,0x4,0x10, 0xc5,0x6,0x0,0x4,0x18,0x0,0xaf,0x42,0x1e,0x20,0xd5,0x8a,0xd2,0xa2,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-21.png 0x0,0x0,0x1,0x3a, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xb0,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x41,0x12,0x20,0x5a,0x33,0xd0,0x42,0x38,0x1b,0x20, 0x80,0x98,0xd0,0x25,0xf,0x1e,0x3c,0x48,0x90,0x8d,0xc,0x0,0x2,0x88,0x9,0xdd, 0x64,0x7,0x7b,0x7,0xb0,0x62,0x8,0xdb,0x1e,0x89,0xed,0x80,0xd5,0x10,0x80,0x0, 0x62,0x0,0x5,0x62,0x43,0x43,0xc3,0x7f,0x18,0x20,0x81,0xd,0xd6,0xb,0x10,0x40, 0x18,0x5e,0x70,0x70,0x70,0x20,0xc8,0x46,0x6,0x0,0x1,0x84,0xe1,0x5,0x7b,0x24, 0x2f,0xd8,0x3b,0x20,0xb1,0x71,0x78,0x1,0x20,0x80,0x28,0xf6,0x2,0x40,0x0,0x51, 0xec,0x5,0x80,0x0,0x22,0x3e,0x16,0x1c,0xec,0xb1,0x7a,0x1,0x20,0x80,0x28,0xf6, 0x2,0x40,0x0,0x61,0x18,0x40,0xc,0x40,0x36,0x0,0x20,0x80,0x60,0x49,0xf9,0x11, 0x72,0xf2,0x24,0x5,0x0,0x4,0x10,0x23,0xa5,0xb9,0x11,0x20,0x80,0x98,0x18,0x28, 0x4,0x0,0x1,0x6,0x0,0xe1,0xa2,0x1d,0x3c,0x1d,0x74,0xd5,0x4b,0x0,0x0,0x0, 0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-13.png 0x0,0x0,0x1,0x66, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xdc,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x60,0x8c,0xc6,0xc6,0x46,0xc,0x93,0xea,0xeb,0xeb, 0x19,0x9,0x19,0x0,0x10,0x40,0x2c,0xa8,0x1a,0x1a,0x18,0x10,0x6,0x36,0x10,0xe5, 0x2,0x80,0x0,0x62,0xc2,0x26,0x8,0xd2,0x4c,0x8c,0xed,0x20,0x0,0x10,0x40,0x4c, 0xc4,0x28,0x2,0x79,0xf,0x9b,0x17,0x41,0x0,0x20,0x80,0x98,0xf0,0xd9,0xe,0xd3, 0x88,0xec,0x35,0x74,0x0,0x10,0x40,0x2c,0xb8,0x6c,0x44,0xf,0x13,0x64,0x39,0x64, 0xef,0x1,0x4,0x10,0x56,0x3,0xf0,0xd9,0xd8,0xd0,0x0,0x96,0x83,0x1b,0x2,0x10, 0x40,0xc,0xa0,0x74,0x0,0xc2,0x40,0x9,0x90,0xad,0x44,0x63,0x90,0x7a,0x90,0x3e, 0x80,0x0,0x42,0x71,0x1,0x28,0x4d,0x21,0x47,0x1f,0x7a,0xb4,0x82,0x6c,0x5,0x2, 0x90,0x66,0x78,0x38,0x1,0x4,0x10,0x13,0x2e,0xe7,0x83,0x14,0x80,0x34,0xa1,0xa7, 0x7,0x64,0xcd,0x20,0x0,0x10,0x40,0x28,0x5e,0x80,0x32,0xc1,0x18,0xe6,0x44,0x98, 0x1c,0x32,0x1f,0x19,0x3,0x4,0x10,0x3,0xa6,0x22,0xec,0x86,0xe0,0xc2,0x0,0x1, 0x84,0x21,0x40,0xaa,0x21,0x0,0x1,0x44,0x30,0x25,0x82,0xc2,0x4,0x57,0x2a,0x4, 0x1,0x80,0x0,0x62,0xc1,0x96,0x3,0x1b,0x1b,0x19,0x88,0xce,0xe3,0x0,0x1,0x6, 0x0,0x15,0xcc,0xe9,0x89,0xb0,0x32,0x8,0xa9,0x0,0x0,0x0,0x0,0x49,0x45,0x4e, 0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-1.png 0x0,0x0,0x1,0x50, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc6,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x88,0x51,0xc4,0xc8,0xd8,0x88,0xd5,0x96,0xff,0xff, 0xeb,0x19,0x1,0x2,0x88,0x89,0x81,0x42,0x0,0x10,0x40,0x14,0x1b,0x0,0x10,0x40, 0x2c,0x98,0xce,0x65,0x24,0x10,0x28,0xd,0x28,0x3c,0x80,0x0,0x62,0xc1,0xf4,0xd7, 0x7f,0x46,0x90,0x21,0xd8,0x2,0x17,0x28,0x8e,0x21,0x6,0x10,0x40,0x58,0xbd,0xd0, 0xd0,0xd0,0x80,0x55,0x31,0x36,0x0,0x10,0x40,0x4c,0x30,0x67,0x37,0x36,0x42,0x42, 0x1a,0x44,0x83,0xc,0x20,0x36,0x7a,0x1,0x2,0x8,0xac,0x10,0xa8,0xe1,0x3f,0xc4, 0xf5,0xff,0xa1,0x42,0xd8,0x1,0x4c,0xd,0x32,0x6,0x8,0x20,0x4,0x3,0x28,0x9, 0x32,0x8,0x9b,0x21,0x30,0x3e,0x36,0x3,0x0,0x2,0x8,0xce,0x40,0x76,0x5,0xb2, 0x21,0x30,0x83,0x41,0x34,0x36,0x3,0x0,0x2,0x8,0x95,0x83,0xe4,0xa,0x5c,0x7c, 0x74,0x3,0x0,0x2,0x8,0x85,0x83,0xee,0xa,0x62,0x30,0x40,0x0,0x61,0xa,0xa0, 0xd9,0x4a,0x8,0x3,0x4,0x10,0x23,0x7a,0x74,0xc1,0x52,0x22,0x28,0x41,0x11,0x13, 0x8b,0x0,0x1,0xc4,0x48,0x69,0x76,0x6,0x8,0x30,0x0,0xd9,0x7f,0x29,0xad,0xbe, 0x7b,0x1c,0x8d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-6.png 0x0,0x0,0x1,0xff, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x75,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0xc8, 0x96,0x81,0x81,0x41,0x16,0x88,0x85,0x81,0x98,0x3,0x88,0x7f,0x3,0xf1,0x47,0x20, 0x7e,0xb,0xc4,0x9f,0x19,0x20,0x80,0x17,0x2a,0xcf,0xf,0xc4,0xac,0x40,0xfc,0x3, 0x2a,0xff,0x18,0x20,0x80,0x18,0x80,0x6,0x44,0x1,0x19,0xff,0xb1,0x61,0xa0,0x5c, 0x22,0x8,0xe3,0x91,0x8f,0x2,0x8,0x20,0x26,0xa8,0xc9,0xc,0xff,0xff,0xff,0x87, 0x63,0x10,0x0,0x4a,0xb6,0x3,0x29,0x1,0x10,0x86,0xb2,0x31,0xd4,0x80,0xf4,0x2, 0x4,0x10,0x13,0xd4,0xd9,0x70,0xc0,0xc8,0xc8,0x8,0xd2,0xbc,0x19,0xea,0x54,0x38, 0x6,0x89,0x81,0xe4,0xd0,0x0,0x7,0x40,0x0,0x31,0x41,0xfd,0xc,0xd7,0xc,0x32, 0xbd,0xdf,0xdb,0xce,0x17,0xea,0x4c,0x18,0xf8,0xf,0x12,0x3,0xc9,0xa1,0x19,0xf2, 0x1b,0x20,0x80,0x98,0xa0,0x1,0x6,0xb7,0x19,0xc9,0x90,0x52,0x68,0x60,0xfd,0x0, 0xb1,0x61,0x9a,0xd1,0x5c,0xf2,0x11,0x20,0x80,0x98,0xa0,0xa1,0x9,0xf3,0xf3,0x4d, 0x20,0xdd,0xd,0x55,0x98,0x1,0xe4,0x7f,0x0,0x61,0x10,0x1b,0x2a,0xd6,0xd,0x55, 0xd3,0xe,0x35,0xe0,0x2d,0x40,0x0,0x31,0x2,0x39,0x8e,0x40,0x86,0x2,0x34,0xc0, 0x58,0xa1,0x12,0x3f,0xa0,0x9a,0xbf,0x43,0xf9,0x9c,0x50,0x79,0x58,0x78,0xfd,0x86, 0xca,0x3f,0x0,0x8,0x20,0x26,0x6,0xa,0x1,0x40,0x0,0x81,0xc,0xe0,0x5,0xfa, 0x71,0x1e,0x90,0x16,0x85,0x62,0x11,0x20,0x7f,0x22,0xd4,0x56,0x38,0x86,0x8a,0x89, 0xc0,0xd4,0x41,0xf5,0xf0,0x2,0x4,0x10,0x3,0x72,0x42,0x1,0xb2,0x37,0x41,0xa2, 0xfb,0x3f,0x8c,0x9f,0x7,0xc2,0x68,0x62,0x9b,0x90,0x13,0x1a,0x40,0x0,0xb1,0x40, 0x93,0x27,0x3,0x34,0x94,0x7d,0x91,0x42,0xbb,0x1b,0xe6,0x67,0x68,0xc0,0x96,0xa2, 0xab,0x1,0xe9,0x5,0x8,0x20,0x26,0xa4,0x80,0x63,0x40,0x8e,0x2a,0x50,0xcc,0x22, 0xa7,0x2f,0xe4,0x28,0x46,0x2,0xac,0x0,0x1,0xc4,0x4,0xd,0x71,0x6,0x64,0x43, 0xa0,0x9,0xe9,0x37,0x32,0x86,0x25,0x24,0x34,0xf0,0x3,0x20,0x80,0xe0,0xe9,0x0, 0x64,0x3a,0xc,0x83,0x0,0x50,0x43,0x25,0x2c,0x1d,0x40,0xd9,0x18,0x6a,0x40,0x7a, 0x1,0x2,0x88,0x91,0xd2,0xec,0xc,0x10,0x60,0x0,0x7c,0xc2,0xd7,0x8f,0x1b,0xcb, 0x90,0x1c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-21.png 0x0,0x0,0x1,0x4c, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc2,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xd8,0x0,0x46,0xc6, 0xff,0x60,0x8c,0x43,0xc,0x20,0x80,0x18,0xa0,0x5e,0xf8,0x8f,0xd,0x83,0xe4,0x1a, 0x40,0x34,0xc,0x3,0x49,0x18,0xbb,0x1,0xca,0x7,0x8,0x20,0xb8,0x1,0x38,0x0, 0x3,0x86,0x21,0x48,0x9a,0x41,0x18,0x20,0x80,0x18,0xc1,0x4,0x23,0xe3,0x7f,0x28, 0x8d,0xe1,0x3,0xa0,0x38,0x23,0xdc,0xd9,0x8,0x41,0xb8,0x42,0x80,0x0,0x62,0x42, 0x53,0x8c,0x8e,0x51,0x34,0x37,0x22,0x87,0x1,0x14,0x0,0x4,0x10,0x8a,0x17,0xb0, 0x85,0x1,0xba,0xb3,0xd1,0xc3,0x4,0x20,0x80,0x50,0xbc,0x80,0x2d,0xe,0x1a,0xa1, 0xb6,0xd5,0x23,0x39,0x1b,0x59,0xc,0x20,0x80,0x88,0xf,0x3,0x1c,0x0,0x20,0x80, 0x58,0xd0,0xc3,0x0,0xb,0x80,0x9,0x62,0x35,0x8,0x20,0x80,0x58,0x50,0xd3,0x7, 0x6e,0xcb,0x40,0x4e,0x4,0xc9,0xa3,0xbb,0x8,0x20,0x80,0x88,0x71,0x1,0x5e,0x0, 0x10,0x40,0xa4,0xb8,0x0,0xab,0x38,0x40,0x0,0x51,0xec,0x2,0x80,0x0,0x62,0x21, 0xc6,0x76,0x7c,0x0,0x20,0xc0,0x0,0x49,0x70,0xbc,0x23,0x76,0xb0,0x1c,0xf2,0x0, 0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-22.png 0x0,0x0,0x1,0x53, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x41,0x12,0x60,0x38,0x78,0xf0,0x20,0x8a,0x22,0x7b, 0x7b,0x7b,0xac,0x62,0x40,0xb,0xe1,0x7c,0x80,0x0,0x62,0x42,0x96,0x3c,0x70,0xe0, 0x0,0x83,0x83,0xbd,0x3,0x18,0x23,0x8b,0xd9,0x3b,0x38,0x80,0x31,0x36,0x0,0x10, 0x40,0x4c,0xc,0x14,0x2,0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0x62,0x41,0x17,0x68, 0x68,0x6c,0x80,0x38,0x1d,0x8,0x41,0xfe,0x5,0x7,0x72,0x3,0x44,0xc,0x9b,0x27, 0x0,0x2,0x88,0x5,0x2d,0x64,0xb1,0x85,0x36,0x5e,0x17,0x0,0x4,0x10,0x8a,0x1, 0xc4,0xc6,0x2,0x32,0x0,0x8,0x20,0x8c,0x58,0xb0,0x7,0xc6,0x80,0x3d,0x5a,0x2c, 0x38,0x0,0x35,0x39,0xa0,0x69,0x84,0x1,0x80,0x0,0xa2,0x38,0x10,0x1,0x2,0x88, 0x62,0x3,0x0,0x2,0x8,0x23,0x16,0x1a,0xa1,0xb1,0xc0,0x80,0x14,0xb,0xd,0xd0, 0x94,0x77,0x0,0x4b,0x18,0x0,0x4,0x10,0x23,0x28,0x33,0x51,0x92,0x17,0x0,0x2, 0x88,0x91,0xd2,0xdc,0x8,0x10,0x40,0x14,0x87,0x1,0x40,0x80,0x1,0x0,0xdc,0x8e, 0x3d,0x8c,0xd1,0xdd,0x44,0x10,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-10.png 0x0,0x0,0x1,0x23, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x99,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xf0,0xc8,0x11,0x65,0x32,0x40,0x0,0x61,0x35,0xa0, 0xb1,0xb1,0xf1,0x3f,0xb1,0x86,0x0,0x4,0x10,0x3e,0x17,0x80,0xc,0x22,0x68,0x8, 0x40,0x0,0xe1,0x35,0xa0,0xbe,0xbe,0x9e,0x91,0x90,0x21,0x0,0x1,0xc4,0x44,0xc8, 0x89,0x84,0xc,0x1,0x8,0x20,0x26,0x62,0x2,0xa,0x9f,0x21,0x0,0x1,0xc4,0x44, 0x6c,0x74,0xe1,0x32,0x4,0x20,0x80,0x98,0x48,0x89,0x73,0xa0,0x21,0xb0,0x80,0x85, 0x3,0x80,0x0,0x22,0xc5,0x80,0xff,0x20,0xcd,0x20,0x97,0x20,0xb,0x2,0x4,0x10, 0x13,0x25,0x9a,0x41,0x0,0x20,0x80,0x98,0x28,0xd1,0xc,0x2,0x0,0x1,0xc4,0x44, 0x89,0x66,0x10,0x0,0x8,0x20,0x82,0x29,0x11,0x9f,0x66,0x10,0x0,0x8,0x20,0x26, 0x4a,0x34,0x83,0x0,0x40,0x0,0x31,0x52,0x9a,0x9d,0x1,0x2,0xc,0x0,0x79,0xd1, 0x36,0x1d,0x65,0xc3,0x44,0xcf,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-4.png 0x0,0x0,0x0,0xfe, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x74,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x41,0x12,0x20,0x5a,0x33,0xd0,0x42,0x38,0x1b,0x20, 0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0, 0x1,0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x44, 0xb1,0x1,0x0,0x1,0xc4,0x82,0x2d,0x79,0x92,0x2,0x0,0x2,0x88,0x91,0xd2,0xdc, 0x8,0x10,0x40,0x14,0x7b,0x1,0x20,0xc0,0x0,0x29,0xb,0xe,0xa2,0xb,0xb2,0x5d, 0x4f,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-5.png 0x0,0x0,0x1,0x2f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0xc4,0xc8,0xd0,0xc0,0x80,0x11,0x8,0xff,0xeb,0xff,0x33, 0xe2,0xd5,0xd4,0xc8,0xf8,0x1f,0xa6,0x6,0x20,0x80,0x18,0x40,0x81,0x8,0xe,0xc8, 0x6,0x10,0xf5,0x9f,0x81,0x18,0x8c,0xac,0x16,0x20,0x80,0x98,0x70,0xd9,0x0,0xc2, 0xd8,0xf8,0xe8,0x34,0x40,0x0,0x61,0x98,0x8a,0x6c,0x3a,0xd8,0x7b,0x48,0xfc,0x86, 0x86,0x6,0xc,0x35,0x0,0x1,0xc4,0x82,0xcb,0x5,0xc8,0x61,0x81,0xce,0x47,0x6, 0x0,0x1,0x84,0xd5,0x0,0x98,0xc2,0xc6,0xc6,0x46,0xc,0x83,0xd0,0xd,0x1,0x8, 0x20,0x16,0x6c,0x9a,0x9,0xb9,0xa0,0x1,0x8,0x61,0x86,0x1,0x4,0x10,0x23,0xa5, 0x49,0x19,0x20,0x80,0x28,0x4e,0x48,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x44,0xb1, 0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0x6,0x0,0x9e,0x55,0x8e,0xcf,0x93,0x4a, 0xe6,0x76,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-18.png 0x0,0x0,0x1,0x65, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xdb,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0x94,0x1,0x8d,0x8d,0x8d,0xf,0x41,0x18,0x9b,0x1c,0x40,0x0,0x11,0xed,0x82, 0x86,0xfa,0x7a,0x39,0x6c,0x86,0x0,0x4,0x10,0xb,0xb2,0x2d,0xc4,0x18,0x2,0x54, 0xf8,0xb0,0xbe,0xbe,0x5e,0x1e,0x26,0x6,0x10,0x40,0xc,0xd0,0x58,0x78,0xd8,0xd0, 0xd0,0xf0,0x10,0xcc,0x21,0x2,0x83,0xd4,0xc2,0xb8,0x0,0x1,0x4,0x33,0x0,0x24, 0xf8,0x9f,0x58,0x3,0xa0,0x86,0x1c,0x7,0x31,0x1,0x2,0x8,0xc5,0x0,0x62,0xd, 0x41,0x76,0x1,0x40,0x0,0xb1,0x20,0xfb,0xb1,0xbe,0xbe,0x1,0x18,0x18,0x38,0xfd, 0xf,0xa1,0x1b,0x1b,0x1f,0x21,0x8b,0x3,0x4,0x10,0xdc,0x5,0x20,0x3,0x91,0x69, 0x64,0xc,0x73,0x19,0xb2,0xcd,0x30,0xc,0x10,0x40,0xb0,0x68,0x4,0x9b,0xa,0x54, 0x0,0x35,0x14,0x81,0x61,0xf2,0x20,0x9b,0x51,0x42,0x1f,0xa,0x0,0x2,0x8,0x6e, 0x12,0x28,0x26,0xa0,0xb6,0x3f,0x84,0xb1,0x51,0xf9,0xd8,0x83,0x4,0x20,0x80,0x18, 0x91,0x33,0x13,0x23,0x23,0x23,0x48,0xa1,0x3c,0x88,0x46,0xb2,0x40,0x1e,0x5f,0xda, 0x0,0x8,0x20,0x46,0x4a,0x73,0x23,0x40,0x0,0x51,0x9c,0x99,0x0,0x2,0xc,0x0, 0xb7,0xe6,0x1,0xde,0x26,0xa6,0x19,0x96,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-22.png 0x0,0x0,0x1,0xa5, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x1b,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xc0,0x24,0x23,0xe3,0x7f,0x30,0x26,0x3,0x0,0x4, 0x10,0x53,0x23,0x99,0x1a,0x61,0x0,0x20,0x80,0xc0,0x2e,0x68,0x4,0x11,0xff,0xff, 0x33,0xc2,0x4,0x19,0x81,0x86,0x12,0x8b,0x1,0x2,0x88,0x11,0x12,0x6,0x30,0x57, 0x40,0xc,0x1,0x49,0x10,0x13,0x36,0x40,0x75,0xc,0x0,0x1,0xc4,0xd4,0xd8,0x88, 0xd7,0xb,0x8c,0x30,0xc,0x52,0x8c,0x8c,0x61,0x0,0x20,0x80,0x20,0x5e,0x68,0x44, 0xd8,0x8e,0xa6,0x19,0x44,0xfc,0x87,0xf8,0xf0,0x3f,0xd8,0xb5,0x30,0xc,0x3,0x0, 0x1,0x4,0x16,0x64,0x84,0x7a,0xe1,0x3f,0xa6,0x21,0x8,0x3,0x60,0x6,0x42,0x3, 0x1d,0xac,0xf,0xe8,0x12,0x80,0x0,0x62,0x62,0xc4,0xe2,0x5,0x46,0x88,0x73,0xfe, 0xc3,0x34,0xa3,0xb9,0x4,0xc5,0x5,0x0,0x1,0xc4,0xc2,0x0,0x8d,0x86,0xff,0xf5, 0xd0,0x0,0x6c,0x6c,0x44,0x35,0xb0,0xbe,0x1e,0x42,0x83,0xfc,0x9,0x64,0xc3,0xfc, 0xf,0x33,0x4,0x20,0x80,0x20,0xc,0xa8,0xb1,0xc8,0x7e,0x4,0x8b,0x37,0x34,0x40, 0x18,0x40,0x1a,0xa1,0x4,0x1,0x40,0xe6,0x0,0x4,0x10,0x13,0x86,0x8d,0xe8,0x0, 0x68,0xf3,0xff,0xfa,0x7a,0x46,0x68,0xbc,0x63,0xc4,0x2,0x40,0x0,0x31,0x82,0x6d, 0x1,0x19,0x5,0x54,0x84,0x9c,0x90,0xfe,0xff,0x47,0x9,0xd0,0xff,0xb8,0xd2,0x1, 0x40,0x0,0x41,0x62,0x81,0x11,0x16,0x40,0xc,0x28,0x9,0x9,0xd9,0x26,0x74,0x0, 0x93,0x7,0x8,0x20,0x26,0x46,0x46,0xdc,0x5e,0x40,0xf,0x13,0x6c,0xe9,0x0,0x20, 0x80,0x98,0xa0,0x1e,0x85,0xdb,0x8e,0xe2,0x3c,0x2,0x18,0x4,0x0,0x2,0xc,0x0, 0x8f,0xd,0xb5,0x9a,0xb7,0xe,0x8,0xc,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-4.png 0x0,0x0,0x1,0x42, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xb8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8c,0x8c,0x8c,0x70,0xd3,0x80,0x6,0x33, 0x12,0x63,0x0,0x40,0x0,0x31,0x21,0x6b,0xfe,0xcf,0x80,0x80,0xc8,0x86,0xe1,0x3, 0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20,0x26,0x64,0x27,0x33,0x32,0x30,0x32, 0x34,0x2,0x21,0x88,0x46,0xf3,0xc2,0x7f,0x24,0x8c,0xc2,0x7,0x8,0x20,0x14,0x2f, 0x34,0x30,0x34,0x80,0xd9,0x20,0x1a,0xe6,0x85,0xc6,0xc6,0x46,0x18,0xcd,0x80,0x8d, 0xf,0x10,0x40,0x4c,0xe8,0x81,0x47,0x2a,0x0,0x8,0x20,0x26,0x70,0xe0,0x11,0x19, 0xe2,0xd8,0x0,0x40,0x0,0xb1,0x20,0x6b,0x86,0x79,0x81,0x14,0x0,0x10,0x40,0x4c, 0xe8,0xf1,0x8e,0x4e,0x13,0x2,0x0,0x1,0x44,0x71,0x34,0x2,0x4,0x10,0x13,0xb6, 0x54,0x48,0x4a,0xc0,0x2,0x4,0x10,0xc5,0xb1,0x0,0x10,0x40,0x2c,0xd8,0xfc,0x4b, 0x4a,0xac,0x0,0x4,0x10,0xd1,0x61,0x50,0x5f,0x5f,0x8f,0x95,0xf,0x10,0x40,0x44, 0x19,0x0,0x4a,0x75,0xd0,0x94,0xc7,0x88,0xce,0x7,0x8,0x30,0x0,0xdd,0xb0,0x4c, 0x2f,0xee,0x5b,0x2d,0x60,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-2-3.png 0x0,0x0,0x1,0x5f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xd5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xd0,0x5,0x18,0x19,0x19,0xff,0x83,0x30,0xb1,0x6, 0x0,0x4,0x10,0x13,0xba,0x66,0x20,0x0,0x11,0x8c,0xc4,0x1a,0x2,0x10,0x40,0x4c, 0xd8,0x4,0x49,0x71,0x1,0x40,0x0,0x61,0xf5,0x2,0x2c,0x5c,0x40,0xec,0xc6,0xc6, 0x46,0xbc,0x86,0x1,0x4,0x10,0x3,0x48,0x31,0xc,0x3,0xc1,0x7f,0x18,0x0,0xb1, 0x1b,0x1a,0x1a,0xc0,0x34,0x54,0x9c,0x1,0x1b,0x6,0x8,0x20,0xac,0x9a,0x61,0x6, 0x20,0x98,0x10,0xc3,0xb0,0x19,0x0,0x10,0x40,0x8c,0x60,0x2,0xc9,0xd9,0xd8,0x83, 0x84,0x11,0x66,0x3,0x23,0xba,0x24,0x40,0x0,0x31,0xc1,0x24,0x80,0x0,0xa7,0x66, 0xa0,0xed,0x38,0x83,0x0,0x20,0x80,0x98,0x90,0xc2,0x2,0xdd,0x10,0x46,0x58,0xb4, 0xe2,0xb,0x43,0x80,0x0,0xc2,0xc,0x14,0x68,0x80,0xa1,0x7,0x1c,0xd0,0x11,0x60, 0x26,0x2a,0xfd,0x9f,0x1,0x20,0x80,0xb0,0x87,0x2c,0xd6,0x50,0x47,0xe5,0xc2,0xc, 0x0,0x8,0x20,0x26,0x1c,0xae,0xc2,0x70,0x76,0x63,0x23,0x76,0x1f,0x0,0x4,0x10, 0x13,0xb1,0x29,0xae,0xbe,0x1e,0xbb,0x38,0x40,0x0,0xb1,0x10,0x6b,0x0,0x2e,0x17, 0x0,0x4,0x10,0x23,0xa5,0xd9,0x19,0x20,0xc0,0x0,0x38,0xf8,0xe2,0x78,0xd9,0x52, 0xdc,0xd8,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-8.png 0x0,0x0,0x1,0x39, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xaf,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0xb1, 0xe0,0x52,0x70,0xf0,0xe0,0x41,0xa2,0xc,0x2,0x8,0x20,0x16,0x5c,0x9a,0xed,0xed, 0xed,0x19,0xf0,0xc9,0x1d,0x38,0x70,0x0,0xcc,0x7,0x8,0x20,0x26,0x72,0x34,0x23, 0xbb,0xe,0x20,0x80,0x98,0xc8,0xd1,0x8c,0xac,0x6,0x20,0x80,0x58,0xd0,0xfd,0x8c, 0xcb,0xef,0xc8,0x9a,0x91,0xd5,0x0,0x4,0x10,0x3,0x28,0x1d,0x34,0x34,0x34,0xfc, 0x7,0x1,0xa0,0xbf,0xfe,0xe3,0x2,0x30,0x39,0x18,0xd,0xd5,0xc3,0x0,0x10,0x40, 0x64,0xb9,0x0,0x19,0x0,0x4,0x10,0xb,0x21,0x5,0x84,0xc2,0x7,0x20,0x80,0x48, 0x72,0x1,0x36,0x0,0x10,0x40,0x2c,0x84,0x14,0x10,0x2,0x0,0x1,0xc4,0xc4,0x40, 0x21,0x0,0x8,0x20,0x16,0xf4,0xb4,0x4d,0x2a,0x0,0x8,0x20,0x46,0x4a,0xb3,0x33, 0x40,0x80,0x1,0x0,0x44,0xf2,0x82,0x8b,0xc3,0x16,0xc0,0x0,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-18.png 0x0,0x0,0x1,0xaf, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x25,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0xc0,0x24,0x23,0x23,0xc4,0x94,0xff,0xff,0x19,0x89, 0xd5,0xc8,0xc8,0xc8,0x0,0xd6,0x3,0x10,0x40,0x4c,0x8d,0x30,0xcd,0x78,0x15,0xa3, 0xaa,0x61,0x64,0x6c,0x84,0xf3,0x1,0x2,0x88,0x9,0x44,0x34,0x22,0xd9,0xde,0xd8, 0xd8,0xf8,0x1f,0xa4,0x1,0x19,0x37,0x34,0x34,0x60,0x18,0x2,0xd2,0x5,0xf4,0x3d, 0x23,0x40,0x0,0x31,0x42,0xc2,0x0,0x26,0x9,0x52,0xf,0x12,0xfa,0x8f,0xcb,0x25, 0x40,0x4d,0x10,0x8b,0x80,0x4,0x58,0x11,0x40,0x0,0x31,0x35,0x36,0xa2,0x9a,0xc, 0xb5,0xd,0x5,0x3,0x5d,0x85,0xaa,0xb9,0x11,0xe1,0x5,0x80,0x0,0x62,0x4,0xaa, 0x7,0x73,0xea,0xeb,0x71,0x7,0x20,0xd4,0x55,0x70,0x79,0x98,0x1,0xff,0xeb,0xeb, 0x19,0x1,0x2,0x8,0xec,0x5,0x46,0xa8,0x17,0xfe,0x33,0x90,0x10,0xb,0x50,0x3d, 0x0,0x1,0xc4,0xc4,0xd8,0xc8,0x48,0x72,0x42,0x40,0xd6,0x3,0x10,0x40,0x4c,0xd0, 0x0,0x25,0xc9,0x76,0x64,0x3d,0x0,0x1,0x4,0xf5,0x2,0x3,0xd4,0xb,0xc,0x8c, 0xb8,0xfc,0x8d,0xc5,0x1d,0x60,0x3d,0x0,0x1,0xc4,0x84,0x1c,0xa2,0xc8,0x9a,0x61, 0x71,0x8f,0x8c,0x1b,0xa1,0x6a,0x91,0x63,0xe,0x20,0x80,0x18,0x81,0xf1,0x6,0xf, 0x51,0x24,0x9b,0xf1,0xa6,0x3,0x98,0x1,0xa0,0x98,0x3,0x8,0x20,0x6,0x88,0x62, 0x10,0xf1,0x1f,0xac,0x11,0xaa,0x19,0xe4,0x82,0xff,0x10,0x5f,0x21,0x30,0x48,0xc, 0xa6,0xe6,0x3f,0x54,0x13,0x40,0x0,0x81,0x92,0xce,0x7f,0x74,0x3,0x60,0x86,0x20, 0xf3,0x91,0x71,0x3,0x4c,0x3,0x10,0x3,0x4,0x10,0x13,0x72,0xba,0x46,0x76,0xee, 0x7f,0x2,0x39,0x13,0x96,0x7f,0x0,0x2,0xc,0x0,0x72,0xef,0xc0,0xfd,0xb2,0x78, 0xb0,0x83,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-7-4.png 0x0,0x0,0x2,0x1a, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x90,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x8a,0xb6,0x1d,0x66,0x1,0xd2,0x4c,0x40,0xcc,0x8, 0xc4,0x30,0xd3,0xfe,0x41,0x31,0xb2,0xe9,0x8c,0x48,0x18,0x6,0xfe,0x3,0x4,0x10, 0x48,0x33,0x7,0xc8,0x20,0x20,0x66,0x46,0x52,0x8,0x33,0xe0,0x2f,0x92,0x81,0x4c, 0x50,0x36,0x4c,0x1d,0xc8,0xf0,0x3f,0x0,0x1,0x4,0xd2,0xc8,0x5,0xc4,0x9c,0x40, 0xcc,0x6,0xd5,0xc,0x52,0xf8,0x1b,0x24,0x9,0xa5,0xff,0x43,0xd,0x82,0xb9,0x92, 0x5,0xc9,0x80,0x9f,0x0,0x1,0x4,0xe2,0xf0,0x0,0x31,0x3f,0x94,0x66,0x86,0x62, 0x98,0x1,0x3f,0xa0,0x9a,0xff,0x20,0x39,0x1f,0x66,0x0,0x48,0xec,0x2b,0x40,0x0, 0x81,0x4c,0xe5,0xef,0xf7,0xb6,0x3b,0x7,0xc4,0x87,0x80,0x6c,0x69,0x20,0xbd,0x7, 0x48,0xcb,0x2,0xb1,0x14,0x10,0x4b,0x40,0xb1,0x18,0x10,0x8b,0x83,0xd8,0x20,0xb5, 0x50,0xfa,0x12,0x90,0x16,0x4,0x8,0x20,0x90,0x69,0xec,0x85,0x5b,0xf,0x5,0x2, 0x5,0xd6,0x83,0x4,0xa0,0xa6,0xb,0x3,0xf9,0x13,0x91,0x43,0x1b,0xa8,0x26,0xc, 0x4a,0x47,0x2,0xe5,0xb6,0x41,0x85,0x39,0x1,0x2,0x8,0x16,0x3,0xcc,0x68,0x1, 0xc4,0x8,0x54,0x98,0xd,0xa4,0xbf,0x23,0x85,0x5,0x8a,0x1a,0xa0,0x7c,0x10,0x48, 0x1d,0x40,0x0,0x81,0x18,0x16,0x40,0xec,0xf,0xd,0x94,0xff,0x20,0x8d,0x40,0x9c, 0x1,0xe3,0x23,0x89,0x47,0x80,0x30,0x94,0x1d,0x2,0xa5,0xad,0x0,0x2,0x88,0x5, 0x1a,0x50,0x9f,0xa1,0xa6,0x86,0xc0,0x2,0x8,0xc8,0xf6,0x85,0xda,0xc,0x8f,0x46, 0xa0,0xd3,0x77,0x0,0xc5,0x3d,0x91,0xa2,0xf7,0x2b,0x40,0x0,0x81,0x9c,0xaa,0xc, 0x94,0xb8,0x3,0xa4,0xad,0xa1,0xb6,0xc1,0xe2,0x1f,0x86,0x61,0x9,0xc,0x39,0xb1, 0xc1,0xe4,0xbe,0x2,0x4,0x10,0xc8,0x5,0x5f,0x80,0x9a,0x15,0xa0,0xd1,0xf3,0x1f, 0x4d,0x33,0x72,0x2,0x62,0x82,0xe2,0xff,0x48,0xa9,0xf4,0x27,0x40,0x0,0x81,0x34, 0x7d,0x83,0x3a,0x15,0x39,0x5,0xc2,0x30,0x3,0x92,0x1,0x8c,0x68,0x6,0x80,0xc0, 0x5f,0x80,0x0,0x2,0x19,0xf0,0x13,0x29,0xc5,0xc1,0x24,0xff,0xf5,0x79,0xd9,0x82, 0x15,0x1,0xf3,0xa,0x23,0x92,0x41,0x8c,0x68,0x79,0xe9,0x3f,0x40,0x0,0x81,0xc2, 0x0,0xd9,0x6f,0xe0,0xcc,0x3,0xd4,0x4c,0x74,0x16,0x5,0x8,0x20,0x46,0x4a,0xb3, 0x33,0x40,0x80,0x1,0x0,0x9,0x5d,0x9e,0x2c,0xdc,0x71,0xd7,0x8c,0x0,0x0,0x0, 0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-3.png 0x0,0x0,0x2,0x55, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xcb,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x48, 0x8a,0x81,0x81,0x41,0x4,0x88,0x25,0x81,0x58,0x2,0xca,0xe6,0x61,0x80,0x80,0x2f, 0x40,0xfc,0x6,0x88,0x5f,0x0,0xf1,0x73,0x28,0xfb,0x33,0x10,0x7f,0x7,0xe2,0x3f, 0x20,0x5,0x0,0x1,0xc4,0x2,0xd5,0xa0,0x8,0xc4,0x6a,0x40,0xac,0xd4,0xef,0x6d, 0x97,0xc1,0x80,0x4,0x80,0x16,0xcc,0x0,0x52,0xf7,0x80,0x98,0x3,0x2a,0xf4,0x17, 0x9,0xff,0x7,0x8,0x20,0x26,0xa8,0xcd,0x6a,0xfc,0xa7,0xf7,0x75,0x81,0x34,0xff, 0xff,0xff,0x9f,0x1,0x19,0x83,0xc4,0x40,0x72,0x50,0xb,0x40,0x6a,0xf9,0x81,0x98, 0xd,0x88,0x41,0x7a,0x19,0x0,0x2,0x88,0x5,0xea,0x6c,0xa5,0x86,0x86,0x6,0xb0, 0x6,0x10,0x60,0x64,0x64,0x4,0xd3,0x30,0x43,0x40,0xfc,0xc2,0xad,0x4e,0x4a,0x40, 0xa1,0x57,0x40,0xfc,0x16,0x88,0x3f,0x2,0xf1,0x37,0x90,0x2b,0x0,0x2,0x8,0x64, 0x8a,0x8,0xcc,0x66,0x5c,0x0,0xe6,0x12,0xa8,0x77,0x79,0x81,0x98,0x1d,0xe6,0x2, 0x80,0x0,0x62,0x41,0xa,0x30,0xb8,0xcd,0xe8,0x7c,0x24,0xc3,0x41,0xce,0xe7,0x4, 0x62,0x56,0x98,0x1,0x0,0x1,0xc4,0xc4,0x40,0x1a,0xe0,0x84,0x6,0x26,0xc8,0x0, 0x66,0x90,0x0,0x40,0x0,0xb1,0x40,0xa3,0xa,0xc5,0x26,0x2c,0x36,0xc3,0x0,0x1b, 0xd4,0xf9,0x6c,0x50,0xbd,0xcc,0x0,0x1,0x4,0x72,0xc1,0x1b,0x50,0x54,0xa1,0x3b, 0x1f,0xdd,0x2b,0x40,0x35,0x7,0xa0,0x36,0x73,0x41,0xbd,0xd,0x72,0xd,0x1b,0x40, 0x0,0x31,0x41,0x13,0xc9,0x3d,0x50,0x2c,0xa0,0x87,0x3e,0xb2,0x6b,0x80,0x81,0xe8, 0x0,0xb5,0x1d,0x14,0xe,0x42,0x40,0x2c,0x8,0xc4,0xdc,0x0,0x1,0xc4,0x4,0x4d, 0x61,0xb7,0x3e,0x9a,0x3a,0x95,0xc1,0x5c,0x82,0x8c,0xa1,0x36,0xc3,0xc,0x49,0x82, 0x6a,0x94,0x80,0x62,0x61,0x80,0x0,0x62,0xc4,0x91,0x94,0x61,0xa1,0xcd,0x6,0x75, 0x36,0x3b,0x54,0x33,0x2c,0x75,0x56,0x2,0xa9,0xc7,0x40,0xfc,0x0,0x20,0x80,0x98, 0xa0,0x69,0xfb,0x25,0x10,0xdf,0x7,0xe2,0xab,0x40,0x7c,0xe,0x88,0x4f,0x0,0xf1, 0x71,0x28,0x7d,0x16,0x24,0xe,0xd4,0xd4,0x82,0xe4,0x92,0x76,0x20,0x25,0x0,0x72, 0xd,0x40,0x0,0x31,0x41,0x33,0xc6,0x67,0x68,0x2a,0x3,0x99,0x7a,0x17,0x88,0x6f, 0x2,0xf1,0x35,0xa8,0x81,0xd7,0x41,0x5e,0x4,0xe2,0x87,0x50,0x9b,0x61,0x86,0x4c, 0x1,0xb9,0x12,0x20,0x80,0x40,0x5e,0x0,0x87,0x15,0x34,0x4d,0x30,0x43,0x69,0x18, 0x9b,0x5,0xea,0x15,0x64,0x7f,0xb,0x40,0x35,0x83,0x1,0x40,0x0,0xc1,0x12,0xd2, 0x7f,0x68,0xee,0xfa,0x5,0xc4,0x3f,0xa0,0xe9,0x1c,0xe4,0xaa,0x4f,0x40,0xfc,0x1e, 0xea,0xc5,0x27,0x20,0x3f,0x43,0x5d,0x12,0x6,0xd,0xb,0x17,0x80,0x0,0x3,0x0, 0x38,0x39,0x9d,0x96,0xa2,0x5f,0xb5,0x1d,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-9.png 0x0,0x0,0x1,0x2f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x4,0x37,0xa0,0x91,0x91,0xf1,0x3f,0x8,0x23,0x4b,0x62,0xe3,0xa3,0x8b,0x1,0x4, 0x10,0x4e,0x17,0xc0,0x14,0xa2,0x6b,0x40,0x7,0x0,0x1,0xc4,0x0,0xa,0x44,0x64, 0xdc,0xc0,0x0,0xa2,0xf0,0xb3,0x91,0x31,0x40,0x0,0x31,0x60,0x13,0x84,0x29,0x46, 0xa7,0xb1,0x61,0x80,0x0,0xc2,0x69,0x3b,0xaa,0x3a,0xdc,0xae,0x0,0x8,0x20,0x46, 0x58,0x3a,0x40,0xf7,0x6b,0xfd,0x7f,0xe4,0xf0,0x40,0xf5,0x76,0xfd,0xff,0xff,0x70, 0x11,0x80,0x0,0xa2,0xd8,0x5,0x0,0x1,0x44,0x71,0x18,0x0,0x4,0x10,0xc5,0xb1, 0x0,0x10,0x40,0x18,0x61,0x0,0xf3,0x1f,0x72,0x98,0xa0,0x8b,0x21,0x87,0x1,0x40, 0x0,0xe1,0x4c,0x48,0x30,0x45,0x28,0x1,0x86,0x5,0x0,0x4,0x10,0x23,0xa5,0xb9, 0x11,0x20,0x80,0x28,0xce,0x4c,0x0,0x1,0x6,0x0,0xfd,0x4d,0x34,0x9e,0x7e,0xb5, 0xba,0x6,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-14.png 0x0,0x0,0x1,0x2f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0x59,0xa6,0xd4,0xd7,0xd7, 0x33,0x2,0x4,0x10,0xb,0x12,0x87,0x24,0xcd,0x40,0x4b,0xc1,0x34,0x40,0x0,0x31, 0x31,0x50,0x8,0x0,0x2,0x88,0x5,0x97,0xc4,0xc1,0x83,0x7,0x51,0xf8,0xf6,0xf6, 0xf6,0x58,0xd5,0x1,0x4,0x10,0xb,0x21,0x8d,0xe8,0xe2,0xe8,0x6,0x1,0x4,0x10, 0x13,0xba,0x22,0x5c,0x36,0xc1,0x34,0xa3,0x5b,0x0,0x10,0x40,0x4c,0xe8,0x9a,0x71, 0xb9,0x0,0x97,0x1a,0x80,0x0,0xc2,0x1b,0x88,0xf8,0x5c,0x3,0x3,0x0,0x1,0xc4, 0x84,0xee,0x3c,0x64,0x4d,0xd8,0x2,0x12,0x5d,0xd,0x40,0x0,0x31,0x11,0xf2,0x23, 0xa1,0x30,0x2,0x8,0x20,0x16,0x5c,0xce,0x26,0x36,0x1a,0x1,0x2,0x88,0x85,0x12, 0xff,0x83,0x0,0x40,0x0,0x51,0x9c,0x12,0x1,0x2,0x88,0x5,0x3d,0x6d,0x93,0xa, 0x0,0x2,0x88,0x91,0xd2,0xec,0xc,0x10,0x60,0x0,0x3,0x21,0x3c,0x67,0x2c,0x6c, 0x23,0x90,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-8.png 0x0,0x0,0x1,0x4f, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc5,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x1e,0x0,0x92,0x64,0xc4,0xa7,0x0,0x20,0x80,0x98,0x8,0x68,0x46,0xa6,0xb1, 0x2,0x80,0x0,0xc2,0x65,0xc0,0xff,0xc6,0xc6,0x46,0x30,0x3,0x4a,0xe3,0x34,0x4, 0x20,0x80,0x70,0x19,0xc0,0x58,0x5f,0x5f,0x8f,0xec,0x74,0x46,0xa0,0x41,0x58,0xd, 0x1,0x8,0x20,0x7c,0x5e,0x60,0x40,0xf6,0x3f,0x9a,0x81,0x70,0x0,0x10,0x40,0x8c, 0x48,0x81,0x48,0x30,0xc0,0xb0,0xa9,0x3,0x8,0x20,0x26,0x74,0x3f,0x13,0x2,0xe8, 0x61,0x2,0x10,0x40,0x20,0x17,0xfc,0xc7,0xe5,0x6c,0x3c,0x31,0x3,0x57,0xb,0x10, 0x40,0x2c,0x50,0xd,0xc8,0x2e,0xf8,0x8f,0xcd,0xbf,0xc8,0x81,0x8,0x94,0x7,0xbb, 0x4,0x44,0x3,0x4,0x10,0x3,0xc8,0x1,0x50,0xfc,0x1f,0x89,0x8d,0xf,0xff,0x6f, 0x68,0x68,0x80,0xab,0x5,0x8,0x20,0x14,0x49,0x64,0x9,0x5c,0x86,0xa2,0xab,0x1, 0x8,0x20,0x92,0x6c,0xc3,0x86,0x1,0x2,0x8,0x5f,0x4a,0xfc,0x8f,0x87,0xf,0x7, 0x0,0x1,0x84,0xd7,0x76,0x18,0xc0,0xe7,0xa,0x80,0x0,0xa2,0xd8,0xb,0x0,0x1, 0xc4,0x48,0x20,0x3b,0x13,0x4,0x0,0x1,0x6,0x0,0x9d,0xc8,0x29,0xb4,0xdb,0x88, 0x51,0xf9,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-1.png 0x0,0x0,0x1,0x20, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0x96,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x60,0x8c,0xc6,0xc6,0x46,0x92,0x4d,0xaa,0xaf,0xaf, 0x67,0x4,0x8,0x20,0x6,0x90,0xb,0x40,0xb8,0xa1,0xa1,0x1,0xc8,0x80,0x40,0x10, 0x1b,0x2a,0xfc,0x1f,0x5d,0x1c,0xa6,0x1,0xa2,0xe6,0x3f,0x3,0x40,0x0,0x31,0x31, 0x50,0x8,0x0,0x2,0x88,0x11,0x16,0x6,0xe4,0x7a,0x1,0x20,0x80,0x50,0xbc,0x80, 0xec,0x6c,0xa0,0x69,0x60,0x8c,0xcf,0x3b,0x20,0x41,0x80,0x0,0xa2,0xd8,0xb,0x0, 0x1,0x44,0xb1,0x17,0x0,0x2,0x88,0xe2,0x58,0x0,0x8,0x20,0x8a,0xbd,0x0,0x10, 0x40,0x14,0x7b,0x1,0x20,0x80,0xd0,0xbc,0x80,0x70,0x1e,0x2e,0x67,0x43,0x23,0x7, 0xee,0x5,0x80,0x0,0xa2,0xd8,0xb,0x0,0x1,0x44,0xb1,0x17,0x0,0x2,0x88,0x91, 0xd2,0xdc,0x8,0x10,0x40,0x14,0x7b,0x1,0x20,0xc0,0x0,0x2f,0xa0,0xcb,0x7b,0x35, 0x8d,0x2d,0x8f,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-2-7.png 0x0,0x0,0x1,0xa5, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x1b,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xc0,0x24,0x23,0xe3,0x7f,0x30,0x26,0x3,0x0,0x4, 0x10,0x53,0x23,0x99,0x1a,0x61,0x0,0x20,0x80,0xc0,0x2e,0x68,0x4,0x11,0xff,0xff, 0x33,0xc2,0x4,0x19,0x81,0x86,0x12,0x8b,0x1,0x2,0x88,0x11,0x12,0x6,0x30,0x57, 0x40,0xc,0x1,0x49,0x10,0x13,0x36,0x40,0x75,0xc,0x0,0x1,0xc4,0xd4,0xd8,0x88, 0xd7,0xb,0x8c,0x30,0xc,0x52,0x8c,0x8c,0x61,0x0,0x20,0x80,0x20,0x5e,0x68,0x44, 0xd8,0x8e,0xa6,0x19,0x44,0xfc,0x87,0xf8,0xf0,0x3f,0xd8,0xb5,0x30,0xc,0x3,0x0, 0x1,0x4,0x16,0x64,0x84,0x7a,0xe1,0x3f,0xa6,0x21,0x8,0x3,0x60,0x6,0x42,0x3, 0x1d,0xac,0xf,0xe8,0x12,0x80,0x0,0x62,0x62,0xc4,0xe2,0x5,0x46,0x88,0x73,0xfe, 0xc3,0x34,0xa3,0xb9,0x4,0xc5,0x5,0x0,0x1,0xc4,0xc2,0x0,0x8d,0x86,0xff,0xf5, 0xd0,0x0,0x6c,0x6c,0x44,0x35,0xb0,0xbe,0x1e,0x42,0x83,0xfc,0x9,0x64,0xc3,0xfc, 0xf,0x33,0x4,0x20,0x80,0x20,0xc,0xa8,0xb1,0xc8,0x7e,0x4,0x8b,0x37,0x34,0x40, 0x18,0x40,0x1a,0xa1,0x4,0x1,0x40,0xe6,0x0,0x4,0x10,0x13,0x86,0x8d,0xe8,0x0, 0x68,0xf3,0xff,0xfa,0x7a,0x46,0x68,0xbc,0x63,0xc4,0x2,0x40,0x0,0x31,0x82,0x6d, 0x1,0x19,0x5,0x54,0x84,0x9c,0x90,0xfe,0xff,0x47,0x9,0xd0,0xff,0xb8,0xd2,0x1, 0x40,0x0,0x41,0x62,0x81,0x11,0x16,0x40,0xc,0x28,0x9,0x9,0xd9,0x26,0x74,0x0, 0x93,0x7,0x8,0x20,0x26,0x46,0x46,0xdc,0x5e,0x40,0xf,0x13,0x6c,0xe9,0x0,0x20, 0x80,0x98,0xa0,0x1e,0x85,0xdb,0x8e,0xe2,0x3c,0x2,0x18,0x4,0x0,0x2,0xc,0x0, 0x8f,0xd,0xb5,0x9a,0xb7,0xe,0x8,0xc,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44, 0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-14.png 0x0,0x0,0x1,0x4b, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xc1,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xb0,0x9,0x32,0x32,0x30,0xe2,0x37,0x95,0x11,0x21, 0xf,0x10,0x40,0x2c,0x10,0x3e,0x3,0x5c,0x0,0xe8,0x20,0x46,0x52,0x5c,0x0,0x10, 0x40,0x8c,0xe8,0x5e,0x0,0xdb,0x8e,0xe4,0x0,0xc,0x3,0x41,0xb6,0xff,0xff,0xf, 0x17,0x3,0x8,0x20,0x16,0x6c,0xa6,0x22,0x6b,0x42,0x76,0x1d,0x58,0xe,0x4d,0x2d, 0x40,0x0,0xb1,0x10,0x72,0x22,0xa6,0xb,0x18,0xfe,0xc3,0xc,0x5,0xc9,0x1,0x4, 0x10,0xb,0xba,0xf3,0x81,0xee,0x63,0x24,0xc5,0x50,0x80,0x0,0x62,0x22,0x29,0xce, 0xd0,0xfc,0xf,0x2,0x0,0x1,0xc4,0xc4,0x40,0x21,0x0,0x8,0x20,0x26,0x52,0x9d, 0x8f,0xe,0x0,0x2,0x88,0x9,0x1e,0x9b,0x50,0x9a,0x81,0x50,0x22,0x42,0x3,0x0, 0x1,0x4,0xd,0x44,0x50,0xc0,0x22,0xbb,0x0,0x8b,0x21,0x8c,0xe0,0xd0,0xc3,0x70, 0x21,0x40,0x0,0xb1,0x60,0x77,0x3e,0x36,0xaf,0x60,0x73,0xdd,0x7f,0x46,0x80,0x0, 0x62,0x21,0xcd,0xc7,0x98,0x6,0x3,0x4,0x10,0x23,0xa5,0xb9,0x11,0x20,0x80,0x28, 0x8e,0x46,0x80,0x0,0x3,0x0,0x83,0xc6,0x3d,0x21,0x3d,0x2d,0xd5,0x39,0x0,0x0, 0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-2.png 0x0,0x0,0x1,0x7a, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xf0,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x4,0x35,0x80,0xf1,0x3f, 0x23,0x1c,0x33,0xc0,0x71,0x23,0x63,0xe3,0x7f,0x6,0x46,0x6,0x24,0xcc,0x8,0xc1, 0xc,0x8c,0x70,0x67,0x3,0x4,0x10,0xc4,0x0,0x90,0x6a,0xb8,0x99,0x8c,0x38,0xec, 0x82,0x8a,0xff,0x47,0x55,0x1,0x10,0x40,0x4c,0xc8,0xf2,0xb8,0xd,0xc1,0xae,0x19, 0x4,0x0,0x2,0x88,0x9,0x2e,0x83,0x61,0x8,0x1a,0x40,0xd1,0x8c,0x50,0x5,0x10, 0x40,0x4c,0xc,0xe8,0x82,0xd8,0xc,0xc1,0xa1,0x19,0x4,0x0,0x2,0x88,0x9,0x43, 0x25,0x3,0x24,0x8c,0xfe,0xc3,0x9d,0xcd,0x8,0xe,0x3f,0xb8,0x1c,0x1a,0x0,0x8, 0x20,0x46,0x50,0x3a,0x0,0x87,0x36,0x16,0x50,0xff,0xbf,0x1,0x28,0xd7,0xc0,0x80, 0x5d,0xae,0x1e,0x6c,0x3,0x40,0x0,0x31,0x80,0x13,0x12,0x88,0x40,0xc3,0x20,0xb2, 0x81,0xa1,0x1,0xc2,0xc3,0xa5,0x0,0x88,0x1,0x2,0x88,0x9,0x33,0xb4,0x21,0x91, 0xe,0x8b,0x6a,0xb0,0xf3,0xff,0x33,0xc2,0xe5,0xd0,0x1,0x40,0x0,0x31,0xa1,0x47, 0xd5,0x7f,0x2c,0xb1,0xc8,0x88,0x12,0x76,0xa8,0x92,0x0,0x1,0xc4,0x44,0x48,0x33, 0x21,0x43,0x0,0x2,0x88,0x9,0x25,0x72,0x18,0xb1,0x47,0x15,0x8c,0xcf,0x88,0x45, 0xa,0x20,0x80,0x98,0x8,0x6b,0xc6,0xe7,0x12,0x6,0x6,0x80,0x0,0x62,0xa4,0x34, 0x3b,0x3,0x4,0x18,0x0,0x5b,0xc6,0x6f,0xec,0xbe,0xaf,0xfc,0xef,0x0,0x0,0x0, 0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-1.png 0x0,0x0,0x1,0x67, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xdd,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x90,0x39,0x8c,0x8c,0x8c,0x70,0xd3,0x80,0x6,0x33, 0x12,0x63,0x0,0x40,0x0,0xb1,0x20,0x6b,0xfe,0xcf,0xf0,0x1f,0xc5,0x30,0x98,0x21, 0xf8,0xc,0x6,0x8,0x20,0x16,0x62,0x6c,0x41,0xd6,0x84,0x6c,0x30,0x8,0x0,0x4, 0x10,0x13,0xb2,0x22,0x46,0x6,0x46,0x86,0x46,0x20,0x4,0xd1,0xc4,0x7a,0x1,0x20, 0x80,0x18,0x61,0x81,0x8,0x32,0xb9,0x81,0xa1,0x1,0x2e,0x1,0x62,0xa3,0xdb,0x8c, 0xcd,0x65,0x0,0x1,0xc4,0x84,0x4b,0x92,0x90,0xdf,0x61,0x7c,0x80,0x0,0x62,0x42, 0xf7,0x13,0xb2,0x2,0x5c,0x9a,0x90,0xc5,0x1,0x2,0x8,0xc5,0xb,0x28,0xe1,0x41, 0x64,0x94,0x2,0x4,0x10,0x23,0x72,0x42,0x82,0xb9,0x6,0xe1,0x2a,0x90,0x21,0xa8, 0x86,0xa1,0x1b,0xa,0x10,0x40,0x4c,0xf8,0xc2,0x17,0xa4,0x19,0x44,0x43,0xbc,0x3, 0xf3,0x16,0xaa,0x2a,0x80,0x0,0x62,0xc1,0x1d,0xca,0xd8,0x5c,0x80,0x50,0x3,0x13, 0x3,0x8,0x20,0x16,0xdc,0xb1,0x80,0xd0,0xdc,0xd0,0x80,0xdd,0x8d,0x20,0x71,0x80, 0x0,0x62,0xc1,0x1d,0x48,0x84,0x35,0x83,0xf4,0x1,0x4,0x10,0xce,0x30,0x20,0x46, 0x33,0x88,0xd,0x10,0x40,0x8c,0xd8,0xb2,0x33,0xae,0x84,0x85,0x2d,0x5a,0x1,0x2, 0xc,0x0,0x22,0xd4,0x92,0x11,0xce,0xaa,0xe6,0xfb,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-7.png 0x0,0x0,0x1,0xfe, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x74,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x48, 0x8c,0x81,0x81,0x81,0xb,0x88,0xf9,0x81,0x98,0xf,0x88,0x99,0x80,0x98,0xd,0x88, 0x59,0x81,0xf8,0x37,0x3,0x4,0xc0,0xd8,0xbf,0x80,0xf8,0x1f,0x10,0x7f,0x2,0xe2, 0x8f,0x40,0xfc,0xd,0x20,0x80,0x98,0xa0,0x9a,0x5,0x81,0x58,0xa2,0xdf,0xdb,0xee, 0x10,0x90,0x96,0x7,0x62,0x25,0x20,0x7b,0x2b,0x88,0x46,0x63,0xcb,0x43,0xd5,0x48, 0x40,0xf5,0x70,0x1,0x4,0x10,0xb,0xd4,0x66,0x90,0x2b,0x64,0xa1,0xb6,0xa9,0x3, 0x31,0x37,0x94,0xad,0xc9,0x80,0x0,0x20,0xf6,0x57,0x28,0x1b,0xa6,0xf6,0x1f,0x40, 0x0,0x31,0x0,0xbd,0x60,0xb,0x64,0xfc,0x27,0x7,0x83,0xf4,0x2,0x4,0x10,0xc8, 0x5,0x4c,0x40,0x46,0x3c,0xc8,0x66,0xa0,0xf3,0xaa,0x80,0xec,0xd,0xa0,0xb0,0x0, 0xb2,0x9d,0x80,0xec,0x7d,0x20,0x6b,0x90,0xd8,0x9f,0x80,0xec,0x0,0x20,0xbb,0xd, 0xc8,0xbe,0x9,0xd2,0xb,0x10,0x40,0x2c,0xd0,0x0,0xe3,0x44,0x72,0x36,0x2c,0x20, 0x19,0x90,0x68,0x18,0x9b,0xf,0xca,0xe6,0x86,0xea,0x61,0x3,0x8,0x20,0x90,0x17, 0xbc,0x28,0xf0,0x82,0x17,0x40,0x0,0x81,0x5c,0xf0,0x1b,0xc8,0xc8,0x0,0x5,0x12, 0xd0,0x79,0xf9,0x50,0xa7,0x32,0x1,0xd9,0xe,0x40,0xf6,0x1,0xa8,0x17,0x60,0xec, 0xff,0x40,0xb6,0x23,0x90,0x3d,0x19,0xea,0x85,0xbf,0x0,0x1,0x84,0xec,0x44,0xb2, 0x0,0x40,0x0,0x51,0xea,0x5,0x1f,0x80,0x0,0xa2,0xd4,0xb,0xbf,0x1,0x2,0x88, 0x9,0x9a,0x3c,0xbf,0x23,0x25,0x92,0x4f,0xd0,0xe4,0xca,0x0,0xa5,0x61,0xec,0xff, 0xd0,0xe4,0xb,0x2,0x5f,0x81,0x6,0x4d,0x1,0xe9,0x5,0x8,0x20,0xb2,0x13,0x12, 0x50,0x5f,0x4,0x10,0x5b,0x1,0x4,0x10,0xc8,0x5,0x9f,0x80,0xc,0xf,0x20,0x4e, 0x85,0x86,0x49,0x1b,0x10,0x4f,0x84,0xb2,0x27,0x22,0xb1,0x27,0x0,0x71,0xb,0x94, 0x9d,0x4,0xa4,0xde,0x0,0xf1,0x67,0x80,0x0,0x62,0x81,0x3a,0xb,0x39,0x36,0x6e, 0x42,0x13,0x9,0x8,0x5c,0x47,0x12,0xbf,0x1,0xf5,0x2a,0x8,0x3c,0x6,0xe2,0x57, 0x20,0xbd,0x0,0x1,0xc4,0x48,0x42,0x76,0x6,0x85,0xd5,0x4f,0x50,0xdc,0x83,0x6c, 0x6,0xe2,0xf,0xa0,0xec,0xc,0x10,0x60,0x0,0xc2,0x49,0xd4,0xf2,0x18,0x63,0xa8, 0xe6,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-10.png 0x0,0x0,0x1,0x42, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xb8,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0x94,0x1,0x8d,0x8d,0x8d,0xf,0x41,0x18,0x9b,0x1c,0x40,0x0,0x11,0xed,0x82, 0x86,0xfa,0x7a,0x39,0x6c,0x86,0x0,0x4,0x10,0xb,0xb2,0x2d,0xc4,0x18,0x2,0x54, 0xf8,0xb0,0xbe,0xbe,0x5e,0x1e,0x26,0x6,0x10,0x40,0xc,0xd0,0x58,0x78,0xd8,0xd0, 0xd0,0xf0,0x10,0xcc,0x21,0x2,0x83,0xd4,0xc2,0xb8,0x0,0x1,0x4,0x33,0x0,0x24, 0xf8,0x9f,0x58,0x3,0xa0,0x86,0x1c,0x7,0x31,0x1,0x2,0x88,0x2c,0x3,0x90,0x5d, 0x0,0x10,0x40,0x2c,0x28,0x7e,0x6c,0x6c,0xc4,0xe7,0x7f,0x98,0x9a,0x47,0xc8,0x61, 0x0,0x10,0x40,0xf0,0x30,0xc0,0x87,0x61,0xae,0x43,0xb6,0x19,0x86,0x1,0x2,0x88, 0x91,0x50,0x52,0x66,0x64,0x64,0x4,0x19,0x0,0x66,0xa3,0xd8,0xc,0x5,0x0,0x1, 0x44,0x94,0x1,0x50,0x97,0xca,0x63,0x93,0x7,0x8,0x20,0x46,0x4a,0x33,0x13,0x40, 0x0,0x51,0x9c,0x17,0x0,0x2,0x88,0x62,0x3,0x0,0x2,0xc,0x0,0xe1,0x64,0xce, 0xfc,0x23,0x2f,0xaa,0x9,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60, 0x82, // /work/depthmap/depthmap/images/win/b-1-23.png 0x0,0x0,0x1,0x94, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0xa,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x0,0xb9,0xa0,0xa1,0xa1,0xe1,0x3f,0x3a,0x38,0x70, 0xe0,0xc0,0x7f,0x6,0x20,0xc4,0x26,0x7,0x15,0x3,0xeb,0x5,0x8,0x20,0x16,0x7c, 0xb6,0x1c,0x38,0x78,0x80,0x81,0xc1,0x1,0xbf,0x4b,0x0,0x2,0x88,0x9,0x9b,0xe0, 0xc1,0x83,0x7,0x19,0xec,0x1d,0x1c,0x18,0x80,0xae,0x60,0xb0,0xb7,0x77,0x0,0xf3, 0x71,0x1,0x80,0x0,0x62,0xc2,0xa5,0xb9,0xb1,0xa1,0x1,0xe4,0x4f,0x60,0xf8,0x34, 0xe0,0x35,0x4,0x20,0x80,0x58,0x90,0x35,0x82,0x0,0xb2,0x66,0x68,0x60,0x1,0xd, 0x1,0xd1,0x20,0x43,0xe,0x60,0x18,0x0,0x10,0x40,0x70,0x17,0x38,0x38,0xd8,0x43, 0xc,0x2,0x3a,0x1b,0xa6,0x19,0x29,0xc4,0xc1,0x2e,0x81,0x59,0x80,0xc,0x0,0x2, 0x8,0x6e,0x40,0x43,0x43,0x23,0xd8,0xcf,0xe,0x58,0x9c,0xb,0xe2,0x37,0x34,0xd4, 0x83,0xe5,0x41,0xae,0x43,0x6,0x0,0x1,0x84,0x11,0x8d,0x20,0x36,0x28,0xfa,0x40, 0xd1,0x8,0x8f,0x4e,0x86,0xff,0xff,0xd1,0xd5,0xc0,0xa2,0x11,0x20,0x80,0xb0,0xa6, 0x3,0x64,0x43,0xd0,0x35,0xa3,0x1b,0x0,0x10,0x40,0x2c,0x38,0x52,0x19,0x30,0x79, 0x2,0xd3,0x1,0x8,0x2,0xc3,0xcd,0xde,0xbe,0x1e,0x67,0x34,0x2,0x4,0x10,0x13, 0xfe,0xe4,0xda,0x40,0x30,0x49,0x3,0x4,0x10,0x23,0xc8,0x19,0x94,0xe4,0x5,0x80, 0x0,0x62,0xa4,0x34,0x37,0x2,0x4,0x10,0x13,0x3,0x85,0x0,0x20,0xc0,0x0,0x9a, 0x1b,0xe9,0x57,0xdc,0x62,0x76,0xe4,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae, 0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-4-11.png 0x0,0x0,0x1,0x47, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xbd,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0xc0,0x24,0x23,0xe3,0x7f,0x30,0x86,0x1,0x12,0xf8, 0x0,0x1,0xc4,0xd4,0x88,0x2c,0x1,0x4,0xa4,0xf2,0x1,0x2,0x8,0xec,0x82,0x46, 0x10,0xf1,0xff,0x3f,0x23,0x5c,0x11,0x9,0x7c,0x80,0x0,0x62,0x84,0x84,0x1,0xcc, 0x54,0x98,0x22,0xe2,0xf9,0x0,0x1,0xc4,0xd4,0xd8,0x88,0xe6,0x44,0x12,0xf9,0x0, 0x1,0x4,0xf1,0x42,0x23,0xb2,0xe9,0xa4,0xf1,0x1,0x2,0x8,0xec,0x5,0x46,0xa8, 0x93,0xfe,0xc3,0x4,0x49,0xe0,0x3,0x4,0x10,0x13,0x23,0x9a,0x93,0x48,0xe5,0x3, 0x4,0x10,0x13,0x2c,0x58,0xff,0x23,0x39,0x91,0x14,0x3e,0x40,0x0,0x41,0xbd,0xc0, 0x0,0x75,0x12,0x3,0xd4,0x89,0xc4,0xf3,0x1,0x2,0x8,0xe8,0x85,0x46,0x34,0x27, 0x92,0xc6,0x7,0x8,0x20,0x26,0x58,0xb0,0xc2,0x4c,0x27,0x95,0xf,0x10,0x40,0x10, 0x2f,0x30,0x42,0x9d,0xf4,0x1f,0x2a,0x48,0x2,0x1f,0x20,0x80,0x98,0x18,0x19,0xd1, 0x9c,0x48,0x22,0x1f,0x20,0x80,0x98,0x60,0xc1,0xa,0x33,0x9d,0x54,0x3e,0x40,0x80, 0x1,0x0,0xea,0x35,0x8f,0x4d,0x9e,0x6,0xe8,0xf5,0x0,0x0,0x0,0x0,0x49,0x45, 0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-5.png 0x0,0x0,0x1,0x30, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa6,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x58,0x40,0x44,0x63,0x63,0x23,0xc9,0xa6,0xd4,0xd7,0xd7, 0x33,0x82,0x68,0x80,0x0,0x62,0x41,0x12,0x20,0x5a,0x33,0xd0,0x42,0x38,0x1b,0x20, 0x80,0x58,0x90,0x25,0x18,0x19,0x19,0x71,0x6a,0xc2,0xe5,0x55,0x80,0x0,0x62,0x21, 0x46,0x21,0x3e,0x83,0x1,0x2,0x88,0x89,0x58,0x67,0x83,0xc,0xc1,0x66,0x10,0x40, 0x0,0x11,0x65,0x0,0xc8,0x55,0xb8,0xbc,0x0,0x10,0x40,0x4c,0xc,0x14,0x2,0x80, 0x0,0x62,0xc2,0xe7,0x64,0x62,0x0,0x40,0x0,0x31,0xe1,0x8a,0x26,0x90,0x93,0x89, 0x31,0x4,0x20,0x80,0x98,0x8,0xf9,0x9d,0x90,0x21,0x0,0x1,0xc4,0x82,0xcb,0xe9, 0xe,0xe,0xe,0x60,0xfa,0xc0,0x81,0x3,0x78,0xd,0x1,0x8,0x20,0x16,0x62,0x12, 0xb,0xbe,0xfc,0x2,0x10,0x40,0x2c,0xd8,0x92,0x27,0x29,0x0,0x20,0x80,0x18,0x29, 0xcd,0x8d,0x0,0x1,0x44,0x71,0x3a,0x0,0x8,0x30,0x0,0xa1,0xaf,0x2b,0x30,0x35, 0xa0,0x78,0x49,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-7-1.png 0x0,0x0,0x1,0x89, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xff,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x50,0x78,0x8c,0x8c,0xff,0xc1,0x98,0x4,0x0,0x10, 0x40,0x70,0x3,0x1a,0x89,0xd0,0xc8,0x88,0x45,0xd,0x40,0x0,0xa1,0xb8,0xa0,0x11, 0x44,0xfc,0xff,0xcf,0x8,0x66,0x37,0x36,0xfe,0x7,0x69,0x40,0xc6,0xd,0xd,0xd, 0x18,0x86,0x0,0x4,0x10,0x23,0x6a,0x18,0xc0,0x24,0x41,0xea,0x41,0x52,0xff,0x71, 0xb9,0x4,0x68,0xf,0xc4,0x22,0x80,0x0,0x42,0x78,0xa1,0x11,0xd5,0x64,0xa8,0x6d, 0x28,0x18,0xe8,0x2a,0x14,0xcd,0x20,0x0,0x10,0x40,0x70,0x17,0xc0,0xc,0xa8,0xaf, 0x47,0x48,0x62,0xb,0x3,0x64,0xcd,0x20,0x0,0x10,0x40,0x28,0x5e,0x60,0x84,0x7a, 0xe1,0x3f,0x3,0x6e,0x43,0xd0,0x1,0x40,0x0,0xc1,0xbd,0xc0,0xd8,0xc8,0x48,0x56, 0x82,0x0,0x8,0x20,0xd4,0x74,0xd0,0x48,0x9a,0xed,0x20,0x0,0x10,0x40,0x68,0x5e, 0x60,0x80,0x7a,0x81,0x81,0x11,0x9f,0xbf,0x91,0x1,0x40,0x0,0x21,0x79,0xa1,0xf1, 0x3f,0xb6,0x40,0x83,0xc5,0x3d,0x32,0x6e,0x44,0x52,0xb,0x10,0x40,0x70,0x17,0xc0, 0xc,0xf8,0x5f,0x5f,0xcf,0x88,0x64,0x33,0xc1,0x74,0x0,0x10,0x40,0x20,0x6,0x1c, 0x83,0x92,0x21,0x8,0x23,0xf8,0xc,0x20,0x17,0xfc,0x87,0xf8,0xa,0x81,0x41,0x62, 0x30,0x35,0x0,0x1,0x84,0xa4,0xb9,0xe1,0x3f,0xba,0x1,0x30,0x43,0x90,0xf9,0xe8, 0x18,0x20,0x80,0x50,0x63,0x1,0x18,0xd,0x40,0x31,0x94,0x0,0xc3,0x17,0x80,0x20, 0x0,0x10,0x60,0x0,0xa7,0xf4,0xb0,0xed,0x68,0x61,0x68,0xf4,0x0,0x0,0x0,0x0, 0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-5-10.png 0x0,0x0,0x1,0xd0, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x1,0x46,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0x2c,0xdc,0x7a,0x88, 0x97,0x81,0x81,0x81,0xd,0x88,0x39,0x80,0x98,0x15,0x88,0xff,0x2,0xf1,0x2f,0x20, 0xfe,0x9,0xc5,0xbf,0xa0,0x62,0x58,0x1,0x40,0x0,0xb1,0x40,0x35,0x83,0xc,0xe1, 0x3,0x62,0x4e,0xa8,0xf8,0x77,0x20,0xfe,0x2,0xc4,0x9f,0xa0,0x7c,0x9c,0x86,0x0, 0x4,0x10,0x13,0xd4,0x66,0x90,0x66,0xd1,0x7e,0x6f,0xbb,0x13,0x40,0x5a,0xe,0x8a, 0x25,0x81,0x58,0x18,0x88,0xb9,0xa1,0x96,0x30,0x63,0x33,0x0,0x20,0x80,0x98,0xa0, 0xce,0xe6,0x4,0x6a,0xde,0xd3,0xd0,0xd0,0xc0,0x0,0xa4,0x57,0x1,0xf9,0xf2,0x50, 0x4c,0xd0,0x10,0x80,0x0,0x62,0x82,0x39,0xd,0x18,0x16,0x61,0x20,0x3,0xa0,0x86, 0x4c,0x1,0xa,0xc9,0x10,0xe3,0x12,0x80,0x0,0x62,0x82,0xfa,0xf,0xe4,0xe7,0xef, 0x40,0x43,0x72,0x90,0xc,0xe9,0x4,0x8a,0x49,0x13,0x32,0x4,0x20,0x80,0x98,0xa0, 0x21,0xd,0xa,0xb0,0xf7,0x20,0xc,0x34,0xa4,0x1c,0xc9,0x90,0x36,0x42,0x86,0x0, 0x4,0x10,0xcc,0x0,0x50,0x68,0xbf,0x1,0xe2,0x67,0x40,0xfc,0x2,0x68,0x48,0x15, 0xb1,0x86,0x0,0x4,0x10,0xcc,0xb,0x5f,0x81,0xf8,0x2d,0x10,0x3f,0x7,0xe2,0x47, 0x40,0xfc,0x94,0x58,0x43,0x0,0x2,0x88,0x9,0x29,0xe1,0x90,0x65,0x8,0x40,0x0, 0x31,0x41,0xc3,0x82,0x14,0x43,0x24,0x80,0x58,0xa,0x88,0x45,0x40,0xe9,0x7,0x20, 0x80,0x98,0x90,0x62,0x84,0x58,0x43,0x40,0xb1,0x23,0x8,0xc5,0x3c,0x0,0x1,0xc4, 0x84,0x96,0x2e,0xf0,0x19,0x52,0x8e,0x96,0x4e,0x40,0xc9,0x9e,0x13,0x20,0x80,0x98, 0xb0,0xa4,0x4e,0x5c,0x86,0x3c,0x41,0x4b,0x27,0xa0,0x14,0xcb,0x0,0x10,0x40,0x2c, 0x38,0x32,0x19,0xcc,0x10,0x64,0xf0,0x1b,0x14,0xdd,0xe0,0x14,0xb,0xd4,0xc,0xa4, 0x5d,0x40,0x89,0xf,0x20,0x80,0x70,0x19,0x80,0xcd,0x10,0x90,0x1,0x9f,0x41,0xce, 0x6,0x6a,0xb6,0x80,0xa6,0xde,0x4f,0x0,0x1,0x6,0x0,0x39,0x85,0xa4,0x4,0xab, 0x33,0xb2,0x92,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82, // /work/depthmap/depthmap/images/win/b-6-6.png 0x0,0x0,0x1,0x33, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13, 0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1, 0x8e,0x7c,0xfb,0x51,0x93,0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a, 0x25,0x0,0x0,0x80,0x83,0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75, 0x30,0x0,0x0,0xea,0x60,0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5, 0x46,0x0,0x0,0x0,0xa9,0x49,0x44,0x41,0x54,0x78,0xda,0x62,0xfc,0xff,0xff,0x3f, 0x3,0x25,0x0,0x20,0x80,0x98,0x18,0x28,0x4,0x0,0x1,0x44,0xb1,0x1,0x0,0x1, 0x44,0xb1,0x1,0x0,0x1,0x44,0xb1,0x1,0x0,0x1,0xc4,0xc2,0xc0,0xc8,0x80,0x19, 0x8a,0xff,0x81,0xa2,0xf8,0x0,0x48,0xf,0x54,0xd,0x40,0x0,0xb1,0xc0,0x15,0x23, 0x9,0x92,0x2,0x0,0x2,0x88,0x9,0xa7,0xd,0xc8,0x2e,0x43,0xe6,0xa3,0xd1,0x0, 0x1,0xc4,0x84,0xd3,0x79,0x20,0xc,0xd3,0x8,0xe5,0x37,0x36,0x36,0x22,0x5c,0x9, 0xa5,0x1,0x2,0x88,0x11,0x9e,0x90,0x60,0xa,0x91,0x6d,0x46,0xf6,0x1e,0x3a,0x1f, 0xca,0x6,0x8,0x20,0x16,0xac,0x5e,0x80,0x4a,0x82,0x6d,0x4,0x82,0xfa,0xff,0xf5, 0x38,0xc3,0x9,0x20,0x80,0x18,0x40,0x2e,0x0,0x63,0x10,0x89,0xcc,0xc6,0xc3,0x6f, 0x68,0x68,0x80,0xf3,0x1,0x2,0x88,0x91,0xd2,0xbc,0x0,0x10,0x40,0x14,0x27,0x24, 0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0xa2,0xd8,0x0,0x80,0x0,0x3,0x0,0xed,0x40, 0x60,0x6d,0xc2,0xf8,0xd5,0xe0,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42, 0x60,0x82, // /work/depthmap/depthmap/images/win/b-1-19.png 0x0,0x0,0x0,0xf8, 0x89, 0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0, 0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61, 0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8e,0x7c,0xfb,0x51,0x93, 0x0,0x0,0x0,0x20,0x63,0x48,0x52,0x4d,0x0,0x0,0x7a,0x25,0x0,0x0,0x80,0x83, 0x0,0x0,0xf9,0xff,0x0,0x0,0x80,0xe9,0x0,0x0,0x75,0x30,0x0,0x0,0xea,0x60, 0x0,0x0,0x3a,0x98,0x0,0x0,0x17,0x6f,0x92,0x5f,0xc5,0x46,0x0,0x0,0x0,0x83, 0x49,0x44,0x41,0x54,0x38,0x4f,0xa5,0x92,0x51,0xe,0xc0,0x20,0x8,0x43,0xdd,0xcd, 0x3d,0x1a,0x37,0x73,0xd6,0xa4,0x8b,0x1a,0xaa,0x64,0x90,0x10,0xfd,0xb0,0x8f,0xa, 0x3c,0xad,0x47,0xc9,0x4,0x0,0x99,0x28,0x19,0xf1,0x70,0x1f,0x1,0xd4,0x5a,0x1b, 0xd2,0x8b,0x30,0x0,0x62,0xf,0xf2,0x1,0x58,0x45,0x9d,0xac,0xbe,0x43,0x6,0xa0, 0xf,0x41,0x5a,0xf4,0x6c,0xcf,0x90,0x5f,0x80,0xf9,0x3b,0xb,0x40,0x35,0x6a,0x77, 0x21,0x1d,0x98,0xd9,0xf8,0x8a,0x97,0xd7,0x1e,0x40,0x8c,0x5e,0xf0,0xc4,0x9d,0xc9, 0x8a,0x72,0xa,0x14,0xe2,0x1,0x0,0x73,0xb2,0xc1,0xd7,0x3d,0xd8,0xab,0x13,0x42, 0x17,0x6a,0xe1,0x96,0x45,0xc2,0x63,0x8e,0xf5,0x26,0x24,0x30,0xb4,0x89,0xa7,0x75, 0x4f,0x3,0x5e,0x52,0x14,0x48,0x6e,0xfc,0x80,0x3e,0x1f,0x0,0x0,0x0,0x0,0x49, 0x45,0x4e,0x44,0xae,0x42,0x60,0x82, }; static const unsigned char qt_resource_name[] = { // images 0x0,0x6, 0x7,0x3,0x7d,0xc3, 0x0,0x69, 0x0,0x6d,0x0,0x61,0x0,0x67,0x0,0x65,0x0,0x73, // new.png 0x0,0x7, 0x4,0xca,0x57,0xa7, 0x0,0x6e, 0x0,0x65,0x0,0x77,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // down.png 0x0,0x8, 0x6,0xe1,0x5a,0x27, 0x0,0x64, 0x0,0x6f,0x0,0x77,0x0,0x6e,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // win 0x0,0x3, 0x0,0x0,0x7d,0xfe, 0x0,0x77, 0x0,0x69,0x0,0x6e, // save.png 0x0,0x8, 0x8,0xc8,0x58,0x67, 0x0,0x73, 0x0,0x61,0x0,0x76,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // paste.png 0x0,0x9, 0xa,0xa8,0xba,0x47, 0x0,0x70, 0x0,0x61,0x0,0x73,0x0,0x74,0x0,0x65,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur 0x0,0x3, 0x0,0x0,0x6a,0xc2, 0x0,0x63, 0x0,0x75,0x0,0x72, // open.png 0x0,0x8, 0x6,0xc1,0x59,0x87, 0x0,0x6f, 0x0,0x70,0x0,0x65,0x0,0x6e,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00006.png 0x0,0xc, 0xe,0x61,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00007.png 0x0,0xc, 0xe,0x62,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // icon-1-2.png 0x0,0xc, 0x1,0xf1,0x95,0x67, 0x0,0x69, 0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00008.png 0x0,0xc, 0xe,0x63,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // icon-1-3.png 0x0,0xc, 0x1,0xf2,0x95,0x67, 0x0,0x69, 0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00009.png 0x0,0xc, 0xe,0x64,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // icon-1-4.png 0x0,0xc, 0x1,0xf3,0x95,0x67, 0x0,0x69, 0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // icon-1-5.png 0x0,0xc, 0x1,0xf4,0x95,0x67, 0x0,0x69, 0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // icon-1-1.png 0x0,0xc, 0x1,0xf8,0x95,0x67, 0x0,0x69, 0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00001.png 0x0,0xc, 0xe,0x6c,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00002.png 0x0,0xc, 0xe,0x6d,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00003.png 0x0,0xc, 0xe,0x6e,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00004.png 0x0,0xc, 0xe,0x6f,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // cur00005.png 0x0,0xc, 0xe,0x70,0xf1,0x27, 0x0,0x63, 0x0,0x75,0x0,0x72,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x30,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-5.png 0x0,0x9, 0x7,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-4.png 0x0,0x9, 0x5,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-9.png 0x0,0x9, 0x4,0xc,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-19.png 0x0,0xa, 0x0,0x48,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-7-5.png 0x0,0x9, 0xa,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x37,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-4.png 0x0,0x9, 0x8,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-15.png 0x0,0xa, 0x0,0x4c,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-9.png 0x0,0x9, 0x7,0xc,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-2.png 0x0,0x9, 0x4,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-8.png 0x0,0x9, 0x5,0xb,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-15.png 0x0,0xa, 0x0,0x4c,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-3.png 0x0,0x9, 0x9,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-16.png 0x0,0xa, 0x0,0x45,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-2.png 0x0,0x9, 0x7,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-8.png 0x0,0x9, 0x8,0xb,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-11.png 0x0,0xa, 0x0,0x50,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-1.png 0x0,0x9, 0x5,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-6.png 0x0,0x9, 0x4,0x9,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-10.png 0x0,0xa, 0x0,0x4f,0xf6,0x67, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x31,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-16.png 0x0,0xa, 0x0,0x45,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-7-2.png 0x0,0x9, 0xa,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x37,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-1.png 0x0,0x9, 0x8,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-11.png 0x0,0xa, 0x0,0x50,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-7.png 0x0,0x9, 0x9,0xa,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-12.png 0x0,0xa, 0x0,0x49,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-6.png 0x0,0x9, 0x7,0x9,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-5.png 0x0,0x9, 0x5,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-20.png 0x0,0xa, 0x0,0x5f,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-12.png 0x0,0xa, 0x0,0x49,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-5.png 0x0,0x9, 0x8,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-20.png 0x0,0xa, 0x0,0x5f,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x32,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-3.png 0x0,0x9, 0x4,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-4.png 0x0,0x9, 0x9,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-17.png 0x0,0xa, 0x0,0x46,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-3.png 0x0,0x9, 0x7,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-9.png 0x0,0x9, 0x8,0xc,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-2.png 0x0,0x9, 0x5,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-7.png 0x0,0x9, 0x4,0xa,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-11.png 0x0,0xa, 0x0,0x50,0xf6,0x67, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x31,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-17.png 0x0,0xa, 0x0,0x46,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-7-3.png 0x0,0x9, 0xa,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x37,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-2.png 0x0,0x9, 0x8,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-8.png 0x0,0x9, 0x9,0xb,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-13.png 0x0,0xa, 0x0,0x4a,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-7.png 0x0,0x9, 0x7,0xa,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-6.png 0x0,0x9, 0x5,0x9,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-12.png 0x0,0xa, 0x0,0x49,0xf6,0x67, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x31,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-21.png 0x0,0xa, 0x0,0x60,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-13.png 0x0,0xa, 0x0,0x4a,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-1.png 0x0,0x9, 0x9,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-6.png 0x0,0x9, 0x8,0x9,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-21.png 0x0,0xa, 0x0,0x60,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x32,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-22.png 0x0,0xa, 0x0,0x59,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-10.png 0x0,0xa, 0x0,0x4f,0xf7,0xa7, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x31,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-4.png 0x0,0x9, 0x4,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-5.png 0x0,0x9, 0x9,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-18.png 0x0,0xa, 0x0,0x47,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-22.png 0x0,0xa, 0x0,0x59,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x32,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-4.png 0x0,0x9, 0x7,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-3.png 0x0,0x9, 0x5,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-8.png 0x0,0x9, 0x4,0xb,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-18.png 0x0,0xa, 0x0,0x47,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-7-4.png 0x0,0x9, 0xa,0x7,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x37,0x0,0x2d,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-3.png 0x0,0x9, 0x8,0x6,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-9.png 0x0,0x9, 0x9,0xc,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-14.png 0x0,0xa, 0x0,0x4b,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-8.png 0x0,0x9, 0x7,0xb,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x38,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-1.png 0x0,0x9, 0x4,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-2-7.png 0x0,0x9, 0x5,0xa,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x32,0x0,0x2d,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-14.png 0x0,0xa, 0x0,0x4b,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x34,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-2.png 0x0,0x9, 0x9,0x5,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x32,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-1.png 0x0,0x9, 0x7,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-7.png 0x0,0x9, 0x8,0xa,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x37,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-10.png 0x0,0xa, 0x0,0x4f,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-23.png 0x0,0xa, 0x0,0x5a,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x32,0x0,0x33,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-4-11.png 0x0,0xa, 0x0,0x50,0xf7,0xa7, 0x0,0x62, 0x0,0x2d,0x0,0x34,0x0,0x2d,0x0,0x31,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-5.png 0x0,0x9, 0x4,0x8,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x35,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-7-1.png 0x0,0x9, 0xa,0x4,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x37,0x0,0x2d,0x0,0x31,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-5-10.png 0x0,0xa, 0x0,0x4f,0xf6,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x35,0x0,0x2d,0x0,0x31,0x0,0x30,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-6-6.png 0x0,0x9, 0x9,0x9,0x9d,0x47, 0x0,0x62, 0x0,0x2d,0x0,0x36,0x0,0x2d,0x0,0x36,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, // b-1-19.png 0x0,0xa, 0x0,0x48,0xf7,0xc7, 0x0,0x62, 0x0,0x2d,0x0,0x31,0x0,0x2d,0x0,0x31,0x0,0x39,0x0,0x2e,0x0,0x70,0x0,0x6e,0x0,0x67, }; static const unsigned char qt_resource_struct[] = { // : 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1, // :/images 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x2, // :/images/cur 0x0,0x0,0x0,0x76,0x0,0x2,0x0,0x0,0x0,0xe,0x0,0x0,0x0,0x5a, // :/images/win 0x0,0x0,0x0,0x3c,0x0,0x2,0x0,0x0,0x0,0x51,0x0,0x0,0x0,0x9, // :/images/new.png 0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0, // :/images/open.png 0x0,0x0,0x0,0x82,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x10,0xc6, // :/images/down.png 0x0,0x0,0x0,0x26,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3,0x58, // :/images/save.png 0x0,0x0,0x0,0x48,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x5,0xae, // :/images/paste.png 0x0,0x0,0x0,0x5e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0xa,0x55, // :/images/win/b-5-16.png 0x0,0x0,0x4,0x10,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x47,0x7a, // :/images/win/b-1-16.png 0x0,0x0,0x3,0x62,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3d,0xd3, // :/images/win/b-5-17.png 0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x65,0x26, // :/images/win/b-1-17.png 0x0,0x0,0x5,0x6c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x5c,0x32, // :/images/win/b-5-18.png 0x0,0x0,0x8,0x24,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x83,0x80, // :/images/win/b-1-18.png 0x0,0x0,0x7,0xa8,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7c,0x88, // :/images/win/b-5-19.png 0x0,0x0,0x2,0x84,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x30,0x61, // :/images/win/b-1-19.png 0x0,0x0,0x9,0xfa,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0xa0,0x5f, // :/images/win/b-5-12.png 0x0,0x0,0x4,0xf0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x55,0x8f, // :/images/win/b-6-12.png 0x0,0x0,0x6,0xac,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6f,0x77, // :/images/win/b-1-12.png 0x0,0x0,0x4,0x8c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x50,0x2b, // :/images/win/b-5-13.png 0x0,0x0,0x6,0xe0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x71,0xc4, // :/images/win/b-1-13.png 0x0,0x0,0x6,0x62,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6b,0x61, // :/images/win/b-5-14.png 0x0,0x0,0x8,0xe8,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x90,0x30, // :/images/win/b-1-14.png 0x0,0x0,0x8,0x86,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x8a,0xdd, // :/images/win/b-5-15.png 0x0,0x0,0x3,0x30,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3b,0x5f, // :/images/win/b-1-15.png 0x0,0x0,0x2,0xce,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x36,0x68, // :/images/win/b-5-10.png 0x0,0x0,0x9,0xc8,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x9d,0x54, // :/images/win/b-6-10.png 0x0,0x0,0x3,0xf6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x46,0x42, // :/images/win/b-4-10.png 0x0,0x0,0x7,0x5e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x79,0x2c, // :/images/win/b-1-10.png 0x0,0x0,0x9,0x4a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x96,0x6a, // :/images/win/b-5-11.png 0x0,0x0,0x4,0x5a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x4d,0xa3, // :/images/win/b-6-11.png 0x0,0x0,0x5,0xe6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x63,0xf6, // :/images/win/b-4-11.png 0x0,0x0,0x9,0x7e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x99,0x48, // :/images/win/b-1-11.png 0x0,0x0,0x3,0xac,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x42,0xd5, // :/images/win/b-5-22.png 0x0,0x0,0x7,0xc2,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7d,0xf1, // :/images/win/b-1-22.png 0x0,0x0,0x7,0x44,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x77,0xd5, // :/images/win/b-1-23.png 0x0,0x0,0x9,0x64,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x97,0xb0, // :/images/win/b-5-20.png 0x0,0x0,0x5,0x22,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x58,0x65, // :/images/win/b-1-20.png 0x0,0x0,0x4,0xd6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x54,0x17, // :/images/win/b-5-21.png 0x0,0x0,0x7,0x2a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x76,0x85, // :/images/win/b-1-21.png 0x0,0x0,0x6,0xc6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x70,0x86, // :/images/win/b-1-1.png 0x0,0x0,0x8,0xb8,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x8d,0x63, // :/images/win/b-1-2.png 0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x38,0xd1, // :/images/win/b-1-3.png 0x0,0x0,0x5,0x3c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x59,0xcb, // :/images/win/b-1-4.png 0x0,0x0,0x7,0x78,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7a,0x53, // :/images/win/b-1-5.png 0x0,0x0,0x9,0x98,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x9a,0x93, // :/images/win/b-1-6.png 0x0,0x0,0x3,0xde,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x44,0xf5, // :/images/win/b-1-7.png 0x0,0x0,0x5,0xce,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x62,0x9e, // :/images/win/b-1-8.png 0x0,0x0,0x8,0xc,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x82,0x43, // :/images/win/b-1-9.png 0x0,0x0,0x2,0x6c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x2f,0x6, // :/images/win/b-2-1.png 0x0,0x0,0x3,0xc6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x43,0xb8, // :/images/win/b-2-2.png 0x0,0x0,0x5,0xb6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x61,0x65, // :/images/win/b-2-3.png 0x0,0x0,0x7,0xf4,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x80,0xe0, // :/images/win/b-2-4.png 0x0,0x0,0x2,0x54,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x2d,0xb1, // :/images/win/b-2-5.png 0x0,0x0,0x4,0xbe,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x52,0xcd, // :/images/win/b-2-6.png 0x0,0x0,0x6,0x94,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6e,0x20, // :/images/win/b-2-7.png 0x0,0x0,0x8,0xd0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x8e,0x87, // :/images/win/b-2-8.png 0x0,0x0,0x3,0x18,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3a,0x31, // :/images/win/b-4-1.png 0x0,0x0,0x9,0x1a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x92,0xfd, // :/images/win/b-4-2.png 0x0,0x0,0x3,0x7c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3e,0xfb, // :/images/win/b-4-3.png 0x0,0x0,0x5,0x86,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x5d,0x9a, // :/images/win/b-4-4.png 0x0,0x0,0x7,0xdc,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7f,0x9a, // :/images/win/b-4-5.png 0x0,0x0,0x2,0x3c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x2c,0x60, // :/images/win/b-4-6.png 0x0,0x0,0x4,0xa6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x51,0x7e, // :/images/win/b-4-7.png 0x0,0x0,0x6,0x7c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6c,0xb7, // :/images/win/b-4-8.png 0x0,0x0,0x8,0xa0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x8c,0x10, // :/images/win/b-4-9.png 0x0,0x0,0x2,0xe8,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x37,0x90, // :/images/win/b-5-1.png 0x0,0x0,0x4,0x42,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x4b,0x57, // :/images/win/b-5-2.png 0x0,0x0,0x6,0x32,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x68,0x43, // :/images/win/b-5-3.png 0x0,0x0,0x8,0x56,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x87,0x51, // :/images/win/b-5-4.png 0x0,0x0,0x2,0xb6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x34,0x16, // :/images/win/b-5-5.png 0x0,0x0,0x5,0xa,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x56,0xf6, // :/images/win/b-5-6.png 0x0,0x0,0x7,0x12,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x74,0x82, // :/images/win/b-5-7.png 0x0,0x0,0x9,0x32,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x94,0x68, // :/images/win/b-5-8.png 0x0,0x0,0x3,0x94,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x40,0x71, // :/images/win/b-5-9.png 0x0,0x0,0x5,0x9e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x5e,0xff, // :/images/win/b-6-1.png 0x0,0x0,0x6,0xfa,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x73,0x2e, // :/images/win/b-6-2.png 0x0,0x0,0x9,0x2,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x91,0x7f, // :/images/win/b-6-3.png 0x0,0x0,0x3,0x4a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x3c,0x73, // :/images/win/b-6-4.png 0x0,0x0,0x5,0x54,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x5a,0xfe, // :/images/win/b-6-5.png 0x0,0x0,0x7,0x90,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x7b,0x55, // :/images/win/b-6-6.png 0x0,0x0,0x9,0xe2,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x9f,0x28, // :/images/win/b-6-7.png 0x0,0x0,0x4,0x74,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x4e,0xd0, // :/images/win/b-6-8.png 0x0,0x0,0x6,0x4a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x6a,0x30, // :/images/win/b-6-9.png 0x0,0x0,0x8,0x6e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x89,0xaa, // :/images/win/b-7-1.png 0x0,0x0,0x9,0xb0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x9b,0xc7, // :/images/win/b-7-2.png 0x0,0x0,0x4,0x2a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x48,0xd1, // :/images/win/b-7-3.png 0x0,0x0,0x6,0x1a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x66,0x7b, // :/images/win/b-7-4.png 0x0,0x0,0x8,0x3e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x85,0x33, // :/images/win/b-7-5.png 0x0,0x0,0x2,0x9e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x31,0xb5, // :/images/cur/icon-1-2.png 0x0,0x0,0x0,0xd4,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1c,0x39, // :/images/cur/icon-1-3.png 0x0,0x0,0x1,0x10,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1e,0x21, // :/images/cur/icon-1-4.png 0x0,0x0,0x1,0x4c,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x20,0x66, // :/images/cur/icon-1-5.png 0x0,0x0,0x1,0x6a,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x21,0xc5, // :/images/cur/icon-1-1.png 0x0,0x0,0x1,0x88,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x22,0xed, // :/images/cur/cur00006.png 0x0,0x0,0x0,0x98,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x18,0xe3, // :/images/cur/cur00007.png 0x0,0x0,0x0,0xb6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1a,0x7a, // :/images/cur/cur00008.png 0x0,0x0,0x0,0xf2,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1d,0x56, // :/images/cur/cur00009.png 0x0,0x0,0x1,0x2e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1f,0xac, // :/images/cur/cur00001.png 0x0,0x0,0x1,0xa6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x23,0xf2, // :/images/cur/cur00002.png 0x0,0x0,0x1,0xc4,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x25,0xbd, // :/images/cur/cur00003.png 0x0,0x0,0x1,0xe2,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x27,0x55, // :/images/cur/cur00004.png 0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x28,0xdf, // :/images/cur/cur00005.png 0x0,0x0,0x2,0x1e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x2a,0x99, }; QT_BEGIN_NAMESPACE extern Q_CORE_EXPORT bool qRegisterResourceData (int, const unsigned char *, const unsigned char *, const unsigned char *); extern Q_CORE_EXPORT bool qUnregisterResourceData (int, const unsigned char *, const unsigned char *, const unsigned char *); QT_END_NAMESPACE int QT_MANGLE_NAMESPACE(qInitResources_mdi)() { QT_PREPEND_NAMESPACE(qRegisterResourceData) (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qInitResources_mdi)) int QT_MANGLE_NAMESPACE(qCleanupResources_mdi)() { QT_PREPEND_NAMESPACE(qUnregisterResourceData) (0x01, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } Q_DESTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(qCleanupResources_mdi)) ================================================ FILE: depthmapX/renderthread.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include "mainwindow.h" CMSCommunicator::CMSCommunicator() { m_function = -1; simple_version = true; // we want simple dX // TV // GetApp()->m_process_count += 1; } CMSCommunicator::~CMSCommunicator() { } inline void CMSCommunicator::CommPostMessage(int m, int x) const { QGraphDoc *pDoc = (QGraphDoc *)parent_doc; pDoc->ProcPostMessage(m, x); } void CMSCommunicator::runAnalysis(QGraphDoc &graphDoc) { bool success = m_analysis->run(this); if (success) { graphDoc.SetUpdateFlag(m_successUpdateFlagType, m_successUpdateFlagModified); graphDoc.SetRedrawFlag(m_successRedrawFlagViewType, m_successRedrawFlag, m_successRedrawReason); } } //! [0] RenderThread::RenderThread(QObject *parent) : QThread(parent) { abort = false; } //! [0] //! [1] RenderThread::~RenderThread() { mutex.lock(); abort = true; condition.wakeOne(); mutex.unlock(); wait(); } //! [1] //! [2] void RenderThread::render(void* Praram) { m_parent = Praram; if (!isRunning()) { start(NormalPriority); } else { restart = true; condition.wakeOne(); } } //! [2] //! [3] void RenderThread::run() { QGraphDoc *pDoc = (QGraphDoc *) m_parent; CMSCommunicator *comm = pDoc->m_communicator; comm->parent_doc = m_parent; MainWindow* pMain = (MainWindow*)pDoc->m_mainFrame; if (comm) { // move simple setting to comm comm->simple_version = pMain->m_simpleVersion; int ok; switch (comm->GetFunction()) { case CMSCommunicator::IMPORT: ok = pDoc->m_meta_graph->loadLineData( comm, comm->GetOption() ); if (ok == 1) { pDoc->modifiedFlag = true; } else if (ok == -1) { emit showWarningMessage(tr("Warning"), tr("An error was found in the import file")); } // This might change the line layers available, alert the layer chooser: QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADDRAWING)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_TOTAL, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::IMPORTMIF: ok = pDoc->m_meta_graph->loadMifMap( comm, comm->getInFileStream(), comm->GetInfile2() ); switch (ok) { case MINFO_MULTIPLE: //BUG //QMessageBox::warning(0, tr("Warning"), tr("The imported MIF file contains multiple shapes per object.\n Please note that depthmapX has broken these up, so each shape has one row of attribute data.\n Please consult your MapInfo provider for details."), QMessageBox::Ok, QMessageBox::Ok); case MINFO_OK: pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); break; case MINFO_HEADER: emit showWarningMessage(tr("Warning"), tr("depthmapX had a problem reading the header information in your MIF file.")); break; case MINFO_TABLE: emit showWarningMessage(tr("Warning"), tr("depthmapX had a problem reading the table data in your MID file.")); break; case MINFO_MIFPARSE: emit showWarningMessage(tr("Warning"), tr("depthmapX had a problem reading the shape data in your MIF file.\n\ Please ensure that your shape data contains only points, lines, polylines or regions.")); break; case MINFO_OBJROWS: emit showWarningMessage(tr("Warning"), tr("depthmapX had a problem reading the shape data in your MIF file.\n\ It seems as though there are a different number of shapes to rows in the associated table.\n\ This may be due to the existance of unsupported shape types in the file.")); break; } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_TOTAL, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEPOINTS: ok = pDoc->m_meta_graph->makePoints( comm->GetSeedPoint(), comm->GetOption(), comm ); if (ok) { pDoc->modifiedFlag = true; } QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADGRAPH)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEGRAPH: ok = pDoc->m_meta_graph->makeGraph( comm, pDoc->m_make_algorithm, pDoc->m_make_maxdist ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::ANALYSEGRAPH: ok = pDoc->m_meta_graph->analyseGraph( comm, pMain->m_options, comm->simple_version); pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEISOVIST: if (comm->GetSeedAngle() == -1.0) { ok = pDoc->m_meta_graph->makeIsovist( comm, comm->GetSeedPoint(), 0, 0, comm->simple_version ); } else { double ang1 = comm->GetSeedAngle() - comm->GetSeedFoV() * 0.5; double ang2 = comm->GetSeedAngle() + comm->GetSeedFoV() * 0.5; if (ang1 < 0.0) ang1 += 2.0 * M_PI; if (ang2 > 2.0 * M_PI) ang2 -= 2.0 * M_PI; ok = pDoc->m_meta_graph->makeIsovist( comm, comm->GetSeedPoint(), ang1, ang2, comm->simple_version ); } if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } // Tell the sidebar about the new map: QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADGRAPH)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEISOVISTSFROMFILE: { try { auto isovists = EntityParsing::parseIsovists(comm->GetInfile2(), ','); comm->CommPostMessage(Communicator::NUM_STEPS, isovists.size()); int isovistIdx = 1; for (IsovistDefinition &isovist : isovists) { comm->CommPostMessage(Communicator::CURRENT_STEP, isovistIdx); pDoc->m_meta_graph->makeIsovist(comm, isovist.getLocation(), isovist.getLeftAngle(), isovist.getRightAngle(), comm->simple_version); isovistIdx++; } pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); // Tell the sidebar about the new map: QApplication::postEvent( pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void *)pDoc, QGraphDoc::CONTROLS_LOADGRAPH)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } catch (EntityParsing::EntityParseException &e) { emit showWarningMessage(tr("Warning"), tr("depthmapX was unable to parse the isovists test file. Error: %1") .arg(QString::fromStdString(e.what()))); } break; } case CMSCommunicator::MAKEISOVISTPATH: // the graph is going to build this path from a selection in a data map: // a data map must be topmost with lines or polylines selected // linedata must be displayed as per usual ok = pDoc->m_meta_graph->makeIsovistPath( comm, comm->GetSeedAngle(), comm->simple_version ); // Tell the sidebar about the new map: QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADGRAPH)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEALLLINEMAP: ok = pDoc->m_meta_graph->makeAllLineMap( comm, comm->GetSeedPoint() ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } // Tell the sidebar about the new map: QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADGRAPH)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEFEWESTLINEMAP: ok = pDoc->m_meta_graph->makeFewestLineMap( comm, comm->GetOption() ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEDRAWING: { // option 1 is: 0 a data map, 1 an axial map ok = pDoc->m_meta_graph->convertToDrawing( comm, comm->GetString().toStdString(), (comm->GetOption(1) == 0)); if (ok) { pDoc->modifiedFlag = true; } else { emit showWarningMessage(tr("Warning"), tr("No objects currently visible in drawing layers")); } // Tell the sidebar about the new map: QApplication::postEvent(pMain, new QmyEvent((enum QEvent::Type)FOCUSGRAPH, (void*)pDoc, QGraphDoc::CONTROLS_LOADDRAWING)); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_TOTAL, QGraphDoc::NEW_DATA ); break; } case CMSCommunicator::MAKEUSERMAP: ok = pDoc->m_meta_graph->convertDrawingToAxial( comm, comm->GetString().toStdString()); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } else { emit showWarningMessage(tr("Warning"), tr("No objects currently visible in drawing layers")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEUSERMAPSHAPE: ok = pDoc->m_meta_graph->convertDataToAxial( comm, comm->GetString().toStdString(), (comm->GetOption(0) == 1), (comm->GetOption(1) == 1) ); if (ok) { if (comm->GetOption(0) == 0) { // note: there is both a new table and a deleted table, but deleted table leads to a greater redraw: pDoc->SetUpdateFlag(QGraphDoc::DELETED_TABLE); } else { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } } else { emit showWarningMessage(tr("Warning"), tr("No lines available in current layer to convert to axial lines")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEUSERSEGMAP: ok = pDoc->m_meta_graph->convertDrawingToSegment( comm, comm->GetString().toStdString() ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } else { emit showWarningMessage(tr("Warning"), tr("No objects currently visible in drawing layers")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEUSERSEGMAPSHAPE: ok = pDoc->m_meta_graph->convertDataToSegment( comm, comm->GetString().toStdString(), (comm->GetOption(0) == 1), (comm->GetOption(1) == 1) ); if (ok) { if (comm->GetOption(0) == 0) { // note: there is both a new table and a deleted table, but deleted table leads to a greater redraw: pDoc->SetUpdateFlag(QGraphDoc::DELETED_TABLE); } else { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } } else { emit showWarningMessage(tr("Warning"), tr("No lines available in current layer to convert to segments")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::MAKEGATESMAP: { // note: relies on the fact that make data map from drawing sets option 1 to -1, whereas make data layer from graph it to either 0 or 1 int shapeMapType = ShapeMap::DRAWINGMAP; bool copydata = false; if(comm->GetOption(1) != -1) { shapeMapType = ShapeMap::DATAMAP; copydata = (comm->GetOption(1) != 0); } ok = pDoc->m_meta_graph->convertToData( comm, comm->GetString().toStdString(), (comm->GetOption(0) == 1), shapeMapType, copydata ); if (ok) { if (comm->GetOption(0) == 0) { // note: there is both a new table and a deleted table, but deleted table leads to a greater redraw: pDoc->SetUpdateFlag(QGraphDoc::DELETED_TABLE); } else { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } } else { emit showWarningMessage(tr("Warning"), tr("No objects currently visible in drawing layers")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; } case CMSCommunicator::MAKECONVEXMAP: { // note: relies on the fact that make convex map from drawing sets option 1 to -1, whereas make convex map from data sets it to either 0 or 1 int shapeMapType = ShapeMap::DRAWINGMAP; bool copydata = false; if(comm->GetOption(1) != -1) { shapeMapType = ShapeMap::DATAMAP; copydata = (comm->GetOption(1) != 0); } ok = pDoc->m_meta_graph->convertToConvex( comm, comm->GetString().toStdString(), (comm->GetOption(0) == 1), shapeMapType, copydata); if (ok) { if (comm->GetOption(0) == 0) { // note: there is both a new table and a deleted table, but deleted table leads to a greater redraw: pDoc->SetUpdateFlag(QGraphDoc::DELETED_TABLE); } else { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } } else { emit showWarningMessage(tr("Warning"), tr("No polygons currently visible in drawing layers")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; } case CMSCommunicator::MAKEBOUNDARYMAP: break; case CMSCommunicator::MAKESEGMENTMAP: // convert percentage to fraction, and pass to metagraph ok = pDoc->m_meta_graph->convertAxialToSegment( comm, comm->GetString().toStdString(), (comm->GetOption(0) == 1), (comm->GetOption(1) == 1), double(comm->GetOption(2)) / 100.0); if (ok) { if (comm->GetOption(0) == 0) { // note: there is both a new table and a deleted table, but deleted table leads to a greater redraw: pDoc->SetUpdateFlag(QGraphDoc::DELETED_TABLE); } else { pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); } } else { emit showWarningMessage(tr("Warning"), tr("No lines exist in map to convert to segments")); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::AXIALANALYSIS: ok = pDoc->m_meta_graph->analyseAxial( comm, pMain->m_options, comm->simple_version ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::SEGMENTANALYSISTULIP: ok = pDoc->m_meta_graph->analyseSegmentsTulip( comm, pMain->m_options ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::SEGMENTANALYSISANGULAR: ok = pDoc->m_meta_graph->analyseSegmentsAngular( comm, pMain->m_options ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::TOPOMETANALYSIS: ok = pDoc->m_meta_graph->analyseTopoMet( comm, pMain->m_options ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); break; case CMSCommunicator::POINTDEPTH: { // Set up for options step depth selection Options options; options.global = 0; options.point_depth_selection = 1; ok = pDoc->m_meta_graph->analyseGraph( comm, options, comm->simple_version); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA ); } break; case CMSCommunicator::METRICPOINTDEPTH: { // Set up for options metric point depth selection Options options; options.global = 0; options.point_depth_selection = 2; ok = pDoc->m_meta_graph->analyseGraph( comm, options, comm->simple_version ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA ); } break; case CMSCommunicator::ANGULARPOINTDEPTH: { // Set up for options angular point depth selection Options options; options.global = 0; options.point_depth_selection = 3; ok = pDoc->m_meta_graph->analyseGraph( comm, options, comm->simple_version ); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA ); } break; case CMSCommunicator::TOPOLOGICALPOINTDEPTH: { // Set up for options topological point depth selection (segment maps only) Options options; options.global = 0; options.point_depth_selection = 4; ok = pDoc->m_meta_graph->analyseGraph( comm, options, comm->simple_version); if (ok) { pDoc->SetUpdateFlag(QGraphDoc::NEW_DATA); } pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA ); } break; case CMSCommunicator::AGENTANALYSIS: { try { pDoc->m_meta_graph->runAgentEngine( comm ); pDoc->SetUpdateFlag(QGraphDoc::NEW_TABLE); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA ); } catch (depthmapX::PointMapException const & e) { emit runtimeExceptionThrown(e.getErrorType(), e.what()); } } break; case CMSCommunicator::FROMCONNECTOR: { comm->runAnalysis(*pDoc); break; } } emit closeWaitDialog(); msleep(100); delete pDoc->m_communicator; // Ensure we delete *the* communicator pDoc->m_communicator = NULL; // REDRAW_TOTAL to REDRAW_GRAPH // recenterView after fill // TV pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA ); } return; } ================================================ FILE: depthmapX/resource.qrc ================================================ images/new.png images/open.png images/save.png images/paste.png images/down.png images/win/b-1-1.png images/win/b-1-2.png images/win/b-1-3.png images/win/b-1-4.png images/win/b-1-5.png images/win/b-1-6.png images/win/b-1-7.png images/win/b-1-8.png images/win/b-1-9.png images/win/b-1-10.png images/win/b-1-11.png images/win/b-1-12.png images/win/b-1-13.png images/win/b-1-14.png images/win/b-1-15.png images/win/b-1-16.png images/win/b-1-17.png images/win/b-1-18.png images/win/b-1-19.png images/win/b-1-20.png images/win/b-1-21.png images/win/b-1-22.png images/win/b-1-23.png images/win/b-2-1.png images/win/b-2-2.png images/win/b-2-3.png images/win/b-2-4.png images/win/b-2-5.png images/win/b-2-6.png images/win/b-2-7.png images/win/b-2-8.png images/win/b-4-1.png images/win/b-4-2.png images/win/b-4-3.png images/win/b-4-4.png images/win/b-4-5.png images/win/b-4-6.png images/win/b-4-7.png images/win/b-4-8.png images/win/b-4-9.png images/win/b-4-10.png images/win/b-4-11.png images/win/b-5-1.png images/win/b-5-2.png images/win/b-5-3.png images/win/b-5-4.png images/win/b-5-5.png images/win/b-5-6.png images/win/b-5-7.png images/win/b-5-8.png images/win/b-5-9.png images/win/b-5-10.png images/win/b-5-11.png images/win/b-5-12.png images/win/b-5-13.png images/win/b-5-14.png images/win/b-5-15.png images/win/b-5-16.png images/win/b-5-17.png images/win/b-5-18.png images/win/b-5-19.png images/win/b-5-20.png images/win/b-5-21.png images/win/b-5-22.png images/win/b-6-1.png images/win/b-6-2.png images/win/b-6-3.png images/win/b-6-4.png images/win/b-6-5.png images/win/b-6-6.png images/win/b-6-7.png images/win/b-6-8.png images/win/b-6-9.png images/win/b-6-10.png images/win/b-6-11.png images/win/b-6-12.png images/win/b-7-1.png images/win/b-7-2.png images/win/b-7-3.png images/win/b-7-4.png images/win/b-7-5.png images/cur/cur00001.png images/cur/cur00002.png images/cur/cur00003.png images/cur/cur00004.png images/cur/cur00005.png images/cur/cur00006.png images/cur/cur00007.png images/cur/cur00008.png images/cur/cur00009.png images/cur/icon-1-1.png images/cur/icon-1-2.png images/cur/icon-1-3.png images/cur/icon-1-4.png images/cur/icon-1-5.png images/depthmapX.png ================================================ FILE: depthmapX/resources/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleDisplayName depthmapX CFBundleDocumentTypes CFBundleTypeExtensions graph CFBundleTypeIconFile graph.icns CFBundleTypeName Graph File CFBundleTypeOSTypes graph CFBundleTypeRole Editor NSDocumentClass GraphDocument CFBundleExecutable depthmapX CFBundleIconFile depthmapX.icns CFBundleIdentifier com.spacegroupucl.depthmapX CFBundleInfoDictionaryVersion 6.0 CFBundleName depthmapX CFBundlePackageType APPL CFBundleSupportedPlatforms MacOSX LSApplicationCategoryType public.app-category.business LSHasLocalizedDisplayName NSAppTransportSecurity NSAllowsArbitraryLoads NSMainNibFile MainMenu NSPrincipalClass depthmapXApplication UTExportedTypeDeclarations UTTypeConformsTo public.data UTTypeDescription Graph File UTTypeIdentifier com.spacegroupucl.graph UTTypeTagSpecification com.apple.ostype GRAPH public.filename-extension graph public.mime-type application/graph ================================================ FILE: depthmapX/settings.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include /** * Tags for settings to be used when reading writing settings. Don't just use * string literals */ namespace SettingTag { const QString position = "pos"; const QString size = "size"; const QString foregroundColour = "forColor"; const QString backgroundColour = "backColor"; const QString antialiasingSamples = "antialisingSamples"; const QString simpleVersion = "simple"; const QString recentFileList = "recentFileList"; const QString mwMaximised = "mainWindowMaximised"; const QString licenseAccepted = "licenseAccepted"; const QString depthmapViewSize = "depthmapViewSize"; const QString legacyMapWindow = "legacyMapWindow"; const QString highlightOnHover = "highlightOnHover"; } /** * @brief Class encapsulating one settings transaction * This is supposed to use one underlying QSettings object for several reads/writes */ class SettingsTransaction { public: virtual const QVariant readSetting( const QString& tag, const QVariant& defaultValue = QVariant()) const = 0; virtual void writeSetting( const QString& tag, const QVariant& value) = 0; virtual ~SettingsTransaction(){} }; /** * @brief The Settings class * Encapsulates reading/writing settings so we don't have to faff around with constructing QSettings in * 7 different location. The read/write methods on this class create a temporary QSettings object, so * if you want to read/write more than one setting in one go, use a transaction. */ class Settings : public SettingsTransaction { public: virtual std::unique_ptr getTransaction() = 0; }; ================================================ FILE: depthmapX/settingsimpl.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "settingsimpl.h" SettingsImpl::SettingsImpl(QSettingsFactory* factory) : mSettingsFactory(factory) { } const QVariant SettingsImpl::readSetting(const QString &tag, const QVariant &defaultValue) const { auto settings = mSettingsFactory->getSettings(); return settings->value(tag, defaultValue); } void SettingsImpl::writeSetting(const QString &tag, const QVariant &value) { auto settings = mSettingsFactory->getSettings(); settings->setValue(tag, value); } class SettingsTransactionImpl : public SettingsTransaction { public: SettingsTransactionImpl(std::unique_ptr &&settings) : mSettings(std::move(settings)) {} virtual const QVariant readSetting(const QString &tag, const QVariant &defaultValue) const { return mSettings->value(tag, defaultValue); } virtual void writeSetting(const QString &tag, const QVariant &value) { mSettings->setValue(tag, value); } private: std::unique_ptr mSettings; }; std::unique_ptr SettingsImpl::getTransaction() { return std::unique_ptr(new SettingsTransactionImpl(mSettingsFactory->getSettings())); } ================================================ FILE: depthmapX/settingsimpl.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "settings.h" #include #include #include class QSettingsFactory { public: virtual std::unique_ptr getSettings() const = 0; virtual ~QSettingsFactory() {} }; class DefaultSettingsFactory : public QSettingsFactory { public: DefaultSettingsFactory() { m_settingsFile = QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation).first() + "/depthmapXsettings.ini"; } // QSettingsFactory interface public: virtual std::unique_ptr getSettings() const { return std::unique_ptr(new QSettings(m_settingsFile, QSettings::IniFormat)); } private: QString m_settingsFile; }; class SettingsImpl : public Settings { public: SettingsImpl(QSettingsFactory *settingsFactory); // SettingsTransaction interface public: virtual const QVariant readSetting(const QString &tag, const QVariant &defaultValue) const; virtual void writeSetting(const QString &tag, const QVariant &value); // Settings interface virtual std::unique_ptr getTransaction(); private: std::unique_ptr mSettingsFactory; }; ================================================ FILE: depthmapX/treeWindow.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include #include #include #include "treeWindow.h" QT_BEGIN_NAMESPACE IndexWidget::IndexWidget(QWidget *parent) : QTreeWidget(parent) { setColumnCount(2); setHeaderLabels(columnNames); header()->setSectionResizeMode(Column::MAP, QHeaderView::Stretch); header()->setSectionResizeMode(Column::EDITABLE, QHeaderView::ResizeToContents); header()->resizeSection(Column::EDITABLE, 10); header()->setStretchLastSection(false); installEventFilter(this); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), parent, SLOT(OnSelchangingTree(QTreeWidgetItem*, int))); } void IndexWidget::removeAllItem(QTreeWidgetItem *start) { int index; QTreeWidgetItem *currentItem = start; if(currentItem) { QTreeWidgetItem *parent = currentItem->parent(); if (parent) { index = parent->indexOfChild(currentItem); delete parent->takeChild(index); } else { index = indexOfTopLevelItem(currentItem); delete takeTopLevelItem(index); } } } QTreeWidgetItem * IndexWidget::addNewItem(const QString &title, QTreeWidgetItem* parent) { QTreeWidgetItem *newItem = 0; QStringList columnStrings(title); if (parent != NULL) { newItem = new QTreeWidgetItem(parent, columnStrings); } else { newItem = new QTreeWidgetItem(this, columnStrings); } setCurrentItem(newItem); newItem->setFlags(newItem->flags() &~ (Qt::ItemIsEditable | Qt::ItemIsSelectable)); return newItem; } QT_END_NAMESPACE ================================================ FILE: depthmapX/treeWindow.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef indexWidget_H #define indexWidget_H #include QT_BEGIN_NAMESPACE class QEvent; class QTreeWidgetItem; class IndexWidget : public QTreeWidget { Q_OBJECT private: enum Column {MAP = 0, EDITABLE = 1}; public: IndexWidget(QWidget *parent = 0); QString m_mapColumn = "Map"; QString m_editableColumn = "Editable"; void setItemVisibility(QTreeWidgetItem* item, Qt::CheckState checkState) { item->setCheckState(Column::MAP, checkState); } void setItemEditability(QTreeWidgetItem* item, Qt::CheckState checkState) { item->setCheckState(Column::EDITABLE, checkState); } void setItemReadOnly(QTreeWidgetItem* item) { item->setData(Column::EDITABLE, Qt::CheckStateRole, QVariant()); } bool isItemSetVisible(QTreeWidgetItem* item) { return item->checkState(Column::MAP); } bool isItemSetEditable(QTreeWidgetItem* item) { return item->checkState(Column::EDITABLE); } bool isMapColumn(int col) { return col == Column::MAP; } bool isEditableColumn(int col) { return col == Column::EDITABLE; } signals: void requestShowLink(const QUrl& url); public slots: void removeAllItem(QTreeWidgetItem *start); QTreeWidgetItem * addNewItem(const QString& title, QTreeWidgetItem *parent = NULL); private: QStringList columnNames = (QStringList() << m_mapColumn << m_editableColumn); }; QT_END_NAMESPACE #endif // BOOKMARK_WIDGET_H ================================================ FILE: depthmapX/views/3dview/3dview.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "3dview.h" #include "depthmapX/mainwindow.h" #include "genlib/xmlparse.h" #include #include #include #include #ifdef __APPLE__ #include #include #else #include #include #endif #include "glureimpl.h" #ifndef _WIN32 // Not working? #define LOBYTE(w) ((unsigned char)((w)&0xff)) #define GetRValue(rgb) (LOBYTE(rgb)) #define GetGValue(rgb) (LOBYTE((rgb) >> 8)) #define GetBValue(rgb) (LOBYTE((rgb) >> 16)) #else #define finite _finite #endif #define ID_ADD_AGENT 32947 #define ID_3D_PAN 32948 #define ID_3D_ZOOM 32949 #define ID_3D_ROT 32950 #define ID_3D_PAUSE 32951 #define ID_3D_PLAY_LOOP 32981 #define ID_3D_FILLED 32983 ///////////////////////////////////////////////////////////////////////////// // Q3DView Q3DView::Q3DView(QWidget *parent, QGraphDoc *doc) : QOpenGLWidget(parent) { m_points = NULL; m_pointcount = 0; m_mouse_mode = ID_3D_ROT; // resouce m_mouse_mode_on = 0; m_key_mode_on = 0; m_quick_draw = false; m_animating = false; m_drawtrails = false; m_fill = true; m_track = 0.0; m_right_mouse = false; // Quick mod - TV m_panx = m_pany = m_rotx = m_roty = 0.0f; m_zoom = 1.0f; m_roty = 60.0f; QTimer *m_Timer = new QTimer(this); connect(m_Timer, SIGNAL(timeout()), this, SLOT(timerSlot())); setWindowIcon(QIcon(tr(":/images/cur/icon-1-3.png"))); pDoc = doc; setWindowTitle(pDoc->m_base_title + ":3D View"); m_Timer->start(20); grabKeyboard(); pDoc->m_redraw_flag[QGraphDoc::VIEW_3D] = QGraphDoc::REDRAW_TOTAL; OnRedraw(0, 0); setMouseTracking(true); } Q3DView::~Q3DView() { // Quick mod - TV releaseKeyboard(); } ///////////////////////////////////////////////////////////////////////////// // Q3DView drawing // void Q3DView::paintEvent(QPaintEvent *event) void Q3DView::paintGL() { OnRedraw(0, 0); DrawScene(); } int Q3DView::OnRedraw(int wParam, int lParam) { int flag = pDoc->GetRedrawFlag(QGraphDoc::VIEW_3D); if (flag != QGraphDoc::REDRAW_DONE) { // while (!pDoc->SetRedrawFlag(QGraphDoc::VIEW_3D, QGraphDoc::REDRAW_DONE)) { // prefer waitformultipleobjects here // sleep(1); } // if (flag == QGraphDoc::REDRAW_TOTAL) { qWarning("Reload\n"); ReloadLineData(); ReloadPointData(); m_quick_draw = false; } } return 0; } ///////////////////////////////////////////////////////////////////////////// // Q3DView message handlers void Q3DView::timerEvent(QTimerEvent *event) { if (m_mouse_mode == ID_3D_PLAY_LOOP) { PlayLoop(); SetModelMat(); m_quick_draw = true; if (!m_animating) { // if animating will redraw below DrawScene(); } update(); } else if (m_key_mode_on) { QSize diff(0, 0); switch (m_keydown) { /*case 37:*/ case Qt::Key_Left: diff.setWidth(-2); break; /*case 38:*/ case Qt::Key_Up: diff.setHeight(-2); break; // up arrow: note, as per MS reversed y /*case 39:*/ case Qt::Key_Right: diff.setWidth(2); break; /*case 40:*/ case Qt::Key_Down: diff.setHeight(2); } switch (m_key_mode_on) { case ID_3D_ROT: Rot(diff); break; case ID_3D_PAN: Pan(diff); break; case ID_3D_ZOOM: Zoom(diff); break; } SetModelMat(); m_quick_draw = true; if (!m_animating) { // if animating will redraw below DrawScene(); } } if (m_animating && !pDoc->m_communicator && pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessedPoints()) { PointMap &pointmap = pDoc->m_meta_graph->getDisplayedPointMap(); m_animating = false; for (size_t i = 0; i < m_mannequins.size(); i++) { m_mannequins[i].frame(); if (m_mannequins[i].m_frame == 0) { if (m_mannequins[i].m_playback) { int j = m_mannequins[i].m_trace_id; Trace &trace = m_traces[j]; if (m_mannequins[i].m_time >= trace.starttime && m_mannequins[i].m_time <= trace.endtime) { // active zone: m_mannequins[i].m_active = true; size_t k = 0; while (k < m_traces[j].events.size() && m_traces[j].events[k].t < m_mannequins[i].m_time) { k++; } if (k < m_traces[j].events.size()) { Point2f p = (Point2f)m_traces[j].events[k]; PixelRef pix = pointmap.pixelate(p); // note, take the pix before you scale! p.normalScale(m_region); m_mannequins[i].advance(p); auto iter = m_pixels.find(pix); if (iter != m_pixels.end()) { if (iter->second.m_value < 10) { iter->second.m_value += 1; } } } } else { m_mannequins[i].m_active = false; } } else { int j = m_mannequins[i].m_agent_id; m_agents[j].onMove(); Point2f p = m_agents[j].getLocation(); p.normalScale(m_region); m_mannequins[i].advance(p); // // pretty coloured pixels PixelRef pix = m_agents[j].getNode(); auto iter = m_pixels.find(pix); if (iter != m_pixels.end()) { if (iter->second.m_value < 10) { iter->second.m_value += 1; } } } } } m_animating = true; update(); } } // void Q3DView::Init() void Q3DView::initializeGL() { initializeOpenGLFunctions(); m_oldRect = QRect(0, 0, width(), height()); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); glEnableClientState(GL_VERTEX_ARRAY); } void Q3DView::DrawScene() { std::unique_lock lock(m_draw_mutex, std::try_to_lock); if (!lock.owns_lock()) { return; } makeCurrent(); SetModelMat(); QRgb bg = qRgb(0, 0, 0); QRgb fg = qRgb(128, 128, 128); glClearColor((GLfloat)GetRValue(bg) / 255.0f, (GLfloat)GetGValue(bg) / 255.0f, (GLfloat)GetBValue(bg) / 255.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0f, 0.0f, 0.0f); if (m_male_template.m_init) { for (size_t i = 0; i < m_mannequins.size(); i++) { if (m_mannequins[i].m_active) { if (i % 2 == 0) { m_mannequins[i].draw(m_male_template, m_drawtrails, m_fill); } else { m_mannequins[i].draw(m_female_template, m_drawtrails, m_fill); } } } } if (m_fill) { if (!m_animating) { if (pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessedPoints()) { // okay, you can go for it and draw all the squares in cutesy 3d: PointMap &pointmap = pDoc->m_meta_graph->getDisplayedPointMap(); AttributeTable &table = pointmap.getAttributeTable(); for (auto iter = table.begin(); iter != table.end(); iter++) { PixelRef pix = iter->getKey().value; PafColor color; int col = pointmap.getDisplayedAttribute(); float value = iter->getRow().getNormalisedValue(col); if (value != -1.0f) { color.makeAxmanesque(value); glColor3f(color.redf(), color.greenf(), color.bluef()); Point2f p = pointmap.depixelate(pix); p.normalScale(m_region); glPushMatrix(); glTranslatef(p.x, p.y, 0.0f); glVertexPointer(3, GL_FLOAT, 0, m_rect); glDrawArrays(GL_QUADS, 0, 4); glPopMatrix(); } } } } else { for (auto pixel : m_pixels) { int &value = pixel.second.m_value; if (value != -1) { if (pafrand() % 10000 == 0) { value--; } PafColor color; color.makeAxmanesque(float(value) / 10.0f); glColor3f(color.redf(), color.greenf(), color.bluef()); Point2f &p = pixel.second.m_point; glPushMatrix(); glTranslatef(p.x, p.y, 0.0f); glVertexPointer(3, GL_FLOAT, 0, m_rect); glDrawArrays(GL_QUADS, 0, 4); glPopMatrix(); } } } } glColor3f((GLfloat)GetRValue(fg) / 255.0f, (GLfloat)GetGValue(fg) / 255.0f, (GLfloat)GetBValue(fg) / 255.0f); if (m_pointcount) { glVertexPointer(3, GL_FLOAT, 0, m_points); glDrawArrays(GL_LINES, 0, m_pointcount); } glFlush(); #if defined(_MSC_VER) SwapBuffers(wglGetCurrentDC()); #else ; #endif } void Q3DView::Reshape(int x, int y) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluReimpl::gluPerspective(45.0f, (GLfloat)x / (GLfloat)y, 0.1f, 3.0f); // leave matrix mode in model view: glMatrixMode(GL_MODELVIEW); } void Q3DView::OnRecentreView() { SetModelMat(); } void Q3DView::SetModelMat() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(-m_panx, m_pany, -m_zoom); glRotatef(-m_roty, 1.0f, 0.0f, 0.0f); glRotatef(-m_rotx, 0.0f, 0.0f, 1.0f); glTranslatef(-0.5f, -0.5f, 0.0f); } void Q3DView::ReloadLineData() { if (m_points) { delete[] m_points; m_points = NULL; } m_region = QtRegion(); if (pDoc->m_meta_graph && pDoc->m_meta_graph->getState() & MetaGraph::LINEDATA) { // should really check communicator is not open... auto mgraphLock = pDoc->m_meta_graph->getLock(); std::unique_lock drawLock(m_draw_mutex); std::vector lines; for (const auto &pixelGroup : pDoc->m_meta_graph->m_drawingFiles) { for (const auto &pixel : pixelGroup.m_spacePixels) { if (pixel.isShown()) { if (m_region.atZero()) { m_region = pixel.getRegion(); } else { m_region = runion(m_region, pixel.getRegion()); } auto refShapes = pixel.getAllShapes(); for (const auto &refShape : refShapes) { const SalaShape &shape = refShape.second; if (shape.isLine()) { lines.push_back(shape.getLine()); } else if (shape.isPolyLine() || shape.isPolygon()) { for (int n = 0; n < shape.m_points.size() - 1; n++) { lines.push_back(Line(shape.m_points[n], shape.m_points[n + 1])); } if (shape.isPolygon()) { lines.push_back(Line(shape.m_points.back(), shape.m_points.front())); } } } } } } m_pointcount = lines.size() * 2; if (m_pointcount) { // now scale up to a nice square region around midpoint: if (m_region.width() > m_region.height()) { double oldheight = m_region.height(); m_region.bottom_left.y -= (m_region.width() - oldheight) / 2; m_region.top_right.y += (m_region.width() - oldheight) / 2; } else { double oldwidth = m_region.width(); m_region.bottom_left.x -= (m_region.height() - oldwidth) / 2; m_region.top_right.x += (m_region.height() - oldwidth) / 2; } m_points = new GLfloat[m_pointcount * 3]; for (int i = 0; i < m_pointcount; i++) { Point2f p; if (i % 2 == 0) { p = lines[i / 2].start(); } else { p = lines[i / 2].end(); } p.normalScale(m_region); m_points[i * 3 + 0] = p.x; m_points[i * 3 + 1] = p.y; m_points[i * 3 + 2] = 0.0; } } } // note: as affects region, will also affect point data: ReloadPointData(); } const GLfloat g_rect[][3] = { {-0.5f, -0.5f, -0.05f}, {0.5f, -0.5f, -0.05f}, {0.5f, 0.5f, -0.05f}, {-0.5f, 0.5f, -0.05f}}; void Q3DView::ReloadPointData() { m_mannequins.clear(); m_agents.clear(); m_animating = false; if (pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessedPoints()) { // if (!m_region.atZero()) { GLfloat unit = pDoc->m_meta_graph->getDisplayedPointMap().getSpacing() / m_region.width(); m_male_template.Init(unit, true); m_female_template.Init(unit, false); for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { m_rect[i][j] = unit * g_rect[i][j]; } } } else { m_male_template.Destroy(); m_female_template.Destroy(); } // m_pixels.clear(); PointMap &map = pDoc->m_meta_graph->getDisplayedPointMap(); AttributeTable &table = map.getAttributeTable(); for (const auto &iter : table) { PixelRef pix = iter.getKey().value; Point2f p = map.depixelate(pix); p.normalScale(m_region); m_pixels[pix] = C3DPixelData(p); } } else { m_male_template.Destroy(); m_female_template.Destroy(); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// void Q3DView::On3dPan() { m_mouse_mode = ID_3D_PAN; } void Q3DView::On3dRot() { m_mouse_mode = ID_3D_ROT; } void Q3DView::On3dZoom() { m_mouse_mode = ID_3D_ZOOM; } void Q3DView::OnPlayLoop() { m_mouse_mode = ID_3D_PLAY_LOOP; } void Q3DView::OnAddAgent() { m_mouse_mode = ID_ADD_AGENT; } void Q3DView::OnToolsAgentLoadProgram() { QString template_string; template_string += "Text files (*.txt)\nAll files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QStringList infiles = QFileDialog::getOpenFileNames(0, tr("Import"), "", template_string, &selectedFilter, options); if (!infiles.size()) { return; } std::string filename = infiles[0].toStdString(); if (!filename.empty()) { m_animating = false; std::unique_lock lock(m_draw_mutex); m_agents.clear(); m_mannequins.clear(); if (!m_agent_program.open(filename)) { QMessageBox::warning(this, tr("depthmapX"), tr("Unable to understand agent program"), QMessageBox::Ok, QMessageBox::Ok); } } else { QMessageBox::warning(this, tr("depthmapX"), tr("No file selected"), QMessageBox::Ok, QMessageBox::Ok); } } void Q3DView::On3dFilled() { if (m_fill) { m_fill = false; } else { m_fill = true; } update(); } void Q3DView::OnAgentTrails() { if (m_drawtrails) { m_drawtrails = false; } else { m_drawtrails = true; } } ///////////////////////////////////////////////////////////////////////////////////////// void Q3DView::OnLButtonDown(unsigned int nFlags, QPoint point) { m_right_mouse = false; switch (m_mouse_mode) { case ID_3D_PAN: case ID_3D_ROT: case ID_3D_ZOOM: m_mouse_mode_on = m_mouse_mode; m_mouse_origin = point; break; case ID_ADD_AGENT: { if (m_male_template.m_init) { CreateAgent(point); } } break; } } void Q3DView::OnLButtonUp(unsigned int nFlags, QPoint point) { m_mouse_mode_on = 0; m_quick_draw = false; update(); } QSize Q3DView::sizeHint() const { return QSize(2000, 2000); } void Q3DView::OnRButtonDown(unsigned int nFlags, QPoint point) { m_right_mouse = true; std::unique_lock lock(m_draw_mutex); m_mouse_origin = point; } void Q3DView::OnRButtonUp(unsigned int nFlags, QPoint point) { m_right_mouse = false; m_quick_draw = false; update(); } void Q3DView::OnMouseMove(unsigned int nFlags, QPoint point) { if (m_mouse_mode_on && point != m_mouse_origin) { QSize diff(m_mouse_origin.x() - point.x(), m_mouse_origin.y() - point.y()); switch (m_mouse_mode) { case ID_3D_PAN: Pan(diff); m_mouse_origin = point; break; case ID_3D_ROT: Rot(diff); m_mouse_origin = point; break; case ID_3D_ZOOM: Zoom(diff); m_mouse_origin = point; break; } SetModelMat(); m_quick_draw = true; update(); } else if (m_right_mouse && point != m_mouse_origin) { // always pan with right mouse QSize diff(m_mouse_origin.x() - point.x(), m_mouse_origin.y() - point.y()); Pan(diff); m_mouse_origin = point; SetModelMat(); m_quick_draw = true; update(); } } void Q3DView::Pan(QSize diff) { m_panx += 0.005f * (diff.width()); if (m_panx < -1.0f) { m_panx = -1.0f; } else if (m_panx > 1.0f) { m_panx = 1.0f; } m_pany += 0.005f * (diff.height()); if (m_pany < -1.0f) { m_pany = -1.0f; } else if (m_pany > 1.0f) { m_pany = 1.0f; } } void Q3DView::Rot(QSize diff) { m_rotx += 0.5f * (diff.width()); if (m_rotx < -180.0f) { m_rotx = 180.0f; } else if (m_rotx > 180.0f) { m_rotx = -180.0f; } m_roty += 0.5f * (diff.height()); if (m_roty < 0.0f) { m_roty = 0.0f; } else if (m_roty > 90.0f) { m_roty = 90.0f; } } void Q3DView::Zoom(QSize diff) { m_zoom += 0.005f * (diff.height()); if (m_zoom < 0.02f) { m_zoom = 0.02f; } else if (m_zoom > 2.5f) { m_zoom = 2.5f; } } void Q3DView::PlayLoop() { m_rotx += 0.05f; if (m_rotx < -180.0f) { m_rotx = 180.0f; } else if (m_rotx > 180.0f) { m_rotx = -180.0f; } m_track += 0.001 * M_PI; if (m_track > 2.0 * M_PI) { m_track -= 2.0 * M_PI; } m_roty += 0.05f * cosf(m_track); if (m_roty < 0.0f) { m_roty = 0.0f; } else if (m_roty > 75.0f) { m_roty = 75.0f; } m_zoom -= 0.001f * sinf(m_track); if (m_zoom < 0.02f) { m_zoom = 0.02f; } else if (m_zoom > 2.5f) { m_zoom = 2.5f; } } void Q3DView::CreateAgent(QPoint point) { if (!m_male_template.m_init) { return; } std::unique_lock lock(m_draw_mutex); bool animating = m_animating; m_animating = false; // click test GLint viewport[4]; GLdouble mvmatrix[16], projmatrix[16]; glViewport(0, 0, width(), height()); glGetIntegerv(GL_VIEWPORT, viewport); Reshape(viewport[2], viewport[3]); SetModelMat(); glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix); glGetDoublev(GL_PROJECTION_MATRIX, projmatrix); GLint realy = viewport[3] - point.y(); GLdouble wx1, wy1, wz1, wx2, wy2, wz2; gluReimpl::gluUnProject((GLdouble)point.x(), (GLdouble)realy, 0.0, mvmatrix, projmatrix, viewport, &wx1, &wy1, &wz1); gluReimpl::gluUnProject((GLdouble)point.x(), (GLdouble)realy, 1.0, mvmatrix, projmatrix, viewport, &wx2, &wy2, &wz2); // 0 plane has to lie between wz1 and wz2: if (std::isfinite(wz1) && std::isfinite(wz2) && wz1 > 0 && wz2 < 0) { double scaling = wz1 / (wz2 - wz1); Point2f p(wx1 - scaling * (wx2 - wx1), wy1 - scaling * (wy2 - wy1)); if (pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessedPoints()) { // okay, you can go for it and add an agent: PointMap &pointmap = pDoc->m_meta_graph->getDisplayedPointMap(); p.denormalScale(m_region); PixelRef pix = pointmap.pixelate(p); if (pointmap.getPoint(pix).filled()) { m_agents.push_back(Agent(&m_agent_program, &pointmap)); m_agents.back().onInit(pix); Point2f p2 = m_agents.back().getLocation(); p2.normalScale(m_region); m_mannequins.push_back(QMannequin(p2, m_agents.size() - 1)); m_agents.back().onMove(); p2 = m_agents.back().getLocation(); p2.normalScale(m_region); m_mannequins.back().advance(p2); m_animating = true; } } } m_animating |= animating; } ////////////////////////////////////////////////////////////////////////////////////// const GLfloat g_male_mannequin_points[][3] = { {0.0f, 0.0f, 0.3f}, // 0 top head {0.0f, 0.0f, 0.0f}, // 1 top spine {0.0f, 0.0f, -0.7f}, // 2 base spine {-0.25f, 0.0f, 0.0f}, // 3 left shoulder {-0.15f, 0.0f, -0.7f}, // 4 left hip {0.25f, 0.0f, 0.0f}, // 5 right shoulder {0.15f, 0.0f, -0.7f}, // 6 right hip {-0.25f, 0.0f, -0.8f}, // 7 bottom left arm (hung from top spine) {-0.15f, 0.0f, 0.0f}, // 8 top left leg (hung from base spine) {-0.15f, 0.0f, -1.0f} // 9 bottom left leg (hung from base spine) }; const GLfloat g_female_mannequin_points[][3] = { {0.0f, 0.0f, 0.3f}, // 0 top head {0.0f, 0.0f, 0.0f}, // 1 top spine {0.0f, 0.0f, -0.7f}, // 2 base spine {-0.2f, 0.0f, 0.0f}, // 3 left shoulder {-0.2f, 0.0f, -0.7f}, // 4 left hip {0.2f, 0.0f, 0.0f}, // 5 right shoulder {0.2f, 0.0f, -0.7f}, // 6 right hip {-0.25f, 0.0f, -0.8f}, // 7 bottom left arm (hung from top spine) {-0.2f, 0.0f, 0.0f}, // 8 top left leg (hung from base spine) {-0.1f, 0.0f, -1.0f} // 9 bottom left leg (hung from base spine) }; CMannequinTemplate::CMannequinTemplate() { m_init = false; m_unit = 0.0f; } CMannequinTemplate::~CMannequinTemplate() {} void CMannequinTemplate::Init(GLfloat unit, bool male) { m_unit = unit; m_male = male; for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { m_points[i][j] = m_unit * (male ? g_male_mannequin_points[i][j] : g_female_mannequin_points[i][j]); } } m_init = true; } void CMannequinTemplate::Destroy() { m_init = false; m_unit = 0.0f; } QMannequin::QMannequin(const Point2f &startloc, int id, bool playback) { m_left = true; m_paused = false; m_frame = 0; m_zrot = 0.0f; m_startloc = startloc; m_nextloc = startloc; m_pointcount = 0; m_pointstart = 0; m_time = 0.0; m_active = true; m_playback = playback; if (m_playback) { m_trace_id = id; } else { m_agent_id = id; } } QMannequin::QMannequin(const QMannequin &man) { m_left = man.m_left; m_paused = man.m_paused; m_frame = man.m_frame; m_zrot = man.m_zrot; m_startloc = man.m_startloc; m_lastloc = man.m_lastloc; m_nextloc = man.m_nextloc; m_pointcount = man.m_pointcount; m_pointstart = man.m_pointstart; memcpy(m_points + m_pointstart, man.m_points + man.m_pointstart * 3, m_pointcount * sizeof(GLfloat) * 3); m_time = man.m_time; m_active = man.m_active; m_playback = man.m_playback; m_trace_id = man.m_trace_id; m_agent_id = man.m_agent_id; } QMannequin &QMannequin::operator=(const QMannequin &man) { if (&man != this) { m_left = man.m_left; m_paused = man.m_paused; m_frame = man.m_frame; m_zrot = man.m_zrot; m_startloc = man.m_startloc; m_lastloc = man.m_lastloc; m_nextloc = man.m_nextloc; m_pointcount = man.m_pointcount; m_pointstart = man.m_pointstart; memcpy(m_points + m_pointstart, man.m_points + man.m_pointstart * 3, m_pointcount * sizeof(GLfloat) * 3); m_time = man.m_time; m_active = man.m_active; m_playback = man.m_playback; m_trace_id = man.m_trace_id; m_agent_id = man.m_agent_id; } return *this; } void QMannequin::frame() { m_frame++; if (m_frame >= 24) { m_frame = 0; m_time += 1.0; m_left = m_left ? false : true; } } void QMannequin::advance(const Point2f &nextloc) { m_lastloc = m_nextloc; m_nextloc = nextloc; if (m_nextloc == m_lastloc) { m_paused = true; } else { Point2f vec = m_nextloc - m_lastloc; vec.normalise(); m_zrot = 90.0 + 180.0 * vec.angle() / M_PI; m_paused = false; // m_pointcount++; if (m_pointcount > 25) { m_pointstart++; m_pointcount = 25; if (m_pointstart > 25) { memcpy(m_points, m_points + (m_pointstart - 1) * 3, (m_pointcount - 1) * sizeof(GLfloat) * 3); m_pointstart = 0; m_pointcount = 25; } } int base = (m_pointstart + m_pointcount - 1) * 3; m_points[base] = m_lastloc.x; m_points[base + 1] = m_lastloc.y; m_points[base + 2] = 0.0f; } } void QMannequin::draw(CMannequinTemplate &templ, bool drawtrails, bool highlight) { if (!highlight) { if (templ.m_male) { glColor3f(0.4f, 0.4f, 0.8f); } else { glColor3f(0.7f, 0.4f, 0.6f); } } else { if (templ.m_male) { glColor3f(0.8f, 0.8f, 1.0f); } else { glColor3f(1.0f, 0.8f, 0.9f); } } glPushMatrix(); // based on 24 frames per second: GLfloat framef = GLfloat(m_frame % 24) / 24.0f; if (m_paused) { framef = 0.0f; } glTranslatef(framef * m_nextloc.x + (1.0f - framef) * m_lastloc.x, framef * m_nextloc.y + (1.0f - framef) * m_lastloc.y, 0.0f); glRotatef(m_zrot, 0.0f, 0.0f, 1.0f); // now use framef as a swing: framef *= 2.0f; if (framef > 1.0f) { framef = 2.0f - framef; } GLfloat swing = framef * 30.0f * (m_left ? -1.0f : 1.0f); GLfloat h = cos(M_PI * 0.16667f * framef) + 0.7f; // 2 * M_PI * 30.0f * framef / 360.0f = M_PI * 0.16667 * framef glTranslatef(0.0f, 0.0f, h * templ.m_unit); glBegin(GL_LINES); // head glVertex3fv(templ.m_points[0]); glVertex3fv(templ.m_points[1]); // spine glVertex3fv(templ.m_points[1]); glVertex3fv(templ.m_points[2]); // shoulders glVertex3fv(templ.m_points[3]); glVertex3fv(templ.m_points[5]); // hips glVertex3fv(templ.m_points[4]); glVertex3fv(templ.m_points[6]); glEnd(); glPushMatrix(); glRotatef(swing, 1.0f, 0.0f, 0.0f); glBegin(GL_LINES); // left arm glVertex3fv(templ.m_points[3]); glVertex3fv(templ.m_points[7]); glEnd(); glRotatef(180.0f, 0.0f, 0.0f, 1.0f); glRotatef(2.0 * swing, 1.0f, 0.0f, 0.0f); glBegin(GL_LINES); // right arm (n.b., reuse same point pair) glVertex3fv(templ.m_points[3]); glVertex3fv(templ.m_points[7]); glEnd(); glPopMatrix(); glTranslatef(0.0f, 0.0f, -0.7f * templ.m_unit); glRotatef(-swing, 1.0f, 0.0f, 0.0f); glBegin(GL_LINES); // left leg glVertex3fv(templ.m_points[8]); glVertex3fv(templ.m_points[9]); glEnd(); glRotatef(180.0f, 0.0f, 0.0f, 1.0f); glRotatef(2.0 * -swing, 1.0f, 0.0f, 0.0f); glBegin(GL_LINES); // right leg (n.b., reuse same point pair) glVertex3fv(templ.m_points[8]); glVertex3fv(templ.m_points[9]); glEnd(); glPopMatrix(); // trails... if (drawtrails && m_pointcount > 1) { glVertexPointer(3, GL_FLOAT, 0, m_points); glDrawArrays(GL_LINE_STRIP, m_pointstart, m_pointcount); } } void Q3DView::OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) { // Quick mod - TV switch (nChar) { // case 37: case 38: case 39: case 40: case Qt::Key_Left: case Qt::Key_Up: case Qt::Key_Right: case Qt::Key_Down: m_key_mode_on = m_mouse_mode; m_keydown = nChar; break; // case 33: // Page Up case Qt::Key_PageUp: switch (m_mouse_mode) { case ID_ADD_AGENT: m_mouse_mode = ID_3D_ZOOM; break; case ID_3D_ROT: m_mouse_mode = ID_ADD_AGENT; break; case ID_3D_PAN: m_mouse_mode = ID_3D_ROT; break; case ID_3D_ZOOM: m_mouse_mode = ID_3D_PAN; break; } break; // case 34: // Page Down case Qt::Key_PageDown: switch (m_mouse_mode) { case ID_ADD_AGENT: m_mouse_mode = ID_3D_ROT; break; case ID_3D_ROT: m_mouse_mode = ID_3D_PAN; break; case ID_3D_PAN: m_mouse_mode = ID_3D_ZOOM; break; case ID_3D_ZOOM: m_mouse_mode = ID_ADD_AGENT; break; } break; // case 'T': case Qt::Key_T: OnAgentTrails(); break; // case 'A': case Qt::Key_A: { QPoint point; // ::GetCursorPos(&point); CreateAgent(point); } break; } } void Q3DView::OnKeyUp(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags) { m_key_mode_on = 0; } bool Q3DView::OnMouseWheel(unsigned int nFlags, short zDelta, QPoint pt) { QSize diff(0, -zDelta / 5); Zoom(diff); SetModelMat(); m_quick_draw = true; update(); return 0; } void Q3DView::OnToolsImportTraces() { QString template_string; template_string += "XML files (*.xml)\nText files (*.txt)\nAll files (*.*)"; QFileDialog::Options options = 0; QString selectedFilter; QStringList infiles = QFileDialog::getOpenFileNames(0, tr("Import Traces"), "", template_string, &selectedFilter, options); if (!infiles.size()) { return; } std::string filename = infiles[0].toStdString(); if (!filename.empty()) { m_animating = false; std::unique_lock lock(m_draw_mutex); m_agents.clear(); m_traces.clear(); m_mannequins.clear(); // std::ifstream file(filename.c_str()); // Eva's XMLs do not have the header yet: xmlelement traceset; QString elementname; while (file && elementname != "traceset") { traceset.parse(file, false); elementname = QString(traceset.name.c_str()).toLower(); } while (file) { xmlelement trace; trace.parse(file, true); elementname = QString(trace.name.c_str()).toLower(); if (elementname == "trace") { m_traces.push_back(Trace()); bool firstevent = true; for (int j = 0; j < trace.subelements.size(); j++) { // these should be events: xmlelement &traceevent = trace.subelements[j]; if (traceevent.name == "event") { double x = QString(traceevent.attributes["x"].c_str()).toDouble(); double y = QString(traceevent.attributes["y"].c_str()).toDouble(); double t = QString(traceevent.attributes["t"].c_str()).toDouble(); m_traces.back().events.push_back(Event2f(x, y, t)); if (firstevent) { m_traces.back().starttime = t; firstevent = false; } } } if (m_traces.back().events.size() >= 1) { m_traces.back().endtime = m_traces.back().events.back().t; Point2f p = m_traces.back().events[0]; p.normalScale(m_region); m_mannequins.push_back(QMannequin(p, m_traces.size() - 1, true)); m_mannequins.back().m_active = false; } } } } else { QMessageBox::warning(this, tr("depthmapX"), tr("No file selected"), QMessageBox::Ok, QMessageBox::Ok); } } void Q3DView::OnToolsAgentsPause() { m_animating = false; } void Q3DView::OnToolsAgentsStop() { m_animating = false; for (int i = 0; i < m_mannequins.size(); i++) { if (m_mannequins[i].m_playback) { m_mannequins[i].m_active = false; m_mannequins[i].m_time = 0.0; m_mannequins[i].m_nextloc = m_mannequins[i].m_startloc; } } for (auto pixel : m_pixels) { pixel.second.m_value = -1; } } void Q3DView::OnToolsAgentsPlay() { m_animating = true; } void Q3DView::closeEvent(QCloseEvent *event) { pDoc->m_view[QGraphDoc::VIEW_3D] = NULL; if (!pDoc->OnCloseDocument(QGraphDoc::VIEW_3D)) { pDoc->m_view[QGraphDoc::VIEW_3D] = this; event->ignore(); } } // void Q3DView::resizeEvent(QResizeEvent *event) void Q3DView::resizeGL(int w, int h) { Reshape(m_oldRect.right(), m_oldRect.bottom()); OnRecentreView(); pDoc->m_view[QGraphDoc::VIEW_3D] = this; if (w > 0) { glViewport(0, 0, w, h); m_oldRect.setRight(w); m_oldRect.setBottom(h); Reshape(w, h); } } void Q3DView::mouseMoveEvent(QMouseEvent *event) { OnMouseMove(0, event->pos()); } void Q3DView::mousePressEvent(QMouseEvent *event) { switch (event->button()) { case Qt::LeftButton: OnLButtonDown(0, event->pos()); ((MainWindow *)pDoc->m_mainFrame)->update3DToolbar(); break; case Qt::RightButton: OnRButtonDown(0, event->pos()); break; default: break; } } void Q3DView::mouseReleaseEvent(QMouseEvent *event) { switch (event->button()) { case Qt::LeftButton: OnLButtonUp(0, event->pos()); break; case Qt::RightButton: OnRButtonUp(0, event->pos()); break; default: break; } } void Q3DView::keyPressEvent(QKeyEvent *event) { OnKeyDown(event->key(), event->count(), 0); } void Q3DView::keyReleaseEvent(QKeyEvent *event) { OnKeyUp(event->key(), event->count(), 0); } void Q3DView::wheelEvent(QWheelEvent *event) { OnMouseWheel(0, event->delta(), event->pos()); } void Q3DView::timerSlot() { timerEvent(NULL); } ================================================ FILE: depthmapX/views/3dview/3dview.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "depthmapX/GraphDoc.h" #include "salalib/agents/agentprogram.h" #include #include #include #include #include #define ID_ADD_AGENT 32947 #define ID_3D_PAN 32948 #define ID_3D_ZOOM 32949 #define ID_3D_ROT 32950 #define ID_3D_PAUSE 32951 #define ID_3D_PLAY_LOOP 32981 #define ID_3D_FILLED 32983 ///////////////////////////////////////////////////////////////////////////// // CScreenAgent struct CMannequinTemplate { bool m_init; float m_unit; bool m_male; float m_points[10][3]; CMannequinTemplate(); virtual ~CMannequinTemplate(); void Init(float unit, bool male); void Destroy(); }; struct QMannequin { float m_zrot; // facing direction Point2f m_startloc; Point2f m_lastloc; Point2f m_nextloc; int m_frame; bool m_left; bool m_paused; // these are used when replaying a trace bool m_active; bool m_playback; double m_time; // int m_agent_id; int m_trace_id; // QMannequin(const Point2f &lastloc = Point2f(), int id = -1, bool playback = false); QMannequin(const QMannequin &man); QMannequin &operator=(const QMannequin &man); void draw(CMannequinTemplate &templ, bool drawtrails, bool highlight); void frame(); void advance(const Point2f &nextloc); // big long array to record trails! float m_points[150]; int m_pointstart; int m_pointcount; }; struct Trace { double starttime; double endtime; std::vector events; }; struct C3DPixelData { Point2f m_point; int m_value; C3DPixelData(const Point2f &p = Point2f()) { m_point = p; m_value = -1; } }; ///////////////////////////////////////////////////////////////////////////// class Q3DView : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT // Attributes public: Q3DView(QWidget *parent = NULL, QGraphDoc *doc = NULL); // protected constructor used by dynamic creation ~Q3DView(); QSize sizeHint() const; QGraphDoc *pDoc; unsigned int *m_nTimerID; QRect m_oldRect; float m_fRadius; QPainter *m_pDC; // bool m_quick_draw; std::mutex m_draw_mutex; bool m_animating; bool m_drawtrails; bool m_fill; double m_track; // camera track -- used in playloop // // QtRegion m_region; float *m_points; float m_rect[4][3]; std::map m_pixels; // int m_pointcount; // int m_mouse_mode; int m_mouse_mode_on; bool m_right_mouse; int m_key_mode_on; int m_keydown; QPoint m_mouse_origin; // float m_panx; float m_pany; float m_rotx; float m_roty; float m_zoom; // // use to initialise mannequintemplate: CMannequinTemplate m_male_template; CMannequinTemplate m_female_template; std::vector m_mannequins; std::vector m_agents; std::vector m_traces; AgentProgram m_agent_program; // // used to keep track of internal time for all agents double m_global_time; // // Operations public: // void Init(); void CreateRGBPalette(); void Reshape(int x, int y); void DrawScene(); void ReloadLineData(); void ReloadPointData(); void SetModelMat(); void CreateAgent(QPoint point); void Rot(QSize diff); void Pan(QSize diff); void Zoom(QSize diff); void PlayLoop(); // My message map functions int OnRedraw(int wParam, int lParam); void OnLButtonDown(unsigned int nFlags, QPoint point); void OnRecentreView(); void On3dPan(); void On3dRot(); void On3dZoom(); void OnAddAgent(); void OnMouseMove(unsigned int nFlags, QPoint point); void OnLButtonUp(unsigned int nFlags, QPoint point); void OnAgentTrails(); void OnToolsAgentLoadProgram(); void OnKeyDown(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags); void OnKeyUp(unsigned int nChar, unsigned int nRepCnt, unsigned int nFlags); void OnPlayLoop(); void On3dFilled(); bool OnMouseWheel(unsigned int nFlags, short zDelta, QPoint pt); void OnRButtonDown(unsigned int nFlags, QPoint point); void OnRButtonUp(unsigned int nFlags, QPoint point); void OnToolsImportTraces(); void OnToolsAgentsPause(); void OnToolsAgentsStop(); void OnToolsAgentsPlay(); public slots: void timerSlot(); protected: void initializeGL(); void resizeGL(int w, int h); void paintGL(); virtual void timerEvent(QTimerEvent *event); // virtual void paintEvent(QPaintEvent *event); virtual void keyPressEvent(QKeyEvent *event); virtual void keyReleaseEvent(QKeyEvent *event); // virtual void resizeEvent(QResizeEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void wheelEvent(QWheelEvent *event); // virtual void contextMenuEvent(QContextMenuEvent *event); virtual void closeEvent(QCloseEvent *event); }; ================================================ FILE: depthmapX/views/3dview/glureimpl.h ================================================ // Taken from https://github.com/Alexpux/superglu/blob/master/libutil/project.c // Only provided here temporarily until the 3DView is converted to modern OpenGL /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: The application programming interfaces ** established by SGI in conjunction with the Original Code are The ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X ** Window System(R) (Version 1.3), released October 19, 1998. This software ** was created using the OpenGL(R) version 1.2.1 Sample Implementation ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** ** $Date$ $Revision$ ** $Header$ */ #pragma once #include #ifdef __APPLE__ #include #include #else #include #include #endif namespace gluReimpl { /* ** Make m an identity matrix */ static void __gluMakeIdentityd(GLdouble m[16]) { m[0 + 4 * 0] = 1; m[0 + 4 * 1] = 0; m[0 + 4 * 2] = 0; m[0 + 4 * 3] = 0; m[1 + 4 * 0] = 0; m[1 + 4 * 1] = 1; m[1 + 4 * 2] = 0; m[1 + 4 * 3] = 0; m[2 + 4 * 0] = 0; m[2 + 4 * 1] = 0; m[2 + 4 * 2] = 1; m[2 + 4 * 3] = 0; m[3 + 4 * 0] = 0; m[3 + 4 * 1] = 0; m[3 + 4 * 2] = 0; m[3 + 4 * 3] = 1; } #define __glPi 3.14159265358979323846 void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) { GLdouble m[4][4]; double sine, cotangent, deltaZ; double radians = fovy / 2 * __glPi / 180; deltaZ = zFar - zNear; sine = sin(radians); if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) { return; } cotangent = cos(radians) / sine; __gluMakeIdentityd(&m[0][0]); m[0][0] = cotangent / aspect; m[1][1] = cotangent; m[2][2] = -(zFar + zNear) / deltaZ; m[2][3] = -1; m[3][2] = -2 * zNear * zFar / deltaZ; m[3][3] = 0; glMultMatrixd(&m[0][0]); } static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4], GLdouble out[4]) { int i; for (i = 0; i < 4; i++) { out[i] = in[0] * matrix[0 * 4 + i] + in[1] * matrix[1 * 4 + i] + in[2] * matrix[2 * 4 + i] + in[3] * matrix[3 * 4 + i]; } } /* ** inverse = invert(src) */ static int __gluInvertMatrixd(const GLdouble src[16], GLdouble inverse[16]) { int i, j, k, swap; double t; GLdouble temp[4][4]; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { temp[i][j] = src[i * 4 + j]; } } __gluMakeIdentityd(inverse); for (i = 0; i < 4; i++) { /* ** Look for largest element in column */ swap = i; for (j = i + 1; j < 4; j++) { if (fabs(temp[j][i]) > fabs(temp[i][i])) { swap = j; } } if (swap != i) { /* ** Swap rows. */ for (k = 0; k < 4; k++) { t = temp[i][k]; temp[i][k] = temp[swap][k]; temp[swap][k] = t; t = inverse[i * 4 + k]; inverse[i * 4 + k] = inverse[swap * 4 + k]; inverse[swap * 4 + k] = t; } } if (temp[i][i] == 0) { /* ** No non-zero pivot. The matrix is singular, which shouldn't ** happen. This means the user gave us a bad matrix. */ return GL_FALSE; } t = temp[i][i]; for (k = 0; k < 4; k++) { temp[i][k] /= t; inverse[i * 4 + k] /= t; } for (j = 0; j < 4; j++) { if (j != i) { t = temp[j][i]; for (k = 0; k < 4; k++) { temp[j][k] -= temp[i][k] * t; inverse[j * 4 + k] -= inverse[i * 4 + k] * t; } } } } return GL_TRUE; } static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16], GLdouble r[16]) { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { r[i * 4 + j] = a[i * 4 + 0] * b[0 * 4 + j] + a[i * 4 + 1] * b[1 * 4 + j] + a[i * 4 + 2] * b[2 * 4 + j] + a[i * 4 + 3] * b[3 * 4 + j]; } } } GLint gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4], GLdouble *objx, GLdouble *objy, GLdouble *objz) { double finalMatrix[16]; double in[4]; double out[4]; __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix); if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return (GL_FALSE); in[0] = winx; in[1] = winy; in[2] = winz; in[3] = 1.0; /* Map x and y from window coordinates */ in[0] = (in[0] - viewport[0]) / viewport[2]; in[1] = (in[1] - viewport[1]) / viewport[3]; /* Map to range -1 to 1 */ in[0] = in[0] * 2 - 1; in[1] = in[1] * 2 - 1; in[2] = in[2] * 2 - 1; __gluMultMatrixVecd(finalMatrix, in, out); if (out[3] == 0.0) return (GL_FALSE); out[0] /= out[3]; out[1] /= out[3]; out[2] /= out[3]; *objx = out[0]; *objy = out[1]; *objz = out[2]; return (GL_TRUE); } } // namespace glureimpl ================================================ FILE: depthmapX/views/CMakeLists.txt ================================================ target_sources(depthmapX PRIVATE mapview.cpp viewhelpers.cpp glview/gllinesuniform.cpp glview/glview.cpp glview/gllines.cpp glview/glrastertexture.cpp glview/glpolygons.cpp glview/glutriangulator.cpp glview/gltrianglesuniform.cpp glview/glpointmap.cpp glview/glshapegraph.cpp glview/glshapemap.cpp glview/gldynamicrect.cpp glview/gldynamicline.cpp plotview/plotview.cpp tableview/tableview.cpp depthmapview/depthmapview.cpp 3dview/3dview.cpp glview/glregularpolygons.cpp glview/gltriangles.cpp PUBLIC mapview.h viewhelpers.h glview/gllinesuniform.h glview/glview.h glview/gllines.h glview/glrastertexture.h glview/glpolygons.h glview/glutriangulator.h glview/gltrianglesuniform.h glview/glpointmap.h glview/glshapegraph.h glview/glshapemap.h glview/gldynamicrect.h glview/gldynamicline.h plotview/plotview.h tableview/tableview.h depthmapview/depthmapview.h glview/glregularpolygons.h glview/gltriangles.h 3dview/3dview.h) ================================================ FILE: depthmapX/views/depthmapview/depthmapview.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "depthmapX/views/viewhelpers.h" #include "depthmapview.h" #include "mainwindow.h" class QToolBar; #include "compatibilitydefines.h" #define DMP_TIMER_SPLASH 1 #define DMP_TIMER_REDRAW 2 #define DMP_TIMER_HOVER 3 #define DMP_TIMER_3DVIEW 4 // version 5.0 dll exports have split out the attribute table // functionality, so a single class operates with the VGA interface // and the Axial interface, this means previous DLLs will not work // with version 5.0 and above // version 5.09 dll has reconfigured the data layers into shape layers: // this means previous DLLs will not work with version 5.09 and above // version 7.08 dll has a very slight change so that the analysis type // is sent to the attribute table -- if it is vga it will work off pixelrefs, // otherwise it will work off rowids // version 7.09 dll has a new version number function so that "idepthmap.h" // can be included multiple times in user projects // version 8.00 dll has significant upgrades to the naming conventions, // the ability to perform whole graph analyses and adding shapes // version 10.04 dll has further upgrades to naming conventions, // also, extra functions for the sala.dll build: includes graph opening, closing and so on // QT_BEGIN_NAMESPACE // Palette entries... // A set of colours we would really like to have static int pressed_nFlags; inline Point2f QDepthmapView::LogicalUnits(const QPoint &p) { return m_centre + Point2f(m_unit * double(p.x() - m_physical_centre.width()), m_unit *double(m_physical_centre.height() - p.y())); } inline QPoint QDepthmapView::PhysicalUnits(const Point2f &p) { return QPoint(m_physical_centre.width() + int((p.x - m_centre.x) / m_unit + 0.4999), m_physical_centre.height() - int((p.y - m_centre.y) / m_unit + 0.4999)); } inline int PixelDist(QPoint a, QPoint b) { return (int)sqrt(double((b.x() - a.x()) * (b.x() - a.x()) + (b.y() - a.y()) * (b.y() - a.y()))); } static QRgb colorMerge(QRgb color, QRgb mergecolor) { return (color & 0x006f6f6f) | (mergecolor & 0x00a0a0a0); } QDepthmapView::QDepthmapView(QGraphDoc &pDoc, Settings &settings, QWidget *parent) : MapView(pDoc, settings, parent) { m_drag_rect_a.setRect(0, 0, 0, 0); m_drag_rect_b.setRect(0, 0, 0, 0); // Several screen drawing booleans: m_continue_drawing = false; m_drawing = false; m_queued_redraw = false; m_viewport_set = false; m_clear = false; m_redraw = false; m_redraw_all = false; m_redraw_no_clear = false; m_resize_viewport = false; m_invalidate = false; // our own invalidation m_right_mouse_drag = false; m_alt_mode = false; m_current_mode = NONE; m_snap = false; m_repaint_tag = 0; m_showlinks = false; m_mouse_mode = SELECT; m_fillmode = FULLFILL; m_active_point_handle = -1; m_poly_points = 0; PafColor selcol(SALA_SELECTED_COLOR); m_selected_color = qRgb(selcol.redb(), selcol.greenb(), selcol.blueb()); m_initialSize = m_settings.readSetting(SettingTag::depthmapViewSize, QSize(2000, 2000)).toSize(); installEventFilter(this); setAttribute(Qt::WA_NoBackground, 1); setMouseTracking(1); setWindowIcon(QIcon(tr(":/images/cur/icon-1-4.png"))); } QDepthmapView::~QDepthmapView() { m_settings.writeSetting(SettingTag::depthmapViewSize, size()); } int QDepthmapView::OnRedraw(int wParam, int lParam) { if (m_pDoc.GetRemenuFlag(QGraphDoc::VIEW_MAP)) { m_pDoc.SetRemenuFlag(QGraphDoc::VIEW_MAP, false); // redo the menus for this *view* directly: //((CChildFrame*) GetParentFrame())->m_view_selector.RedoMenu( *m_pDoc.m_meta_graph ); } if (m_pDoc.GetRedrawFlag(QGraphDoc::VIEW_MAP) != QGraphDoc::REDRAW_DONE) { if (!m_pDoc.m_communicator) { m_queued_redraw = false; switch (m_pDoc.GetRedrawFlag(QGraphDoc::VIEW_MAP)) { case QGraphDoc::REDRAW_POINTS: if (m_pDoc.m_meta_graph->viewingProcessedLines()) { // Axial lines are thicker on selection, so background needs clearing m_redraw_all = true; } else { m_redraw_no_clear = true; } break; case QGraphDoc::REDRAW_GRAPH: m_redraw_all = true; break; case QGraphDoc::REDRAW_TOTAL: m_viewport_set = false; m_redraw_all = true; break; } m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_DONE); repaint(); } else { killTimer(Tid_redraw); startTimer(100); m_queued_redraw = true; } } return 0; } static QPoint hit_point; bool QDepthmapView::eventFilter(QObject *object, QEvent *e) { // Get the keyboard modifiers and set them in pressed_nFlags. switch (e->type()) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: { Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); pressed_nFlags = (keyMods & Qt::ShiftModifier) ? pressed_nFlags |= MK_SHIFT : pressed_nFlags &= ~MK_SHIFT; pressed_nFlags = (keyMods & Qt::ControlModifier) ? pressed_nFlags |= MK_CONTROL : pressed_nFlags &= ~MK_CONTROL; break; } default: break; } if (e->type() == QEvent::ToolTip) { if (!m_pDoc.m_communicator) { if (m_pDoc.m_meta_graph) { if (m_pDoc.m_meta_graph->viewingProcessed() && m_pDoc.m_meta_graph->getSelCount() > 1) { float val = m_pDoc.m_meta_graph->getSelAvg(); int count = m_pDoc.m_meta_graph->getSelCount(); if (val == -1.0f) setToolTip("Null selection"); else if (val != -2.0f) setToolTip(QString("Selection\nAverage: %1\nCount: %2").arg(val).arg(count)); else setToolTip(""); } else if (m_pDoc.m_meta_graph->viewingProcessed()) { // and that it has an appropriate state to display a hover wnd float val = m_pDoc.m_meta_graph->getLocationValue(LogicalUnits(hit_point)); if (val == -1.0f) setToolTip("No value"); else if (val != -2.0f) setToolTip(QString("%1").arg(val)); else setToolTip(""); } } } } return QObject::eventFilter(object, e); } void QDepthmapView::timerEvent(QTimerEvent *event) { if (event->timerId() == Tid_redraw) { if (m_queued_redraw) { // Internal own redraw OnRedraw(0, 0); } else if (m_continue_drawing) { if (!m_drawing) { m_internal_redraw = true; repaint(); } } } } void QDepthmapView::InitViewport(const QRect &phys_bounds, QGraphDoc *pDoc) { QtRegion bounds = pDoc->m_meta_graph->getBoundingBox(); m_unit = __max(bounds.width() / double(phys_bounds.width()), bounds.height() / double(phys_bounds.height())); m_centre = bounds.getCentre(); m_physical_centre = QSize(phys_bounds.width() / 2, phys_bounds.height() / 2); m_viewport_set = true; } QtRegion QDepthmapView::LogicalViewport(const QRect &phys_bounds, QGraphDoc *pDoc) { if (m_resize_viewport) { m_physical_centre = QSize(phys_bounds.width() / 2, phys_bounds.height() / 2); m_resize_viewport = false; } return QtRegion(LogicalUnits(QPoint(phys_bounds.left(), phys_bounds.bottom())), LogicalUnits(QPoint(phys_bounds.right(), phys_bounds.top()))); } void QDepthmapView::SetRedrawflag() { if (m_pDoc.GetRemenuFlag(QGraphDoc::VIEW_MAP)) m_pDoc.SetRemenuFlag(QGraphDoc::VIEW_MAP, false); if (m_pDoc.GetRedrawFlag(QGraphDoc::VIEW_MAP) != QGraphDoc::REDRAW_DONE) { if (m_pDoc.m_communicator) { m_queued_redraw = false; switch (m_pDoc.GetRedrawFlag(QGraphDoc::VIEW_MAP)) { case QGraphDoc::REDRAW_POINTS: if (m_pDoc.m_meta_graph->viewingProcessedLines()) { // Axial lines are thicker on selection, so background needs clearing m_redraw_all = true; } else { m_redraw_no_clear = true; } break; case QGraphDoc::REDRAW_GRAPH: m_redraw_all = true; break; case QGraphDoc::REDRAW_TOTAL: m_viewport_set = false; m_redraw_all = true; break; } m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_DONE); } else { killTimer(Tid_redraw); Tid_redraw = startTimer(100); m_queued_redraw = true; } } } void QDepthmapView::paintEvent(QPaintEvent *) { QPainter pDC(m_pixmap); SetRedrawflag(); foreach (QWidget *widget, QApplication::topLevelWidgets()) { MainWindow *mainWin = qobject_cast(widget); if (mainWin) { m_foreground = mainWin->m_foreground; m_background = mainWin->m_background; mainWin->updateToolbar(); break; } } /* if (pDC->IsPrinting()) { if (!m_pDoc.m_meta_graph->setLock(this)) { return; } PrintBaby(pDC, m_pDoc); m_pDoc.m_meta_graph->releaseLock(this); return; }*/ auto lock = m_pDoc.m_meta_graph->getLockDeferred(); if (!lock.try_lock()) { return; } m_drawing = true; QRect rect; int state = m_pDoc.m_meta_graph->getState(); if (m_invalidate) { // selected colour is used for picking up highlights in OnMouseMove pDC.setPen(QPen(QBrush(QColor(m_selected_color)), 1, Qt::DotLine, Qt::RoundCap)); if (m_invalidate & DRAWLINE) { if ((m_repaint_tag & DRAWLINE) && (m_invalidate == DRAWLINE || m_invalidate == LINEOFF)) { QRect tmpRect(PhysicalUnits(m_old_line.start()), PhysicalUnits(m_old_line.end())); DrawLine(&pDC, tmpRect, 0); m_repaint_tag &= ~DRAWLINE; } else if (m_invalidate == DRAWLINE || m_invalidate == LINEON) { QRect tmpRect(PhysicalUnits(m_line.start()), PhysicalUnits(m_line.end())); DrawLine(&pDC, tmpRect, 1); m_old_line = m_line; m_repaint_tag |= DRAWLINE; } m_invalidate = 0; } else if (m_invalidate & SNAP) { if ((m_repaint_tag & SNAP) && (m_invalidate == SNAP || m_invalidate == SNAPOFF)) { QPoint tmppoint(PhysicalUnits(m_old_snap_point)); DrawCross(&pDC, tmppoint, 0); m_repaint_tag &= ~SNAP; } if (m_invalidate == SNAP || m_invalidate == SNAPON) { QPoint tmppoint(PhysicalUnits(m_snap_point)); DrawCross(&pDC, tmppoint, 1); m_repaint_tag |= SNAP; } m_old_snap_point = m_snap_point; m_invalidate = 0; } else { pDC.setCompositionMode(QPainter::RasterOp_SourceXorDestination); if (!m_drag_rect_b.isEmpty()) pDC.drawRect(m_drag_rect_b); if (!m_drag_rect_a.isEmpty()) pDC.drawRect(m_drag_rect_a); pDC.setCompositionMode(QPainter::CompositionMode_SourceOver); m_drag_rect_b = m_drag_rect_a; m_invalidate = 0; } } else if (m_redraw_all || m_redraw_no_clear) { m_repaint_tag = 0; // <- for things that remember pixels in last paint colour (e.g., DrawCross and DrawLine rect = QRect(0, 0, width(), height()); m_redraw = true; if (!m_viewport_set && state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) { InitViewport(rect, &m_pDoc); } if (m_redraw_all) { m_clear = true; } m_redraw_all = false; m_redraw_no_clear = false; } else if (!m_internal_redraw) { // Give up on this: it just doesn't work on NT // && DCB_RESET != pDC->GetBoundsRect(rect, DCB_RESET)) { rect = QRect(0, 0, width(), height()); m_clear = true; m_redraw = true; } m_internal_redraw = false; // if redraw signalled: if (m_redraw && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) && m_viewport_set) { // note that the redraw rect is dependent on the cleared portion above // note you *must* check *state* before drawing, you cannot rely on view_class as it can be set up before the // layer is ready to draw: if (state & MetaGraph::POINTMAPS && (!m_pDoc.m_meta_graph->getDisplayedPointMap().isProcessed() || m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWBACKVGA)) && !m_pDoc.m_communicator) // <- m_communicator because I'm having thread locking problems { m_pDoc.m_meta_graph->getDisplayedPointMap().setScreenPixel(m_unit); // only used by points (at the moment!) m_pDoc.m_meta_graph->getDisplayedPointMap().makeViewportPoints(LogicalViewport(rect, &m_pDoc)); } if (state & MetaGraph::SHAPEGRAPHS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWAXIAL | MetaGraph::VIEWBACKAXIAL))) { m_pDoc.m_meta_graph->getDisplayedShapeGraph().makeViewportShapes(LogicalViewport(rect, &m_pDoc)); } if (state & MetaGraph::DATAMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKDATA | MetaGraph::VIEWDATA))) { m_pDoc.m_meta_graph->getDisplayedDataMap().makeViewportShapes(LogicalViewport(rect, &m_pDoc)); } if (state & MetaGraph::LINEDATA) { m_pDoc.m_meta_graph->makeViewportShapes(LogicalViewport(rect, &m_pDoc)); } m_continue_drawing = true; m_redraw = false; } if (m_clear) { pDC.fillRect(rect, QBrush(QColor(m_background))); m_clear = false; } // If the meta graph (at least) contains a DXF, draw it: if (m_continue_drawing && (state & (MetaGraph::LINEDATA | MetaGraph::SHAPEGRAPHS | MetaGraph::DATAMAPS)) && m_viewport_set) { if (Output(&pDC, &m_pDoc, true)) { Tid_redraw = startTimer(100); m_continue_drawing = true; } else { m_continue_drawing = false; // Finished: kill the timer: if (!m_queued_redraw) { killTimer(Tid_redraw); } } } else { m_continue_drawing = false; // can't draw for some reason } m_drawing = false; QPainter screenPainter(this); screenPainter.drawPixmap(0, 0, width(), height(), *m_pixmap); } void QDepthmapView::resizeGL(int w, int h) { // m_viewport_set = false; m_redraw_all = true; m_resize_viewport = true; m_pDoc.m_view[QGraphDoc::VIEW_MAP] = this; m_pixmap = new QPixmap(w, h); update(); } void QDepthmapView::BeginDrag(QPoint point) { m_current_mode = NONE; int handle = -1; for (size_t i = 0; i < m_point_handles.size(); i++) { QPoint pt = PhysicalUnits(m_point_handles[i]); if (abs(pt.x() - point.x()) < 7 && abs(pt.y() - point.y()) < 7) { handle = (int)i; m_mouse_mode |= OVERHANDLE; SetCursor(m_mouse_mode); break; } } m_active_point_handle = handle; // for now, only two handles exist: if (m_active_point_handle != -1) { if (m_active_point_handle == 0) { m_line = Line(m_point_handles[1], m_point_handles[0]); } else { m_line = Line(m_point_handles[0], m_point_handles[1]); } m_mouse_mode |= DRAWLINE; m_mouse_mode &= ~OVERHANDLE; SetCursor(m_mouse_mode); m_invalidate = LINEON; update(); } } void QDepthmapView::mouseMoveEvent(QMouseEvent *e) { QPoint point = e->pos(); if (pressed_nFlags & MK_CONTROL) { if (pressed_nFlags & MK_SHIFT) { // CTRL and SHIFT key down together, snap to displayed drawing layers // (note, don't use SHIFT on it's own, because that's already used for multiple select) MetaGraph *graph = m_pDoc.m_meta_graph; Point2f p = LogicalUnits(point); double d = -1.0; for (int i = 0; i < graph->getLineFileCount(); i++) { for (int j = 0; j < graph->getLineLayerCount(i); j++) { ShapeMap &map = graph->getLineLayer(i, j); if (map.isShown()) { Point2f px = map.getClosestVertex(p); if (!px.atZero() && (d == -1 || dist(p, px) < d)) { d = dist(p, px); m_snap_point = px; } } } } if (d != -1) { point = PhysicalUnits(m_snap_point); if (!m_snap) { m_invalidate = SNAPON; m_snap = true; update(); } else if (m_old_snap_point != m_snap_point) { m_invalidate = SNAP; m_snap = true; update(); } } } else { // If only CTRL key down, snap to grid if (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWBACKVGA)) { PointMap &map = m_pDoc.m_meta_graph->getDisplayedPointMap(); if (m_pDoc.m_meta_graph->getDisplayedPointMap().getSpacing() / m_unit > 20) { // hi-res snap when zoomed in m_snap_point = map.depixelate(map.pixelate(LogicalUnits(point), false, 2), 0.5); } else { m_snap_point = map.depixelate(map.pixelate(LogicalUnits(point))); } point = PhysicalUnits(m_snap_point); if (!m_snap) { m_invalidate = SNAPON; m_snap = true; update(); } else if (m_old_snap_point != m_snap_point) { m_invalidate = SNAP; m_snap = true; update(); } } } } else if (m_snap) { m_invalidate = SNAPOFF; update(); m_snap = false; } // Left button down... if (pressed_nFlags & MK_LBUTTON) { if (m_current_mode == DRAG) { point -= m_mouse_point; m_drag_rect_a.translate(point); m_centre.x -= double(point.x()) * m_unit; m_centre.y += double(point.y()) * m_unit; m_mouse_point += point; m_invalidate = DRAG; update(); } else if (m_current_mode == SELECT || m_current_mode == ZOOM_IN || m_current_mode == JOIN || m_current_mode == UNJOIN) { int x1, y1, x2, y2; if (m_mouse_point.x() > point.x()) { x1 = point.x(); x2 = m_mouse_point.x() - 1; } else { x1 = m_mouse_point.x(); x2 = point.x() - 1; } if (m_mouse_point.y() > point.y()) { y1 = point.y(); y2 = m_mouse_point.y() - 1; } else { y1 = m_mouse_point.y(); y2 = point.y() - 1; } m_drag_rect_a = QRect(x1, y1, x2 - x1, y2 - y1); m_invalidate = SELECT; update(); } // NB. deliberatle mouse mode not current mode else if (m_mouse_mode == (SELECT | OVERHANDLE)) { // ideally, I would enforce click once, move to location, and click again, but this // at least allows novices to use it easily: if (abs(point.x() - m_mouse_point.x()) + abs(point.y() - m_mouse_point.y()) > 3) { BeginDrag(m_mouse_point); m_current_mode = SELECT | DRAWLINE; } } // NB. deliberatle mouse mode not current mode else if (m_mouse_mode == LINETOOL) { // ideally, I would enforce click once, move to location, and click again, but this // at least allows novices to use it easily: if (PixelDist(point, m_mouse_point) > 6) { m_mouse_mode |= DRAWLINE; m_current_mode = m_mouse_mode; m_line = Line(m_mouse_location, LogicalUnits(point)); m_invalidate = LINEON; update(); } } else if (m_current_mode == PENCIL) { if (m_mouse_point != point && m_pDoc.m_meta_graph->getDisplayedPointMap().pixelate(LogicalUnits(point)) != m_pDoc.m_meta_graph->getDisplayedPointMap().pixelate(LogicalUnits(m_mouse_point))) { m_pDoc.m_meta_graph->getDisplayedPointMap().fillPoint(LogicalUnits(point), true); m_redraw_no_clear = true; m_mouse_point = point; // Redraw scene update(); } } else if (m_current_mode == ERASE) { if (m_mouse_point != point && m_pDoc.m_meta_graph->getDisplayedPointMap().pixelate(LogicalUnits(point)) != m_pDoc.m_meta_graph->getDisplayedPointMap().pixelate(LogicalUnits(m_mouse_point))) { m_pDoc.m_meta_graph->getDisplayedPointMap().fillPoint(LogicalUnits(point), false); m_redraw_no_clear = true; m_mouse_point = point; // Redraw scene update(); } } } else if (pressed_nFlags & MK_RBUTTON) { if (!m_right_mouse_drag && abs(point.x() - m_mouse_point.x()) + abs(point.y() - m_mouse_point.y()) > 3) { // begin right mouse drag: SetCursor(DRAG); m_mouse_point = point; m_drag_rect_a = QRect(0, 0, width(), height()); m_drag_rect_b = QRect(0, 0, 0, 0); m_invalidate = DRAG; update(); // SetCapture(); m_right_mouse_drag = true; } else if (m_right_mouse_drag) { // continue right mouse drag point -= m_mouse_point; m_drag_rect_a.translate(point); m_centre.x -= double(point.x()) * m_unit; m_centre.y += double(point.y()) * m_unit; m_mouse_point += point; m_invalidate = DRAG; update(); } } else if ((m_mouse_mode & SELECT) && !(m_mouse_mode & DRAWLINE) && !m_right_mouse_drag) { // in select mode, might be over a point handle -- if so, change the cursor: if (m_point_handles.size()) { bool found = false; for (size_t i = 0; i < m_point_handles.size(); i++) { QPoint pt = PhysicalUnits(m_point_handles[i]); if (abs(pt.x() - point.x()) < 7 && abs(pt.y() - point.y()) < 7) { found = true; m_mouse_mode |= OVERHANDLE; SetCursor(m_mouse_mode); break; } } if (!found && (m_mouse_mode & OVERHANDLE)) { m_mouse_mode &= ~OVERHANDLE; SetCursor(m_mouse_mode); } } else if (m_mouse_mode & OVERHANDLE) { m_mouse_mode &= ~OVERHANDLE; SetCursor(m_mouse_mode); } } if (!m_right_mouse_drag) { if (m_mouse_mode & DRAWLINE) { m_line = Line(m_line.t_start(), m_snap ? m_snap_point : LogicalUnits(point)); if (m_line.t_end() != m_old_line.t_end()) { m_invalidate = DRAWLINE; update(); } } else if (m_mouse_mode & JOINB) { point -= m_mouse_point; m_drag_rect_a.translate(point); m_mouse_point += point; // Redraw scene m_invalidate = JOINB; update(); } } m_pDoc.m_position = m_snap ? m_snap_point : LogicalUnits(point); m_pDoc.UpdateMainframestatus(); hit_point = point; } void QDepthmapView::mouseDoubleClickEvent(QMouseEvent *e) {} void QDepthmapView::mousePressEvent(QMouseEvent *e) { switch (e->button()) { case Qt::LeftButton: pressed_nFlags = MK_LBUTTON; break; case Qt::RightButton: pressed_nFlags = MK_RBUTTON; break; default: break; } QPoint point = e->pos(); if (pressed_nFlags & MK_RBUTTON) { if (m_snap) { point = PhysicalUnits(m_snap_point); } m_mouse_point = point; } else { if (m_snap) { point = PhysicalUnits(m_snap_point); } m_mouse_point = point; m_mouse_location = m_snap ? m_snap_point : LogicalUnits(point); // Just reset? m_current_mode = NONE; if (m_current_mode == NONE) { m_current_mode = m_mouse_mode; switch (m_mouse_mode) { case DRAG: { m_mouse_point = point; m_drag_rect_a = QRect(0, 0, width(), height()); m_drag_rect_b = QRect(0, 0, 0, 0); m_invalidate = DRAG; update(); // SetCapture(); } break; case SELECT: case ZOOM_IN: case JOIN: case UNJOIN: { m_mouse_point = point; m_drag_rect_a = QRect(0, 0, 0, 0); m_drag_rect_b = QRect(0, 0, 0, 0); m_invalidate = SELECT; update(); // SetCapture(); } break; case PENCIL: { m_current_mode = PENCIL; // Fill the point m_pDoc.m_meta_graph->getDisplayedPointMap().fillPoint(LogicalUnits(point), true); m_mouse_point = point; // Redraw scene m_redraw_no_clear = true; update(); } break; case ERASE: // no longer used break; default: break; } } } } void QDepthmapView::BeginJoin() { if (m_pDoc.m_meta_graph->getSelCount() > 1 && m_pDoc.m_meta_graph->viewingProcessedPoints()) { QtRegion r = m_pDoc.m_meta_graph->getDisplayedPointMap().getSelBounds(); QRect rect(PhysicalUnits(Point2f(r.bottom_left.x, r.top_right.y)), PhysicalUnits(Point2f(r.top_right.x, r.bottom_left.y))); int spacer = int(ceil(5.0 * m_pDoc.m_meta_graph->getDisplayedPointMap().getSpacing() / (m_unit * 10.0))); m_mouse_point = this->rect().center(); m_drag_rect_a = QRect(-rect.width() - spacer / 2, -rect.height() - spacer / 2, spacer / 2, spacer / 2); m_drag_rect_a.translate(m_mouse_point); } else { m_drag_rect_a = QRect(0, 0, 0, 0); } m_drag_rect_b = QRect(0, 0, 0, 0); m_mouse_mode |= JOINB; SetCursor(m_mouse_mode); } void QDepthmapView::mouseReleaseEvent(QMouseEvent *e) { QPoint point = e->pos(); if (pressed_nFlags & MK_LBUTTON) { if (m_snap) { point = PhysicalUnits(m_snap_point); } Point2f location = m_snap ? m_snap_point : LogicalUnits(point); switch (m_current_mode) { case ZOOM_IN: if (m_drag_rect_a.width() > 2 && m_drag_rect_a.height() > 2) { QRect rect = QRect(0, 0, width(), height()); double ratio = __min(double(rect.height() / double(m_drag_rect_a.height())), double(rect.width()) / double(m_drag_rect_a.width())); ZoomTowards(1.0 / ratio, LogicalUnits(m_drag_rect_a.center())); } else { ZoomTowards(0.75, m_centre); } break; case ZOOM_OUT: { ZoomTowards(1.5, m_centre); } break; case DRAG: { // Stop drag rect... m_drag_rect_a = QRect(0, 0, 0, 0); m_invalidate = DRAG; update(); // Redraw scene m_invalidate = 0; m_redraw_all = true; update(); } break; case UNJOIN: case SELECT: case JOIN: { QtRegion r; if (m_drag_rect_a.isEmpty()) { r = QtRegion(LogicalUnits(m_mouse_point), LogicalUnits(m_mouse_point)); } else { r = QtRegion(LogicalUnits(QPoint(m_drag_rect_a.left(), m_drag_rect_a.bottom())), LogicalUnits(QPoint(m_drag_rect_a.right(), m_drag_rect_a.top()))); } // Stop drag rect... m_drag_rect_a = QRect(0, 0, 0, 0); m_invalidate = SELECT; update(); if (!m_pDoc.m_communicator) { // After checking that processing isn't occurring... // Do the selection (might take a while if someone selects the lot...) if (pressed_nFlags & MK_SHIFT) { m_pDoc.m_meta_graph->setCurSel(r, true); // <- add to current sel } else { m_pDoc.m_meta_graph->setCurSel(r, false); // <- reset current sel } // Redraw scene m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_SELECTION); } } break; case JOIN | JOINB: { m_current_mode = NONE; // now get on with join: bool ok = false; bool clearcursor = false; if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { ok = m_pDoc.m_meta_graph->getDisplayedPointMap().mergePoints(LogicalUnits(point)); } else if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { if (m_pDoc.m_meta_graph->getSelCount() == 1) { ok = m_pDoc.m_meta_graph->getDisplayedShapeGraph().linkShapes(LogicalUnits(point)); } else { // oops: you are only allowed to join lines one to one: m_pDoc.m_meta_graph->clearSel(); clearcursor = true; } } if (clearcursor || ok) { m_mouse_mode = JOIN; SetCursor(JOIN); m_drag_rect_a = QRect(0, 0, 0, 0); if (ok) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } else { m_redraw_all = true; update(); } } } break; case UNJOIN | JOINB: { m_current_mode = NONE; // now get on with unjoin: bool ok = false; bool clearcursor = false; if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { if (m_pDoc.m_meta_graph->getSelCount() == 1) { ok = m_pDoc.m_meta_graph->getDisplayedShapeGraph().unlinkShapes(LogicalUnits(point)); } else { // oops: you are only allowed to join lines one to one: m_pDoc.m_meta_graph->clearSel(); clearcursor = true; } } if (clearcursor || ok) { m_mouse_mode = UNJOIN; SetCursor(UNJOIN); m_drag_rect_a = QRect(0, 0, 0, 0); if (ok) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } else { m_redraw_all = true; update(); } } } break; case SELECT | DRAWLINE: { m_current_mode = NONE; m_mouse_mode &= ~DRAWLINE; m_invalidate = LINEOFF; SetCursor(m_mouse_mode); update(); if (m_pDoc.m_meta_graph->moveSelShape(Line(m_line.t_start(), location))) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } } break; case SELECT | OVERHANDLE: BeginDrag(point); break; case LINETOOL: case POLYGONTOOL: { m_current_mode = NONE; m_mouse_mode |= DRAWLINE; m_line = Line(location, location); m_invalidate = LINEON; update(); } break; case LINETOOL | DRAWLINE: { m_current_mode = NONE; m_mouse_mode &= ~DRAWLINE; m_invalidate = LINEOFF; update(); if (m_pDoc.m_meta_graph->makeShape(Line(m_line.t_start(), location))) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } } break; case POLYGONTOOL | DRAWLINE: { m_current_mode = NONE; m_mouse_mode &= ~DRAWLINE; m_invalidate = LINEOFF; update(); // if it's the first part, just make it a line: if (m_poly_points == 0) { m_currentlyEditingShapeRef = m_pDoc.m_meta_graph->polyBegin(Line(m_line.t_start(), location)); m_poly_start = m_line.t_start(); m_poly_points += 2; m_mouse_mode |= DRAWLINE; m_line = Line(location, location); m_invalidate = LINEON; update(); } else if (m_poly_points > 2 && PixelDist(point, PhysicalUnits(m_poly_start)) < 6) { // check to see if it's back to the original start point, if so, close off m_pDoc.m_meta_graph->polyClose(m_currentlyEditingShapeRef); m_poly_points = 0; m_currentlyEditingShapeRef = -1; } else { m_pDoc.m_meta_graph->polyAppend(m_currentlyEditingShapeRef, location); m_poly_points += 1; m_mouse_mode |= DRAWLINE; m_line = Line(location, location); m_invalidate = LINEON; update(); } m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } break; case FILL: m_pDoc.OnFillPoints(location, m_fillmode); break; case SEEDISOVIST: m_current_mode = NONE; m_pDoc.OnMakeIsovist(location); break; case SEEDHALFOVIST: m_current_mode = NONE; m_mouse_mode |= DRAWLINE; m_line = Line(location, location); m_invalidate = LINEON; update(); break; case SEEDHALFOVIST | DRAWLINE: { m_current_mode = NONE; m_mouse_mode &= ~DRAWLINE; m_invalidate = LINEOFF; update(); Point2f vec = m_line.vector(); vec.normalise(); m_pDoc.OnMakeIsovist(m_line.t_start(), vec.angle()); } break; case SEEDAXIAL: m_pDoc.OnToolsAxialMap(location); // switch to select mode (stops you accidently pressing twice) OnEditSelect(); break; } if (m_mouse_mode == JOIN) { if (m_pDoc.m_meta_graph->isSelected()) { BeginJoin(); } } else if (m_mouse_mode == UNJOIN) { if (m_pDoc.m_meta_graph->isSelected()) { if (m_pDoc.m_meta_graph->viewingProcessedPoints()) { if (m_pDoc.m_meta_graph->getDisplayedPointMap().unmergePoints()) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } } else { m_mouse_mode |= JOINB; SetCursor(m_mouse_mode); } } } } else { if (m_snap) { point = PhysicalUnits(m_snap_point); } // Right click now only acts as a cancel, // (and because I personally am used to right-click to zoom out, zoom out! if (!m_right_mouse_drag) { // cancel any tool which uses drawline: if (m_mouse_mode & DRAWLINE) { m_mouse_mode &= ~DRAWLINE; if (m_mouse_mode & POLYGONTOOL && m_poly_points > 0) { m_poly_points = 0; m_currentlyEditingShapeRef = -1; m_pDoc.m_meta_graph->polyCancel(m_currentlyEditingShapeRef); m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } else { m_invalidate = LINEOFF; update(); } } // cancel other tools: switch (m_mouse_mode) { case ZOOM_IN: ZoomTowards(0.75, m_centre); break; case JOIN | JOINB: case UNJOIN | JOINB: m_mouse_mode &= ~JOINB; SetCursor(m_mouse_mode); // drop through intentional case SELECT: if (m_pDoc.m_meta_graph->isSelected()) { m_pDoc.m_meta_graph->clearSel(); // Redraw scene m_redraw_no_clear = true; update(); } break; case PENCIL: { m_pDoc.m_meta_graph->getDisplayedPointMap().fillPoint(LogicalUnits(point), false); m_redraw_all = true; update(); } break; } } else { m_right_mouse_drag = false; SetCursor(m_mouse_mode); // Stop drag rect... m_drag_rect_a = QRect(0, 0, 0, 0); m_invalidate = DRAG; update(); // Redraw scene m_invalidate = 0; m_redraw_all = true; update(); } } pressed_nFlags &= ~MK_LBUTTON; pressed_nFlags &= ~MK_RBUTTON; } void QDepthmapView::wheelEvent(QWheelEvent *e) { short zDelta = e->delta(); QPoint position = e->pos(); QPoint centre(m_physical_centre.width(), m_physical_centre.height()); auto zoomFactor = 1.0 + std::abs(double(zDelta)) / 120.0; if (zDelta > 0) { zoomFactor = 1.0 / zoomFactor; } Point2f newCentre = ViewHelpers::calculateCenter(position, centre, zoomFactor); // Same as LogicalUnits() with non-discreet input newCentre.x = m_centre.x + m_unit * double(newCentre.x - m_physical_centre.width()); newCentre.y = m_centre.y + m_unit * double(m_physical_centre.height() - newCentre.y); if (!IsAtZoomLimits(zoomFactor, 10)) { ZoomTowards(zoomFactor, newCentre); } } // provides a way to limit how much can we zoom out in relation to the window // and graph bounding box size to avoid problems when zooming out too far bool QDepthmapView::IsAtZoomLimits(double ratio, double maxZoomOutRatio) { if (ratio < 1) { return false; } // for zoom out QtRegion bounds = m_pDoc.m_meta_graph->getBoundingBox(); double maxUnit = __max(bounds.width() / width(), bounds.height() / height()); return m_unit * ratio > maxZoomOutRatio * maxUnit; } void QDepthmapView::ZoomTowards(double ratio, const Point2f &point) { m_centre = point; m_unit *= ratio; m_invalidate = 0; // Redraw m_redraw_all = true; update(); } QSize QDepthmapView::sizeHint() const { return m_initialSize; } void QDepthmapView::saveToFile() {} void QDepthmapView::postLoadFile() { m_redraw_all = 1; setWindowTitle(m_pDoc.m_base_title + ":Map View"); } bool QDepthmapView::Output(QPainter *pDC, QGraphDoc *pDoc, bool screendraw) { unsigned long ticks = 0; // GetTickCount(); int state = pDoc->m_meta_graph->getState(); bool b_continue = false; int spacer = GetSpacer(pDoc); if (!pDoc->m_communicator) { int viewclass = pDoc->m_meta_graph->getViewClass(); if (viewclass & MetaGraph::VIEWVGA) { if (!b_continue && viewclass & MetaGraph::VIEWBACKAXIAL) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedShapeGraph(), true, spacer, ticks, screendraw); } if (!b_continue && viewclass & MetaGraph::VIEWBACKDATA) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedDataMap(), true, spacer, ticks, screendraw); } if (!b_continue) { b_continue = DrawPoints(pDC, pDoc, spacer, ticks, screendraw); } } else if (!b_continue && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { if (viewclass & MetaGraph::VIEWBACKVGA) { b_continue = DrawPoints(pDC, pDoc, spacer, ticks, screendraw); } if (!b_continue && viewclass & MetaGraph::VIEWBACKDATA) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedDataMap(), true, spacer, ticks, screendraw); } if (!b_continue) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedShapeGraph(), false, spacer, ticks, screendraw); } } else if (!b_continue && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { if (viewclass & MetaGraph::VIEWBACKAXIAL) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedShapeGraph(), true, spacer, ticks, screendraw); } if (!b_continue && viewclass & MetaGraph::VIEWBACKVGA) { b_continue = DrawPoints(pDC, pDoc, spacer, ticks, screendraw); } if (!b_continue) { b_continue = DrawShapes(pDC, pDoc->m_meta_graph->getDisplayedDataMap(), false, spacer, ticks, screendraw); } } } if (!b_continue && state & MetaGraph::LINEDATA) { bool nextlayer = false, first = true; pDC->setPen(QPen(QBrush(QColor(m_foreground)), spacer / 20 + 1, Qt::SolidLine, Qt::RoundCap)); while ((b_continue = pDoc->m_meta_graph->findNextShape(nextlayer))) { /* Line l = pDoc->m_meta_graph->SuperSpacePixel::getNextLine(); if (nextlayer || first) { PafColor color; color = pDoc->m_meta_graph->SuperSpacePixel::getLineColor(); pDC->SelectObject(oldpen); pen.DeleteObject(); if (color.alphab() != 0) { pen.CreatePen( PS_SOLID, spacer/20+1, color ); } else { pen.CreatePen( PS_SOLID, spacer/20+1, GetApp()->m_foreground ); } pDC->SelectObject(&pen); first = false; nextlayer = false; }*/ const SalaShape &shape = pDoc->m_meta_graph->getNextShape(); spacer = GetSpacer(pDoc); if (shape.isPoint()) { } else if (shape.isLine()) { Line line = shape.getLine(); QPoint p1 = PhysicalUnits(line.start()); QPoint p2 = PhysicalUnits(line.end()); if (p1 != p2) { pDC->drawLine(p1, p2); } } else { size_t i; for (i = 1; i < shape.m_points.size(); i++) { pDC->drawLine(PhysicalUnits(shape.m_points[i - 1]), PhysicalUnits(shape.m_points[i])); } if (shape.isClosed()) { pDC->drawLine(PhysicalUnits(shape.m_points[i - 1]), PhysicalUnits(shape.m_points[0])); } } } } if (!b_continue && spacer > 1 && pDoc->m_meta_graph->viewingProcessedShapes() && pDoc->m_meta_graph->m_showtext) { /* setFont(QFont("Arial", 10, 10)); pDC->setPen(QPen(QBrush(QColor(m_foreground)), 1, Qt::SolidLine, Qt::FlatCap)); // display the layer attribute data: // THIS NEEDS SORTING OUT ShapeMap& map = pDoc->m_meta_graph->getDisplayedDataMap(); for (int i = 0; i < map.getObjectCount(); i++) { if (map.getDisplayedAttributeValue(i) > 0) { std::string text = map.getDisplayedAttributeText(i); QPoint p = PhysicalUnits(map.getCentroid(i)); QSize sz = pDC->GetTextExtent(text.c_str()); pDC->drawText(p.x(), p.y()-(sz.height()/2), text.c_str()); } }*/ } if (!b_continue && m_showlinks) { pDC->setBrush(QBrush(QColor(m_foreground), Qt::SolidPattern)); if (pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWVGA && pDoc->m_meta_graph->getDisplayedPointMap().isProcessed()) { PointMap &map = pDoc->m_meta_graph->getDisplayedPointMap(); // merge lines pDC->setPen(QPen(QBrush(QColor(00, 255, 0)), spacer / 10 + 1, Qt::SolidLine)); while ((b_continue = map.findNextMergeLine())) { Line line = map.getNextMergeLine(); DrawLink(pDC, spacer, line); } } else if ((state & MetaGraph::SHAPEGRAPHS) && (pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL)) { // link lines pDC->setPen(QPen(QBrush(QColor(00, 255, 0)), spacer / 10 + 1, Qt::SolidLine)); while ((b_continue = pDoc->m_meta_graph->getDisplayedShapeGraph().findNextLinkLine())) { Line line = pDoc->m_meta_graph->getDisplayedShapeGraph().getNextLinkLine(); DrawLink(pDC, spacer, line); } pDC->setPen(QPen(QBrush(QColor(255, 00, 00)), spacer / 10 + 1, Qt::SolidLine)); pDC->setBrush(QBrush(QColor(m_background), Qt::SolidPattern)); while ((b_continue = pDoc->m_meta_graph->getDisplayedShapeGraph().findNextUnlinkPoint())) { QPoint p = PhysicalUnits(pDoc->m_meta_graph->getDisplayedShapeGraph().getNextUnlinkPoint()); p -= QPoint(2 + spacer / 2, 2 + spacer / 2); QRect rect(p, QSize(spacer + 4, spacer + 4)); pDC->drawEllipse(rect); } } } return b_continue; } bool QDepthmapView::DrawPoints(QPainter *pDC, QGraphDoc *pDoc, int spacer, unsigned long ticks, bool screendraw) { unsigned long c_tick = 0; bool b_continue = false; PointMap &map = pDoc->m_meta_graph->getDisplayedPointMap(); bool muted = (map.isProcessed() && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWBACKVGA); if (m_showlinks) { if (!muted) { muted = true; } else { return b_continue; // too confusing! } } if (pDoc->m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKAXIAL | MetaGraph::VIEWBACKDATA)) { spacer /= 2; // allow see through to axial lines } bool monochrome = (map.isProcessed() && map.getDisplayParams().colorscale == DisplayParams::MONOCHROME); // if (monochrome) { // standardbrush = new QBrush( GetApp()->m_foreground ); //} pDC->setBrush(QBrush(QColor(m_foreground), Qt::SolidPattern)); while ((b_continue = map.findNextPoint())) { Point2f logical = map.getNextPointLocation(); PafColor color; color = map.getCurrentPointColor(); if (color.alphab() != 0) { // alpha == 0 is transparent if (monochrome && !map.getPointSelected()) { QPoint p = PhysicalUnits(logical); int subspacer = (3 * color.blueb() * spacer) / 255; if (subspacer >= 1) { pDC->drawEllipse(p.x() - subspacer, p.y() + subspacer, subspacer * 2, subspacer * 2); } else { pDC->drawPoint(p); } } else { QRgb rgb = qRgb(color.redb(), color.greenb(), color.blueb()); if (muted && !map.getPointSelected()) { // keeps selected points bright yellow rgb = colorMerge(rgb, m_background); } QPoint p = PhysicalUnits(logical); if (spacer > 1) { // Standard code pDC->setBrush(QBrush(QColor(rgb), Qt::SolidPattern)); pDC->fillRect(QRect(p.x() - spacer, p.y() - spacer, spacer * 2, spacer * 2), QBrush(QColor(rgb))); } else { pDC->drawPoint(p); } } } if (screendraw && c_tick++ > 10000) break; } if (!b_continue && pDoc->m_meta_graph->m_showgrid) { pDC->setPen(QPen(QBrush(QColor(colorMerge(m_foreground, m_background))), 1, Qt::SolidLine)); if (pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { // show grid as though points are filling the spaces while ((b_continue = map.findNextRow())) { Line logical = map.getNextRow(); pDC->drawLine(PhysicalUnits(logical.start()), PhysicalUnits(logical.end())); } while ((b_continue = map.findNextCol())) { Line logical = map.getNextCol(); pDC->drawLine(PhysicalUnits(logical.start()), PhysicalUnits(logical.end())); } } else { // show actual grid while ((b_continue = map.findNextPointRow())) { Line logical = map.getNextPointRow(); pDC->drawLine(PhysicalUnits(logical.start()), PhysicalUnits(logical.end())); } while ((b_continue = map.findNextPointCol())) { Line logical = map.getNextPointCol(); pDC->drawLine(PhysicalUnits(logical.start()), PhysicalUnits(logical.end())); } } } return b_continue; } bool QDepthmapView::DrawShapes(QPainter *pDC, ShapeMap &map, bool muted, int spacer, unsigned long ticks, bool screendraw) { unsigned long c_tick = 0; bool b_continue = false; if (m_showlinks) { if (!muted) { muted = true; } else { return b_continue; // too confusing! } } bool monochrome = (map.getDisplayParams().colorscale == DisplayParams::MONOCHROME); if (screendraw && !muted) { // i.e., at the front... implies can select... allow this draw to overwrite any existing point handle // locations: m_point_handles.clear(); } QPen pen(QBrush(QColor(m_foreground)), spacer / 20 + 1, Qt::SolidLine); bool dummy; int count = 0; while ((b_continue = map.findNextShape(dummy))) { count++; PafColor color; // n.b., MONOCHROME settings only for line thickness... color = map.getShapeColor(); bool selected = map.getShapeSelected(); // n.b., getNextShape clears polygon ready for next, so get polygon color and selected attribute before this: const SalaShape &poly = map.getNextShape(); QPoint *points = NULL; int drawable = 0; if (!poly.isPoint() && !poly.isLine() && !poly.m_points.empty()) { points = new QPoint[poly.m_points.size()]; if (poly.m_points.size() > 0) drawable++; for (auto &point : poly.m_points) { points[drawable] = PhysicalUnits(point); if (points[drawable] != points[drawable - 1]) { drawable++; } } } // QBrush brush; QPen pen2; QRgb rgb; int tempspacer = selected ? spacer * 3 : spacer; if (!monochrome || selected) { rgb = qRgb(color.redb(), color.greenb(), color.blueb()); if (muted && !selected) { rgb = colorMerge(rgb, m_background); } if (poly.isClosed() || poly.isPoint()) { brush = QBrush(QColor(rgb), Qt::SolidPattern); } else { pen2 = QPen(QBrush(QColor(rgb)), tempspacer / 10 + 1, Qt::SolidLine); } } else { int thickness = (spacer * color.blueb()) / 255; if (thickness < 1) { // note, monochrome excludes lines below 'thin' threshold continue; } if (poly.isClosed()) { brush = QBrush(QColor(m_background), Qt::SolidPattern); } pen2 = QPen(QBrush(QColor(m_foreground)), thickness, Qt::SolidLine); } if (poly.isClosed()) { if (drawable > 1) { if (!map.m_show_lines) { pDC->setPen(Qt::NoPen); } else if (monochrome && !selected) { pDC->setPen(pen2); } else { pDC->setPen(pen2); } if (!map.m_show_fill) { pDC->setBrush(Qt::NoBrush); } else { pDC->setBrush(brush); } pDC->drawPolygon(points, drawable); // if (map.m_show_centroids) { Point2f p = poly.getCentroid(); pDC->setPen(QColor(255, 255, 0)); pDC->drawPoint(PhysicalUnits(p)); } } else { pDC->setPen(QColor(rgb)); pDC->drawPoint(points[0]); } } else { if (poly.isPoint()) { QPoint point = PhysicalUnits(poly.getPoint()); if (tempspacer < 2) { pDC->setPen(QColor(rgb)); pDC->drawPoint(point); } else { QRect rect(point.x() - tempspacer / 2, point.y() - tempspacer / 2, tempspacer, tempspacer); if (tempspacer < 4) { pDC->setBrush(QBrush(QColor(rgb), Qt::SolidPattern)); pDC->drawRect(rect); } else { pDC->setPen(pen); pDC->setBrush(brush); pDC->drawEllipse(rect); } } } else if (poly.isLine()) { pDC->setPen(pen2); Line l = poly.getLine(); QPoint start = PhysicalUnits(l.start()); QPoint end = PhysicalUnits(l.end()); if (start != end) { pDC->drawLine(start, end); } if (selected && screendraw && !muted && map.getSelCount() == 1 && map.isEditable()) { m_point_handles.push_back(l.start()); m_point_handles.push_back(l.end()); } } else { if (drawable > 1) { pDC->setPen(pen2); pDC->drawPolyline(points, drawable); } else { pDC->setPen(QColor(rgb)); pDC->drawPoint(points[0]); } } } if (points) { delete[] points; } if (screendraw && c_tick++ > 10000) break; } if (screendraw && !muted) { // i.e., at the front... implies can select... allow this draw to overwrite to draw point handle locations: for (size_t i = 0; i < m_point_handles.size(); i++) { DrawPointHandle(pDC, PhysicalUnits(m_point_handles[i])); } } return b_continue; } void QDepthmapView::DrawLink(QPainter *pDC, int spacer, const Line &logical) { spacer += 4; QPoint p1 = PhysicalUnits(logical.start()); QPoint p2 = PhysicalUnits(logical.end()); pDC->drawLine(p1, p2); p1 -= QPoint(spacer / 2, spacer / 2); p2 -= QPoint(spacer / 2, spacer / 2); QRect rect1(p1, QSize(spacer, spacer)); QRect rect2(p2, QSize(spacer, spacer)); pDC->drawEllipse(rect1); pDC->drawEllipse(rect2); } void QDepthmapView::DrawPointHandle(QPainter *pDC, QPoint pt) { QRect rect(pt.x() - 7, pt.y() - 7, 14, 14); pDC->setBrush(QBrush(QColor(m_foreground), Qt::SolidPattern)); pDC->drawRect(rect); rect.adjust(1, 1, 1, 1); // DeflateRect(1,1,1,1); pDC->setBrush(QBrush(QColor(m_background), Qt::SolidPattern)); pDC->drawRect(rect); rect.adjust(1, 1, 1, 1); // DeflateRect(1,1,1,1); pDC->setBrush(QBrush(QColor(m_selected_color), Qt::SolidPattern)); pDC->drawRect(rect); } void QDepthmapView::OutputEPS(std::ofstream &stream, QGraphDoc *pDoc, bool includeScale) { // This output EPS is a copy of the standard output... obviously, if you change // standard output, remember to change this one too! // now the two are a little out of synch if (!m_viewport_set) { QMessageBox::warning(this, tr("Warning"), tr("Can't save screen as the Depthmap window is not initialised"), QMessageBox::Ok, QMessageBox::Ok); return; } QRect clrect, rect; clrect = QRect(0, 0, width(), height()); // GetClientRect( clrect ); stream << "%!PS-Adobe-3.0 EPSF-3.0\n" << "%%BoundingBox: 0 0 " << clrect.width() << " " << clrect.height() << "\n" << "%%Creator: " << TITLE_BASE << std::endl; // temporarily inflate resolution for EPS draw rect = QRect(clrect.left() * 10, clrect.top() * 10, clrect.width() * 10, clrect.height() * 10); QPoint oldcentre = QPoint(m_physical_centre.width(), m_physical_centre.height()); double oldunit = m_unit; m_physical_centre = QSize(rect.width() / 2, rect.height() / 2); m_unit /= 10; int bg = (int)m_background; float bgr = float(GetRValue(bg)) / 255.0f; float bgg = float(GetGValue(bg)) / 255.0f; float bgb = float(GetBValue(bg)) / 255.0f; int fg = (int)m_foreground; float fgr = float(GetRValue(fg)) / 255.0f; float fgg = float(GetGValue(fg)) / 255.0f; float fgb = float(GetBValue(fg)) / 255.0f; stream << "/M {moveto} def" << std::endl; stream << "/L {lineto} def" << std::endl; stream << "/R {rlineto} def" << std::endl; stream << "/C {setrgbcolor} def" << std::endl; stream << "/W {setlinewidth} def" << std::endl; stream << "newpath\n" << 0 << " " << 0 << " M\n" << clrect.width() << " " << 0 << " R\n" << 0 << " " << clrect.height() << " R\n" << -clrect.width() << " " << 0 << " R\n" << "closepath\n" << bgr << " " << bgg << " " << bgb << " C\n" << "fill" << std::endl; int state = pDoc->m_meta_graph->getState(); QtRegion logicalviewport = LogicalViewport(rect, pDoc); if (state & MetaGraph::POINTMAPS) { pDoc->m_meta_graph->getDisplayedPointMap().setScreenPixel(m_unit); // only used by points (at the moment!) pDoc->m_meta_graph->getDisplayedPointMap().makeViewportPoints(logicalviewport); } if (state & MetaGraph::SHAPEGRAPHS) { pDoc->m_meta_graph->getDisplayedShapeGraph().makeViewportShapes(logicalviewport); } if (state & MetaGraph::DATAMAPS) { pDoc->m_meta_graph->getDisplayedDataMap().makeViewportShapes(logicalviewport); } if (state & MetaGraph::LINEDATA) { pDoc->m_meta_graph->makeViewportShapes(logicalviewport); } double spacer = GetSpacer(pDoc) / 10.0; if (spacer < 0.1) { spacer = 0.1; } if (state & MetaGraph::POINTMAPS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { // Define EPS box using spacer dimensions: stream << "/bx\n" << " { newpath M\n" << " " << 2 * spacer << " " << 0 << " R\n" << " " << 0 << " " << 2 * spacer << " R\n" << " " << 2 * -spacer << " " << 0 << " R\n" << " closepath } def" << std::endl; stream << "/fbx\n" << " { C fill } def" << std::endl; PointMap &map = pDoc->m_meta_graph->getDisplayedPointMap(); while (map.findNextPoint()) { Point2f logical = map.getNextPointLocation(); PafColor color = map.getCurrentPointColor(); if (color.alphab() != 0) { // alpha == 0 is transparent QPoint p = PhysicalUnits(logical); // Now do EPS box... remember the coordinate system is the right way up! stream << p.x() / 10.0 - spacer << " " << (rect.height() - p.y()) / 10.0 - spacer << " bx" << std::endl; stream << color.redf() << " " << color.greenf() << " " << color.bluef() << " fbx" << std::endl; } } } if (state & MetaGraph::SHAPEGRAPHS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { ShapeMap &map = pDoc->m_meta_graph->getDisplayedShapeGraph(); OutputEPSMap(stream, map, logicalviewport, rect, spacer); } if (state & MetaGraph::DATAMAPS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { ShapeMap &map = pDoc->m_meta_graph->getDisplayedDataMap(); OutputEPSMap(stream, map, logicalviewport, rect, spacer); } if (state & MetaGraph::LINEDATA) { stream << "newpath" << std::endl; bool nextlayer = false; bool first = true; int style = 0; while (pDoc->m_meta_graph->findNextShape(nextlayer)) { const SalaShape &shape = pDoc->m_meta_graph->getNextShape(); Line l; if (shape.isPoint()) { } else if (shape.isLine()) { Line line = shape.getLine(); OutputEPSLine(stream, line, spacer, logicalviewport, rect); } else { OutputEPSPoly(stream, shape, spacer, logicalviewport, rect); } } int fg = (int)m_foreground; float fgr = float(GetRValue(fg)) / 255.0f; float fgg = float(GetGValue(fg)) / 255.0f; float fgb = float(GetBValue(fg)) / 255.0f; if (style == 1) { stream << "[" << spacer / 10 + 1 << "]"; } else { stream << "[]"; } stream << " 0 setdash" << std::endl; stream << fgr << " " << fgg << " " << fgb << " C" << std::endl; stream << spacer / 10 + 1 << " W" << std::endl; stream << "stroke" << std::endl; } // loaded paths if (pDoc->m_evolved_paths.size()) { stream << "newpath" << std::endl; for (size_t i = 0; i < pDoc->m_evolved_paths.size(); i++) { const std::vector &path = pDoc->m_evolved_paths[i]; if (path.size() > 1) { QPoint last = PhysicalUnits(path[0]); stream << (last.x() - spacer / 40) / 10.0 << " " << (rect.height() - last.y() + spacer / 40) / 10.0 << " M\n" << std::endl; for (size_t j = 1; j < path.size(); j++) { QPoint next = PhysicalUnits(path[j]); stream << (next.x() - last.x() - spacer / 40) / 10.0 << " " << (last.y() - next.y() - spacer / 40) / 10.0 << " L" << std::endl; last = next; } stream << fgr << " " << fgg << " " << fgb << " C" << std::endl; stream << spacer / 20 + 1 << " W" << std::endl; stream << "stroke" << std::endl; } } } /* if (pDoc->m_agent_manager && pDoc->m_agent_manager->isPaused()) { if (pDoc->m_agent_manager->isEcomorphic()) { // draw the ecomorphic artworks Ecomorph& eco = pDoc->m_agent_manager->getEcomorph(); for (int i = 0; i < eco.arts().size(); i++) { PixelRef pos = eco.arts()[i].getPos(); Point2f logical = pDoc->m_meta_graph->getDisplayedPointMap().depixelate(pos); // this is in units of logical is unit based so this actually works okay: QPoint p = PhysicalUnits(Point2f(logical.x, logical.y)); QPoint bottomleft = PhysicalUnits(Point2f(logical.x - 0.5, logical.y - 0.5)); // Now do EPS box... remember the coordinate system is the right way up! stream << (p.x - spacer) / 10.0 << " " << (rect.Height() - p.y - spacer) / 10.0 << " bx" << std::endl; stream << bgr << " " << bgg << " " << bgb << " fbx" << std::endl; // And cover with line: stream << (bottomleft.x - spacer/20) / 10.0 << " " << (rect.Height() - bottomleft.y + spacer/20) / 10.0 << " M\n" << (spacer * 2 - spacer/20) / 10.0 << " " << 0 << " L\n" << 0 << " " << (spacer * 2 - spacer/20) / 10.0 << " L\n" << (-spacer * 2 + spacer/20) / 10.0 << " " << 0 << " L\n" << 0 << " " << (-spacer * 2 + spacer/20) / 10.0 << " L" << std::endl; stream << fgr << " " << fgg << " " << fgb << " setrgbcolor" << std::endl; stream << spacer/10+1 << " setlinewidth" << std::endl; stream << "stroke" << std::endl; } } } */ if (includeScale) { // add the scale to the bottom lefthand corner double logicalwidth = m_unit * rect.width(); if (logicalwidth > 10) { int workingwidth = floor(log10(logicalwidth / 2) * 2.0); int barwidth = (int)pow(10.0, (double)(workingwidth / 2)) * ((workingwidth % 2 == 0) ? 1 : 5); double physicalbar = double(barwidth) / m_unit; stream << "newpath" << std::endl; stream << "0 0 M 0 18 R" << std::endl; stream << physicalbar / 10.0 << " 0 R 0 -18 R closepath" << std::endl; stream << bgr << " " << bgg << " " << bgb << " C" << std::endl; stream << "fill newpath" << std::endl; stream << fgr << " " << fgg << " " << fgb << " C" << std::endl; stream << "0 12 M" << std::endl; stream << physicalbar / 10.0 << " 0 R" << std::endl; stream << "3 W stroke" << std::endl; stream << "0 6 M 0 7.5 R" << std::endl; stream << physicalbar / 10.0 << " 6 M 0 7.5 R" << std::endl; stream << "1.5 W stroke" << std::endl; stream << "/Arial findfont 12 scalefont setfont" << std::endl; // assume metres! if (barwidth > 1000) { stream << "(" << (barwidth / 1000) << "km) stringwidth pop 2 div" << std::endl; } else { stream << "(" << barwidth << "m) stringwidth pop 2 div" << std::endl; } stream << physicalbar / 20.0 << " exch sub" << std::endl; stream << "0 M" << std::endl; stream << "(" << barwidth << "m) show" << std::endl; } } stream << "showpage" << std::endl; // undo temporary unit setting m_unit = oldunit; m_physical_centre = QSize(oldcentre.x(), oldcentre.y()); } void QDepthmapView::OutputEPSMap(std::ofstream &stream, ShapeMap &map, QtRegion &logicalviewport, QRect &rect, float spacer) { bool monochrome = (map.getDisplayParams().colorscale == DisplayParams::MONOCHROME); double thickness = 1.0, oldthickness = 1.0; bool closed, oldclosed = false; PafColor color, oldcolor; int fg = (int)m_foreground; float fgr = float(GetRValue(fg)) / 255.0f; float fgg = float(GetGValue(fg)) / 255.0f; float fgb = float(GetBValue(fg)) / 255.0f; stream << "newpath" << std::endl; stream << fgr << " " << fgg << " " << fgb << " C" << std::endl; bool dummy; while (map.findNextShape(dummy)) { // note: getNextLine clears current line, so getLineColor before line color = map.getShapeColor(); const SalaShape &shape = map.getNextShape(); closed = shape.isClosed(); if (monochrome) { thickness = 3.0 * (color.blueb() * spacer) / 255.0; // note: anything below 'thin' threshold in monochrome note drawn if (thickness < 0.25) { continue; } if (thickness != oldthickness || closed != oldclosed) { stream << oldthickness << " W" << std::endl; stream << (oldclosed ? "fill" : "stroke") << std::endl; oldthickness = thickness; oldclosed = closed; } } else if (color != oldcolor || closed != oldclosed) { stream << oldcolor.redf() << " " << oldcolor.greenf() << " " << oldcolor.bluef() << " C" << std::endl; stream << (oldclosed ? "fill" : "stroke") << std::endl; oldcolor = color; oldclosed = closed; } Line l; if (shape.isPoint()) { } else if (shape.isLine()) { Line line = shape.getLine(); OutputEPSLine(stream, line, spacer, logicalviewport, rect); } else { OutputEPSPoly(stream, shape, spacer, logicalviewport, rect); } } stream << thickness << " W" << std::endl; if (!monochrome) { stream << color.redf() << " " << color.greenf() << " " << color.bluef() << " C" << std::endl; } stream << (closed ? "fill" : "stroke") << std::endl; } void QDepthmapView::OutputEPSLine(std::ofstream &stream, Line &line, int spacer, QtRegion &logicalviewport, QRect &rect) { bool drewit = false; if (line.crop(logicalviewport)) { QPoint start = PhysicalUnits(line.start()); QPoint end = PhysicalUnits(line.end()); // 10 units corresponds to 1 pixel on the screen if (sqrt(sqr(start.x() - end.x()) + sqr(start.y() - end.y())) > 5.0) { stream << (start.x() / 10.0) << " " << (rect.height() - start.y()) / 10.0 << " M "; stream << (end.x() / 10.0) << " " << (rect.height() - end.y()) / 10.0 << " L" << std::endl; } } } void QDepthmapView::OutputEPSPoly(std::ofstream &stream, const SalaShape &shape, int spacer, QtRegion &logicalviewport, QRect &rect) { bool starter = true; Point2f lastpoint = shape.m_points[0]; int count = shape.isClosed() ? shape.m_points.size() + 1 : shape.m_points.size(); int size = shape.m_points.size(); for (int i = 1; i < count; i++) { Line line(lastpoint, shape.m_points[i % size]); if (line.crop(logicalviewport)) { // note: use t_start and t_end so that this line moves in the correct direction QPoint start = PhysicalUnits(line.t_start()); QPoint end = PhysicalUnits(line.t_end()); // 5.0 is about 1/2 pixel width if (sqrt(sqr(start.x() - end.x()) + sqr(start.y() - end.y())) > 5.0) { if (starter) { stream << start.x() / 10.0 << " " << (rect.height() - start.y()) / 10.0 << " M "; } stream << end.x() / 10.0 << " " << (rect.height() - end.y()) / 10.0 << " L" << std::endl; // note: you must use t_end (true end) so that it takes the end point from the shape[i] end: lastpoint = line.t_end(); starter = false; } } else { lastpoint = shape.m_points[i]; starter = true; } } } void QDepthmapView::DrawCross(QPainter *pDC, QPoint ¢re, bool drawit) { if (drawit) { for (int i = 0; i < 9; i++) { QPoint pos(centre.x() - 4 + i, centre.y()); pDC->setPen(QColor(m_foreground)); pDC->drawPoint(pos); } for (int j = 0; j < 9; j++) { if (j != 4) { QPoint pos(centre.x(), centre.y() - 4 + j); pDC->setPen(QColor(m_foreground)); pDC->drawPoint(pos); } } } else { // erase it for (int i = 0; i < 9; i++) { QPoint pos(centre.x() - 4 + i, centre.y()); pDC->drawPoint(pos); } for (int j = 0; j < 9; j++) { if (j != 4) { QPoint pos(centre.x(), centre.y() - 4 + j); pDC->drawPoint(pos); } } } } int QDepthmapView::GetSpacer(QGraphDoc *pDoc) { int spacer = 1; int viewclass = pDoc->m_meta_graph->getViewClass(); if (viewclass & (MetaGraph::VIEWVGA | MetaGraph::VIEWBACKVGA)) { spacer = int(ceil(5.0 * pDoc->m_meta_graph->getDisplayedPointMap().getSpacing() / (m_unit * 10.0))); } else if (viewclass & MetaGraph::VIEWAXIAL) { spacer = int(ceil(pDoc->m_meta_graph->getDisplayedShapeGraph().getSpacing() / (m_unit * 10.0))); } else if (viewclass & MetaGraph::VIEWDATA) { spacer = int(ceil(pDoc->m_meta_graph->getDisplayedDataMap().getSpacing() / (m_unit * 10.0))); } return spacer; } void QDepthmapView::DrawLine(QPainter *pDC, QRect &line, bool drawit) { if (line.width() == 0 && line.height() == 0) { return; } if (drawit) { m_line_pixels.clear(); } else if (!m_line_pixels.size()) { return; // shouldn't happen, but does appear to } bool wide = (abs(line.width()) > abs(line.height())); pDC->setCompositionMode(QPainter::RasterOp_SourceXorDestination); pDC->setPen(QColor(m_foreground)); if (wide) { int step = (line.width() > 0) ? 1 : -1; for (int i = 0; (i * step) < abs(line.width()); i += step) { QPoint thispixel(i, int((float(line.height()) / float(line.width())) * float(i))); if (drawit) { m_line_pixels.push_back(m_foreground); pDC->drawPoint(line.topLeft() + thispixel); } else { pDC->drawPoint(line.topLeft() + thispixel); } } } else { int step = (line.height() > 0) ? 1 : -1; for (int i = 0; (i * step) < abs(line.height()); i += step) { QPoint thispixel(int((float(line.width()) / float(line.height())) * float(i)), i); if (drawit) { m_line_pixels.push_back(m_foreground); pDC->drawPoint(line.topLeft() + thispixel); } else { pDC->drawPoint(line.topLeft() + thispixel); } } } if (!drawit) { m_line_pixels.clear(); } pDC->setCompositionMode(QPainter::CompositionMode_SourceOver); } void QDepthmapView::SetCursor(int mode) { switch (mode) { case SELECT: m_cursor = QCursor(Qt::ArrowCursor); break; case SELECT | OVERHANDLE: m_cursor = QCursor(QPixmap(":/images/cur/cur00005.png")); break; case DRAG: m_cursor = QCursor(Qt::OpenHandCursor); break; case ZOOM_IN: m_cursor = QCursor(QPixmap(":/images/cur/cur00008.png")); break; case ZOOM_OUT: m_cursor = QCursor(QPixmap(":/images/cur/cur00009.png")); break; case SEEDISOVIST: case SEEDHALFOVIST: case SEEDAXIAL: m_cursor = QCursor(QPixmap(":/images/cur/cur00003.png")); break; case FILL: m_cursor = QCursor(QPixmap(":/images/cur/cur00001.png")); break; case PENCIL: m_cursor = QCursor(QPixmap(":/images/cur/cur00002.png")); break; case LINETOOL: case LINETOOL | DRAWLINE: case POLYGONTOOL: case POLYGONTOOL | DRAWLINE: case SELECT | DRAWLINE: m_cursor = QCursor(Qt::CrossCursor); break; case ERASE: m_cursor = QCursor(QPixmap(":/images/cur/cur00006.png")); break; case JOIN: case UNJOIN: m_cursor = QCursor(Qt::PointingHandCursor); break; case JOIN | JOINB: m_cursor = QCursor(QPixmap(":/images/cur/cur00004.png")); break; case UNJOIN | JOINB: m_cursor = QCursor(QPixmap(":/images/cur/cur00007.png")); break; default: m_cursor = QCursor(Qt::ArrowCursor); break; } setCursor(m_cursor); } // Zoom to Selection void QDepthmapView::OnViewZoomsel() { if (m_pDoc.m_meta_graph && m_pDoc.m_meta_graph->isSelected()) { QtRegion sel_bounds = m_pDoc.m_meta_graph->getSelBounds(); // select a suitable zoom factor based on bounding box dimensions: m_centre = sel_bounds.getCentre(); QRect phys_bounds = this->rect(); if (sel_bounds.area() > 1e-9) { // base area on selection area m_unit = 1.1 * __max(sel_bounds.width() / double(phys_bounds.width()), sel_bounds.height() / double(phys_bounds.height())); } else { // base area on some arbitrary zoom into the map QtRegion map_bounds = m_pDoc.m_meta_graph->getBoundingBox(); m_unit = 0.01 * __max(map_bounds.width() / double(phys_bounds.width()), map_bounds.height() / double(phys_bounds.height())); } // Redraw scene m_redraw_all = true; update(); } } void QDepthmapView::OnViewPan() { m_mouse_mode = DRAG; SetCursor(DRAG); } void QDepthmapView::OnViewZoomIn() { m_mouse_mode = ZOOM_IN; SetCursor(ZOOM_IN); } void QDepthmapView::OnViewZoomOut() { m_mouse_mode = ZOOM_OUT; SetCursor(ZOOM_OUT); } void QDepthmapView::OnEditSelect() { m_mouse_mode = SELECT; SetCursor(SELECT); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnModeIsovist() { m_mouse_mode = SEEDISOVIST; SetCursor(SEEDISOVIST); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnModeTargetedIsovist() { m_mouse_mode = SEEDHALFOVIST; SetCursor(SEEDHALFOVIST); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnModeSeedAxial() { m_mouse_mode = SEEDAXIAL; SetCursor(SEEDAXIAL); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnEditFill() { m_mouse_mode = FILL; m_fillmode = FULLFILL; SetCursor(FILL); } void QDepthmapView::OnEditSemiFill() { m_mouse_mode = FILL; m_fillmode = SEMIFILL; SetCursor(FILL); } // AV TV void QDepthmapView::OnEditAugmentFill() { m_mouse_mode = FILL; m_fillmode = AUGMENT; SetCursor(FILL); } void QDepthmapView::OnEditPencil() { m_mouse_mode = PENCIL; SetCursor(PENCIL); } void QDepthmapView::OnEditEraser() { m_mouse_mode = ERASE; SetCursor(ERASE); } void QDepthmapView::OnEditLineTool() { m_mouse_mode = LINETOOL; SetCursor(LINETOOL); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnEditPolygonTool() { m_mouse_mode = POLYGONTOOL; SetCursor(POLYGONTOOL); if (m_showlinks) { m_showlinks = false; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnModeJoin() { if (m_pDoc.m_meta_graph->getState() & (MetaGraph::POINTMAPS | MetaGraph::SHAPEGRAPHS)) { m_mouse_mode = JOIN; if (!m_pDoc.m_meta_graph->isSelected()) { SetCursor(m_mouse_mode); } else { BeginJoin(); } // Redraw scene m_showlinks = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnModeUnjoin() { if (m_pDoc.m_meta_graph->getState() & (MetaGraph::POINTMAPS | MetaGraph::SHAPEGRAPHS)) { m_mouse_mode = UNJOIN; if (!m_pDoc.m_meta_graph->isSelected()) { SetCursor(m_mouse_mode); } else { if (m_pDoc.m_meta_graph->viewingProcessedPoints()) { m_pDoc.m_meta_graph->clearSel(); } else { m_mouse_mode |= JOINB; SetCursor(m_mouse_mode); } } // Redraw scene m_showlinks = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_MAP, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DEPTHMAPVIEW_SETUP, this); } } void QDepthmapView::OnEditCopy() { QRect rectin = QRect(0, 0, width(), height()); int state = m_pDoc.m_meta_graph->getState(); if (state & MetaGraph::POINTMAPS && (!m_pDoc.m_meta_graph->getDisplayedPointMap().isProcessed() || m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWBACKVGA))) { m_pDoc.m_meta_graph->getDisplayedPointMap().setScreenPixel(m_unit); // only used by points (at the moment!) m_pDoc.m_meta_graph->getDisplayedPointMap().makeViewportPoints(LogicalViewport(rectin, &m_pDoc)); } if (state & MetaGraph::SHAPEGRAPHS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKAXIAL | MetaGraph::VIEWAXIAL))) { m_pDoc.m_meta_graph->getDisplayedShapeGraph().makeViewportShapes(LogicalViewport(rectin, &m_pDoc)); } if (state & MetaGraph::DATAMAPS && (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWBACKDATA | MetaGraph::VIEWDATA))) { m_pDoc.m_meta_graph->getDisplayedDataMap().makeViewportShapes(LogicalViewport(rectin, &m_pDoc)); } if (state & MetaGraph::LINEDATA) { m_pDoc.m_meta_graph->makeViewportShapes(LogicalViewport(rectin, &m_pDoc)); } // Copy to Clipboard QPixmap image(width(), height()); QPainter painter; painter.begin(&image); // paint in picture Output(&painter, &m_pDoc, false); painter.end(); // painting done QClipboard *clipboard = QApplication::clipboard(); clipboard->setPixmap(image); } void QDepthmapView::OnEditSave() { // Very similar to copy to clipboard, only writes an EPS instead of a WMF if (m_pDoc.m_communicator) { QMessageBox::warning(this, tr("Warning"), tr("Another Depthmap process is running, please wait until it completes"), QMessageBox::Ok, QMessageBox::Ok); return; } QString saveas; QFilePath path(windowFilePath()); // saveas = path.m_path + (path.m_name.isEmpty() ? windowTitle() : path.m_name); saveas = path.m_path + tr("*.eps"); QString template_string = tr("Encapsulated Postscript (*.eps)\nScalable Vector Graphics (*.svg)\nAll files (*.*)"); QFileDialog::Options options = 0; QString selectedFilter; QString outfile = QFileDialog::getSaveFileName(0, tr("Save Screen As"), saveas, template_string, &selectedFilter, options); if (outfile.isEmpty()) return; FILE *fp = fopen(outfile.toLatin1(), "wb"); fclose(fp); std::ofstream stream(outfile.toLatin1()); if (stream.fail()) { QMessageBox::warning(this, tr("Warning"), tr("Sorry, unable to open ") + outfile + tr(" for writing"), QMessageBox::Ok, QMessageBox::Ok); return; } QFilePath newpath(outfile); QString ext = newpath.m_ext.toLower(); if (ext == "svg") { OutputSVG(stream, &m_pDoc); } else { QMessageBox::StandardButton reply; reply = QMessageBox::question(this, "", "Would you like to include a scale?", QMessageBox::Yes | QMessageBox::No); bool includeScale = (reply == QMessageBox::Yes); // Set up complete... run the .eps outputter (copied from standard output!) OutputEPS(stream, &m_pDoc, includeScale); } stream.close(); } void QDepthmapView::closeEvent(QCloseEvent *event) { m_pDoc.m_view[QGraphDoc::VIEW_MAP] = NULL; if (!m_pDoc.OnCloseDocument(QGraphDoc::VIEW_MAP)) { m_pDoc.m_view[QGraphDoc::VIEW_MAP] = this; event->ignore(); } } static std::string SVGColor(PafColor color) { std::stringstream text; int r = color.redb(); int g = color.greenb(); int b = color.blueb(); text << std::setfill('0') << "#" << std::setw(2) << std::hex << r << std::setw(2) << std::hex << g << std::setw(2) << std::hex << b; return text.str(); } static QPoint SVGPhysicalUnits(const Point2f &p, const QtRegion &r, int h) { // converts to a 4800 unit wide QtRegion return QPoint(int(4800.0 * ((p.x - r.bottom_left.x) / r.width())), h - int(4800.0 * ((p.y - r.bottom_left.y) / r.width()))); } void QDepthmapView::OutputSVG(std::ofstream &stream, QGraphDoc *pDoc) { // This output SVG is a copy of the standard output... obviously, if you change // standard output, remember to change this one too! // also out of synch with EPS! // now the two are a little out of synch if (!m_viewport_set) { QMessageBox::warning(this, tr("Depthmap"), tr("Can't save screen as the Depthmap window is not initialised"), QMessageBox::Ok, QMessageBox::Ok); return; } QRect rect = QRect(0, 0, width(), height()); // we'll make this 24cm wide whatever, and base the height on it: int h = (4800 * rect.height()) / rect.width(); stream << "" << std::endl; stream << "" << std::endl; stream << "" << std::endl; stream << "" << TITLE_BASE << "" << std::endl; // note, SVG draw completely overrides standard draw physical units to achieve hi-res output // (EPS should probably follow this model too) QtRegion logicalviewport = LogicalViewport(rect, pDoc); stream << "" << std::endl; int state = pDoc->m_meta_graph->getState(); if (state & MetaGraph::POINTMAPS) { pDoc->m_meta_graph->getDisplayedPointMap().setScreenPixel(m_unit); // only used by points (at the moment!) pDoc->m_meta_graph->getDisplayedPointMap().makeViewportPoints(logicalviewport); } if (state & MetaGraph::SHAPEGRAPHS) { pDoc->m_meta_graph->getDisplayedShapeGraph().makeViewportShapes(logicalviewport); } if (state & MetaGraph::DATAMAPS) { pDoc->m_meta_graph->getDisplayedDataMap().makeViewportShapes(logicalviewport); } if (state & MetaGraph::LINEDATA) { pDoc->m_meta_graph->makeViewportShapes(logicalviewport); } if (state & MetaGraph::POINTMAPS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { PointMap &map = pDoc->m_meta_graph->getDisplayedPointMap(); double spacing = map.getSpacing(); double spacer = 4800.0 * (spacing / logicalviewport.width()) / 2.0; stream << "" << std::endl; stream << "" << std::endl; while (map.findNextPoint()) { Point2f logical = map.getNextPointLocation(); PafColor color = map.getCurrentPointColor(); if (color.alphab() != 0) { // alpha == 0 is transparent QPoint p = SVGPhysicalUnits(logical, logicalviewport, h); stream << "" << std::endl; } } stream << "" << std::endl; } if (state & MetaGraph::SHAPEGRAPHS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { ShapeMap &map = pDoc->m_meta_graph->getDisplayedShapeGraph(); OutputSVGMap(stream, map, logicalviewport, h); } if (state & MetaGraph::DATAMAPS && pDoc->m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { ShapeMap &map = pDoc->m_meta_graph->getDisplayedDataMap(); OutputSVGMap(stream, map, logicalviewport, h); } if (state & MetaGraph::LINEDATA) { // arbitrary stroke width for now stream << "" << std::endl; bool nextlayer = false; while (pDoc->m_meta_graph->findNextShape(nextlayer)) { const SalaShape &shape = pDoc->m_meta_graph->getNextShape(); Line l; if (shape.isPoint()) { } else if (shape.isLine()) { Line line = shape.getLine(); OutputSVGLine(stream, line, logicalviewport, h); } else { OutputSVGPoly(stream, shape, logicalviewport, h); } } stream << "" << std::endl; } stream << "" << std::endl; } void QDepthmapView::OutputSVGMap(std::ofstream &stream, ShapeMap &map, QtRegion &logicalviewport, int h) { bool monochrome = (map.getDisplayParams().colorscale == DisplayParams::MONOCHROME); // monochrome not implemented yet! if (monochrome) { QMessageBox::warning(this, tr("Depthmap"), tr("This map is displaying in monochrome, which is not yet supported. Please note your " "SVG file will be empty. Sorry for the inconvenience."), QMessageBox::Ok, QMessageBox::Ok); return; } // I haven't implemented all of these, but I hope I will get there: bool showlines, showfill, showcentroids; map.getPolygonDisplay(showlines, showfill, showcentroids); // arbitrary stroke width for now stream << "" << std::endl; PafColor color, oldcolor; bool closed, oldclosed; bool first = true; bool dummy; while (map.findNextShape(dummy)) { // note: getNextLine clears current line, so getLineColor before line color = map.getShapeColor(); const SalaShape &shape = map.getNextShape(); closed = shape.isClosed(); if (first || color != oldcolor || closed != oldclosed) { if (!first) { stream << "" << std::endl; } else { first = false; } if (closed) { if (showlines) { stream << "" << std::endl; } else { stream << "" << std::endl; } } else { stream << "" << std::endl; } oldcolor = color; oldclosed = closed; } Line l; if (shape.isPoint()) { } else if (shape.isLine()) { Line line = shape.getLine(); OutputSVGLine(stream, line, logicalviewport, h); } else { OutputSVGPoly(stream, shape, logicalviewport, h); } } if (!first) { stream << "" << std::endl; } stream << "" << std::endl; } void QDepthmapView::OutputSVGLine(std::ofstream &stream, Line &line, QtRegion &logicalviewport, int h) { bool drewit = false; if (line.crop(logicalviewport)) { QPoint start = SVGPhysicalUnits(line.start(), logicalviewport, h); QPoint end = SVGPhysicalUnits(line.end(), logicalviewport, h); // 2.0 is about 0.1mm in a standard SVG output size if (dist(Point2f(start.x(), start.y()), Point2f(end.x(), end.y())) >= 2.4f) { stream << "" << std::endl; } } } void QDepthmapView::OutputSVGPoly(std::ofstream &stream, const SalaShape &shape, QtRegion &logicalviewport, int h) { QPoint bl = SVGPhysicalUnits(shape.getBoundingBox().bottom_left, logicalviewport, h); QPoint tr = SVGPhysicalUnits(shape.getBoundingBox().top_right, logicalviewport, h); if (dist(Point2f(bl.x(), bl.y()), Point2f(tr.x(), tr.y())) < 2.0f) { // 2.0 is about 0.1mm in standard SVG output size -- if this is too small, we won't bother trying to draw it at // all return; } if (shape.isOpen()) { // open lines are fairly easy: simply chop lines as they enter and exit stream << "= 2.0f || iter == shape.m_points.end() - 1) { // also, always draw the very last point regardless of distance stream << end.x() << "," << end.y() << " "; drawn = true; } } else { starter = true; drawn = true; } if (drawn) { lastpoint = *iter; drawn = false; } } stream << "\" />" << std::endl; } else { // polygons are hard... have to work out entry and exit points to the clipping frame // and wind according to their direction stream << " eus = shape.getClippingSet(logicalviewport); if (eus.size() == 0) { // this should be a shape that is entirely within the viewport: QPoint last = SVGPhysicalUnits(shape.m_points[0], logicalviewport, h); stream << last.x() << "," << last.y() << " "; auto iter = shape.m_points.begin(); iter++; for (; iter != shape.m_points.end(); iter++) { QPoint next = SVGPhysicalUnits(*iter, logicalviewport, h); if (dist(Point2f(last.x(), last.y()), Point2f(next.x(), next.y())) >= 2.0f) { stream << next.x() << "," << next.y() << " "; last = next; } } } else if (eus.size() == 1) { // dummy: getClippingSet deliberately adds a single empty EdgeU if the polygon is completely outside the // frame (this can happen when a polygon wraps around the frame) } else if (eus.size() >= 2) { int entry = eus[0].entry ? 0 : 1; // this can get very messy (sometimes have to split into separate polys)... here's hoping for the best while (entry < (int)eus.size()) { int exit = int((entry + 1) % eus.size()); Point2f pt = logicalviewport.getEdgeUPoint(eus[entry]); QPoint last = SVGPhysicalUnits(pt, logicalviewport, h); QPoint next; stream << last.x() << "," << last.y() << " "; for (size_t i = eus[entry].index + 1; i != eus[exit].index; i++) { if (i >= shape.m_points.size()) { i = 0; } next = SVGPhysicalUnits(shape.m_points[i], logicalviewport, h); if (dist(Point2f(last.x(), last.y()), Point2f(next.x(), next.y())) >= 2.0f) { stream << next.x() << "," << next.y() << " "; last = next; } } pt = logicalviewport.getEdgeUPoint(eus[exit]); last = SVGPhysicalUnits(pt, logicalviewport, h); stream << last.x() << "," << last.y() << " "; bool breakup = false; if (entry + 2 < (int)eus.size() && ccwEdgeU(eus[entry], eus[entry + 1], eus[entry + 2]) != shape.isCCW()) { breakup = true; } EdgeU &nextentry = breakup ? eus[entry] : eus[(exit + 1) % eus.size()]; if (shape.isCCW()) { if (nextentry.edge != eus[exit].edge || nextentry.u < eus[exit].u) { int edge = eus[exit].edge; do { edge++; if (edge > 3) { edge = 0; } next = SVGPhysicalUnits(logicalviewport.getEdgeUPoint(EdgeU(edge, 0)), logicalviewport, h); stream << next.x() << "," << next.y() << " "; } while (edge != nextentry.edge); } } else { if (nextentry.edge != eus[exit].edge || nextentry.u > eus[exit].u) { int edge = eus[exit].edge; do { edge--; if (edge < 0) { edge = 3; } next = SVGPhysicalUnits(logicalviewport.getEdgeUPoint(EdgeU(edge, 1)), logicalviewport, h); stream << next.x() << "," << next.y() << " "; } while (edge != nextentry.edge); } } if (breakup) { // if (entry + 2 < eus.size() && ccwEdgeU(eus[entry],eus[entry+1],eus[entry+2]) != shape.isCCW()) { stream << "\" />" << std::endl; stream << "" << std::endl; } } void QDepthmapView::OnViewZoomToRegion(QtRegion regionToZoomAt) { m_centre = regionToZoomAt.getCentre(); QRect phys_bounds = this->rect(); m_unit = 1.0 * __max(regionToZoomAt.width() / double(phys_bounds.width()), regionToZoomAt.height() / double(phys_bounds.height())); } ================================================ FILE: depthmapX/views/depthmapview/depthmapview.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "depthmapX/views/mapview.h" #include #include #include #include #define MK_LBUTTON 0x0001 #define MK_RBUTTON 0x0002 #define MK_SHIFT 0x0004 #define MK_CONTROL 0x0008 #define MK_MBUTTON 0x0010 class QDepthmapView : public MapView { Q_OBJECT public: QDepthmapView(QGraphDoc &pDoc, Settings &settings, QWidget *parent = Q_NULLPTR); ~QDepthmapView(); QSize sizeHint() const override; void SetRedrawflag(); void saveToFile(); bool m_showgrid; bool m_showtext; bool m_showlinks; int m_current_mode; // Selectable mouse modes enum { NONE = 0x0000, SELECT = 0x10000, FILL = 0x0002, SEEDAXIAL = 0x0004, LINETOOL = 0x0008, POLYGONTOOL = 0x0010, ZOOMORDRAG = 0x0300, DRAG = 0x0101, ZOOM = 0x0200, ZOOM_IN = 0x0202, ZOOM_OUT = 0x0204, GENERICPENCIL = 0x0800, PENCIL = 0x0801, ERASE = 0x0802, SNAP = 0x1000, SNAPON = 0x1001, SNAPOFF = 0x1002, // snap modes are not used outside invalidate -- '1000' used to test snap DRAWLINE = 0x2000, LINEON = 0x2001, LINEOFF = 0x2002, GENERICISOVIST = 0x4000, SEEDISOVIST = 0x4001, SEEDHALFOVIST = 0x4002, OVERHANDLE = 0x8000, GENERICJOIN = 0x20000, JOINB = 0x00400, JOIN = 0x20001, UNJOIN = 0x20002 }; enum { FULLFILL = 0, SEMIFILL = 1, AUGMENT = 2 }; // AV TV virtual void OnModeJoin() override; virtual void OnModeUnjoin() override; virtual void OnModeSeedAxial() override; virtual void OnModeIsovist() override; virtual void OnModeTargetedIsovist() override; virtual void OnEditLineTool() override; virtual void OnEditPolygonTool() override; virtual void OnEditFill() override; virtual void OnEditSemiFill() override; virtual void OnEditAugmentFill() override; // AV TV virtual void OnViewZoomIn() override; virtual void OnViewZoomOut() override; virtual void OnViewPan() override; virtual void OnViewZoomsel() override; virtual void OnEditSelect() override; virtual void OnEditPencil() override; virtual void postLoadFile() override; virtual void OnEditCopy() override; virtual void OnEditSave() override; virtual void OnViewZoomToRegion(QtRegion regionToZoomAt) override; protected: virtual void timerEvent(QTimerEvent *event) override; virtual void paintEvent(QPaintEvent *event) override; virtual void resizeGL(int w, int h) override; virtual void mouseMoveEvent(QMouseEvent *event) override; virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseReleaseEvent(QMouseEvent *event) override; virtual void closeEvent(QCloseEvent *event) override; virtual void mouseDoubleClickEvent(QMouseEvent *e) override; virtual void wheelEvent(QWheelEvent *e) override; virtual bool eventFilter(QObject *object, QEvent *e) override; public slots: int OnRedraw(int wParam, int lParam); void OnEditEraser(); private: int m_mouse_mode; int Tid_redraw; QSize m_initialSize; //////////////////////////////////////////////////////////////////// QCursor m_cursor; QPoint m_mouse_point; Point2f m_mouse_location; int m_fillmode; QRect m_drag_rect_a; QRect m_drag_rect_b; QRgb m_selected_color; bool ModeOk(); // lots of screen drawing booleans... to be tidied up... bool m_drawing; bool m_continue_drawing; // int m_invalidate; // <- includes the mode bool m_queued_redraw; bool m_internal_redraw; bool m_clear; bool m_redraw; bool m_resize_viewport; bool m_viewport_set; bool m_redraw_all; bool m_redraw_no_clear; bool m_right_mouse_drag; bool m_alt_mode; // logical units: Point2f m_centre; double m_unit; // keep tabs on the screen size: QSize m_physical_centre; // record any previous find location loc: Point2f m_lastfindloc; // Snap to control (must be in map units for accuracy) Point2f m_snap_point; Point2f m_old_snap_point; QRgb m_cross_pixels[18]; bool m_snap; int m_repaint_tag; // Line start and end (must be in map units in case you zoom out / pan while you're drawing! Line m_line; Line m_old_line; std::vector m_line_pixels; std::vector m_point_handles; int m_active_point_handle; int m_currentlyEditingShapeRef = -1; // polygon drawing utilities Point2f m_poly_start; int m_poly_points; QRgb m_background; QRgb m_foreground; /////////////////////////////////////////////////////////////////////// Point2f LogicalUnits(const QPoint &p); QPoint PhysicalUnits(const Point2f &p); // hover information void ResetHoverWnd(const QPoint &p = QPoint(-1, -1)); void CreateHoverWnd(); bool IsAtZoomLimits(double ratio, double maxZoomOutRatio); void ZoomTowards(double ratio, const Point2f &point); void InitViewport(const QRect &phys_bounds, QGraphDoc *pDoc); QtRegion LogicalViewport(const QRect &phys_bounds, QGraphDoc *pDoc); int GetSpacer(QGraphDoc *pDoc); void PrintBaby(QPainter *pDC, QGraphDoc *pDoc); bool Output(QPainter *pDC, QGraphDoc *pDoc, bool screendraw); bool DrawPoints(QPainter *pDC, QGraphDoc *pDoc, int spacer, unsigned long ticks, bool screendraw); bool DrawAxial(QPainter *pDC, QGraphDoc *pDoc, int spacer, unsigned long ticks, bool screendraw); bool DrawShapes(QPainter *pDC, ShapeMap &map, bool muted, int spacer, unsigned long ticks, bool screendraw); void DrawLink(QPainter *pDC, int spacer, const Line &logical); void DrawPointHandle(QPainter *pDC, QPoint pt); // void OutputEPS(std::ofstream &stream, QGraphDoc *pDoc, bool includeScale = true); void OutputEPSMap(std::ofstream &stream, ShapeMap &map, QtRegion &logicalviewport, QRect &rect, float spacer); void OutputEPSLine(std::ofstream &stream, Line &line, int spacer, QtRegion &logicalviewport, QRect &rect); void OutputEPSPoly(std::ofstream &stream, const SalaShape &shape, int spacer, QtRegion &logicalviewport, QRect &rect); void OutputSVG(std::ofstream &stream, QGraphDoc *pDoc); void OutputSVGMap(std::ofstream &stream, ShapeMap &map, QtRegion &logicalviewport, int h); void OutputSVGLine(std::ofstream &stream, Line &line, QtRegion &logicalviewport, int h); void OutputSVGPoly(std::ofstream &stream, const SalaShape &shape, QtRegion &logicalviewport, int h); void FillLocation(QPainter *pDC, QPoint &p, int spacer, unsigned int blocked, QRgb color); void DrawLine(QPainter *pDC, QRect &line, bool drawit); void DrawCross(QPainter *pDC, QPoint ¢re, bool drawit); void SetCursor(int mode); void AltMode(); void BeginJoin(); void BeginDrag(QPoint point); QPixmap *m_pixmap; }; ================================================ FILE: depthmapX/views/glview/gldynamicline.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gldynamicline.h" /** * @brief GLDynamicLine::GLDynamicLine * This class is an OpenGL representation of a dynamic line. See GLDynamicRect * to understand the details of the implementation. This class only uses the * diagonal points of the GLDynamicRect to make a line */ GLDynamicLine::GLDynamicLine() { m_count = 0; m_program = 0; m_data.resize(2); add(0); add(3); } void GLDynamicLine::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel, const QMatrix2x2 &m_selectionBounds) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); m_program->setUniformValue(m_diagVertices2DLoc, m_selectionBounds); m_program->setUniformValue(m_colourVectorLoc, m_colour_stroke); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_LINE_LOOP, 0, vertexCount()); m_program->release(); } ================================================ FILE: depthmapX/views/glview/gldynamicline.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/views/glview/gldynamicrect.h" class GLDynamicLine : public GLDynamicRect { public: GLDynamicLine(); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel, const QMatrix2x2 &m_selectionBounds); }; ================================================ FILE: depthmapX/views/glview/gldynamicrect.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gldynamicrect.h" static const char *vertexShaderSourceCore = // auto-format hack "#version 150\n" "in float vertexIndex;\n" "int idxx;\n" "int idxy;\n" "uniform mat2 diagVertices2D;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " idxx = int(mod(vertexIndex,2.0));\n" " idxy = int(vertexIndex/2.0);\n" " gl_Position = projMatrix * mvMatrix * vec4(diagVertices2D[0][idxx],diagVertices2D[1][idxy],0,1);\n" "}\n"; static const char *fragmentShaderSourceCore = // auto-format hack "#version 150\n" "uniform vec4 colourVector;\n" "out highp vec4 fragColor;\n" "void main() {\n" " fragColor = colourVector;\n" "}\n"; static const char *vertexShaderSource = // auto-format hack "attribute float vertexIndex;\n" "int idxx;\n" "int idxy;\n" "uniform mat2 diagVertices2D;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " idxx = int(mod(vertexIndex,2.0));\n" " idxy = int(vertexIndex/2.0);\n" " gl_Position = projMatrix * mvMatrix * vec4(diagVertices2D[0][idxx],diagVertices2D[1][idxy],0,1);\n" "}\n"; static const char *fragmentShaderSource = // auto-format hack "uniform highp vec4 colourVector;\n" "void main() {\n" " gl_FragColor = colourVector;\n" "}\n"; /** * @brief GLDynamicRect::GLDynamicRect * This class is an OpenGL representation of a dynamic rectangle. The only attribute * sent to the shader is the index of 4 vertices, and the actual position of the * vertices is sent as a uniform 2x2 matrix (bottom-left-x, bottom-left-y, top-right-x, * top-right-y) */ GLDynamicRect::GLDynamicRect() : m_count(0), m_program(0) { m_count = 0; m_data.resize(4); add(0); add(1); add(3); add(2); } void GLDynamicRect::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glVertexAttribPointer(0, DATA_DIMENSIONS, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); m_vbo.release(); } void GLDynamicRect::initializeGL(bool m_core) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertexIndex", 0); m_program->link(); m_program->bind(); m_diagVertices2DLoc = m_program->uniformLocation("diagVertices2D"); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); m_colourVectorLoc = m_program->uniformLocation("colourVector"); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); setupVertexAttribs(); m_program->setUniformValue(m_colourVectorLoc, m_colour_fill); m_program->release(); m_built = true; } void GLDynamicRect::updateGL(bool m_core) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(m_core); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); } } void GLDynamicRect::setFillColour(const QRgb &fillColour) { m_colour_fill.setX(qRed(fillColour) / 255.0); m_colour_fill.setY(qGreen(fillColour) / 255.0); m_colour_fill.setZ(qBlue(fillColour) / 255.0); } void GLDynamicRect::setStrokeColour(const QRgb &strokeColour) { m_colour_stroke.setX(qRed(strokeColour) / 255.0); m_colour_stroke.setY(qGreen(strokeColour) / 255.0); m_colour_stroke.setZ(qBlue(strokeColour) / 255.0); } void GLDynamicRect::cleanup() { m_vbo.destroy(); delete m_program; m_program = 0; } void GLDynamicRect::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel, const QMatrix2x2 &m_selectionBounds) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); m_program->setUniformValue(m_diagVertices2DLoc, m_selectionBounds); m_program->setUniformValue(m_colourVectorLoc, m_colour_fill); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount()); m_program->setUniformValue(m_colourVectorLoc, m_colour_stroke); glFuncs->glDrawArrays(GL_LINE_LOOP, 0, vertexCount()); m_program->release(); } void GLDynamicRect::add(const GLfloat v) { GLfloat *p = m_data.data() + m_count; *p++ = v; m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/gldynamicrect.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include #include #include #include #include #include class GLDynamicRect { public: GLDynamicRect(); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel, const QMatrix2x2 &m_selectionBounds); void initializeGL(bool m_core); void updateGL(bool m_core); void cleanup(); void setFillColour(const QRgb &fillColour); void setStrokeColour(const QRgb &strokeColour); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLDynamicRect(const GLDynamicRect &) = delete; GLDynamicRect &operator=(const GLDynamicRect &) = delete; protected: void add(const GLfloat v); int m_count; bool m_built = false; QVector m_data; QOpenGLBuffer m_vbo; QOpenGLVertexArrayObject m_vao; QOpenGLShaderProgram *m_program; int m_diagVertices2DLoc; int m_projMatrixLoc; int m_mvMatrixLoc; int m_colourVectorLoc; QVector4D m_colour_fill = QVector4D(0.0f, 1.0f, 0.0f, 0.3f); QVector4D m_colour_stroke = QVector4D(1.0f, 1.0f, 1.0f, 1.0f); private: const int DATA_DIMENSIONS = 1; void setupVertexAttribs(); int count() const { return m_count; } const GLfloat *constData() const { return m_data.constData(); } }; ================================================ FILE: depthmapX/views/glview/gllines.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gllines.h" #include #include static const char *vertexShaderSourceCore = // "#version 150\n" "in vec4 vertex;\n" "in vec3 colour;\n" "out vec3 col;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " col = colour.xyz;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSourceCore = // "#version 150\n" "in vec3 col;\n" "out highp vec3 fragColor;\n" "void main() {\n" " fragColor = col;\n" "}\n"; static const char *vertexShaderSource = // "attribute vec4 vertex;\n" "attribute vec3 colour;\n" "varying vec3 col;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " col = colour.xyz;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSource = // "varying highp vec3 col;\n" "void main() {\n" " gl_FragColor = vec4(col, 1.0);\n" "}\n"; /** * @brief GLLines::GLLines * This class is an OpenGL representation of multiple lines of uniform colour */ GLLines::GLLines() : m_count(0), m_program(0) {} void GLLines::loadLineData(const std::vector> &colouredLines) { m_built = false; m_count = 0; m_data.resize(colouredLines.size() * 2 * DATA_DIMENSIONS); for (auto &colouredLine : colouredLines) { const SimpleLine &line = colouredLine.first; const PafColor &colour = colouredLine.second; QVector3D colourVector(colour.redf(), colour.greenf(), colour.bluef()); add(QVector3D(line.start().x, line.start().y, 0.0f), colourVector); add(QVector3D(line.end().x, line.end().y, 0.0f), colourVector); } } void GLLines::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), reinterpret_cast(3 * sizeof(GLfloat))); m_vbo.release(); } void GLLines::initializeGL(bool coreProfile) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, coreProfile ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, coreProfile ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("colour", 1); m_program->link(); m_program->bind(); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); // Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x // implementations this is optional and support may not be present // at all. Nonetheless the below code works in all cases and makes // sure there is a VAO when one is needed. m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // Setup our vertex buffer object. m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); // Store the vertex attribute bindings for the program. setupVertexAttribs(); m_program->release(); m_built = true; } void GLLines::updateGL(bool coreProfile) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(coreProfile); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); m_built = true; } } void GLLines::cleanup() { if (!m_built) return; m_vbo.destroy(); delete m_program; m_program = 0; } void GLLines::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_LINES, 0, vertexCount()); m_program->release(); } void GLLines::add(const QVector3D &v, const QVector3D &c) { GLfloat *p = m_data.data() + m_count; *p++ = v.x(); *p++ = v.y(); *p++ = v.z(); *p++ = c.x(); *p++ = c.y(); *p++ = c.z(); m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/gllines.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include "salalib/pafcolor.h" #include #include #include #include #include #include #include #include class GLLines { friend class testgllines; public: GLLines(); void loadLineData(const std::vector> &colouredLines); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel); void initializeGL(bool coreProfile); void updateGL(bool coreProfile); void cleanup(); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLLines(const GLLines &) = delete; GLLines &operator=(const GLLines &) = delete; private: const int DATA_DIMENSIONS = 6; void setupVertexAttribs(); const GLfloat *constData() const { return m_data.constData(); } void add(const QVector3D &v, const QVector3D &c); QVector m_data; int m_count; bool m_built = false; QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; QOpenGLShaderProgram *m_program; int m_projMatrixLoc; int m_mvMatrixLoc; }; ================================================ FILE: depthmapX/views/glview/gllinesuniform.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gllinesuniform.h" #include static const char *vertexShaderSourceCore = // auto-format hack "#version 150\n" "in vec4 vertex;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSourceCore = // auto-format hack "#version 150\n" "uniform vec4 colourVector;\n" "out highp vec4 fragColor;\n" "void main() {\n" " fragColor = colourVector;\n" "}\n"; static const char *vertexShaderSource = // auto-format hack "attribute vec4 vertex;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSource = // auto-format hack "uniform highp vec4 colourVector;\n" "void main() {\n" " gl_FragColor = colourVector;\n" "}\n"; /** * @brief GLLinesUniform::GLLinesUniform * This class is an OpenGL representation of multiple lines of uniform colour */ GLLinesUniform::GLLinesUniform() : m_count(0), m_program(0) {} void GLLinesUniform::loadLineData(const std::vector &lines, const QRgb &lineColour) { m_built = false; m_count = 0; m_data.resize(lines.size() * 2 * DATA_DIMENSIONS); for (auto &line : lines) { add(QVector3D(line.start().x, line.start().y, 0.0f)); add(QVector3D(line.end().x, line.end().y, 0.0f)); } m_colour.setX(qRed(lineColour) / 255.0f); m_colour.setY(qGreen(lineColour) / 255.0f); m_colour.setZ(qBlue(lineColour) / 255.0f); m_colour.setW(qAlpha(lineColour) / 255.0f); } void GLLinesUniform::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); m_vbo.release(); } void GLLinesUniform::initializeGL(bool coreProfile) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, coreProfile ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, coreProfile ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertex", 0); m_program->link(); m_program->bind(); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); m_colourVectorLoc = m_program->uniformLocation("colourVector"); // Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x // implementations this is optional and support may not be present // at all. Nonetheless the below code works in all cases and makes // sure there is a VAO when one is needed. m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // Setup our vertex buffer object. m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); // Store the vertex attribute bindings for the program. setupVertexAttribs(); m_program->setUniformValue(m_colourVectorLoc, m_colour); m_program->release(); m_built = true; } void GLLinesUniform::updateGL(bool coreProfile) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(coreProfile); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); m_built = true; } } void GLLinesUniform::updateColour(const QRgb &lineColour) { m_colour.setX(qRed(lineColour) / 255.0f); m_colour.setY(qGreen(lineColour) / 255.0f); m_colour.setZ(qBlue(lineColour) / 255.0f); m_program->bind(); m_program->setUniformValue(m_colourVectorLoc, m_colour); m_program->release(); } void GLLinesUniform::cleanup() { if (!m_built) return; m_vbo.destroy(); delete m_program; m_program = 0; } void GLLinesUniform::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_LINES, 0, vertexCount()); m_program->release(); } void GLLinesUniform::add(const QVector3D &v) { GLfloat *p = m_data.data() + m_count; *p++ = v.x(); *p++ = v.y(); *p++ = v.z(); m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/gllinesuniform.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include #include #include #include #include #include #include #include class GLLinesUniform { public: GLLinesUniform(); void loadLineData(const std::vector &lines, const QRgb &lineColour); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel); void initializeGL(bool coreProfile); void updateGL(bool coreProfile); void cleanup(); void updateColour(const QRgb &lineColour); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLLinesUniform(const GLLinesUniform &) = delete; GLLinesUniform &operator=(const GLLinesUniform &) = delete; private: const int DATA_DIMENSIONS = 3; void setupVertexAttribs(); const GLfloat *constData() const { return m_data.constData(); } void add(const QVector3D &v); QVector m_data; int m_count; bool m_built = false; QVector4D m_colour = QVector4D(1.0f, 1.0f, 1.0f, 1.0f); QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; QOpenGLShaderProgram *m_program; int m_projMatrixLoc; int m_mvMatrixLoc; int m_colourVectorLoc; }; ================================================ FILE: depthmapX/views/glview/glpointmap.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glpointmap.h" #include "salalib/geometrygenerators.h" #include "salalib/linkutils.h" void GLPointMap::loadGLObjects(PointMap &pointMap) { QtRegion region = pointMap.getRegion(); m_pointMap.loadRegionData(region.bottom_left.x, region.bottom_left.y, region.top_right.x, region.top_right.y); if (m_showGrid) { std::vector gridData; double spacing = pointMap.getSpacing(); double offsetX = region.bottom_left.x; double offsetY = region.bottom_left.y; for (int x = 1; x < pointMap.getCols(); x++) { gridData.push_back( SimpleLine(offsetX + x * spacing, region.bottom_left.y, offsetX + x * spacing, region.top_right.y)); } for (int y = 1; y < pointMap.getRows(); y++) { gridData.push_back( SimpleLine(region.bottom_left.x, offsetY + y * spacing, region.top_right.x, offsetY + y * spacing)); } m_grid.loadLineData(gridData, m_gridColour); } if (m_showLinks) { const std::vector &mergedPixelLines = depthmapX::getMergedPixelsAsLines(pointMap); std::vector mergedPixelLocations; for (auto &mergeLine : mergedPixelLines) { mergedPixelLocations.push_back(mergeLine.start()); mergedPixelLocations.push_back(mergeLine.end()); } const std::vector &linkFillTriangles = GeometryGenerators::generateMultipleDiskTriangles(32, pointMap.getSpacing() * 0.25, mergedPixelLocations); m_linkFills.loadTriangleData(linkFillTriangles, qRgb(0, 0, 0)); std::vector linkFillPerimeters = GeometryGenerators::generateMultipleCircleLines(32, pointMap.getSpacing() * 0.25, mergedPixelLocations); linkFillPerimeters.insert(linkFillPerimeters.end(), mergedPixelLines.begin(), mergedPixelLines.end()); m_linkLines.loadLineData(linkFillPerimeters, qRgb(0, 255, 0)); } } void GLPointMap::loadGLObjectsRequiringGLContext(const PointMap ¤tPointMap) { QImage data(currentPointMap.getCols(), currentPointMap.getRows(), QImage::Format_RGBA8888); data.fill(Qt::transparent); for (int y = 0; y < currentPointMap.getRows(); y++) { for (int x = 0; x < currentPointMap.getCols(); x++) { PixelRef pix(x, y); PafColor colour = currentPointMap.getPointColor(pix); if (colour.alphab() != 0) { // alpha == 0 is transparent data.setPixelColor(x, y, qRgb(colour.redb(), colour.greenb(), colour.blueb())); } } } m_pointMap.loadPixelData(data); } ================================================ FILE: depthmapX/views/glview/glpointmap.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/views/glview/gllinesuniform.h" #include "depthmapX/views/glview/glrastertexture.h" #include "depthmapX/views/glview/gltrianglesuniform.h" #include "salalib/mgraph.h" class GLPointMap { public: void initializeGL(bool m_core) { m_grid.initializeGL(m_core); m_pointMap.initializeGL(m_core); m_linkLines.initializeGL(m_core); m_linkFills.initializeGL(m_core); } void updateGL(bool m_core) { m_pointMap.updateGL(m_core); m_grid.updateGL(m_core); m_linkLines.updateGL(m_core); m_linkFills.updateGL(m_core); } void cleanup() { m_grid.cleanup(); m_pointMap.cleanup(); m_linkLines.cleanup(); m_linkFills.cleanup(); } void paintGLOverlay(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (m_showLinks) { QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glLineWidth(3); m_linkLines.paintGL(m_mProj, m_mView, m_mModel); m_linkFills.paintGL(m_mProj, m_mView, m_mModel); glFuncs->glLineWidth(1); } } void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { m_pointMap.paintGL(m_mProj, m_mView, m_mModel); if (m_showGrid) m_grid.paintGL(m_mProj, m_mView, m_mModel); } void setGridColour(QRgb gridColour) { m_gridColour = gridColour; } void showLinks(bool showLinks) { m_showLinks = showLinks; } void showGrid(bool showGrid) { m_showGrid = showGrid; } void loadGLObjects(PointMap &pointMap); void loadGLObjectsRequiringGLContext(const PointMap ¤tPointMap); private: GLLinesUniform m_grid; GLRasterTexture m_pointMap; GLLinesUniform m_linkLines; GLTrianglesUniform m_linkFills; QRgb m_gridColour = (qRgb(255, 255, 255) & 0x006f6f6f) | (qRgb(0, 0, 0) & 0x00a0a0a0); bool m_showGrid = true; bool m_showLinks = false; }; ================================================ FILE: depthmapX/views/glview/glpolygons.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glpolygons.h" #include "glutriangulator.h" /** * @brief GLPolygons::GLPolygons * This class is an OpenGL representation of multiple polygons of different colour */ void GLPolygons::loadPolygonData(const std::vector, PafColor>> &colouredPolygons) { m_polygons.clear(); for (auto &colouredPolygon : colouredPolygons) { const std::vector &points = colouredPolygon.first; QRgb colour = qRgb(colouredPolygon.second.redb(), colouredPolygon.second.greenb(), colouredPolygon.second.blueb()); m_polygons.push_back(std::unique_ptr(new GLTrianglesUniform)); std::vector triangulated = GLUTriangulator::triangulate(points); m_polygons.back()->loadTriangleData(triangulated, colour); } } void GLPolygons::initializeGL(bool m_core) { for (auto &polygon : m_polygons) { polygon->initializeGL(m_core); } } void GLPolygons::updateGL(bool m_core) { for (auto &polygon : m_polygons) { polygon->updateGL(m_core); } } void GLPolygons::cleanup() { for (auto &polygon : m_polygons) { polygon->cleanup(); } } void GLPolygons::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { for (auto &polygon : m_polygons) { polygon->paintGL(m_mProj, m_mView, m_mModel); } } ================================================ FILE: depthmapX/views/glview/glpolygons.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/pafcolor.h" #include "depthmapX/views/glview/gltrianglesuniform.h" #include "genlib/p2dpoly.h" #include #include #include #include #include #include #include #include /** * @brief The GLPolygons class is a plain wrapper class for multiple GLPolygon * that acts as if it's a single globject */ class GLPolygons { public: void loadPolygonData(const std::vector, PafColor>> &colouredPolygons); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel); void initializeGL(bool m_core); void updateGL(bool m_core); void cleanup(); private: std::vector> m_polygons; }; ================================================ FILE: depthmapX/views/glview/glrastertexture.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glrastertexture.h" #include #include static const char *vertexShaderSourceCore = // auto-format hack "#version 150\n" "in vec4 vertex;\n" "in vec4 texCoord;\n" "out vec4 texc;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" " texc = texCoord;\n" "}\n"; static const char *fragmentShaderSourceCore = // auto-format hack "#version 150\n" "uniform sampler2D texture;\n" "in mediump vec4 texc;\n" "void main(void)\n" "{\n" " gl_FragColor = texture2D(texture, texc.st);\n" "}\n"; static const char *vertexShaderSource = // auto-format hack "attribute highp vec4 vertex;\n" "attribute mediump vec4 texCoord;\n" "varying mediump vec4 texc;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main(void)\n" "{\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" " texc = texCoord;\n" "}\n"; static const char *fragmentShaderSource = // auto-format hack "uniform sampler2D texture;\n" "varying mediump vec4 texc;\n" "void main(void)\n" "{\n" " gl_FragColor = texture2D(texture, texc.st);\n" "}\n"; GLRasterTexture::GLRasterTexture() : m_count(0), m_program(0), m_texture(QOpenGLTexture::Target2D) {} void GLRasterTexture::loadRegionData(float minX, float minY, float maxX, float maxY) { m_built = false; m_count = 0; m_data.resize(4 * DATA_DIMENSIONS); add(QVector3D(minX, minY, 0), QVector2D(0, 0)); add(QVector3D(maxX, minY, 0), QVector2D(1, 0)); add(QVector3D(maxX, maxY, 0), QVector2D(1, 1)); add(QVector3D(minX, maxY, 0), QVector2D(0, 1)); } void GLRasterTexture::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), reinterpret_cast(3 * sizeof(GLfloat))); m_vbo.release(); } void GLRasterTexture::initializeGL(bool coreProfile) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, coreProfile ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, coreProfile ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("texCoord", 1); m_program->link(); m_program->bind(); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); m_textureSamplerLoc = m_program->uniformLocation("texture"); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // Setup our vertex buffer object. m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); // Store the vertex attribute bindings for the program. setupVertexAttribs(); m_program->setUniformValue(m_textureSamplerLoc, 0); m_program->release(); m_built = true; } void GLRasterTexture::updateGL(bool coreProfile) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(coreProfile); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); m_built = true; } } void GLRasterTexture::loadPixelData(QImage &data) { if (!m_built) return; m_program->bind(); if (m_texture.isCreated()) { m_texture.destroy(); } m_texture.setData(data); m_program->release(); } void GLRasterTexture::cleanup() { if (!m_built) return; m_vbo.destroy(); m_texture.destroy(); delete m_program; m_program = 0; } void GLRasterTexture::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); m_texture.bind(); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFuncs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glFuncs->glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount()); m_program->release(); } void GLRasterTexture::add(const QVector3D &v, const QVector2D &tc) { GLfloat *p = m_data.data() + m_count; *p++ = v.x(); *p++ = v.y(); *p++ = v.z(); *p++ = tc.x(); *p++ = tc.y(); m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/glrastertexture.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include #include #include #include #include class GLRasterTexture { public: GLRasterTexture(); void loadRegionData(float minX, float minY, float maxX, float maxY); void loadPixelData(QImage &data); void paintGL(const QMatrix4x4 &m_proj, const QMatrix4x4 &m_camera, const QMatrix4x4 &m_mModel); void initializeGL(bool coreProfile); void updateGL(bool coreProfile); void cleanup(); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLRasterTexture(const GLRasterTexture &) = delete; GLRasterTexture &operator=(const GLRasterTexture &) = delete; private: int DATA_DIMENSIONS = 5; void setupVertexAttribs(); const GLfloat *constData() const { return m_data.constData(); } void add(const QVector3D &v, const QVector2D &tc); QVector m_data; int m_count; bool m_built = false; QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; QOpenGLShaderProgram *m_program; int m_projMatrixLoc; int m_mvMatrixLoc; int m_textureSamplerLoc; QOpenGLTexture m_texture; }; ================================================ FILE: depthmapX/views/glview/glregularpolygons.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glregularpolygons.h" #include void GLRegularPolygons::loadPolygonData(const std::vector> &colouredPoints, const int sides, const float radius) { init(colouredPoints.size() * sides * 3); std::vector points(sides * 3); float angle = 2 * M_PI / sides; for (int i = 0; i < sides; i++) { points[i * 3] = Point2f(cos((i)*angle) * radius, sin((i)*angle) * radius); points[i * 3 + 1] = Point2f(cos((i + 1) * angle) * radius, sin((i + 1) * angle) * radius); points[i * 3 + 2] = Point2f(0, 0); } Point2f prevCentre(0, 0); for (const auto &colouredPoint : colouredPoints) { const Point2f ¢re = colouredPoint.first; float r = colouredPoint.second.redf(); float g = colouredPoint.second.greenf(); float b = colouredPoint.second.bluef(); for (Point2f &point : points) { point.x -= prevCentre.x; point.y -= prevCentre.y; point.x += centre.x; point.y += centre.y; add(QVector3D(point.x, point.y, 0.0f), QVector3D(r, g, b)); } prevCentre = centre; } } ================================================ FILE: depthmapX/views/glview/glregularpolygons.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/pafcolor.h" #include "depthmapX/views/glview/gltriangles.h" #include "genlib/p2dpoly.h" #include #include #include #include #include #include #include #include /** * @brief Meant to represent regular polygons i.e. those that are equiangular (all angles are equal in measure) and * equilateral (all sides have the same length). Ideal for representing sets of disks/stars/squares etc. */ class GLRegularPolygons : public GLTriangles { public: void loadPolygonData(const std::vector> &colouredPoints, const int sides, const float radius); }; ================================================ FILE: depthmapX/views/glview/glshapegraph.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glshapegraph.h" #include "salalib/geometrygenerators.h" void GLShapeGraph::loadGLObjects(ShapeGraph &shapeGraph) { m_shapeMap.loadGLObjects(shapeGraph); const std::vector &linkLines = shapeGraph.getAllLinkLines(); std::vector linkPointLocations; for (auto &linkLine : linkLines) { linkPointLocations.push_back(linkLine.start()); linkPointLocations.push_back(linkLine.end()); } const std::vector &linkFillTriangles = GeometryGenerators::generateMultipleDiskTriangles(32, shapeGraph.getSpacing() * 0.1, linkPointLocations); m_linkFills.loadTriangleData(linkFillTriangles, qRgb(0, 0, 0)); std::vector linkFillPerimeters = GeometryGenerators::generateMultipleCircleLines(32, shapeGraph.getSpacing() * 0.1, linkPointLocations); linkFillPerimeters.insert(linkFillPerimeters.end(), linkLines.begin(), linkLines.end()); m_linkLines.loadLineData(linkFillPerimeters, qRgb(0, 255, 0)); const std::vector &unlinkPoints = shapeGraph.getAllUnlinkPoints(); const std::vector &unlinkFillTriangles = GeometryGenerators::generateMultipleDiskTriangles(32, shapeGraph.getSpacing() * 0.1, unlinkPoints); m_unlinkFills.loadTriangleData(unlinkFillTriangles, qRgb(255, 255, 255)); const std::vector &unlinkFillPerimeters = GeometryGenerators::generateMultipleCircleLines(32, shapeGraph.getSpacing() * 0.1, unlinkPoints); m_unlinkLines.loadLineData(unlinkFillPerimeters, qRgb(255, 0, 0)); } ================================================ FILE: depthmapX/views/glview/glshapegraph.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/views/glview/gllinesuniform.h" #include "depthmapX/views/glview/glshapemap.h" #include "salalib/mgraph.h" class GLShapeGraph { public: void initializeGL(bool m_core) { m_shapeMap.initializeGL(m_core); m_linkLines.initializeGL(m_core); m_linkFills.initializeGL(m_core); m_unlinkFills.initializeGL(m_core); m_unlinkLines.initializeGL(m_core); } void updateGL(bool m_core) { m_shapeMap.updateGL(m_core); m_linkLines.updateGL(m_core); m_linkFills.updateGL(m_core); m_unlinkFills.updateGL(m_core); m_unlinkLines.updateGL(m_core); } void cleanup() { m_shapeMap.cleanup(); m_linkLines.cleanup(); m_linkFills.cleanup(); m_unlinkFills.cleanup(); m_unlinkLines.cleanup(); } void paintGLOverlay(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (m_showLinks) { QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glLineWidth(3); m_linkLines.paintGL(m_mProj, m_mView, m_mModel); m_linkFills.paintGL(m_mProj, m_mView, m_mModel); m_unlinkLines.paintGL(m_mProj, m_mView, m_mModel); m_unlinkFills.paintGL(m_mProj, m_mView, m_mModel); glFuncs->glLineWidth(1); } } void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { m_shapeMap.paintGL(m_mProj, m_mView, m_mModel); } void showLinks(bool showLinks) { m_showLinks = showLinks; } void loadGLObjects(ShapeGraph &shapeGraph); private: GLShapeMap m_shapeMap; GLLinesUniform m_linkLines; GLTrianglesUniform m_linkFills; GLLinesUniform m_unlinkLines; GLTrianglesUniform m_unlinkFills; bool m_showLinks = false; }; ================================================ FILE: depthmapX/views/glview/glshapemap.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glshapemap.h" void GLShapeMap::loadGLObjects(const std::vector> &colouredLines, const std::vector, PafColor>> &colouredPolygons, const std::vector> &colouredPoints, const int pointSides, const float pointRadius) { m_lines.loadLineData(colouredLines); m_polygons.loadPolygonData(colouredPolygons); m_points.loadPolygonData(colouredPoints, pointSides, pointRadius); } void GLShapeMap::loadGLObjects(ShapeMap &shapeMap) { loadGLObjects(shapeMap.getAllLinesWithColour(), shapeMap.getAllPolygonsWithColour(), shapeMap.getAllPointsWithColour(), 8, shapeMap.getSpacing() * 0.1); } ================================================ FILE: depthmapX/views/glview/glshapemap.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/views/glview/gllines.h" #include "depthmapX/views/glview/glpolygons.h" #include "depthmapX/views/glview/glregularpolygons.h" #include "salalib/mgraph.h" class GLShapeMap { public: void initializeGL(bool m_core) { m_lines.initializeGL(m_core); m_polygons.initializeGL(m_core); m_points.initializeGL(m_core); } void updateGL(bool m_core) { m_lines.updateGL(m_core); m_polygons.updateGL(m_core); m_points.updateGL(m_core); } void cleanup() { m_lines.cleanup(); m_polygons.cleanup(); m_points.cleanup(); } void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { m_lines.paintGL(m_mProj, m_mView, m_mModel); m_polygons.paintGL(m_mProj, m_mView, m_mModel); m_points.paintGL(m_mProj, m_mView, m_mModel); } void loadGLObjects(const std::vector> &colouredLines, const std::vector, PafColor>> &colouredPolygons, const std::vector> &colouredPoints, const int pointSides, const float pointRadius); void loadGLObjects(ShapeMap &shapeMap); private: GLLines m_lines; GLPolygons m_polygons; GLRegularPolygons m_points; }; ================================================ FILE: depthmapX/views/glview/gltriangles.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gltriangles.h" #include // clang-format off static const char *vertexShaderSourceCore = // auto-format hack "#version 150\n" "in vec4 vertex;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSourceCore = // auto-format hack "#version 150\n" "in vec4 colour;\n" "out highp vec4 fragColor;\n" "void main() {\n" " fragColor = colour;\n" "}\n"; static const char *vertexShaderSource = // auto-format hack "attribute vec4 vertex;\n" "attribute vec4 colour;\n" "varying vec4 fragColour;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" " fragColour = colour;\n" "}\n"; static const char *fragmentShaderSource = // auto-format hack "varying highp vec4 fragColour;\n" "void main() {\n" " gl_FragColor = fragColour;\n" "}\n"; // clang-format on void GLTriangles::loadTriangleData(const std::vector, QRgb>> &triangleData) { init(triangleData.size()); for (auto &triangle : triangleData) { float r = qRed(triangle.second) / 255.0; float g = qGreen(triangle.second) / 255.0; float b = qBlue(triangle.second) / 255.0; for (auto &point : triangle.first) { add(QVector3D(point.x, point.y, 0.0f), QVector3D(r, g, b)); } } } void GLTriangles::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); m_vbo.release(); } void GLTriangles::initializeGL(bool m_core) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("colour", 1); m_program->link(); m_program->bind(); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); setupVertexAttribs(); m_program->release(); m_built = true; } void GLTriangles::updateGL(bool m_core) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(m_core); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); m_built = true; } } void GLTriangles::cleanup() { if (!m_built) return; m_vbo.destroy(); delete m_program; m_program = 0; } void GLTriangles::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_TRIANGLES, 0, vertexCount()); m_program->release(); } void GLTriangles::add(const QVector3D &v, const QVector3D &c) { GLfloat *p = m_data.data() + m_count; *p++ = v.x(); *p++ = v.y(); *p++ = v.z(); *p++ = c.x(); *p++ = c.y(); *p++ = c.z(); m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/gltriangles.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include #include #include #include #include #include #include #include /** * @brief General triangles representation. Each triangle may have its own colour */ class GLTriangles { public: GLTriangles() : m_count(0), m_program(0) {} void loadTriangleData(const std::vector, QRgb>> &triangleData); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel); void initializeGL(bool m_core); void updateGL(bool m_core); void cleanup(); void updateColour(const QRgb &polyColour); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLTriangles(const GLTriangles &) = delete; GLTriangles &operator=(const GLTriangles &) = delete; protected: void init(int numTriangles) { m_built = false; m_count = 0; m_data.resize(numTriangles * 3 * DATA_DIMENSIONS); } void add(const QVector3D &v, const QVector3D &c); private: const int DATA_DIMENSIONS = 6; void setupVertexAttribs(); const GLfloat *constData() const { return m_data.constData(); } QVector m_data; int m_count; bool m_built = false; QVector4D m_colour = QVector4D(1.0f, 1.0f, 1.0f, 1.0f); QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; QOpenGLShaderProgram *m_program; int m_projMatrixLoc; int m_mvMatrixLoc; }; ================================================ FILE: depthmapX/views/glview/gltrianglesuniform.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "gltrianglesuniform.h" #include static const char *vertexShaderSourceCore = // auto-format hack "#version 150\n" "in vec4 vertex;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSourceCore = // auto-format hack "#version 150\n" "uniform vec4 colourVector;\n" "out highp vec4 fragColor;\n" "void main() {\n" " fragColor = colourVector;\n" "}\n"; static const char *vertexShaderSource = // auto-format hack "attribute vec4 vertex;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "void main() {\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n"; static const char *fragmentShaderSource = // auto-format hack "uniform highp vec4 colourVector;\n" "void main() {\n" " gl_FragColor = colourVector;\n" "}\n"; /** * @brief GLTrianglesUniform::GLTrianglesUniform * This class is an OpenGL representation of a set of triangles of uniform colour */ GLTrianglesUniform::GLTrianglesUniform() : m_count(0), m_program(0) {} void GLTrianglesUniform::loadTriangleData(const std::vector &points, const QRgb &polyColour) { m_built = false; m_count = 0; m_data.resize(points.size() * DATA_DIMENSIONS); for (auto &point : points) { add(QVector3D(point.x, point.y, 0.0f)); } m_colour.setX(qRed(polyColour) / 255.0); m_colour.setY(qGreen(polyColour) / 255.0); m_colour.setZ(qBlue(polyColour) / 255.0); } void GLTrianglesUniform::setupVertexAttribs() { m_vbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, DATA_DIMENSIONS * sizeof(GLfloat), 0); m_vbo.release(); } void GLTrianglesUniform::initializeGL(bool m_core) { if (m_data.size() == 0) return; m_program = new QOpenGLShaderProgram; m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource); m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource); m_program->bindAttributeLocation("vertex", 0); m_program->link(); m_program->bind(); m_projMatrixLoc = m_program->uniformLocation("projMatrix"); m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); m_colourVectorLoc = m_program->uniformLocation("colourVector"); m_vao.create(); QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_vbo.create(); m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); setupVertexAttribs(); m_program->setUniformValue(m_colourVectorLoc, m_colour); m_program->release(); m_built = true; } void GLTrianglesUniform::updateGL(bool m_core) { if (m_program == 0) { // has not been initialised yet, do that instead initializeGL(m_core); } else { m_vbo.bind(); m_vbo.allocate(constData(), m_count * sizeof(GLfloat)); m_vbo.release(); m_built = true; } } void GLTrianglesUniform::updateColour(const QRgb &polyColour) { m_colour.setX(qRed(polyColour) / 255.0); m_colour.setY(qGreen(polyColour) / 255.0); m_colour.setZ(qBlue(polyColour) / 255.0); m_program->bind(); m_program->setUniformValue(m_colourVectorLoc, m_colour); m_program->release(); } void GLTrianglesUniform::cleanup() { if (!m_built) return; m_vbo.destroy(); delete m_program; m_program = 0; } void GLTrianglesUniform::paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel) { if (!m_built) return; QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); m_program->bind(); m_program->setUniformValue(m_projMatrixLoc, m_mProj); m_program->setUniformValue(m_mvMatrixLoc, m_mView * m_mModel); QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); glFuncs->glDrawArrays(GL_TRIANGLES, 0, vertexCount()); m_program->release(); } void GLTrianglesUniform::add(const QVector3D &v) { GLfloat *p = m_data.data() + m_count; *p++ = v.x(); *p++ = v.y(); *p++ = v.z(); m_count += DATA_DIMENSIONS; } ================================================ FILE: depthmapX/views/glview/gltrianglesuniform.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include #include #include #include #include #include #include #include /** * @brief General triangles representation. All same colour */ class GLTrianglesUniform { public: GLTrianglesUniform(); void loadTriangleData(const std::vector &points, const QRgb &polyColour); void paintGL(const QMatrix4x4 &m_mProj, const QMatrix4x4 &m_mView, const QMatrix4x4 &m_mModel); void initializeGL(bool m_core); void updateGL(bool m_core); void cleanup(); void updateColour(const QRgb &polyColour); int vertexCount() const { return m_count / DATA_DIMENSIONS; } GLTrianglesUniform(const GLTrianglesUniform &) = delete; GLTrianglesUniform &operator=(const GLTrianglesUniform &) = delete; private: const int DATA_DIMENSIONS = 3; void setupVertexAttribs(); const GLfloat *constData() const { return m_data.constData(); } void add(const QVector3D &v); QVector m_data; int m_count; bool m_built = false; QVector4D m_colour = QVector4D(1.0f, 1.0f, 1.0f, 1.0f); QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; QOpenGLShaderProgram *m_program; int m_projMatrixLoc; int m_mvMatrixLoc; int m_colourVectorLoc; }; ================================================ FILE: depthmapX/views/glview/glutriangulator.cpp ================================================ // adapted from: https://stackoverflow.com/questions/12600325/force-glutesselator-to-generate-only-gl-triangles #include "glutriangulator.h" struct TessContext { ~TessContext() { for (size_t i = 0; i < combined.size(); ++i) { delete[] combined[i]; } } typedef std::pair Point; std::vector pts; std::vector combined; }; #ifdef _WIN32 void __stdcall tess_begin(GLenum) {} void __stdcall tess_edgeFlag(GLboolean) {} void __stdcall tess_end() {} #else void tess_begin(GLenum) {} void tess_edgeFlag(GLboolean) {} void tess_end() {} #endif #ifdef _WIN32 void __stdcall tess_vertex #else void tess_vertex #endif (void *data, TessContext *ctx) { GLdouble *coord = (GLdouble *)data; ctx->pts.push_back(TessContext::Point(coord[0], coord[1])); } #ifdef _WIN32 void __stdcall tess_combine #else void tess_combine #endif (GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData, TessContext *ctx) { GLdouble *newVert = new GLdouble[3]; ctx->combined.push_back(newVert); newVert[0] = coords[0]; newVert[1] = coords[1]; newVert[2] = coords[2]; *outData = newVert; } std::vector GLUTriangulator::triangulate(const std::vector &polygon) { std::vector coords; for (size_t i = 0; i < polygon.size(); ++i) { coords.push_back(polygon[i].x); coords.push_back(polygon[i].y); coords.push_back(0); } GLUtesselator *tess = gluNewTess(); #ifdef _WIN32 gluTessCallback(tess, GLU_TESS_BEGIN, (void(__stdcall *)())tess_begin); gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (void(__stdcall *)())tess_edgeFlag); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void(__stdcall *)())tess_vertex); gluTessCallback(tess, GLU_TESS_END, (void(__stdcall *)())tess_end); gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void(__stdcall *)())tess_combine); #else gluTessCallback(tess, GLU_TESS_BEGIN, (void (*)())tess_begin); gluTessCallback(tess, GLU_TESS_EDGE_FLAG, (void (*)())tess_edgeFlag); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (*)())tess_vertex); gluTessCallback(tess, GLU_TESS_END, (void (*)())tess_end); gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (*)())tess_combine); #endif gluTessNormal(tess, 0.0, 0.0, 1.0); TessContext ctx; gluTessBeginPolygon(tess, &ctx); gluTessBeginContour(tess); for (size_t i = 0; i < polygon.size(); ++i) { gluTessVertex(tess, &coords[i * 3], &coords[i * 3]); } gluTessEndContour(tess); gluTessEndPolygon(tess); gluDeleteTess(tess); std::vector ret(ctx.pts.size()); for (size_t i = 0; i < ret.size(); ++i) { ret[i].x = ctx.pts[i].first; ret[i].y = ctx.pts[i].second; } return ret; } ================================================ FILE: depthmapX/views/glview/glutriangulator.h ================================================ #pragma once #include "genlib/p2dpoly.h" #include // This is required to silence the warnings for OpenGL deprecation in macOS #ifndef GL_SILENCE_DEPRECATION #define GL_SILENCE_DEPRECATION true #endif #ifdef __linux__ #include "GL/glu.h" #elif _WIN32 #include "windows.h" #include "GL/glu.h" #else #include "glu.h" #endif class GLUTriangulator { public: static std::vector triangulate(const std::vector &polygon); }; ================================================ FILE: depthmapX/views/glview/glview.cpp ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "glview.h" #include "depthmapX/views/depthmapview/depthmapview.h" #include "mainwindow.h" #include "salalib/geometrygenerators.h" #include "salalib/linkutils.h" #include #include static QRgb colorMerge(QRgb color, QRgb mergecolor) { return (color & 0x006f6f6f) | (mergecolor & 0x00a0a0a0); } GLView::GLView(QGraphDoc &pDoc, Settings &settings, QWidget *parent) : MapView(pDoc, settings, parent), m_eyePosX(0), m_eyePosY(0) { m_core = QCoreApplication::arguments().contains(QStringLiteral("--coreprofile")); m_foreground = settings.readSetting(SettingTag::foregroundColour, qRgb(128, 255, 128)).toInt(); m_background = settings.readSetting(SettingTag::backgroundColour, qRgb(0, 0, 0)).toInt(); m_initialSize = m_settings.readSetting(SettingTag::depthmapViewSize, QSize(2000, 2000)).toSize(); m_antialiasingSamples = settings.readSetting(SettingTag::antialiasingSamples, 0).toInt(); m_highlightOnHover = settings.readSetting(SettingTag::highlightOnHover, true).toBool(); if (m_antialiasingSamples) { QSurfaceFormat format; format.setSamples(m_antialiasingSamples); // Set the number of samples used for multisampling setFormat(format); } loadDrawingGLObjects(); loadAxes(); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { m_visibleShapeGraph.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedShapeGraph()); } m_visiblePointMap.setGridColour(colorMerge(m_foreground, m_background)); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedPointMap()); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { m_visibleDataMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedDataMap()); } m_dragLine.setStrokeColour(m_foreground); m_selectionRect.setStrokeColour(m_background); matchViewToCurrentMetaGraph(); installEventFilter(this); setMouseTracking(true); m_pDoc.m_view[QGraphDoc::VIEW_MAP_GL] = this; } GLView::~GLView() { makeCurrent(); m_selectionRect.cleanup(); m_dragLine.cleanup(); m_axes.cleanup(); m_visibleDrawingLines.cleanup(); m_visiblePointMap.cleanup(); m_visibleShapeGraph.cleanup(); m_visibleDataMap.cleanup(); m_hoveredShapes.cleanup(); doneCurrent(); m_settings.writeSetting(SettingTag::depthmapViewSize, size()); } QSize GLView::minimumSizeHint() const { return QSize(50, 50); } QSize GLView::sizeHint() const { return m_initialSize; } void GLView::initializeGL() { initializeOpenGLFunctions(); glClearColor(qRed(m_background) / 255.0f, qGreen(m_background) / 255.0f, qBlue(m_background) / 255.0f, 1); m_selectionRect.initializeGL(m_core); m_dragLine.initializeGL(m_core); m_axes.initializeGL(m_core); m_visibleDrawingLines.initializeGL(m_core); m_visiblePointMap.initializeGL(m_core); m_visibleShapeGraph.initializeGL(m_core); m_visibleDataMap.initializeGL(m_core); m_hoveredShapes.initializeGL(m_core); m_hoveredPixels.initializeGL(m_core); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.loadGLObjectsRequiringGLContext(m_pDoc.m_meta_graph->getDisplayedPointMap()); } m_mModel.setToIdentity(); m_mView.setToIdentity(); m_mView.translate(0, 0, -1); } void GLView::paintGL() { glEnable(GL_MULTISAMPLE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); if (m_datasetChanged) { loadDrawingGLObjects(); m_visibleDrawingLines.updateGL(m_core); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL && m_pDoc.m_meta_graph->getDisplayedMapRef() != -1) { m_visibleShapeGraph.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedShapeGraph()); m_visibleShapeGraph.updateGL(m_core); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { m_visibleDataMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedDataMap()); m_visibleDataMap.updateGL(m_core); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.loadGLObjects(m_pDoc.m_meta_graph->getDisplayedPointMap()); m_visiblePointMap.updateGL(m_core); m_visiblePointMap.loadGLObjectsRequiringGLContext(m_pDoc.m_meta_graph->getDisplayedPointMap()); } m_datasetChanged = false; } if (m_hoverStoreInvalid) { m_hoveredShapes.updateGL(m_core); m_hoveredPixels.updateGL(m_core); m_hoverStoreInvalid = false; } m_axes.paintGL(m_mProj, m_mView, m_mModel); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.showGrid(m_pDoc.m_meta_graph->m_showgrid); m_visiblePointMap.paintGL(m_mProj, m_mView, m_mModel); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { m_visibleShapeGraph.paintGL(m_mProj, m_mView, m_mModel); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWDATA) { m_visibleDataMap.paintGL(m_mProj, m_mView, m_mModel); glLineWidth(10); m_hoveredShapes.paintGL(m_mProj, m_mView, m_mModel); glLineWidth(1); } m_visibleDrawingLines.paintGL(m_mProj, m_mView, m_mModel); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_visiblePointMap.paintGLOverlay(m_mProj, m_mView, m_mModel); glLineWidth(3); m_hoveredPixels.paintGL(m_mProj, m_mView, m_mModel); glLineWidth(1); } if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { m_visibleShapeGraph.paintGLOverlay(m_mProj, m_mView, m_mModel); glLineWidth(10); m_hoveredShapes.paintGL(m_mProj, m_mView, m_mModel); glLineWidth(1); } float pos[] = {float(std::min(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x())), float(std::min(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y())), float(std::max(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x())), float(std::max(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y()))}; m_selectionRect.paintGL(m_mProj, m_mView, m_mModel, QMatrix2x2(pos)); if ((m_mouseMode & MOUSE_MODE_SECOND_POINT) == MOUSE_MODE_SECOND_POINT) { float pos[] = {float(m_tempFirstPoint.x), float(m_tempFirstPoint.y), float(m_tempSecondPoint.x), float(m_tempSecondPoint.y)}; m_dragLine.paintGL(m_mProj, m_mView, m_mModel, QMatrix2x2(pos)); } } void GLView::loadAxes() { std::vector> axesData; axesData.push_back(std::pair(SimpleLine(0, 0, 1, 0), PafColor(1, 0, 0))); axesData.push_back(std::pair(SimpleLine(0, 0, 0, 1), PafColor(0, 1, 0))); m_axes.loadLineData(axesData); } void GLView::loadDrawingGLObjects() { auto lock = m_pDoc.m_meta_graph->getLock(); m_visibleDrawingLines.loadLineData(m_pDoc.m_meta_graph->getVisibleDrawingLines(), m_foreground); } void GLView::resizeGL(int w, int h) { m_screenWidth = w; m_screenHeight = h; m_screenRatio = GLfloat(w) / h; recalcView(); } void GLView::mouseReleaseEvent(QMouseEvent *event) { if (m_wasPanning) { m_wasPanning = false; return; } QPoint mousePoint = event->pos(); Point2f worldPoint = getWorldPoint(mousePoint); if (!m_pDoc.m_communicator) { QtRegion r; if (m_mouseDragRect.isNull()) { r.bottom_left = worldPoint; r.top_right = worldPoint; } else { r.bottom_left.x = std::min(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x()); r.bottom_left.y = std::min(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y()); r.top_right.x = std::max(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x()); r.top_right.y = std::max(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y()); } bool selected = false; switch (m_mouseMode) { case MOUSE_MODE_NONE: { // nothing, deselect m_pDoc.m_meta_graph->clearSel(); break; } case MOUSE_MODE_SELECT: { // typical selection Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers(); m_pDoc.m_meta_graph->setCurSel(r, keyMods & Qt::ShiftModifier); ((MainWindow *)m_pDoc.m_mainFrame)->updateToolbar(); highlightHoveredItems(r); break; } case MOUSE_MODE_ZOOM_IN: { if (r.width() > 0) { OnViewZoomToRegion(r); recalcView(); } else { zoomBy(0.8, mousePoint.x(), mousePoint.y()); } break; } case MOUSE_MODE_ZOOM_OUT: { zoomBy(1.2, mousePoint.x(), mousePoint.y()); break; } case MOUSE_MODE_FILL_FULL: { m_pDoc.OnFillPoints(worldPoint, 0); break; } case MOUSE_MODE_PENCIL: { m_pDoc.m_meta_graph->getDisplayedPointMap().fillPoint(worldPoint, event->button() == Qt::LeftButton); break; } case MOUSE_MODE_SEED_ISOVIST: { m_pDoc.OnMakeIsovist(worldPoint); break; } case MOUSE_MODE_SEED_TARGETED_ISOVIST: { m_tempFirstPoint = worldPoint; m_tempSecondPoint = worldPoint; m_mouseMode = MOUSE_MODE_SEED_TARGETED_ISOVIST | MOUSE_MODE_SECOND_POINT; break; } case MOUSE_MODE_SEED_TARGETED_ISOVIST | MOUSE_MODE_SECOND_POINT: { Line directionLine(m_tempFirstPoint, worldPoint); Point2f vec = directionLine.vector(); vec.normalise(); m_pDoc.OnMakeIsovist(m_tempFirstPoint, vec.angle()); m_mouseMode = MOUSE_MODE_SEED_TARGETED_ISOVIST; break; } case MOUSE_MODE_SEED_AXIAL: { m_pDoc.OnToolsAxialMap(worldPoint); break; } case MOUSE_MODE_LINE_TOOL: { m_tempFirstPoint = worldPoint; m_tempSecondPoint = worldPoint; m_mouseMode = MOUSE_MODE_LINE_TOOL | MOUSE_MODE_SECOND_POINT; break; } case MOUSE_MODE_LINE_TOOL | MOUSE_MODE_SECOND_POINT: { if (m_pDoc.m_meta_graph->makeShape(Line(m_tempFirstPoint, worldPoint))) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } m_tempFirstPoint = worldPoint; m_tempSecondPoint = worldPoint; m_mouseMode = MOUSE_MODE_LINE_TOOL; break; } case MOUSE_MODE_POLYGON_TOOL: { m_tempFirstPoint = worldPoint; m_tempSecondPoint = worldPoint; m_polyPoints = 0; m_mouseMode = MOUSE_MODE_POLYGON_TOOL | MOUSE_MODE_SECOND_POINT; break; } case MOUSE_MODE_POLYGON_TOOL | MOUSE_MODE_SECOND_POINT: { if (m_polyPoints == 0) { m_currentlyEditingShapeRef = m_pDoc.m_meta_graph->polyBegin(Line(m_tempFirstPoint, worldPoint)); m_polyStart = m_tempFirstPoint; m_tempFirstPoint = m_tempSecondPoint; m_polyPoints += 2; } else if (m_polyPoints > 2 && PixelDist(mousePoint, getScreenPoint(m_polyStart)) < 6) { // check to see if it's back to the original start point, if so, close off m_pDoc.m_meta_graph->polyClose(m_currentlyEditingShapeRef); m_polyPoints = 0; m_currentlyEditingShapeRef = -1; m_mouseMode = MOUSE_MODE_POLYGON_TOOL; } else { m_pDoc.m_meta_graph->polyAppend(m_currentlyEditingShapeRef, worldPoint); m_tempFirstPoint = m_tempSecondPoint; m_polyPoints += 1; } break; } case MOUSE_MODE_POINT_STEP_DEPTH: { m_pDoc.m_meta_graph->setCurSel(r, false); m_pDoc.OnToolsPD(); break; } case MOUSE_MODE_JOIN: { selected = m_pDoc.m_meta_graph->setCurSel(r, false); int selectedCount = m_pDoc.m_meta_graph->getSelCount(); if (selectedCount > 0) { Point2f selectionCentre; if (selectedCount > 1) { QtRegion selBounds = m_pDoc.m_meta_graph->getSelBounds(); selectionCentre.x = (selBounds.bottom_left.x + selBounds.top_right.x) * 0.5; selectionCentre.y = (selBounds.bottom_left.y + selBounds.top_right.y) * 0.5; } else { const std::set &selectedSet = m_pDoc.m_meta_graph->getSelSet(); if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { selectionCentre = m_pDoc.m_meta_graph->getDisplayedPointMap().depixelate(*selectedSet.begin()); } else if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { selectionCentre = m_pDoc.m_meta_graph->getDisplayedShapeGraph() .getAllShapes()[*selectedSet.begin()] .getCentroid(); } } m_tempFirstPoint = selectionCentre; m_tempSecondPoint = selectionCentre; m_mouseMode = MOUSE_MODE_JOIN | MOUSE_MODE_SECOND_POINT; } break; } case MOUSE_MODE_JOIN | MOUSE_MODE_SECOND_POINT: { int selectedCount = m_pDoc.m_meta_graph->getSelCount(); if (selectedCount > 0) { if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { m_pDoc.m_meta_graph->getDisplayedPointMap().mergePoints(worldPoint); } else if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL && selectedCount == 1) { m_pDoc.m_meta_graph->setCurSel(r, true); // add the new one to the selection set const auto &selectedSet = m_pDoc.m_meta_graph->getSelSet(); if (selectedSet.size() == 2) { std::set::iterator it = selectedSet.begin(); int axRef1 = *it; it++; int axRef2 = *it; // axial is only joined one-by-one m_pDoc.modifiedFlag = true; m_pDoc.m_meta_graph->getDisplayedShapeGraph().linkShapesFromRefs(axRef1, axRef2, true); m_pDoc.m_meta_graph->clearSel(); } } m_pDoc.m_meta_graph->clearSel(); m_mouseMode = MOUSE_MODE_JOIN; } break; } case MOUSE_MODE_UNJOIN: { m_pDoc.m_meta_graph->setCurSel(r, false); int selectedCount = m_pDoc.m_meta_graph->getSelCount(); if (selectedCount > 0) { if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { if (m_pDoc.m_meta_graph->getDisplayedPointMap().unmergePoints()) { m_pDoc.modifiedFlag = true; m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA); } } else if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL) { const auto &selectedSet = m_pDoc.m_meta_graph->getSelSet(); Point2f selectionCentre = m_pDoc.m_meta_graph->getDisplayedShapeGraph() .getAllShapes()[*selectedSet.begin()] .getCentroid(); m_tempFirstPoint = selectionCentre; m_tempSecondPoint = selectionCentre; m_mouseMode = MOUSE_MODE_UNJOIN | MOUSE_MODE_SECOND_POINT; } } break; } case MOUSE_MODE_UNJOIN | MOUSE_MODE_SECOND_POINT: { int selectedCount = m_pDoc.m_meta_graph->getSelCount(); if (selectedCount > 0) { if (m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWAXIAL && selectedCount == 1) { m_pDoc.m_meta_graph->setCurSel(r, true); // add the new one to the selection set const auto &selectedSet = m_pDoc.m_meta_graph->getSelSet(); if (selectedSet.size() == 2) { std::set::iterator it = selectedSet.begin(); int axRef1 = *it; it++; int axRef2 = *it; // axial is only joined one-by-one m_pDoc.modifiedFlag = true; m_pDoc.m_meta_graph->getDisplayedShapeGraph().unlinkShapesFromRefs(axRef1, axRef2, true); m_pDoc.m_meta_graph->clearSel(); } } m_pDoc.m_meta_graph->clearSel(); m_mouseMode = MOUSE_MODE_UNJOIN; } break; } } m_pDoc.SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_SELECTION); } m_mouseDragRect.setWidth(0); m_mouseDragRect.setHeight(0); } void GLView::mousePressEvent(QMouseEvent *event) { m_mouseLastPos = event->pos(); } void GLView::mouseMoveEvent(QMouseEvent *event) { int dx = event->x() - m_mouseLastPos.x(); int dy = event->y() - m_mouseLastPos.y(); Point2f worldPoint = getWorldPoint(event->pos()); if (m_mouseDragRect.isNull() && !((m_mouseMode & MOUSE_MODE_SECOND_POINT) == MOUSE_MODE_SECOND_POINT && m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA)) { highlightHoveredItems(QtRegion(worldPoint, worldPoint)); } if (event->buttons() & Qt::RightButton || (event->buttons() & Qt::LeftButton && m_mouseMode == MOUSE_MODE_PAN)) { panBy(dx, dy); m_wasPanning = true; } else if (event->buttons() & Qt::LeftButton) { Point2f lastWorldPoint = getWorldPoint(m_mouseLastPos); if (m_mouseDragRect.isNull()) { m_mouseDragRect.setX(lastWorldPoint.x); m_mouseDragRect.setY(lastWorldPoint.y); } m_mouseDragRect.setWidth(worldPoint.x - m_mouseDragRect.x()); m_mouseDragRect.setHeight(worldPoint.y - m_mouseDragRect.y()); QtRegion hoverRegion; hoverRegion.bottom_left.x = std::min(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x()); hoverRegion.bottom_left.y = std::min(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y()); hoverRegion.top_right.x = std::max(m_mouseDragRect.bottomRight().x(), m_mouseDragRect.topLeft().x()); hoverRegion.top_right.y = std::max(m_mouseDragRect.bottomRight().y(), m_mouseDragRect.topLeft().y()); highlightHoveredItems(hoverRegion); update(); } if ((m_mouseMode & MOUSE_MODE_SECOND_POINT) == MOUSE_MODE_SECOND_POINT) { m_tempSecondPoint = worldPoint; if (m_highlightOnHover && m_pDoc.m_meta_graph->getViewClass() & MetaGraph::VIEWVGA) { PointMap &map = m_pDoc.m_meta_graph->getDisplayedPointMap(); QtRegion selectionBounds = map.getSelBounds(); PixelRef worldPixel = map.pixelate(worldPoint, true); PixelRef boundsPixel = map.pixelate(Point2f(selectionBounds.top_right.x, selectionBounds.bottom_left.y), true); std::set &selection = map.getSelSet(); std::set offsetSelection; for (int ref : selection) { PixelRef pixelRef = PixelRef(ref) + worldPixel - boundsPixel; offsetSelection.insert(pixelRef); } highlightHoveredPixels(map, offsetSelection); } update(); } m_mouseLastPos = event->pos(); m_pDoc.m_position = worldPoint; m_pDoc.UpdateMainframestatus(); } void GLView::wheelEvent(QWheelEvent *event) { QPoint numDegrees = event->angleDelta() / 8; int x = event->x(); int y = event->y(); zoomBy(1 - 0.25f * numDegrees.y() / 15.0f, x, y); event->accept(); } bool GLView::eventFilter(QObject *object, QEvent *e) { if (e->type() == QEvent::ToolTip) { if (!m_pDoc.m_communicator) { if (m_pDoc.m_meta_graph) { if (m_pDoc.m_meta_graph->viewingProcessed() && m_pDoc.m_meta_graph->getSelCount() > 1) { float val = m_pDoc.m_meta_graph->getSelAvg(); int count = m_pDoc.m_meta_graph->getSelCount(); if (val == -1.0f) setToolTip("Null selection"); else if (val != -2.0f) setToolTip(QString("Selection\nAverage: %1\nCount: %2").arg(val).arg(count)); else setToolTip(""); } else if (m_pDoc.m_meta_graph->viewingProcessed()) { // and that it has an appropriate state to display a hover wnd QHelpEvent *helpEvent = static_cast(e); // Tool tip events come as the type QHelpEvent float val = m_pDoc.m_meta_graph->getLocationValue(getWorldPoint(helpEvent->pos())); if (val == -1.0f) setToolTip("No value"); else if (val != -2.0f) { QString s; QTextStream txt(&s); txt.setRealNumberNotation(QTextStream::FixedNotation); txt << val; setToolTip(s); } else setToolTip(""); } } } } return QObject::eventFilter(object, e); } void GLView::highlightHoveredItems(const QtRegion ®ion) { if (!m_highlightOnHover) return; if (m_pDoc.m_meta_graph->viewingProcessedPoints()) { highlightHoveredPixels(m_pDoc.m_meta_graph->getDisplayedPointMap(), region); } else if (m_pDoc.m_meta_graph->viewingProcessedLines()) { highlightHoveredShapes(m_pDoc.m_meta_graph->getDisplayedShapeGraph(), region); } else if (m_pDoc.m_meta_graph->viewingProcessedShapes()) { highlightHoveredShapes(m_pDoc.m_meta_graph->getDisplayedDataMap(), region); } } void GLView::highlightHoveredPixels(const PointMap &map, const QtRegion ®ion) { // n.b., assumes constrain set to true (for if you start the selection off the grid) PixelRef s_bl = map.pixelate(region.bottom_left, true); PixelRef s_tr = map.pixelate(region.top_right, true); std::vector points; PixelRef hoverPixel = -1; for (short i = s_bl.x; i <= s_tr.x; i++) { for (short j = s_bl.y; j <= s_tr.y; j++) { PixelRef ref = PixelRef(i, j); if (map.includes(ref)) { const Point &p = map.getPoint(ref); if (p.filled()) { points.push_back(p); hoverPixel = ref; } } } } if (!points.empty()) { // do not redo the whole thing if we are still hovering the same pixel if (points.size() == 1 && hoverPixel == m_lastHoverPixel) return; std::vector lines; int i = 0; for (Point point : points) { const Point2f &loc = point.getLocation(); lines.push_back(SimpleLine(loc.x - map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5, loc.x - map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x - map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5, loc.x + map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x + map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5, loc.x + map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x + map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5, loc.x - map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5)); i++; } m_hoveredPixels.loadLineData(lines, qRgb(255, 255, 0)); m_hoverStoreInvalid = true; m_hoverHasShapes = true; } else if (m_hoverHasShapes) { m_hoveredPixels.loadLineData(std::vector(), qRgb(255, 255, 0)); m_hoverStoreInvalid = true; m_hoverHasShapes = false; } if (m_hoverStoreInvalid) { update(); } } void GLView::highlightHoveredPixels(const PointMap &map, const std::set &refs) { // n.b., assumes constrain set to true (for if you start the selection off the grid) std::vector points; PixelRef hoverPixel = -1; for (PixelRef ref : refs) { if (map.includes(ref)) { const Point &p = map.getPoint(ref); if (p.filled()) { points.push_back(p); hoverPixel = ref; } } } if (!points.empty()) { // do not redo the whole thing if we are still hovering the same pixel if (points.size() == 1 && hoverPixel == m_lastHoverPixel) return; std::vector lines; int i = 0; for (Point point : points) { const Point2f &loc = point.getLocation(); lines.push_back(SimpleLine(loc.x - map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5, loc.x - map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x - map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5, loc.x + map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x + map.getSpacing() * 0.5, loc.y + map.getSpacing() * 0.5, loc.x + map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5)); lines.push_back(SimpleLine(loc.x + map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5, loc.x - map.getSpacing() * 0.5, loc.y - map.getSpacing() * 0.5)); i++; } m_hoveredPixels.loadLineData(lines, qRgb(255, 255, 0)); m_hoverStoreInvalid = true; m_hoverHasShapes = true; } else if (m_hoverHasShapes) { m_hoveredPixels.loadLineData(std::vector(), qRgb(255, 255, 0)); m_hoverStoreInvalid = true; m_hoverHasShapes = false; } if (m_hoverStoreInvalid) { update(); } } void GLView::highlightHoveredShapes(const ShapeMap &map, const QtRegion ®ion) { auto shapesInRegion = map.getShapesInRegion(region); if (!shapesInRegion.empty()) { std::vector> colouredLines; std::vector, PafColor>> colouredPolygons; std::vector> colouredPoints; for (auto keyShape : shapesInRegion) { AttributeKey key = AttributeKey(keyShape.first); const SalaShape &shape = keyShape.second; const AttributeRow &row = map.getAttributeTable().getRow(key); PafColor colour = dXreimpl::getDisplayColor(key, row, map.getAttributeTableHandle(), true); if (shape.isLine()) { colouredLines.push_back(std::make_pair(SimpleLine(shape.getLine()), colour)); } else if (shape.isPolyLine()) { for (size_t n = 0; n < shape.m_points.size() - 1; n++) { colouredLines.push_back( std::make_pair(SimpleLine(shape.m_points[n], shape.m_points[n + 1]), colour)); } } else if (shape.isPolygon()) { for (size_t n = 0; n < shape.m_points.size() - 1; n++) { colouredLines.push_back( std::make_pair(SimpleLine(shape.m_points[n], shape.m_points[n + 1]), PafColor(1, 1, 0))); } colouredLines.push_back( std::make_pair(SimpleLine(shape.m_points.back(), shape.m_points.front()), PafColor(1, 1, 0))); } else { if (shape.isPoint()) { colouredPoints.push_back(std::make_pair(shape.getCentroid(), PafColor(1, 0, 0))); } } } m_hoveredShapes.loadGLObjects(colouredLines, colouredPolygons, colouredPoints, 8, map.getSpacing() * 0.1); m_hoverStoreInvalid = true; m_hoverHasShapes = true; } else if (m_hoverHasShapes) { m_hoveredShapes.loadGLObjects(std::vector>(), std::vector, PafColor>>(), std::vector>(), 8, map.getSpacing() * 0.1); m_hoverStoreInvalid = true; m_hoverHasShapes = false; } if (m_hoverStoreInvalid) { update(); } } void GLView::zoomBy(float dzf, int mouseX, int mouseY) { float pzf = m_zoomFactor; m_zoomFactor = m_zoomFactor * dzf; if (m_zoomFactor < m_minZoomFactor) m_zoomFactor = m_minZoomFactor; else if (m_zoomFactor > m_maxZoomFactor) m_zoomFactor = m_maxZoomFactor; m_eyePosX += (m_zoomFactor - pzf) * m_screenRatio * GLfloat(mouseX - m_screenWidth * 0.5f) / GLfloat(m_screenWidth); m_eyePosY -= (m_zoomFactor - pzf) * GLfloat(mouseY - m_screenHeight * 0.5f) / GLfloat(m_screenHeight); recalcView(); } void GLView::panBy(int dx, int dy) { m_eyePosX += m_zoomFactor * GLfloat(dx) / m_screenHeight; m_eyePosY -= m_zoomFactor * GLfloat(dy) / m_screenHeight; recalcView(); } void GLView::recalcView() { m_mProj.setToIdentity(); if (m_perspectiveView) { m_mProj.perspective(45.0f, m_screenRatio, 0.01f, 100.0f); m_mProj.scale(1.0f, 1.0f, m_zoomFactor); } else { m_mProj.ortho(-m_zoomFactor * 0.5f * m_screenRatio, m_zoomFactor * 0.5f * m_screenRatio, -m_zoomFactor * 0.5f, m_zoomFactor * 0.5f, 0, 10); } m_mProj.translate(m_eyePosX, m_eyePosY, 0.0f); update(); } Point2f GLView::getWorldPoint(const QPoint &screenPoint) { return Point2f(+m_zoomFactor * float(screenPoint.x() - m_screenWidth * 0.5) / m_screenHeight - m_eyePosX, -m_zoomFactor * float(screenPoint.y() - m_screenHeight * 0.5) / m_screenHeight - m_eyePosY); } QPoint GLView::getScreenPoint(const Point2f &worldPoint) { return QPoint((worldPoint.x + m_eyePosX) * m_screenHeight / m_zoomFactor + m_screenWidth * 0.5, -(worldPoint.y + m_eyePosY) * m_screenHeight / m_zoomFactor + m_screenHeight * 0.5); } void GLView::matchViewToCurrentMetaGraph() { const QtRegion ®ion = m_pDoc.m_meta_graph->getBoundingBox(); OnViewZoomToRegion(region); recalcView(); } void GLView::OnViewZoomToRegion(QtRegion region) { if ((region.top_right.x == 0 && region.bottom_left.x == 0) || (region.top_right.y == 0 && region.bottom_left.y == 0)) // region is unset, don't try to change the view to it return; m_eyePosX = -(region.top_right.x + region.bottom_left.x) * 0.5f; m_eyePosY = -(region.top_right.y + region.bottom_left.y) * 0.5f; if (region.width() > region.height()) { m_zoomFactor = region.top_right.x - region.bottom_left.x; } else { m_zoomFactor = region.top_right.y - region.bottom_left.y; } m_minZoomFactor = m_zoomFactor * 0.001; m_maxZoomFactor = m_zoomFactor * 10; } void GLView::resetView() { m_visiblePointMap.showLinks(false); m_visibleShapeGraph.showLinks(false); m_pDoc.m_meta_graph->clearSel(); update(); } void GLView::OnModeJoin() { if (m_pDoc.m_meta_graph->getViewClass() & (MetaGraph::VIEWVGA | MetaGraph::VIEWAXIAL)) { resetView(); m_mouseMode = MOUSE_MODE_JOIN; m_visiblePointMap.showLinks(true); m_visibleShapeGraph.showLinks(true); m_pDoc.m_meta_graph->clearSel(); notifyDatasetChanged(); } } void GLView::OnModeUnjoin() { if (m_pDoc.m_meta_graph->getState() & (MetaGraph::VIEWVGA | MetaGraph::VIEWAXIAL)) { resetView(); m_mouseMode = MOUSE_MODE_UNJOIN; m_visiblePointMap.showLinks(true); m_visibleShapeGraph.showLinks(true); m_pDoc.m_meta_graph->clearSel(); notifyDatasetChanged(); } } void GLView::OnViewPan() { m_mouseMode = MOUSE_MODE_PAN; } void GLView::OnViewZoomIn() { m_mouseMode = MOUSE_MODE_ZOOM_IN; } void GLView::OnViewZoomOut() { m_mouseMode = MOUSE_MODE_ZOOM_OUT; } void GLView::OnEditFill() { resetView(); m_mouseMode = MOUSE_MODE_FILL_FULL; } void GLView::OnEditSemiFill() { resetView(); m_mouseMode = MOUSE_MODE_FILL_SEMI; } void GLView::OnEditAugmentFill() { resetView(); m_mouseMode = MOUSE_MODE_FILL_AUGMENT; } void GLView::OnEditPencil() { resetView(); m_mouseMode = MOUSE_MODE_PENCIL; } void GLView::OnModeIsovist() { resetView(); m_mouseMode = MOUSE_MODE_SEED_ISOVIST; } void GLView::OnModeTargetedIsovist() { resetView(); m_mouseMode = MOUSE_MODE_SEED_TARGETED_ISOVIST; } void GLView::OnModeSeedAxial() { resetView(); m_mouseMode = MOUSE_MODE_SEED_AXIAL; } void GLView::OnModeStepDepth() { resetView(); m_mouseMode = MOUSE_MODE_POINT_STEP_DEPTH; } void GLView::OnEditLineTool() { resetView(); m_mouseMode = MOUSE_MODE_LINE_TOOL; } void GLView::OnEditPolygonTool() { resetView(); m_mouseMode = MOUSE_MODE_POLYGON_TOOL; } void GLView::OnEditSelect() { resetView(); m_mouseMode = MOUSE_MODE_SELECT; } void GLView::postLoadFile() { matchViewToCurrentMetaGraph(); setWindowTitle(m_pDoc.m_base_title + ":Map View (GL)"); } void GLView::OnViewZoomsel() { if (m_pDoc.m_meta_graph && m_pDoc.m_meta_graph->isSelected()) { OnViewZoomToRegion(m_pDoc.m_meta_graph->getSelBounds()); } } void GLView::closeEvent(QCloseEvent *event) { m_pDoc.m_view[QGraphDoc::VIEW_MAP_GL] = NULL; if (!m_pDoc.OnCloseDocument(QGraphDoc::VIEW_MAP_GL)) { m_pDoc.m_view[QGraphDoc::VIEW_MAP_GL] = this; event->ignore(); } } void GLView::OnEditCopy() { std::unique_ptr tmp(new QDepthmapView(m_pDoc, m_settings)); Point2f topLeftWorld = getWorldPoint(QPoint(0, 0)); Point2f bottomRightWorld = getWorldPoint(QPoint(width(), height())); tmp->setAttribute(Qt::WA_DontShowOnScreen); tmp->show(); tmp->postLoadFile(); tmp->OnViewZoomToRegion(QtRegion(topLeftWorld, bottomRightWorld)); tmp->repaint(); tmp->OnEditCopy(); tmp->close(); } void GLView::OnEditSave() { std::unique_ptr tmp(new QDepthmapView(m_pDoc, m_settings)); Point2f topLeftWorld = getWorldPoint(QPoint(0, 0)); Point2f bottomRightWorld = getWorldPoint(QPoint(width(), height())); tmp->setAttribute(Qt::WA_DontShowOnScreen); tmp->show(); tmp->postLoadFile(); tmp->OnViewZoomToRegion(QtRegion(topLeftWorld, bottomRightWorld)); tmp->OnEditSave(); } ================================================ FILE: depthmapX/views/glview/glview.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/GraphDoc.h" #include "depthmapX/views/glview/gldynamicline.h" #include "depthmapX/views/glview/gldynamicrect.h" #include "depthmapX/views/glview/gllines.h" #include "depthmapX/views/glview/gllinesuniform.h" #include "depthmapX/views/glview/glpointmap.h" #include "depthmapX/views/glview/glpolygons.h" #include "depthmapX/views/glview/glrastertexture.h" #include "depthmapX/views/glview/glshapegraph.h" #include "depthmapX/views/mapview.h" #include #include #include QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) class GLView : public MapView, protected QOpenGLFunctions { Q_OBJECT public: GLView(QGraphDoc &pDoc, Settings &settings, QWidget *parent = Q_NULLPTR); ~GLView(); QSize minimumSizeHint() const override; QSize sizeHint() const override; void notifyDatasetChanged() { m_datasetChanged = true; update(); } void matchViewToCurrentMetaGraph(); virtual void OnModeJoin() override; virtual void OnModeUnjoin() override; virtual void OnViewPan() override; virtual void OnViewZoomIn() override; virtual void OnViewZoomOut() override; virtual void OnEditFill() override; virtual void OnEditSemiFill() override; virtual void OnEditAugmentFill() override; virtual void OnEditPencil() override; virtual void OnModeIsovist() override; virtual void OnModeTargetedIsovist() override; virtual void OnEditLineTool() override; virtual void OnEditPolygonTool() override; virtual void OnModeSeedAxial() override; virtual void OnEditSelect() override; virtual void OnViewZoomsel() override; void OnModeStepDepth(); virtual void postLoadFile() override; virtual void OnEditCopy() override; virtual void OnEditSave() override; virtual void OnViewZoomToRegion(QtRegion region) override; protected: void initializeGL() override; void paintGL() override; void resizeGL(int width, int height) override; void mouseReleaseEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void wheelEvent(QWheelEvent *event) override; bool eventFilter(QObject *object, QEvent *e) override; void closeEvent(QCloseEvent *event) override; private: bool m_perspectiveView = false; bool m_core; QMatrix4x4 m_mProj; QMatrix4x4 m_mView; QMatrix4x4 m_mModel; QRgb m_foreground; QRgb m_background; QSize m_initialSize; GLDynamicRect m_selectionRect; GLDynamicLine m_dragLine; GLLines m_axes; GLShapeGraph m_visibleShapeGraph; GLLinesUniform m_visibleDrawingLines; GLPointMap m_visiblePointMap; GLShapeMap m_visibleDataMap; bool m_highlightOnHover = true; bool m_hoverHasShapes = false; bool m_hoverStoreInvalid = false; GLShapeMap m_hoveredShapes; GLLinesUniform m_hoveredPixels; PixelRef m_lastHoverPixel = -1; QPoint m_mouseLastPos; float m_eyePosX; float m_eyePosY; float m_minZoomFactor = 1; float m_zoomFactor = 20; float m_maxZoomFactor = 200; GLfloat m_screenRatio; int m_screenWidth; int m_screenHeight; bool m_wasPanning = false; int m_antialiasingSamples = 0; // set this to 0 if rendering is too slow Point2f getWorldPoint(const QPoint &screenPoint); QPoint getScreenPoint(const Point2f &worldPoint); bool m_datasetChanged = false; void panBy(int dx, int dy); void recalcView(); void zoomBy(float dzf, int mouseX, int mouseY); void resetView(); void highlightHoveredItems(const QtRegion ®ion); void highlightHoveredPixels(const PointMap &map, const QtRegion ®ion); void highlightHoveredPixels(const PointMap &map, const std::set &refs); void highlightHoveredShapes(const ShapeMap &map, const QtRegion ®ion); void loadAxes(); void loadDrawingGLObjects(); enum { MOUSE_MODE_NONE = 0x0000, MOUSE_MODE_SELECT = 0x10000, MOUSE_MODE_PAN = 0x0101, MOUSE_MODE_ZOOM_IN = 0x0202, MOUSE_MODE_ZOOM_OUT = 0x0204, MOUSE_MODE_FILL_FULL = 0x0001, MOUSE_MODE_FILL_SEMI = 0x0002, MOUSE_MODE_FILL_AUGMENT = 0x0003, MOUSE_MODE_PENCIL = 0x0801, MOUSE_MODE_SEED_ISOVIST = 0x4001, MOUSE_MODE_SEED_TARGETED_ISOVIST = 0x4002, MOUSE_MODE_SEED_AXIAL = 0x0004, MOUSE_MODE_LINE_TOOL = 0x0008, MOUSE_MODE_POLYGON_TOOL = 0x0010, MOUSE_MODE_POINT_STEP_DEPTH = 0x5000, MOUSE_MODE_JOIN = 0x20001, MOUSE_MODE_UNJOIN = 0x20002, MOUSE_MODE_SECOND_POINT = 0x00400, }; int m_mouseMode = MOUSE_MODE_SELECT; QRectF m_mouseDragRect = QRectF(0, 0, 0, 0); Point2f m_tempFirstPoint; Point2f m_tempSecondPoint; int m_currentlyEditingShapeRef = -1; Point2f m_polyStart; int m_polyPoints = 0; inline int PixelDist(QPoint a, QPoint b) { return (int)sqrt(double((b.x() - a.x()) * (b.x() - a.x()) + (b.y() - a.y()) * (b.y() - a.y()))); } }; ================================================ FILE: depthmapX/views/mapview.cpp ================================================ #include "mapview.h" MapView::MapView(QGraphDoc &pDoc, Settings &settings, QWidget *parent) : QOpenGLWidget(parent), m_pDoc(pDoc), m_settings(settings) { } ================================================ FILE: depthmapX/views/mapview.h ================================================ #pragma once #include #include "depthmapX/GraphDoc.h" #include "depthmapX/settings.h" class MapView : public QOpenGLWidget { Q_OBJECT protected: QGraphDoc &m_pDoc; Settings &m_settings; QString m_currentFile; public: MapView(QGraphDoc &pDoc, Settings &settings, QWidget* parent = Q_NULLPTR); virtual void OnModeJoin() = 0; virtual void OnModeUnjoin() = 0; virtual void OnViewPan() = 0; virtual void OnViewZoomIn() = 0; virtual void OnViewZoomOut() = 0; virtual void OnEditFill() = 0; virtual void OnEditSemiFill() = 0; virtual void OnEditAugmentFill() = 0; virtual void OnEditPencil() = 0; virtual void OnModeIsovist() = 0; virtual void OnModeTargetedIsovist() = 0; virtual void OnEditLineTool() = 0; virtual void OnEditPolygonTool() = 0; virtual void OnModeSeedAxial() = 0; virtual void OnEditSelect() = 0; virtual void postLoadFile() = 0; virtual void OnViewZoomsel() = 0; virtual void OnEditCopy() = 0; virtual void OnEditSave() = 0; virtual void OnViewZoomToRegion(QtRegion region) = 0; QGraphDoc *getGraphDoc() { return &m_pDoc; } void setCurrentFile(const QString &fileName) { m_currentFile = fileName; } QString getCurrentFile() { return m_currentFile; } }; ================================================ FILE: depthmapX/views/plotview/plotview.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // depthmapX - spatial network analysis platform // PlotView.cpp : implementation file // #include "plotview.h" #include "mainwindow.h" #include "salalib/attributetablehelpers.h" #include #include #ifdef _WIN32 #define finite _finite #endif ///////////////////////////////////////////////////////////////////////////// // PlotView static int pressed_nFlags; QPlotView::QPlotView() { m_x_axis = -1; m_y_axis = -1; curr_x = -1; curr_y = -1; m_queued_redraw = false; m_view_trend_line = false; m_view_rsquared = false; m_view_monochrome = false; m_view_origin = false; m_view_equation = false; // for drawing drag rect m_drawdragrect = false; m_selecting = false; setAttribute(Qt::WA_NoBackground, 1); setMouseTracking(true); setWindowIcon(QIcon(tr(":/images/cur/icon-1-2.png"))); installEventFilter(this); } ///////////////////////////////////////////////////////////////////////////// // QPlotView drawing int QPlotView::screenX(double x) { return m_screen_bounds.left() + m_screen_bounds.width() * (m_data_bounds.width() ? (x - m_data_bounds.bottom_left.x) / m_data_bounds.width() : 0.5); } int QPlotView::screenY(double y) { return m_screen_bounds.top() - (abs(m_screen_bounds.height()) * (m_data_bounds.height() ? (y - m_data_bounds.bottom_left.y) / m_data_bounds.height() : 0.5)); } double QPlotView::dataX(int x) { return m_data_bounds.bottom_left.x + m_data_bounds.width() * double(x - m_screen_bounds.left()) / double(m_screen_bounds.width()); } double QPlotView::dataY(int y) { return m_data_bounds.bottom_left.y + m_data_bounds.height() * double(m_screen_bounds.top() - y) / double(abs(m_screen_bounds.height())); } QSize QPlotView::sizeHint() const { return QSize(2000, 2000); } static QPoint hit_point; bool QPlotView::eventFilter(QObject *object, QEvent *e) { if (e->type() == QEvent::ToolTip) { if (!pDoc->m_communicator) { // first, check you have a meta graph if (pDoc->m_meta_graph) { if (pDoc->m_meta_graph->viewingProcessed()) { AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); auto xRange = getIndexItemsInValueRange(idx_x, table, dataX(hit_point.x() - 2), dataX(hit_point.x() + 2)); auto yRange = getIndexItemsInValueRange(idx_y, table, dataY(hit_point.y() + 2), dataY(hit_point.y() - 2)); // work out anything near this point... std::set xkeys; for (auto iter = xRange.first; iter != xRange.second; iter++) { xkeys.insert(iter->key); } const AttributeRow *displayRow = nullptr; for (auto iter = yRange.first; iter != yRange.second; iter++) { if (xkeys.find(iter->key) != xkeys.end()) { displayRow = iter->row; break; } } if (displayRow) { // and that it has an appropriate state to display a hover wnd float val = displayRow->getValue(pDoc->m_meta_graph->getDisplayedAttribute()); if (val == -1.0f) setToolTip("No value"); else if (val != -2.0f) setToolTip(QString("%1").arg(val)); } } } } } return QObject::eventFilter(object, e); } void QPlotView::paintEvent(QPaintEvent *event) { QPainter pDC(m_pixmap); QRect rect = QRect(0, 0, width(), height()); PafColor selcol(SALA_SELECTED_COLOR); pDC.setPen(QPen(QBrush(QColor(selcol.redb(), selcol.greenb(), selcol.blueb())), 1, Qt::DotLine, Qt::RoundCap)); /* if (pDC->IsPrinting()) { PrintOutput(pDC, pDoc); } else */ { // if (m_clear) if (m_drawdragrect) { pDC.setCompositionMode(QPainter::RasterOp_SourceAndNotDestination); if (!m_drag_rect_b.isEmpty()) pDC.drawRect(m_drag_rect_b); if (!m_drag_rect_a.isEmpty()) pDC.drawRect(m_drag_rect_a); pDC.setCompositionMode(QPainter::CompositionMode_SourceOver); m_drag_rect_b = m_drag_rect_a; m_drawdragrect = false; } else { m_background = ((MainWindow *)m_parent)->m_background; m_foreground = ((MainWindow *)m_parent)->m_foreground; pDC.fillRect(rect, QBrush(QColor(m_background))); // m_clear = false; Output(&pDC, pDoc, true); OnRedraw(0, 0); } } QPainter screenPainter(this); screenPainter.drawPixmap(0, 0, width(), height(), *m_pixmap); } void QPlotView::resizeEvent(QResizeEvent *event) { pDoc->m_view[QGraphDoc::VIEW_SCATTER] = this; setWindowTitle(pDoc->m_base_title + ":Scatter Plot"); m_pixmap = new QPixmap(width(), height()); } void QPlotView::closeEvent(QCloseEvent *event) { pDoc->m_view[QGraphDoc::VIEW_SCATTER] = NULL; if (!pDoc->OnCloseDocument(QGraphDoc::VIEW_SCATTER)) { pDoc->m_view[QGraphDoc::VIEW_SCATTER] = this; event->ignore(); } } bool QPlotView::Output(QPainter *pDC, QGraphDoc *pDoc, bool screendraw) { // this is going to need a timer at somepoint, but for now, it's all very easy to start off: auto lock = pDoc->m_meta_graph->getLockDeferred(); if (!lock.try_lock()) { return false; } if (pDoc->m_communicator || !pDoc->m_meta_graph->viewingProcessed()) { return false; } AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); AttributeTableHandle &tableHandle = pDoc->m_meta_graph->getAttributeTableHandle(); LayerManagerImpl &layers = pDoc->m_meta_graph->getLayers(); QRect rect = QRect(0, 0, width(), height()); int mindim = __min(rect.width(), rect.height()); // TODO: the calculations are done here for the moment // but should be placed in their own helper method int numVisible = 0; float minVisibleX = std::numeric_limits::max(); float maxVisibleX = std::numeric_limits::min(); float minVisibleY = std::numeric_limits::max(); float maxVisibleY = std::numeric_limits::min(); for (auto iter = table.begin(); iter != table.end(); iter++) { if (isObjectVisible(layers, iter->getRow())) { numVisible++; float xVal = iter->getRow().getValue(m_x_axis); float yVal = iter->getRow().getValue(m_y_axis); minVisibleX = std::min(minVisibleX, xVal); maxVisibleX = std::max(maxVisibleX, xVal); minVisibleY = std::min(minVisibleY, yVal); maxVisibleY = std::max(maxVisibleY, yVal); } } if (numVisible == 0) m_x_axis = m_y_axis = 0; int spacer = floor(2.0 * sqrt(double(mindim) / double(numVisible != 0 ? numVisible : 1))); if (!screendraw && spacer < 4) { spacer = 4; } // text formatting int pointsize; if (mindim > 200) { pointsize = 100; } else { pointsize = 50 + mindim / 4; } QFont font = QFont("Arial", 10, 10); setFont(font); QPen pen = QPen(QBrush(QColor(m_foreground)), 1, Qt::SolidLine, Qt::RoundCap); QPen oldpen = pDC->pen(); pDC->setPen(pen); float minx, miny, maxx, maxy; QString str_minx, str_miny, str_maxx, str_maxy; minx = m_data_bounds.bottom_left.x = m_view_origin ? 0.0 : minVisibleX; miny = m_data_bounds.bottom_left.y = m_view_origin ? 0.0 : minVisibleY; maxx = m_data_bounds.top_right.x = maxVisibleX; maxy = m_data_bounds.top_right.y = maxVisibleY; str_minx = QString(tr("%1")).arg(minx); str_miny = QString(tr("%1")).arg(miny); str_maxx = QString(tr("%1")).arg(maxx); str_maxy = QString(tr("%1")).arg(maxy); // now work out the drawing window for QSize sizex = QSize(str_maxx.length() * 7, 16); QSize sizey = QSize(str_miny.length() * 7, 16); QSize sizey2 = QSize(str_maxy.length() * 7, 16); if (sizey2.width() > sizey.width()) { sizey.rwidth() = sizey2.width(); } // doesn't matter which, just want a height: int texth = sizex.height(); int xaxis_pos = 99 * rect.height() / 100 - 2 * texth; int yaxis_pos = rect.width() / 100 + sizey.width() + texth; int miny_pos = xaxis_pos - texth; m_screen_bounds.setTop(miny_pos); int maxy_pos = rect.height() / 100 + texth / 2; m_screen_bounds.setBottom(maxy_pos); int minx_pos = yaxis_pos + texth; m_screen_bounds.setLeft(minx_pos); int maxx_pos = 99 * rect.width() / 100 - sizex.width() / 2; m_screen_bounds.setRight(maxx_pos); int width = maxx_pos - minx_pos; if (minx == maxx) { minx_pos = maxx_pos = minx_pos + width / 2; m_screen_bounds.setRight(minx_pos); m_screen_bounds.setLeft(minx_pos); width = 0; } int height = maxy_pos - miny_pos; if (miny == maxy) { miny_pos = maxy_pos = miny_pos + height / 2; m_screen_bounds.setBottom(miny_pos); m_screen_bounds.setTop(miny_pos); height = 0; } pDC->setPen(pen); pDC->drawText(minx_pos - 50, 99 * rect.height() / 100 - texth, 100, 16, Qt::AlignCenter, str_minx); if (minx != maxx) { pDC->drawText(maxx_pos - 50, 99 * rect.height() / 100 - texth, 100, 16, Qt::AlignCenter, str_maxx); } pDC->drawText(yaxis_pos - texth - 100, miny_pos - texth / 2, 100, 16, Qt::AlignRight, str_miny); if (miny != maxy) { pDC->drawText(yaxis_pos - texth - 100, maxy_pos - texth / 2, 100, 16, Qt::AlignRight, str_maxy); } pDC->drawLine(QPoint(yaxis_pos - texth / 2, miny_pos), QPoint(yaxis_pos, miny_pos)); if (miny != maxy) { pDC->drawLine(QPoint(yaxis_pos, miny_pos), QPoint(yaxis_pos, maxy_pos)); pDC->drawLine(QPoint(yaxis_pos, maxy_pos), QPoint(yaxis_pos - texth / 2, maxy_pos)); } pDC->drawLine(QPoint(minx_pos, xaxis_pos + texth / 2), QPoint(minx_pos, xaxis_pos)); if (minx != maxx) { pDC->drawLine(QPoint(minx_pos, xaxis_pos), QPoint(maxx_pos, xaxis_pos)); pDC->drawLine(QPoint(maxx_pos, xaxis_pos), QPoint(maxx_pos, xaxis_pos + texth / 2)); } int sel_parity = 0; QPen pen2; for (const auto &iter : table) { if (!isObjectVisible(layers, iter.getRow())) { continue; } float x = iter.getRow().getValue(m_x_axis); float y = iter.getRow().getValue(m_y_axis); if (!std::isfinite(x) || !std::isfinite(y) || x == -1.0f || y == -1.0f) { continue; } QRgb rgb; if (m_view_monochrome) { rgb = m_foreground; } else { PafColor color = dXreimpl::getDisplayColor(iter.getKey(), iter.getRow(), tableHandle); rgb = qRgb(color.redb(), color.greenb(), color.blueb()); } int tempspacer = spacer; if (iter.getRow().isSelected()) { tempspacer = (spacer + 1) * 2 - 1; if (m_view_monochrome) { rgb = qRgb(0xff, 0, 0); } } if (tempspacer == 0) { tempspacer = 1; } if (!m_view_monochrome) { pen2 = QPen(QBrush(QColor(rgb)), spacer, Qt::SolidLine, Qt::FlatCap); // pDC->setPen(QPen(QBrush(QColor(rgb)), spacer, Qt::SolidLine, Qt::FlatCap)); } else if (sel_parity != (iter.getRow().isSelected() ? 1 : -1)) { pen2 = QPen(QBrush(QColor(rgb)), spacer, Qt::SolidLine, Qt::FlatCap); // pDC->setPen(QPen(QBrush(QColor(rgb)), spacer, Qt::SolidLine, Qt::FlatCap)); sel_parity = (iter.getRow().isSelected() ? 1 : -1); } pDC->setPen(pen2); // QPoint point(screenX(x), screenY(y)); pDC->drawLine(QPoint(point.x() - tempspacer, point.y() - tempspacer), QPoint(point.x() + tempspacer + 1, point.y() + tempspacer + 1)); pDC->drawLine(QPoint(point.x() - tempspacer, point.y() + tempspacer), QPoint(point.x() + tempspacer + 1, point.y() - tempspacer - 1)); pDC->setPen(pen); } // trend line if reqd if (m_view_trend_line) { QPoint bl, tr; QString string; if (m_regression.model(m_data_bounds.bottom_left.x) < m_data_bounds.bottom_left.y) { // check line is on page if (m_regression.model(m_data_bounds.top_right.x) > m_data_bounds.bottom_left.y) { bl = QPoint(screenX(m_regression.invmodel(m_data_bounds.bottom_left.y)), m_screen_bounds.top()); if (m_regression.model(m_data_bounds.top_right.x) < m_data_bounds.top_right.y) { tr = QPoint(m_screen_bounds.right(), screenY(m_regression.model(m_data_bounds.top_right.x))); } else { tr = QPoint(screenX(m_regression.invmodel(m_data_bounds.top_right.y)), m_screen_bounds.bottom()); } pDC->drawLine(bl, tr); } } else if (m_regression.model(m_data_bounds.bottom_left.x) > m_data_bounds.top_right.y) { // check line is on page if (m_regression.model(m_data_bounds.top_right.x) < m_data_bounds.top_right.y) { bl = QPoint(screenX(m_regression.invmodel(m_data_bounds.bottom_left.x)), m_screen_bounds.bottom()); if (m_regression.model(m_data_bounds.top_right.x) > m_data_bounds.bottom_left.x) { tr = QPoint(m_screen_bounds.right(), screenY(m_regression.model(m_data_bounds.top_right.x))); } else { tr = QPoint(screenX(m_regression.invmodel(m_data_bounds.top_right.y)), m_screen_bounds.top()); } pDC->drawLine(bl, tr); } } else { bl = QPoint(m_screen_bounds.left(), screenY(m_regression.model(m_data_bounds.bottom_left.x))); double trv = m_regression.model(m_data_bounds.top_right.x); if (trv >= m_data_bounds.bottom_left.y && trv <= m_data_bounds.top_right.y) { string += " v1"; tr = QPoint(m_screen_bounds.right(), screenY(trv)); } else if (m_regression.b() > 0) { // upward inclined string += " v2"; tr = QPoint(screenX(m_regression.invmodel(m_data_bounds.top_right.y)), m_screen_bounds.bottom()); } else { // downward inclined string += " v3"; tr = QPoint(screenX(m_regression.invmodel(m_data_bounds.bottom_left.y)), m_screen_bounds.top()); } pDC->drawLine(bl, tr); } } QString string; int textpos = texth; if (m_view_rsquared) { // set text formating // hope ascii superscript 2 in place! string = QString(tr("R\xb2 = %1").arg(sqr(m_regression.r()))); pDC->drawText(QPointF(rect.width() - string.length() * 7, textpos), string); textpos += texth; } if (m_view_equation) { if (m_regression.a() >= 0) { string = QString(tr("y = %1 x + %1").arg(m_regression.b()).arg(m_regression.a())); } else { string = QString(tr("y = %1 x - %1").arg(m_regression.b()).arg(fabs(m_regression.a()))); } pDC->drawText(QPointF(rect.width() - string.length() * 7, textpos), string); } QString xlabel(table.getColumnName(m_x_axis).c_str()); pDC->drawText(QPointF(width / 2 + minx_pos, 99 * rect.height() / 100 - texth), xlabel); QString ylabel(table.getColumnName(m_y_axis).c_str()); // this is last to avoid switch between hfont and vfont QMatrix matrix; matrix.translate(sizey.width(), rect.height() / 2 + ylabel.length() * 7 / 2); matrix.rotate(270); pDC->setMatrix(matrix); pDC->drawText(QPointF(sizey.width() / 2, height + miny_pos), ylabel); pDC->setPen(oldpen); return true; } // QPlotView message handlers int QPlotView::OnRedraw(int wParam, int lParam) { if (pDoc->GetRemenuFlag(QGraphDoc::VIEW_SCATTER)) { pDoc->SetRemenuFlag(QGraphDoc::VIEW_SCATTER, false); MainWindow *m_Frm = (MainWindow *)pDoc->m_mainFrame; m_Frm->RedoPlotViewMenu(pDoc); } if (pDoc->GetRedrawFlag(QGraphDoc::VIEW_SCATTER) != QGraphDoc::REDRAW_DONE) { if (!pDoc->m_communicator) { m_queued_redraw = false; while (!pDoc->SetRedrawFlag(QGraphDoc::VIEW_SCATTER, QGraphDoc::REDRAW_DONE)) { // prefer waitformultipleobjects here // Sleep(1); } } else { // killTimer(Tid_redraw); // Tid_redraw = startTimer(100); m_queued_redraw = true; } } return 0; } void QPlotView::keyPressEvent(QKeyEvent *e) { char key = e->key(); } void QPlotView::RedoIndices() { if (pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessed()) { AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); idx_x = makeAttributeIndex(table, m_x_axis); idx_y = makeAttributeIndex(table, m_y_axis); } } void QPlotView::timerEvent(QTimerEvent *event) { if (event->timerId() == Tid_redraw) { if (m_queued_redraw) { // Internal own redraw OnRedraw(0, 0); } } } void QPlotView::OnViewTrendLine() { if (m_view_trend_line) { m_view_trend_line = false; } else { m_view_trend_line = true; } update(); } void QPlotView::OnViewRsquared() { if (m_view_rsquared) { m_view_rsquared = false; } else { m_view_rsquared = true; } update(); } void QPlotView::OnViewColor() { if (m_view_monochrome) { m_view_monochrome = false; } else { m_view_monochrome = true; } update(); } void QPlotView::SetAxis(int axis, int col, bool reset) { if (axis == 0) { if (m_x_axis != col) { m_x_axis = col; } } else { if (m_y_axis != col) { m_y_axis = col; } } if (reset) { RedoIndices(); ResetRegression(); } } void QPlotView::ResetRegression() { m_regression.clear(); if (m_x_axis != -1 && m_y_axis != -1 && pDoc->m_meta_graph && pDoc->m_meta_graph->viewingProcessed()) { AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); for (auto iter = table.begin(); iter != table.end(); iter++) { if (isObjectVisible(pDoc->m_meta_graph->getLayers(), iter->getRow())) { float x = iter->getRow().getValue(m_x_axis); float y = iter->getRow().getValue(m_y_axis); if (std::isfinite(x) && std::isfinite(y) && x != -1.0f && y != -1.0f) { m_regression.add(x, y); } } } } } void QPlotView::mousePressEvent(QMouseEvent *e) { switch (e->button()) { case Qt::LeftButton: pressed_nFlags = MK_LBUTTON; break; case Qt::RightButton: pressed_nFlags = MK_RBUTTON; break; default: break; } m_mouse_point = e->pos(); m_drag_rect_a = QRect(0, 0, 0, 0); m_drag_rect_b = QRect(0, 0, 0, 0); m_selecting = true; m_drawdragrect = true; update(); } void QPlotView::mouseMoveEvent(QMouseEvent *e) { if (pressed_nFlags == MK_RBUTTON) return; QPoint point = e->pos(); if (m_selecting) { int x1, y1, x2, y2; if (m_mouse_point.x() > point.x()) { x1 = point.x(); x2 = m_mouse_point.x(); } else { x1 = m_mouse_point.x(); x2 = point.x(); } if (m_mouse_point.y() > point.y()) { y1 = point.y(); y2 = m_mouse_point.y(); } else { y1 = m_mouse_point.y(); y2 = point.y(); } m_drag_rect_a = QRect(x1, y1, x2 - x1, y2 - y1); m_drawdragrect = true; update(); } hit_point = point; } void QPlotView::mouseReleaseEvent(QMouseEvent *e) { if (pressed_nFlags == MK_RBUTTON) { pDoc->m_meta_graph->clearSel(); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_SELECTION); return; } m_selecting = false; AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); auto xRange = getIndexItemsInValueRange(idx_x, table, dataX(m_drag_rect_a.left() - 2), dataX(m_drag_rect_a.right() + 2)); auto yRange = getIndexItemsInValueRange(idx_y, table, dataY(m_drag_rect_a.bottom() + 2), dataY(m_drag_rect_a.top() - 2)); // Stop drag rect... m_drag_rect_a = QRect(0, 0, 0, 0); m_drawdragrect = false; update(); // work out selection std::set xkeys; for (auto iter = xRange.first; iter != xRange.second; iter++) { xkeys.insert(iter->key); } std::vector finalkeys; for (auto iter = yRange.first; iter != yRange.second; iter++) { if (xkeys.find(iter->key) != xkeys.end()) { finalkeys.push_back(iter->key.value); } } // redraw selection set bool add = false; if (pressed_nFlags & MK_SHIFT) { add = true; } pDoc->m_meta_graph->setSelSet(finalkeys, add); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_SELECTION); } void QPlotView::OnViewOrigin() { m_view_origin = !m_view_origin; update(); } void QPlotView::OnViewEquation() { m_view_equation = !m_view_equation; update(); } ================================================ FILE: depthmapX/views/plotview/plotview.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // depthmapX - spatial network analysis platform #include ///////////////////////////////////////////////////////////////////////////// // PlotView view // class CHoverWnd; #include "qpixmap.h" #include #include #include #include "GraphDoc.h" #include "genlib/linreg.h" #define MK_LBUTTON 0x0001 #define MK_RBUTTON 0x0002 #define MK_SHIFT 0x0004 #define MK_CONTROL 0x0008 #define MK_MBUTTON 0x0010 class QPlotView : public QWidget { Q_OBJECT // Attributes public: QGraphDoc *pDoc; QPlotView(); QSize sizeHint() const; int m_x_axis; int m_y_axis; int curr_x; int curr_y; std::vector idx_x; std::vector idx_y; void RedoIndices(); bool m_queued_redraw; bool m_view_origin; bool m_view_trend_line; bool m_view_equation; bool m_view_rsquared; bool m_view_monochrome; LinReg m_regression; // double dataX(int x); int screenX(double x); double dataY(int x); int screenY(double x); // QtRegion m_data_bounds; QRect m_screen_bounds; // QPoint m_mouse_point; QRect m_drag_rect_a; QRect m_drag_rect_b; bool m_selecting; bool m_drawdragrect; QRgb m_background; QRgb m_foreground; void *m_parent; // MainWindow* // Operations public: void SetAxis(int axis, int col, bool reset); void ResetRegression(); bool Output(QPainter *pDC, QGraphDoc *pDoc, bool screendraw); // this is a tells us how many 100ms ticks have passed since the mouse moved int Tid_redraw; void OnViewTrendLine(); void OnViewRsquared(); void OnViewColor(); void OnViewOrigin(); void OnViewEquation(); int OnRedraw(int wParam, int lParam); void OnLButtonDown(bool nFlags, QPoint point); void OnMouseMove(bool nFlags, QPoint point); void OnLButtonUp(bool nFlags, QPoint point); // Implementation protected: virtual bool eventFilter(QObject *object, QEvent *e); virtual void keyPressEvent(QKeyEvent *event); virtual void paintEvent(QPaintEvent *event); virtual void resizeEvent(QResizeEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); virtual void closeEvent(QCloseEvent *event); virtual void timerEvent(QTimerEvent *event); private: QPixmap *m_pixmap; }; ================================================ FILE: depthmapX/views/tableview/tableview.cpp ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "tableview.h" #include "mainwindow.h" #include #include #include #include #include #include #include #include #include #define ROW_HEIGHT 20 #define PG_COUNT 40 TableView::TableView(Settings &settings, QWidget *parent, QGraphDoc *p) : QTableWidget(parent) { m_mainWindow = parent; pDoc = p; m_from = m_curr_row = 0; connect(this, SIGNAL(itemChanged(QTableWidgetItem *)), this, SLOT(itemChanged(QTableWidgetItem *))); connect(this, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(itemEditChanged(QTableWidgetItem *))); RedoTable(); setWindowIcon(QIcon(tr(":/images/cur/icon-1-5.png"))); setWindowTitle(pDoc->m_base_title + ":Table View"); setVerticalScrollMode(QAbstractItemView::ScrollPerItem); m_protect_edit = false; m_initialSize = settings.readSetting(SettingTag::depthmapViewSize, QSize(2000, 2000)).toSize(); } void TableView::focusInEvent(QFocusEvent *e) { RedoTable(); pDoc->SetRedrawFlag(QGraphDoc::VIEW_TABLE, QGraphDoc::REDRAW_DONE); QTableWidget::focusInEvent(e); } void TableView::RedoTable() { clear(); if (pDoc->m_meta_graph->viewingProcessed()) { const AttributeTable &table = pDoc->m_meta_graph->getAttributeTable(); m_column_count = table.getNumColumns(); setColumnCount(m_column_count + 1); connect(horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(colum_Sort(int))); verticalHeader()->hide(); QTableWidgetItem *Item = new QTableWidgetItem("Ref Number"); Item->setTextAlignment(Qt::AlignLeft); setHorizontalHeaderItem(0, Item); for (int i = 0; i < m_column_count; i++) { QTableWidgetItem *Item = new QTableWidgetItem(QString("%1").arg(table.getColumnName(i).c_str())); Item->setTextAlignment(Qt::AlignLeft); setHorizontalHeaderItem(i + 1, Item); } m_row_count = table.getNumRows(); setRowCount(m_row_count); PrepareCache(m_curr_row); } } void TableView::scrollContentsBy(int dx, int dy) { if (dy != 0) { PrepareCache(m_curr_row - dy); m_curr_row -= dy; } QTableWidget::scrollContentsBy(dx, dy); } QSize TableView::sizeHint() const { return m_initialSize; } void TableView::PrepareCache(int to) { m_updating = true; QTableWidgetItem *Item; const AttributeTableHandle &tableHandle = pDoc->m_meta_graph->getAttributeTableHandle(); auto &index = tableHandle.getTableIndex(); int diff = PG_COUNT; if (to + PG_COUNT >= m_row_count) { diff = m_row_count - to; } for (int i = 0; i < diff; i++) { auto &indexItem = index[to + i]; for (int j = 0; j < m_column_count + 1; j++) { if (!j) { Item = item(to + i, j); if (Item) { if (indexItem.row->isSelected()) Item->setCheckState(Qt::Checked); else Item->setCheckState(Qt::Unchecked); } else { Item = new QTableWidgetItem(QString("%1").arg(indexItem.key.value)); if (indexItem.row->isSelected()) Item->setCheckState(Qt::Checked); else Item->setCheckState(Qt::Unchecked); setItem(to + i, 0, Item); continue; } } if (!item(to + i, j)) { Item = new QTableWidgetItem(QString("%1").arg(indexItem.row->getValue(j - 1))); setRowHeight(to + i, ROW_HEIGHT); setItem(to + i, j, Item); } } } m_updating = false; } void TableView::itemChanged(QTableWidgetItem *item) { if (m_updating) return; int row = item->row(); int col = item->column(); MetaGraph *graph = pDoc->m_meta_graph; AttributeTable &table = graph->getAttributeTable(); AttributeTableHandle &tableHandle = graph->getAttributeTableHandle(); auto &index = tableHandle.getTableIndex(); if (col == 0) { std::vector x; x.push_back(index[row].key.value); pDoc->m_meta_graph->setSelSet(x); pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_SELECTION, this); PrepareCache(m_curr_row); } else { double value = -1; try { value = std::stod(item->text().toStdString()); } catch (std::invalid_argument) { QMessageBox::warning(this, tr("Warning"), tr("Cannot convert text to number"), QMessageBox::Ok, QMessageBox::Ok); return; } if (graph && graph->viewingProcessed()) { // go for the change: double value2 = index[row].row->getValue(col - 1); if (value2 == 0 || fabs((value / value2) - 1.0) > 1e-5) { index[row].mutable_row->setValue(col - 1, value); pDoc->modifiedFlag = true; } RedoTable(); // note: this as caller will prevent us from redrawing ourself: // could be either new data or new selection, just go for a big redraw: pDoc->SetRedrawFlag(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_GRAPH, QGraphDoc::NEW_DATA, this); } } } void TableView::colum_Sort(int col_id) { if (col_id - 1 != pDoc->m_meta_graph->getDisplayedAttribute()) { pDoc->m_meta_graph->setDisplayedAttribute(col_id - 1); ((MainWindow *)m_mainWindow)->chooseAttributeOnIndex(col_id); clearContents(); PrepareCache(m_curr_row); return; RedoTable(); } } void TableView::itemEditChanged(QTableWidgetItem *item) { int row = item->row(); int col = item->column(); if (col > 0 && col < pDoc->m_meta_graph->getAttributeTable().getNumColumns() + 1) { // don't let them edit a locked attribute if (pDoc->m_meta_graph->getAttributeTable().getColumn(col - 1).isLocked()) { QMessageBox::warning(this, tr("Warning"), tr("This column is locked and cannot be edited"), QMessageBox::Ok, QMessageBox::Ok); } } } void TableView::closeEvent(QCloseEvent *event) { pDoc->m_view[QGraphDoc::VIEW_TABLE] = NULL; if (!pDoc->OnCloseDocument(QGraphDoc::VIEW_TABLE)) { pDoc->m_view[QGraphDoc::VIEW_TABLE] = this; event->ignore(); } } void TableView::resizeEvent(QResizeEvent *event) { QTableView::resizeEvent(event); pDoc->m_view[QGraphDoc::VIEW_TABLE] = this; } ================================================ FILE: depthmapX/views/tableview/tableview.h ================================================ // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "GraphDoc.h" #include "settings.h" #include class QEvent; class QTableWidgetItem; class TableView : public QTableWidget { Q_OBJECT public: TableView(Settings &settings, QWidget *parent = 0, QGraphDoc *p = 0); QSize sizeHint() const; int m_column_count; int m_row_count; int m_from; int m_curr_row; QWidget *m_mainWindow; QGraphDoc *pDoc; bool m_protect_edit; void RedoTable(); private slots: void itemChanged(QTableWidgetItem *item); void itemEditChanged(QTableWidgetItem *); void colum_Sort(int sort); protected: virtual void closeEvent(QCloseEvent *event); virtual void resizeEvent(QResizeEvent *event); virtual void scrollContentsBy(int dx, int dy); void focusInEvent(QFocusEvent *e); private: void PrepareCache(int to); bool m_custom; QSize m_initialSize; bool m_updating = false; }; ================================================ FILE: depthmapX/views/viewhelpers.cpp ================================================ #include "viewhelpers.h" #include namespace ViewHelpers { Point2f calculateCenter(const QPoint& point, const QPoint &oldCentre, double factor) { int diffX = oldCentre.x() - point.x(); int diffY = oldCentre.y() - point.y(); return Point2f(point.x() + double(diffX) * factor, point.y() + double(diffY) * factor); } std::string getCurrentDate() { time_t now = time(NULL); char timeString[11]; strftime(timeString, 11, "%Y/%m/%d", localtime(&now)); return timeString; } } ================================================ FILE: depthmapX/views/viewhelpers.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef DEPTHMAPX_VIEWHELPERS_H #define DEPTHMAPX_VIEWHELPERS_H #include #include "genlib/p2dpoly.h" #include namespace ViewHelpers { Point2f calculateCenter(const QPoint& point, const QPoint &oldCentre, double factor); std::string getCurrentDate(); } #endif // VIEWHELPERS_H ================================================ FILE: depthmapXTest/CMakeLists.txt ================================================ set(depthmapXTest depthmapXTest) # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) # Instruct CMake to run moc automatically when needed set(CMAKE_AUTOMOC ON) # Create code from a list of Qt designer ui files # set(CMAKE_AUTOUIC ON) # set(CMAKE_AUTORCC ON) # Find the QtWidgets library find_package(Qt5 COMPONENTS Core Widgets Gui OpenGL REQUIRED) include_directories(${QT}) add_compile_definitions(_DEPTHMAP) set(depthmapXTest_SRCS main.cpp testgllines.cpp testgllinesuniform.cpp testglrastertexture.cpp ../depthmapX/views/glview/gllines.h ../depthmapX/views/glview/gllines.cpp ../depthmapX/views/glview/gllinesuniform.h ../depthmapX/views/glview/gllinesuniform.cpp ../depthmapX/views/glview/glrastertexture.h ../depthmapX/views/glview/glrastertexture.cpp) include_directories("../ThirdParty/Catch") set(LINK_LIBS salalib genlib mgraph440) if(APPLE) add_definitions(-DGL_SILENCE_DEPRECATION) endif(APPLE) add_executable(${depthmapXTest} ${depthmapXTest_SRCS}) find_package(OpenGL REQUIRED) target_link_libraries(${depthmapXTest} Qt5::OpenGL salalib genlib OpenGL::GL OpenGL::GLU) ================================================ FILE: depthmapXTest/main.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: depthmapXTest/testgllines.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapX/views/glview/gllines.h" TEST_CASE("Test GLLines::loadLineData()", "") { Point2f line1Start(0,0); Point2f line1End(2,4); PafColor line1colour(255,0,0); Point2f line2Start(1,1); Point2f line2End(3,5); PafColor line2colour(0,255,0); std::vector> colouredLines; std::pair colouredLine1 = std::pair (SimpleLine(line1Start, line1End), line1colour); colouredLines.push_back(colouredLine1); std::pair colouredLine2 = std::pair (SimpleLine(line2Start, line2End), line2colour); colouredLines.push_back(colouredLine2); GLLines gllines; gllines.loadLineData(colouredLines); REQUIRE(gllines.vertexCount() == 4); } ================================================ FILE: depthmapXTest/testgllinesuniform.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapX/views/glview/gllinesuniform.h" TEST_CASE("Test GLLinesUniform::loadLineData()", "") { Point2f line1Start(0,0); Point2f line1End(2,4); Point2f line2Start(1,1); Point2f line2End(3,5); std::vector lines; SimpleLine line1 = SimpleLine(line1Start, line1End); lines.push_back(line1); SimpleLine line2 = SimpleLine(line2Start, line2End); lines.push_back(line2); QRgb lineColour = qRgb(255,0,0); GLLinesUniform gllinesuniform; gllinesuniform.loadLineData(lines, lineColour); REQUIRE(gllinesuniform.vertexCount() == 4); } ================================================ FILE: depthmapXTest/testglrastertexture.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../depthmapX/views/glview/glrastertexture.h" TEST_CASE("Test GLRasterTexture::loadRegionData()", "") { float bottomLeftX = 0; float bottomLeftY = 0; float topRightX = 2; float topRightY = 4; QRgb lineColour = qRgb(255,0,0); GLRasterTexture glrastertexture; glrastertexture.loadRegionData(bottomLeftX, bottomLeftY, topRightX, topRightY); REQUIRE(glrastertexture.vertexCount() == 4); } ================================================ FILE: depthmapXcli/CMakeLists.txt ================================================ set(depthmapXcli depthmapXcli) set(depthmapXcli_SRCS main.cpp printcommunicator.cpp commandlineparser.cpp runmethods.cpp radiusconverter.cpp vgaparser.cpp linkparser.cpp performancewriter.cpp modeparserregistry.cpp visprepparser.cpp axialparser.cpp parsingutils.cpp agentparser.cpp isovistparser.cpp exportparser.cpp importparser.cpp stepdepthparser.cpp segmentparser.cpp mapconvertparser.cpp) set(LINK_LIBS salalib genlib mgraph440) set(modules_cli "" CACHE INTERNAL "modules_cli" FORCE) set(MODULES_GUI FALSE) set(MODULES_CLI TRUE) set(MODULES_CLI_TEST FALSE) set(MODULES_CORE FALSE) set(MODULES_CORE_TEST FALSE) add_subdirectory(../modules modules) add_executable(${depthmapXcli} ${depthmapXcli_SRCS}) target_link_libraries(${depthmapXcli} ${LINK_LIBS} ${modules_cli} ${modules_core}) ================================================ FILE: depthmapXcli/agentparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agentparser.h" #include "exceptions.h" #include #include "radiusconverter.h" #include "runmethods.h" #include "parsingutils.h" #include "salalib/entityparsing.h" #include using namespace depthmapX; AgentParser::AgentParser() : m_agentMode(AgentMode::NONE) {} void AgentParser::parse(int argc, char *argv[]) { std::vector points; std::string pointFile; for ( int i = 1; i < argc; ) { if ( std::strcmp ("-am", argv[i]) == 0) { if (m_agentMode != AgentMode::NONE) { throw CommandLineException("-am can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-am", i) if ( std::strcmp(argv[i], "standard") == 0 ) { m_agentMode = AgentMode::STANDARD; } else if ( std::strcmp(argv[i], "los-length") == 0 ) { m_agentMode = AgentMode::LOS_LENGTH; } else if ( std::strcmp(argv[i], "occ-length") == 0 ) { m_agentMode = AgentMode::OCC_LENGTH; } else if ( std::strcmp(argv[i], "occ-any") == 0 ) { m_agentMode = AgentMode::OCC_ANY; } else if ( std::strcmp(argv[i], "occ-group-45") == 0) { m_agentMode = AgentMode::OCC_GROUP_45; } else if ( std::strcmp(argv[i], "occ-group-60") == 0) { m_agentMode = AgentMode::OCC_GROUP_60; } else if ( std::strcmp(argv[i], "occ-furthest") == 0) { m_agentMode = AgentMode::OCC_FURTHEST; } else if ( std::strcmp(argv[i], "bin-far-dist") == 0) { m_agentMode = AgentMode::BIN_FAR_DIST; } else if ( std::strcmp(argv[i], "bin-angle") == 0) { m_agentMode = AgentMode::BIN_ANGLE; } else if ( std::strcmp(argv[i], "bin-far-dist-angle") == 0) { m_agentMode = AgentMode::BIN_FAR_DIST_ANGLE; } else if ( std::strcmp(argv[i], "bin-memory") == 0) { m_agentMode = AgentMode::BIN_MEMORY; } else { throw CommandLineException(std::string("Invalid AGENTS mode: ") + argv[i]); } } else if ( std::strcmp(argv[i], "-ats") == 0 ) { if (m_totalSystemTimestemps > 0) { throw CommandLineException("-ats can only be used once"); } ENFORCE_ARGUMENT("-ats", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-ats must be a number >0, got ") + argv[i]); } m_totalSystemTimestemps = std::atoi(argv[i]); if (m_totalSystemTimestemps <= 0) { throw CommandLineException(std::string("-ats must be a number >0, got ") + argv[i]); } } else if ( std::strcmp(argv[i], "-arr") == 0 ) { if (m_releaseRate > 0) { throw CommandLineException("-arr can only be used once"); } ENFORCE_ARGUMENT("-arr", i) if (!has_only_digits_dots_commas(argv[i])) { throw CommandLineException(std::string("-arr must be a number >0, got ") + argv[i]); } m_releaseRate = std::atof(argv[i]); if (m_releaseRate <= 0) { throw CommandLineException(std::string("-arr must be a number >0, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-atrails") == 0) { if (m_recordTrailsForAgents >= 0) { throw CommandLineException("-atrails can only be used once"); } ENFORCE_ARGUMENT("-atrails", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-atrails must be a number >=1 or 0 for all (max possible = 50), got ") + argv[i]); } m_recordTrailsForAgents = std::atoi(argv[i]); if (m_recordTrailsForAgents < 0) { throw CommandLineException(std::string("-atrails must be a number >=1 or 0 for all (max possible = 50), got ") + argv[i]); } } else if (std::strcmp(argv[i], "-afov") == 0) { if (m_agentFOV > 0) { throw CommandLineException("-afov can only be used once"); } ENFORCE_ARGUMENT("-afov", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-afov must be a number between 1 and 32, got ") + argv[i]); } m_agentFOV = std::atoi(argv[i]); if (m_agentFOV <= 0 || m_agentFOV > 32) { throw CommandLineException(std::string("-afov must be a number between 1 and 32, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-asteps") == 0) { if (m_agentStepsBeforeTurnDecision > 0) { throw CommandLineException("-asteps can only be used once"); } ENFORCE_ARGUMENT("-asteps", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-asteps must be a number >0, got ") + argv[i]); } m_agentStepsBeforeTurnDecision = std::atoi(argv[i]); if (m_agentStepsBeforeTurnDecision <= 0) { throw CommandLineException(std::string("-asteps must be a number >0, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-alife") == 0) { if (m_agentLifeTimesteps > 0) { throw CommandLineException("-alife can only be used once"); } ENFORCE_ARGUMENT("-alife", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-alife must be a number >0, got ") + argv[i]); } m_agentLifeTimesteps = std::atoi(argv[i]); if (m_agentLifeTimesteps <= 0) { throw CommandLineException(std::string("-alife must be a number >0, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-alocseed") == 0) { if (!pointFile.empty()) { throw CommandLineException("-alocseed cannot be used together with -alocfile"); } if (!points.empty()) { throw CommandLineException("-alocseed cannot be used together with -aloc"); } ENFORCE_ARGUMENT("-alocseed", i) if (!has_only_digits(argv[i])) { std::stringstream message; message << "Invalid starting location seed provided (" << argv[i] << "). Should only contain digits" << std::flush; throw CommandLineException(message.str().c_str()); } m_randomReleaseLocationSeed = std::atof(argv[i]); if (m_randomReleaseLocationSeed < 0 || m_randomReleaseLocationSeed > 10) { throw CommandLineException(std::string("-alocseed must be a number between 0 and 10, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-alocfile") == 0) { if (!points.empty()) { throw CommandLineException("-alocfile cannot be used together with -aloc"); } if (m_randomReleaseLocationSeed > -1) { throw CommandLineException("-alocfile cannot be used together with -alocseed"); } ENFORCE_ARGUMENT("-alocfile", i) pointFile = argv[i]; } else if (std::strcmp(argv[i], "-aloc") == 0) { if (!pointFile.empty()) { throw CommandLineException("-aloc cannot be used together with -alocfile"); } if (m_randomReleaseLocationSeed > -1) { throw CommandLineException("-aloc cannot be used together with -alocseed"); } ENFORCE_ARGUMENT("-aloc", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid starting point provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } points.push_back(argv[i]); } else if (std::strcmp(argv[i], "-ot") == 0) { ENFORCE_ARGUMENT("-ot", i) if ( std::strcmp(argv[i], "graph") == 0 ) { if(std::find(m_outputTypes.begin(), m_outputTypes.end(), OutputType::GRAPH) != m_outputTypes.end()) { throw CommandLineException("Same output type argument (graph) provided twice"); } m_outputTypes.push_back(OutputType::GRAPH); } else if ( std::strcmp(argv[i], "gatecounts") == 0 ) { if(std::find(m_outputTypes.begin(), m_outputTypes.end(), OutputType::GATECOUNTS) != m_outputTypes.end()) { throw CommandLineException("Same output type argument (gatecounts) provided twice"); } m_outputTypes.push_back(OutputType::GATECOUNTS); } else if ( std::strcmp(argv[i], "trails") == 0 ) { if(std::find(m_outputTypes.begin(), m_outputTypes.end(), OutputType::TRAILS) != m_outputTypes.end()) { throw CommandLineException("Same output type argument (trails) provided twice"); } m_outputTypes.push_back(OutputType::TRAILS); } } ++i; } if(m_agentMode == AgentMode::NONE) { m_agentMode = AgentMode::STANDARD; } if (m_totalSystemTimestemps == 0) { throw CommandLineException("Total number of timesteps (-ats ) is required"); } if (m_releaseRate == 0) { throw CommandLineException("Release rate (-arr ) is required"); } if (m_agentFOV == 0) { throw CommandLineException("Agent field-of-view (-afov ) is required"); } if (m_agentStepsBeforeTurnDecision == 0) { throw CommandLineException("Agent number of steps before turn decision (-asteps ) is required"); } if (m_agentLifeTimesteps == 0) { throw CommandLineException("Agent life in timesteps (-alife ) is required"); } if (pointFile.empty() && points.empty() && m_randomReleaseLocationSeed == -1) { throw CommandLineException("Either -aloc, -alocfile or -alocseed must be given"); } if(!pointFile.empty()) { std::ifstream pointsStream(pointFile); if (!pointsStream) { std::stringstream message; message << "Failed to load file " << pointFile << ", error " << std::strerror(errno) << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } std::vector parsed = EntityParsing::parsePoints(pointsStream, '\t'); m_releasePoints.insert(std::end(m_releasePoints), std::begin(parsed), std::end(parsed)); } else if(!points.empty()) { std::stringstream pointsStream; pointsStream << "x,y"; std::vector::iterator iter = points.begin(), end = points.end(); for ( ; iter != end; ++iter ) { pointsStream << "\n" << *iter; } std::vector parsed = EntityParsing::parsePoints(pointsStream, ','); m_releasePoints.insert(std::end(m_releasePoints), std::begin(parsed), std::end(parsed)); } } void AgentParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runAgentAnalysis(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/agentparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include "imodeparser.h" #include "genlib/p2dpoly.h" #include "commandlineparser.h" class AgentParser : public IModeParser { public: virtual std::string getModeName() const { return "AGENTS"; } virtual std::string getHelp() const { return "Mode options for AGENTS:\n"\ "-am one of:\n" " standard\n"\ " los-length (Line of Sight length)\n"\ " occ-length (Occluded length)\n"\ " occ-any (Any occlusions)\n"\ " occ-group-45 (Occlusion group bins - 45 degrees)\n"\ " occ-group-60 (Occlusion group bins - 60 degrees)\n"\ " occ-furthest (Furthest occlusion per bin)\n"\ " bin-far-dist (Per bin far distance weighted)\n"\ " bin-angle (Per bin angle weighted)\n"\ " bin-far-dist-angle (Per bin far-distance and angle weighted)\n"\ " bin-memory (Per bin memory)\n"\ "-ats set total system timesteps\n"\ "-arr set agent release rate (likelyhood of release per timestep)\n"\ "-atrails record trails for this amount of agents (set to 0 to record all"\ ", with max possible currently = 50)\n"\ "-afov set agent field-of-view (bins)\n"\ "-asteps set agent steps before turn decision\n"\ "-alife set agent total lifetime (in timesteps)\n"\ "-alocseed set agents to start at random locations with specific seed (0 to 10)\n"\ "-alocfile \n"\ "-aloc provided in csv (x1,y1) "\ "for example \"0.1,0.2\". Provide multiple times for multiple links\n"\ "-ot available output types (may use more than one):"\ " graph (graph file, default)"\ " gatecounts (csv with cells of grid with gate counts)"\ " trails (csv with lines showing path traversed by each agent)"; } public: AgentParser(); virtual void parse(int argc, char *argv[]); virtual void run(const CommandLineParser &clp, IPerformanceSink& perfWriter) const; enum AgentMode{ NONE, STANDARD, LOS_LENGTH, OCC_LENGTH, OCC_ANY, OCC_GROUP_45, OCC_GROUP_60, OCC_FURTHEST, BIN_FAR_DIST, BIN_ANGLE, BIN_FAR_DIST_ANGLE, BIN_MEMORY }; enum OutputType{ GRAPH, GATECOUNTS, TRAILS }; // agent options AgentMode getAgentMode() const { return m_agentMode; } int totalSystemTimestemps() const { return m_totalSystemTimestemps; } double releaseRate() const { return m_releaseRate; } int recordTrailsForAgents() const { return m_recordTrailsForAgents; } int randomReleaseLocationSeed() const { return m_randomReleaseLocationSeed; } int agentFOV() const { return m_agentFOV; } int agentStepsBeforeTurnDecision() const { return m_agentStepsBeforeTurnDecision; } int agentLifeTimesteps() const { return m_agentLifeTimesteps; } std::vector getReleasePoints() const { return m_releasePoints; } std::vector outputTypes() const { return m_outputTypes; } private: // agent options AgentMode m_agentMode; int m_totalSystemTimestemps = 0; double m_releaseRate = 0.0; int m_recordTrailsForAgents = -1; int m_agentFOV = 0; // Field of view (bins) int m_agentStepsBeforeTurnDecision = 0; // Steps before turn decision int m_agentLifeTimesteps = 0; // Timesteps in system int m_randomReleaseLocationSeed = -1; std::vector m_releasePoints; std::vector m_outputTypes; }; ================================================ FILE: depthmapXcli/axialparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "axialparser.h" #include "parsingutils.h" #include "exceptions.h" #include "salalib/entityparsing.h" #include "runmethods.h" #include using namespace depthmapX; AxialParser::AxialParser() : m_runFewestLines(false), m_runAnalysis(false), m_choice(false), m_local(false), m_rra(false) { } std::string AxialParser::getModeName() const { return "AXIAL"; } std::string AxialParser::getHelp() const { return "Mode options for Axial Analysis:\n"\ " -xl , Calculate all lines map from this seed point (can be used more than once)\n" " -xf Calculate fewest lines map from all lines map\n"\ " -xa run axial anlysis with specified radii\n"\ " All modes expect to find the required input in the in graph\n"\ " Any combination of flags above can be specified, they will always be run in the order -aa -af -au -ax\n"\ " Further flags for axial analysis are:\n"\ " -xac Include choice (betweenness)\n"\ " -xal Include local measures\n"\ " -xar Include RA, RRA and total depth\n"\ " -xaw perform weighted analysis using this attribute\n"\ "\n"; } void AxialParser::parse(int argc, char **argv) { for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "-xl") == 0) { ENFORCE_ARGUMENT("-xl", i) m_allAxesRoots.push_back(EntityParsing::parsePoint(argv[i])); } else if(std::strcmp(argv[i], "-xf") == 0) { m_runFewestLines = true; } else if (std::strcmp(argv[i], "-xa") == 0) { ENFORCE_ARGUMENT("-xa", i) if (m_runAnalysis) { throw CommandLineException("-xa can only be used once"); } m_radii = depthmapX::parseRadiusList(argv[i]); m_runAnalysis = true; } else if (std::strcmp(argv[i], "-xal") == 0) { m_local = true; } else if (std::strcmp(argv[i], "-xac") == 0) { m_choice = true; } else if(std::strcmp(argv[i], "-xar") == 0) { m_rra = true; } else if (std::strcmp(argv[i], "-xaw") == 0) { ENFORCE_ARGUMENT("-xaw", i) m_attribute = argv[i]; } } if (!runAllLines() && !runFewestLines() && !runUnlink() && !runAnalysis()) { throw CommandLineException("No axial analysis mode present"); } } void AxialParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runAxialAnalysis(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/axialparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "genlib/p2dpoly.h" class AxialParser : public IModeParser { public: AxialParser(); // IModeParser interface public: std::string getModeName() const; std::string getHelp() const; void parse(int argc, char **argv); void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; // accessors bool runAllLines() const { return !m_allAxesRoots.empty(); } const std::vector & getAllAxesRoots() const{ return m_allAxesRoots; } bool runFewestLines() const { return m_runFewestLines; } bool runUnlink() const { // not supported for now return false; } bool runAnalysis() const { return m_runAnalysis; } bool useChoice() const { return m_choice; } bool useLocal() const { return m_local; } bool calculateRRA() const { return m_rra; } const std::vector& getRadii() const { return m_radii;} const std::string getAttribute() const { return m_attribute;} private: std::vector m_allAxesRoots; bool m_runFewestLines; bool m_runAnalysis; std::vector m_radii; bool m_choice; bool m_local; bool m_rra; std::string m_attribute; }; ================================================ FILE: depthmapXcli/commandlineparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "commandlineparser.h" #include "exceptions.h" #include "imodeparserfactory.h" #include "parsingutils.h" #include "version.h" #include #include #include using namespace depthmapX; void CommandLineParser::printHelp(){ std::cout << "Usage: depthmapXcli -m -f -o [-s] [-t ] [-p] [mode options]\n" << " depthmapXcli -v prints the current version\n" << " depthmapXcli -h prints this help text\n" << "-s enables simple mode\n" << "-t enables output of runtimes as csv file\n" << "-p enables text progress printing\n" << "Possible modes are:\n"; std::for_each(_parserFactory.getModeParsers().begin(), _parserFactory.getModeParsers().end(), [](const ModeParserVec::value_type &p)->void{ std::cout << " " << p->getModeName() << "\n"; }); std::cout << "\n"; std::for_each(_parserFactory.getModeParsers().begin(), _parserFactory.getModeParsers().end(), [](const ModeParserVec::value_type &p)->void{ std::cout << p->getHelp() << "\n"; }); std::cout << std::flush; } void CommandLineParser::printVersion(){ std::cout << TITLE_BASE << "\n" << std::flush; } CommandLineParser::CommandLineParser(const IModeParserFactory &parserFactory) : m_simpleMode(false), _parserFactory(parserFactory), _modeParser(0) {} void CommandLineParser::parse(size_t argc, char *argv[]) { m_valid = false; m_printVersionMode = false; if (argc <= 1) { throw CommandLineException("No commandline parameters provided - don't know what to do"); } for ( size_t i = 1; i < argc; ) { if ( std::strcmp("-h", argv[i])== 0) { return; } else if ( std::strcmp("-v", argv[i])== 0) { m_printVersionMode = true; return; } else if ( std::strcmp ("-m", argv[i]) == 0) { if ( _modeParser) { throw CommandLineException("-m can only be used once"); } ENFORCE_ARGUMENT("-m", i) for (auto iter = _parserFactory.getModeParsers().begin(), end = _parserFactory.getModeParsers().end(); iter != end; ++iter ) { if ((*iter)->getModeName() == argv[i]) { _modeParser = iter->get(); break; } } if (!_modeParser) { throw CommandLineException(std::string("Invalid mode: ") + argv[i]); } } else if ( std::strcmp ("-f", argv[i]) == 0) { ENFORCE_ARGUMENT("-f", i) m_fileName = argv[i]; } else if ( std::strcmp ("-o", argv[i]) == 0) { ENFORCE_ARGUMENT("-o", i) m_outputFile = argv[i]; } else if ( std::strcmp ("-t", argv[i]) == 0) { ENFORCE_ARGUMENT("-t", i) m_timingFile = argv[i]; } else if ( std::strcmp("-s", argv[i]) == 0) { m_simpleMode = true; } else if ( std::strcmp("-p", argv[i]) == 0) { m_printProgress = true; } ++i; } if (!_modeParser) { throw CommandLineException("-m for mode is required"); } if (m_fileName.empty()) { throw CommandLineException("-f for input file is required"); } if (m_outputFile.empty()) { throw CommandLineException("-o for output file is required"); } _modeParser->parse(argc, argv); m_valid = true; } void CommandLineParser::run(IPerformanceSink &perfWriter) const { if (!m_valid || !_modeParser) { throw CommandLineException("Trying to run with invalid command line parameters"); } _modeParser->run(*this, perfWriter); } ================================================ FILE: depthmapXcli/commandlineparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include class IModeParserFactory; class IModeParser; class IPerformanceSink; class CommandLineParser { public: CommandLineParser(const IModeParserFactory &parserFactory); void parse(size_t argc, char *argv[]); const std::string &getFileName() const { return m_fileName; } const std::string &getOuputFile() const {return m_outputFile;} const std::string &getTimingFile() const {return m_timingFile;} bool isValid() const { return m_valid; } bool printVersionMode() const { return m_printVersionMode; } bool simpleMode() const { return m_simpleMode; } bool printProgress() const { return m_printProgress; } const IModeParser& modeOptions() const{ return *_modeParser;}; void printHelp(); void printVersion(); void run(IPerformanceSink &perfWriter) const; private: std::string m_fileName; std::string m_outputFile; std::string m_timingFile; bool m_valid; bool m_printVersionMode; bool m_simpleMode; bool m_printProgress; const IModeParserFactory &_parserFactory; IModeParser * _modeParser; }; ================================================ FILE: depthmapXcli/exceptions.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/exceptions.h" #include namespace depthmapX { class CommandLineException : public depthmapX::BaseException { public: CommandLineException(std::string message) : depthmapX::BaseException(message) {} }; class SetupCheckException : public depthmapX::BaseException { public: SetupCheckException(std::string message) : depthmapX::BaseException(message) {} }; } ================================================ FILE: depthmapXcli/exportparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "exportparser.h" #include "exceptions.h" #include #include "runmethods.h" #include "parsingutils.h" #include using namespace depthmapX; ExportParser::ExportParser() : m_exportMode(ExportMode::NONE) {} void ExportParser::parse(int argc, char *argv[]) { for ( int i = 1; i < argc; ) { if ( std::strcmp ("-em", argv[i]) == 0) { if (m_exportMode != ExportParser::NONE) { throw CommandLineException("-em can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-em", i) if ( std::strcmp(argv[i], "pointmap-data-csv") == 0 ) { m_exportMode = ExportMode::POINTMAP_DATA_CSV; } else if ( std::strcmp(argv[i], "pointmap-connections-csv") == 0 ) { m_exportMode = ExportMode::POINTMAP_CONNECTIONS_CSV; } else if ( std::strcmp(argv[i], "pointmap-links-csv") == 0 ) { m_exportMode = ExportMode::POINTMAP_LINKS_CSV; } else if ( std::strcmp(argv[i], "shapegraph-map-csv") == 0 ) { m_exportMode = ExportMode::SHAPEGRAPH_MAP_CSV; } else if ( std::strcmp(argv[i], "shapegraph-map-mif") == 0 ) { m_exportMode = ExportMode::SHAPEGRAPH_MAP_MIF; } else if ( std::strcmp(argv[i], "shapegraph-connections-csv") == 0 ) { m_exportMode = ExportMode::SHAPEGRAPH_CONNECTIONS_CSV; } else if ( std::strcmp(argv[i], "shapegraph-links-unlinks-csv") == 0 ) { m_exportMode = ExportMode::SHAPEGRAPH_LINKS_UNLINKS_CSV; } else { throw CommandLineException(std::string("Invalid EXPORT mode: ") + argv[i]); } } ++i; } } void ExportParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::exportData(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/exportparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "commandlineparser.h" #include class ExportParser : public IModeParser { public: virtual std::string getModeName() const { return "EXPORT"; } virtual std::string getHelp() const { return "Mode options for EXPORT:\n"\ "-em one of:\n"\ " pointmap-data-csv\n"\ " pointmap-connections-csv\n"\ " pointmap-links-csv\n"\ " shapegraph-map-csv\n"\ " shapegraph-map-mif\n"\ " shapegraph-connections-csv\n"\ " shapegraph-links-unlinks-csv\n"; } public: ExportParser(); virtual void parse(int argc, char *argv[]); virtual void run(const CommandLineParser &clp, IPerformanceSink& perfWriter) const; enum ExportMode{ NONE, POINTMAP_DATA_CSV, POINTMAP_CONNECTIONS_CSV, POINTMAP_LINKS_CSV, SHAPEGRAPH_MAP_CSV, SHAPEGRAPH_MAP_MIF, SHAPEGRAPH_CONNECTIONS_CSV, SHAPEGRAPH_LINKS_UNLINKS_CSV }; ExportMode getExportMode() const { return m_exportMode; } private: ExportMode m_exportMode; }; ================================================ FILE: depthmapXcli/imodeparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Interface to encapsulate handling command line and invoking the respective // depthmapX mode #include "performancesink.h" #include "commandlineparser.h" class IModeParser { public: virtual std::string getModeName() const = 0; virtual std::string getHelp() const = 0; virtual void parse( int argc, char **argv) = 0; virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const = 0; virtual ~IModeParser(){} }; ================================================ FILE: depthmapXcli/imodeparserfactory.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include #include typedef std::vector > ModeParserVec; class IModeParserFactory { public: virtual const ModeParserVec &getModeParsers() const = 0; virtual ~IModeParserFactory(){} }; ================================================ FILE: depthmapXcli/importparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "importparser.h" #include "exceptions.h" #include "runmethods.h" #include "parsingutils.h" #include #include #include using namespace depthmapX; void ImportParser::parse(int argc, char *argv[]) { for ( int i = 1; i < argc; ++i) { if ( strcmp ("-if", argv[i]) == 0) { ENFORCE_ARGUMENT("-if", i) m_filesToImport.push_back(argv[i]); } else if ( std::strcmp ("-it", argv[i]) == 0) { ENFORCE_ARGUMENT("-it", i) if ( std::strcmp(argv[i], "drawing") == 0 ) { m_importMapType = depthmapX::ImportType::DRAWINGMAP; } else if ( std::strcmp(argv[i], "data") == 0 ) { m_importMapType = depthmapX::ImportType::DATAMAP; } else { throw CommandLineException(std::string("Invalid map import (-it) type: ") + argv[i]); } } else if ( strcmp ("-iaa", argv[i]) == 0) { m_importAsAttributes = true; } } } void ImportParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::importFiles(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/importparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "commandlineparser.h" #include "salalib/importtypedefs.h" #include #include class ImportParser : public IModeParser { public: virtual std::string getModeName() const { return "IMPORT"; } virtual std::string getHelp() const { return "Mode options for IMPORT:\n"\ " The file provided by -f here will be used as the base. If that file"\ "is not a graph, a new graph will be created and the file will be imported\n"\ " -if one or more files to import\n"\ " -it Import map type (to convert to)\n"\ " Possible map types:\n"\ " - drawing (default, does not preserve attributes, typically for dxf files)\n"\ " - data (preserves attributes, typically for csv and tsv files)\n"\ " -iaa will import and attach attributes to an existing map\n"; } public: virtual void parse(int argc, char *argv[]); virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; const std::vector & getFilesToImport() const { return m_filesToImport; } const bool toImportAsAttrbiutes() const { return m_importAsAttributes; } const depthmapX::ImportType getImportMapType() const { return m_importMapType; } private: depthmapX::ImportType m_importMapType = depthmapX::ImportType::DRAWINGMAP; std::vector m_filesToImport; bool m_importAsAttributes = false; }; ================================================ FILE: depthmapXcli/isovistparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "isovistparser.h" #include "parsingutils.h" #include "exceptions.h" #include "salalib/entityparsing.h" #include #include "runmethods.h" #include using namespace depthmapX; IsovistParser::IsovistParser() { } std::string IsovistParser::getModeName() const { return "ISOVIST"; } std::string IsovistParser::getHelp() const { return "Arguments for isovist mode:\n" \ " -ii Define an isoivist at position x,y with\n"\ " optional direction angle and view angle for partial isovists\n"\ " -if load isovist definitions from a file (csv)\n"\ " the relevant headers must be called x, y, angle and viewangle\n"\ " the latter two are optional.\n"\ " Those two arguments cannot be mixed\n"\ " Angles for partial isovists are in degrees, counted anti-clockwise with 0°\n"\ " pointing to the right.\n\n"; } void IsovistParser::parse(int argc, char **argv) { std::string isovistFile; for( int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "-ii") == 0 ) { if ( !isovistFile.empty()) { throw CommandLineException("-ii cannot be used together with -if"); } ENFORCE_ARGUMENT("-ii", i); m_isovists.push_back(EntityParsing::parseIsovist(argv[i])); } else if( std::strcmp(argv[i], "-if") == 0) { if ( !isovistFile.empty()) { throw CommandLineException("-if can only be used once"); } if (!m_isovists.empty()) { throw depthmapX::CommandLineException("-if cannot be used together with -ii"); } ENFORCE_ARGUMENT("-if",i); isovistFile = argv[i]; } } if (!isovistFile.empty()) { std::ifstream file(isovistFile); if ( !file.good()) { std::stringstream message; message << "Failed to find file " << isovistFile; throw depthmapX::CommandLineException(message.str()); } m_isovists = EntityParsing::parseIsovists(file, ','); } if (m_isovists.empty()) { throw CommandLineException("No isovists defined. Use -ii or -if"); } } void IsovistParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runIsovists(clp, m_isovists, perfWriter); } ================================================ FILE: depthmapXcli/isovistparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "salalib/isovistdef.h" #include class IsovistParser : public IModeParser { public: IsovistParser(); // IModeParser interface public: std::string getModeName() const; std::string getHelp() const; void parse(int argc, char **argv); void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; const std::vector &getIsovists() const{ return m_isovists;} private: std::vector m_isovists; }; ================================================ FILE: depthmapXcli/linkparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "linkparser.h" #include "salalib/mgraph.h" #include "exceptions.h" #include "runmethods.h" #include "parsingutils.h" #include #include #include using namespace depthmapX; void LinkParser::parse(int argc, char *argv[]) { for ( int i = 1; i < argc; ) { if ( std::strcmp ("-lmt", argv[i]) == 0) { ENFORCE_ARGUMENT("-lmt", i) if ( std::strcmp(argv[i], "pointmaps") == 0 ) { m_mapTypeGroup = MapTypeGroup::POINTMAPS; } else if ( std::strcmp(argv[i], "shapegraphs") == 0 ) { m_mapTypeGroup = MapTypeGroup::SHAPEGRAPHS; } else { throw CommandLineException(std::string("Invalid LINK map type group: ") + argv[i]); } } else if ( std::strcmp ("-lm", argv[i]) == 0) { ENFORCE_ARGUMENT("-lm", i) if ( std::strcmp(argv[i], "link") == 0 ) { m_linkMode = LinkMode::LINK; } else if ( std::strcmp(argv[i], "unlink") == 0 ) { m_linkMode = LinkMode::UNLINK; } else { throw CommandLineException(std::string("Invalid LINK mode: ") + argv[i]); } } else if ( std::strcmp ("-lt", argv[i]) == 0) { ENFORCE_ARGUMENT("-lt", i) if ( std::strcmp(argv[i], "coords") == 0 ) { m_linkType = LinkType::COORDS; } else if ( std::strcmp(argv[i], "refs") == 0 ) { m_linkType = LinkType::REFS; } else { throw CommandLineException(std::string("Invalid LINK type: ") + argv[i]); } } else if ( std::strcmp ("-lf", argv[i]) == 0) { if (!m_linksFile.empty()) { throw CommandLineException("-lf can only be used once at the moment"); } else if (m_manualLinks.size() != 0) { throw CommandLineException("-lf can not be used in conjunction with -lnk"); } ENFORCE_ARGUMENT("-lf", i) m_linksFile = argv[i]; } else if ( std::strcmp ("-lnk", argv[i]) == 0) { if (!m_linksFile.empty()) { throw CommandLineException("-lf can not be used in conjunction with -lnk"); } ENFORCE_ARGUMENT("-lnk", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid link provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } m_manualLinks.push_back(argv[i]); } ++i; } if ( m_manualLinks.size() == 0 && m_linksFile.empty()) { throw CommandLineException("one of -lf or -lnk must be provided"); } } void LinkParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::linkGraph(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/linkparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/mgraph.h" #include "imodeparser.h" #include "commandlineparser.h" #include #include class LinkParser : public IModeParser { public: enum MapTypeGroup { POINTMAPS, SHAPEGRAPHS }; enum LinkMode { LINK, UNLINK }; enum LinkType { COORDS, REFS }; LinkParser(): m_mapTypeGroup(POINTMAPS), m_linkMode(LINK), m_linkType(COORDS) {} virtual std::string getModeName() const { return "LINK"; } virtual std::string getHelp() const { return "Mode options for LINK:\n"\ " -lmt Map type group to select displayed map from. One of:\n"\ " pointmaps (default, vga: link)\n"\ " shapegraphs (axial:link/unlink, segment:link, convex:link)\n"\ " -lm one of:\n"\ " link (default)\n"\ " unlink\n"\ " -lt one of:\n"\ " coords (default, provided as x,y or x1,y1,x2,y2 coordinates)\n"\ " refs (provided as the ids (Ref) of the shapes)\n"\ " -lnk provided in csv (x1,y1,x2,y2)\n"\ " for example \"0.1,0.2,0.2,0.4\" to create a link from 0.1,0.2\n"\ " to 0.2,0.4. In the case of axial-map unlinks a single (x,y) set may\n" " be provided. In the case of refs provide the ids in csv (reffrom,refto)" " Provide multiple times for multiple links/unlinks\n"\ " -lf as in -lnk\n"; } public: virtual void parse(int argc, char *argv[]); virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; //link options const std::string & getLinksFile() const { return m_linksFile; } const std::vector & getManualLinks() const { return m_manualLinks; } const MapTypeGroup& getMapTypeGroup() const { return m_mapTypeGroup; } const LinkMode& getLinkMode() const { return m_linkMode; } const LinkType& getLinkType() const { return m_linkType; } private: std::string m_linksFile; std::vector m_manualLinks; MapTypeGroup m_mapTypeGroup; LinkMode m_linkMode; LinkType m_linkType; }; ================================================ FILE: depthmapXcli/main.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "commandlineparser.h" #include "runmethods.h" #include "performancewriter.h" #include "modeparserregistry.h" int main(int argc, char *argv[]) { ModeParserRegistry registry; CommandLineParser args(registry); try{ args.parse(argc, argv); if (!args.isValid()) { if (args.printVersionMode()) { args.printVersion(); } else { args.printHelp(); } return 0; } PerformanceWriter perfWriter(args.getTimingFile()); args.run(perfWriter); perfWriter.write(); } catch( std::exception &e) { std::cout << e.what() << "\n" << "Type 'depthmapXcli -h' for help" << std::endl; return -1; } return 0; } ================================================ FILE: depthmapXcli/mapconvertparser.cpp ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mapconvertparser.h" #include "parsingutils.h" #include "exceptions.h" #include "runmethods.h" #include using namespace depthmapX; void MapConvertParser::parse(int argc, char **argv) { for (int i = 1; i < argc; ++i) { if ( std::strcmp ("-co", argv[i]) == 0) { if (m_outMapType != ShapeMap::EMPTYMAP) { throw CommandLineException("-co can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-co", i) if ( std::strcmp(argv[i], "drawing") == 0 ) { m_outMapType = ShapeMap::DRAWINGMAP; } else if ( std::strcmp(argv[i], "axial") == 0 ) { m_outMapType = ShapeMap::AXIALMAP; } else if ( std::strcmp(argv[i], "segment") == 0 ) { m_outMapType = ShapeMap::SEGMENTMAP; } else if ( std::strcmp(argv[i], "data") == 0 ) { m_outMapType = ShapeMap::DATAMAP; } else if ( std::strcmp(argv[i], "convex") == 0) { m_outMapType = ShapeMap::CONVEXMAP; } else { throw CommandLineException(std::string("Invalid map output (-co) type: ") + argv[i]); } } else if(std::strcmp(argv[i], "-con") == 0) { ENFORCE_ARGUMENT("-con", i) m_outMapName = argv[i]; } else if(std::strcmp(argv[i], "-cir") == 0) { m_removeInputMap = true; } else if (std::strcmp(argv[i], "-coc") == 0) { m_copyAttributes = true; } else if (std::strcmp(argv[i], "-crsl") == 0) { ENFORCE_ARGUMENT("-crsl", i) if (!has_only_digits_dots(argv[i])) { throw CommandLineException(std::string("-crsl must be a number >0, got ") + argv[i]); } m_removeStubLengthPRC = std::stod(argv[i]); if (!(m_removeStubLengthPRC > 0)) { throw CommandLineException(std::string("-crsl must be a number >0, got ") + argv[i]); } } } if (m_outMapType == ShapeMap::EMPTYMAP) { throw CommandLineException("A valid output map type (-co) is required"); } if (m_outMapName == "") { throw CommandLineException("A valid output map name (-con) is required"); } } void MapConvertParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runMapConversion(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/mapconvertparser.h ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "salalib/shapemap.h" class MapConvertParser : public IModeParser { public: MapConvertParser(): m_outMapType(ShapeMap::EMPTYMAP), m_outMapName(""), m_removeInputMap(false), m_copyAttributes(false), m_removeStubLengthPRC(0) {} // IModeParser interface public: std::string getModeName() const { return "MAPCONVERT"; } std::string getHelp() const { return "Mode options for Map Conversion:\n"\ " -co Output map type (to convert to)\n"\ " Possible input/output map types:\n"\ " - drawing\n"\ " - axial\n"\ " - segment\n"\ " - data\n"\ " - convex\n"\ " -con Output map name\n"\ " -cir Remove input map\n"\ " -coc Copy attributes to output map (Only between DATA, AXIAL and SEGMENT)\n"\ " -crsl <%> Percent of line length of axial stubs to remove (Only for AXIAL -> SEGMENT)\n\n"; } void parse(int argc, char **argv); void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; int outputMapType() const { return m_outMapType; } std::string outputMapName() const { return m_outMapName; } bool removeInputMap() const { return m_removeInputMap; } bool copyAttributes() const { return m_copyAttributes; } double removeStubLength() const { return m_removeStubLengthPRC; } private: int m_outMapType; std::string m_outMapName; bool m_removeInputMap; bool m_copyAttributes; double m_removeStubLengthPRC; }; ================================================ FILE: depthmapXcli/modeparserregistry.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "modeparserregistry.h" #include "importparser.h" #include "linkparser.h" #include "vgaparser.h" #include "visprepparser.h" #include "axialparser.h" #include "segmentparser.h" #include "agentparser.h" #include "isovistparser.h" #include "exportparser.h" #include "stepdepthparser.h" #include "mapconvertparser.h" #include "modules/segmentshortestpaths/cli/segmentshortestpathparser.h" void ModeParserRegistry::populateParsers() { // Register any mode parsers here REGISTER_PARSER(VgaParser); REGISTER_PARSER(LinkParser); REGISTER_PARSER(VisPrepParser); REGISTER_PARSER(AxialParser); REGISTER_PARSER(SegmentParser); REGISTER_PARSER(AgentParser); REGISTER_PARSER(IsovistParser); REGISTER_PARSER(ExportParser); REGISTER_PARSER(ImportParser); REGISTER_PARSER(StepDepthParser); REGISTER_PARSER(MapConvertParser); REGISTER_PARSER(SegmentShortestPathParser); // ********* } ================================================ FILE: depthmapXcli/modeparserregistry.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "imodeparserfactory.h" #include #include class ModeParserRegistry : public IModeParserFactory { public: ModeParserRegistry() { populateParsers(); } const ModeParserVec &getModeParsers() const {return m_availableParsers;} private: void populateParsers(); ModeParserVec m_availableParsers; }; #define REGISTER_PARSER(parser)\ m_availableParsers.push_back(std::unique_ptr(new parser)); ================================================ FILE: depthmapXcli/parsingutils.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "parsingutils.h" #include #include #include #include #include "exceptions.h" std::vector depthmapX::parseRadiusList(const std::string &radiusList) { std::vector result; std::stringstream stream(radiusList); bool addN = false; while(stream.good()) { std::string value; getline(stream, value, ','); if ( value == "n" || value == "N") { addN = true; } else { char *end; long int val = std::strtol(value.c_str(), &end, 10 ); if (val == 0 ) { std::stringstream message; message << "Found either 0 or unparsable radius " << value << std::flush; throw CommandLineException(message.str()); } if (val < 0) { throw CommandLineException("Radius must be either n or a positive integer"); } if (strlen(end) > 0) { std::stringstream message; message << "Found non integer radius " << value << std::flush; throw CommandLineException(message.str()); } result.push_back((double)val); } } std::sort(result.begin(), result.end()); if (result.empty() || addN) { result.push_back(-1.0); } return result; } ================================================ FILE: depthmapXcli/parsingutils.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #define PASTE(arg) arg #define ENFORCE_ARGUMENT(flag, counter)\ if ( ++ PASTE(counter) >= argc \ || (argv[ PASTE(counter)][0] == '-' && !isdigit(argv[ PASTE(counter)][1]) && argv[ PASTE(counter)][1] != '.') )\ {\ throw CommandLineException(flag " requires an argument");\ }\ #include #include namespace depthmapX{ inline bool has_only_digits(const std::string &s){ return s.find_first_not_of( "0123456789" ) == std::string::npos; } inline bool has_only_digits_dots(const std::string &s){ return s.find_first_not_of( "0123456789." ) == std::string::npos; } inline bool has_only_digits_dots_commas(const std::string &s){ return s.find_first_not_of( "0123456789,.-" ) == std::string::npos; } std::vector parseRadiusList(const std::string &radiusList); } ================================================ FILE: depthmapXcli/performancesink.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include //Interface for performance writers class IPerformanceSink { public: virtual void addData(const std::string &message, double timeInSeconds) = 0; virtual ~IPerformanceSink(){} }; ================================================ FILE: depthmapXcli/performancewriter.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "performancewriter.h" #include #include #include PerformanceWriter::PerformanceWriter(const std::string &filename) : m_filename(filename) { } void PerformanceWriter::addData(const std::string &message, double timeInSeconds) { std::stringstream ss; ss << "\"" << message << "\"," << timeInSeconds << "\n"; m_data.push_back(ss.str()); } void PerformanceWriter::write() const { if (!m_filename.empty()) { std::ofstream outfile(m_filename); outfile << "\"action\",\"duration\"\n"; std::for_each(m_data.begin(), m_data.end(), [&outfile](const std::string& line)mutable ->void{(outfile) << line;}); outfile << std::flush; } } ================================================ FILE: depthmapXcli/performancewriter.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "performancesink.h" #include #include class PerformanceWriter : public IPerformanceSink { private: std::vector m_data; std::string m_filename; public: PerformanceWriter(const std::string &filename); void addData( const std::string &message, double timeInSeconds); void write() const; }; ================================================ FILE: depthmapXcli/printcommunicator.cpp ================================================ // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "depthmapXcli/printcommunicator.h" void PrintCommunicator::CommPostMessage(int m, int x) const { switch (m) { case Communicator::NUM_STEPS: num_steps = x; break; case Communicator::CURRENT_STEP: step = x; break; case Communicator::NUM_RECORDS: num_records = x; break; case Communicator::CURRENT_RECORD: record = x; if (record > num_records) record = num_records; std::cout << "step: " << step << "/" << num_steps << " " << "record: " << record << "/" << num_records << std::endl; break; default: break; } } ================================================ FILE: depthmapXcli/printcommunicator.h ================================================ // Copyright (C) 2020, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/comm.h" class PrintCommunicator : public ICommunicator { public: PrintCommunicator() { num_steps = 0; step = 0; num_records = 0; record = 0; } virtual ~PrintCommunicator() {} virtual void CommPostMessage(int m, int x) const; }; ================================================ FILE: depthmapXcli/radiusconverter.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "radiusconverter.h" #include "exceptions.h" #include #include #include using namespace depthmapX; double RadiusConverter::ConvertForVisibility(const std::string &radius) const { if (radius == "n") { return -1.0; } char *end; long rad = std::strtol(radius.c_str(), &end, 10); if (rad < 1 || rad > 99) { throw SetupCheckException(std::string("Radius for visibility analysis must be n for the whole range or an integer between 1 and 99 inclusive. Got ") + radius); } return static_cast(rad); } double RadiusConverter::ConvertForMetric(const std::string &radius) const { if (radius == "n") { return -1.0; } char *end; double rad = strtod(radius.c_str(), &end); if ( rad <= 0 ) { throw SetupCheckException(std::string("Radius for metric vga must be n for the whole range or a positive number. Got ") + radius); } if (std::isnan(rad)) { throw SetupCheckException("Radius NaN?! Really?"); } if (std::isinf(rad)) { throw SetupCheckException("Radius inf?! Who are you kidding?"); } return rad; } ================================================ FILE: depthmapXcli/radiusconverter.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include class IRadiusConverter { public: virtual double ConvertForVisibility(const std::string &radius) const = 0; virtual double ConvertForMetric(const std::string &radius) const = 0; virtual ~IRadiusConverter(){} }; class RadiusConverter : public IRadiusConverter { public: virtual double ConvertForVisibility(const std::string &radius) const; virtual double ConvertForMetric(const std::string &radius) const; }; ================================================ FILE: depthmapXcli/runmethods.cpp ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "runmethods.h" #include "salalib/mgraph.h" #include "salalib/linkutils.h" #include "radiusconverter.h" #include "exceptions.h" #include "simpletimer.h" #include "printcommunicator.h" #include #include #include #include "salalib/entityparsing.h" #include #include namespace dm_runmethods { std::unique_ptr loadGraph(const std::string& filename, IPerformanceSink &perfWriter) { std::unique_ptr mgraph(new MetaGraph); std::cout << "Loading graph " << filename << std::flush; DO_TIMED( "Load graph file", auto result = mgraph->readFromFile(filename);) if ( result != MetaGraph::OK) { std::stringstream message; message << "Failed to load graph from file " << filename << ", error " << result << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } std::cout << " ok\n" << std::flush; return mgraph; } std::unique_ptr getCommunicator(const CommandLineParser &clp) { if (clp.printProgress()) { return std::unique_ptr(new PrintCommunicator()); } return nullptr; } void importFiles(const CommandLineParser &cmdP, const ImportParser &parser, IPerformanceSink &perfWriter) { std::ifstream mainFileStream(cmdP.getFileName().c_str()); if(!mainFileStream.good()) { std::stringstream message; message << "File not found: " << cmdP.getFileName() << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } std::unique_ptr mgraph(new MetaGraph); DO_TIMED( "Load graph file", auto result = mgraph->readFromFile(cmdP.getFileName());) if ( result != MetaGraph::OK && result != MetaGraph::NOT_A_GRAPH) { std::stringstream message; message << "Failed to load graph from file " << cmdP.getFileName() << ", error " << result << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } if ( result == MetaGraph::NOT_A_GRAPH) { // not a graph, try to import the file std::string ext = cmdP.getFileName().substr(cmdP.getFileName().length() - 4, cmdP.getFileName().length() - 1); std::ifstream file(cmdP.getFileName()); depthmapX::ImportFileType importFileType = depthmapX::ImportFileType::TSV; if(dXstring::toLower(ext) == ".csv") { importFileType = depthmapX::ImportFileType::CSV; } else if (dXstring::toLower(ext) == ".dxf") { importFileType = depthmapX::ImportFileType::DXF; } depthmapX::importFile(*mgraph, file, getCommunicator(cmdP).get(), cmdP.getFileName(), parser.getImportMapType(), importFileType); } else if ( result == MetaGraph::OK) { if(parser.toImportAsAttrbiutes()) { if(mgraph->getDisplayedMapType() == ShapeMap::EMPTYMAP) { throw depthmapX::RuntimeException("No map displayed to attach attributes to"); } std::vector fileNames = parser.getFilesToImport(); for(std::string fileName: fileNames) { std::string ext = fileName.substr(fileName.length() - 4, fileName.length() - 1); std::ifstream file(fileName); char delimiter = '\t'; if(dXstring::toLower(ext) == ".csv") { delimiter = ','; } DO_TIMED("Importing attributes", depthmapX::importAttributes(mgraph->getDisplayedMapAttributes(), file, delimiter);) } } } DO_TIMED("Writing graph", mgraph->write(cmdP.getOuputFile().c_str(),METAGRAPH_VERSION, false);) } void linkGraph(const CommandLineParser &cmdP, const LinkParser &parser, IPerformanceSink &perfWriter) { auto mgraph = loadGraph(cmdP.getFileName().c_str(), perfWriter); if (parser.getLinkMode() == LinkParser::LinkMode::UNLINK && parser.getMapTypeGroup() == LinkParser::MapTypeGroup::SHAPEGRAPHS && mgraph->getDisplayedShapeGraph().getMapType() != ShapeMap::AXIALMAP) { throw depthmapX::RuntimeException("Unlinking is only available for axial maps and pointmaps"); } char delimiter = '\t'; std::stringstream linksStream; if(!parser.getLinksFile().empty()) { std::ifstream fileStream(parser.getLinksFile()); if (!linksStream) { std::stringstream message; message << "Failed to load file " << parser.getLinksFile() << ", error " << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } linksStream << fileStream.rdbuf(); fileStream.close(); } else if(!parser.getManualLinks().empty()) { delimiter = ','; std::string header = "x1,y1,x2,y2"; if(parser.getLinkType() == LinkParser::LinkType::REFS) { header = "reffrom,refto"; } else if(parser.getLinkMode() == LinkParser::LinkMode::UNLINK) { header = "x,y"; } linksStream << header; auto iter = parser.getManualLinks().begin(), end = parser.getManualLinks().end(); for ( ; iter != end; ++iter ) { linksStream << "\n" << *iter; } } SimpleTimer t; if(parser.getLinkMode() == LinkParser::LinkMode::LINK) { if(parser.getMapTypeGroup() == LinkParser::MapTypeGroup::SHAPEGRAPHS) { auto& shapeGraph = mgraph->getDisplayedShapeGraph(); if(parser.getLinkType() == LinkParser::LinkType::COORDS) { std::vector mergeLines = EntityParsing::parseLines(linksStream, delimiter); for(auto line: mergeLines) { QtRegion region(line.start(), line.start()); shapeGraph.setCurSel(region); shapeGraph.linkShapes(line.end()); } } else { auto mergePairs = EntityParsing::parseRefPairs(linksStream, delimiter); for(auto pair: mergePairs) { // apparently this also unlinks if already linked or crossing shapeGraph.linkShapesFromRefs(pair.first, pair.second); } } } else { std::vector newLinks; PointMap& currentMap = mgraph->getDisplayedPointMap(); if(parser.getLinkType() == LinkParser::LinkType::COORDS) { std::vector mergeLines = EntityParsing::parseLines(linksStream, delimiter); std::vector linkPairsFromCoords = depthmapX::pixelateMergeLines(mergeLines, currentMap); newLinks.insert(newLinks.end(), linkPairsFromCoords.begin(), linkPairsFromCoords.end()); } else { auto mergePairs = EntityParsing::parseRefPairs(linksStream, delimiter); for(auto pair: mergePairs) { newLinks.push_back(PixelRefPair(pair.first, pair.second)); } } depthmapX::mergePixelPairs(newLinks, currentMap); } } else { if(parser.getMapTypeGroup() == LinkParser::MapTypeGroup::SHAPEGRAPHS) { auto& shapeGraph = mgraph->getDisplayedShapeGraph(); if(parser.getLinkType() == LinkParser::LinkType::COORDS) { auto mergePoints = EntityParsing::parsePoints(linksStream, delimiter); for(auto point: mergePoints) { shapeGraph.unlinkAtPoint(point); } } else { auto mergePairs = EntityParsing::parseRefPairs(linksStream, delimiter); for(auto pair: mergePairs) { shapeGraph.unlinkShapesFromRefs(pair.first, pair.second); } } } else { std::vector newLinks; PointMap& currentMap = mgraph->getDisplayedPointMap(); if(parser.getLinkType() == LinkParser::LinkType::COORDS) { std::vector mergeLines = EntityParsing::parseLines(linksStream, delimiter); std::vector linkPairsFromCoords = depthmapX::pixelateMergeLines(mergeLines, currentMap); newLinks.insert(newLinks.end(), linkPairsFromCoords.begin(), linkPairsFromCoords.end()); } else { auto mergePairs = EntityParsing::parseRefPairs(linksStream, delimiter); for(auto pair: mergePairs) { newLinks.push_back(PixelRefPair(pair.first, pair.second)); } } depthmapX::unmergePixelPairs(newLinks, currentMap); } } perfWriter.addData("Linking graph", t.getTimeInSeconds()); DO_TIMED("Writing graph", mgraph->write(cmdP.getOuputFile().c_str(),METAGRAPH_VERSION, false);) } void runVga(const CommandLineParser &cmdP, const VgaParser &vgaP, const IRadiusConverter &converter, IPerformanceSink &perfWriter) { auto mgraph = loadGraph(cmdP.getFileName().c_str(), perfWriter); std::unique_ptr options(new Options()); std::cout << "Getting options..." << std::flush; switch(vgaP.getVgaMode()) { case VgaParser::VgaMode::VISBILITY: options->output_type = Options::OUTPUT_VISUAL; options->local = vgaP.localMeasures(); options->global = vgaP.globalMeasures(); if (options->global ) { options->radius = converter.ConvertForVisibility(vgaP.getRadius()); } break; case VgaParser::VgaMode::METRIC: options->output_type = Options::OUTPUT_METRIC; options->radius = converter.ConvertForMetric(vgaP.getRadius()); break; case VgaParser::VgaMode::ANGULAR: options->output_type = Options::OUTPUT_ANGULAR; break; case VgaParser::VgaMode::ISOVIST: options->output_type = Options::OUTPUT_ISOVIST; break; case VgaParser::VgaMode::THRU_VISION: options->output_type = Options::OUTPUT_THRU_VISION; break; default: throw depthmapX::SetupCheckException("Unsupported VGA mode"); } std::cout << " ok\nAnalysing graph..." << std::flush; DO_TIMED("Run VGA", mgraph->analyseGraph(getCommunicator(cmdP).get(), *options, cmdP.simpleMode() )) std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mgraph->write(cmdP.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void fillGraph(MetaGraph& graph, const Point2f& point) { auto r = graph.getRegion(); if (!r.contains(point)) { throw depthmapX::RuntimeException("Point outside of target region"); } graph.makePoints(point, 0, nullptr); } void runVisualPrep( const CommandLineParser &clp, double gridSize, const std::vector &fillPoints, double maxVisibility, bool boundaryGraph, bool makeGraph, bool unmakeGraph, bool removeLinksWhenUnmaking, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(),perfWriter); std::cout << "Initial checks... " << std::flush; auto state = mGraph->getState(); if (~state & MetaGraph::LINEDATA) { throw depthmapX::RuntimeException("Graph must have line data before preparing VGA"); } if(gridSize > 0) { // Create a new pointmap and set tha grid QtRegion r = mGraph->getRegion(); GridProperties gp(__max(r.width(), r.height())); if ( gridSize > gp.getMax() || gridSize < gp.getMin()) { std::stringstream message; message << "Chosen grid spacing " << gridSize << " is outside of the expected interval of " << gp.getMin() << " <= spacing <= " << gp.getMax() << std::flush; throw depthmapX::RuntimeException(message.str()); } std::cout << "ok\nSetting up grid... " << std::flush; mGraph->addNewPointMap(); DO_TIMED("Setting grid", mGraph->setGrid(gridSize, Point2f(0.0, 0.0))) } else if(mGraph->getPointMaps().empty()) { std::stringstream message; message << "No map exists to use. Please create a new one by providing a grid size" << std::flush; throw depthmapX::RuntimeException(message.str()); } if(unmakeGraph) { if(!mGraph->getDisplayedPointMap().isProcessed()) { std::stringstream message; message << "Current map has not had its graph made so there's nothing to unmake" << std::flush; throw depthmapX::RuntimeException(message.str()); } DO_TIMED("Unmaking graph", mGraph->getDisplayedPointMap().unmake(removeLinksWhenUnmaking)) } else { if(fillPoints.size() > 0) { std::cout << "ok\nFilling grid... " << std::flush; DO_TIMED("Filling grid", for_each(fillPoints.begin(), fillPoints.end(), [&mGraph](const Point2f &point)->void{fillGraph(*mGraph, point);})) } if(makeGraph) { std::cout << "ok\nMaking graph... " << std::flush; DO_TIMED("Making graph", mGraph->makeGraph(getCommunicator(clp).get(), boundaryGraph ? 1 : 0, maxVisibility)) } } std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void runAxialAnalysis(const CommandLineParser &clp, const AxialParser &ap, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(), perfWriter); auto state = mGraph->getState(); if ( ap.runAllLines()) { if (~state & MetaGraph::LINEDATA) { throw depthmapX::RuntimeException("Line drawing must be loaded before axial map can be constructed"); } std::cout << "Making all line map... " << std::flush; DO_TIMED("Making all axes map", for_each (ap.getAllAxesRoots().begin(),ap.getAllAxesRoots().end(), [&mGraph, &clp](const Point2f &point)->void{mGraph->makeAllLineMap(getCommunicator(clp).get(), point);} )) std::cout << "ok" << std::endl; } if (ap.runFewestLines()) { if (~state & MetaGraph::LINEDATA) { throw depthmapX::RuntimeException("Line drawing must be loaded before fewest line map can be constructed"); } if (!mGraph->hasAllLineMap()) { throw depthmapX::RuntimeException("All line map must be constructed before fewest lines can be constructed. Use -aa to do this"); } std::cout << "Constructing fewest line map... " << std::flush; DO_TIMED("Fewest line map", mGraph->makeFewestLineMap(getCommunicator(clp).get(), 1)) std::cout << "ok" << std::endl; } if (ap.runAnalysis()) { std::cout << "Running axial analysis... " << std::flush; Options options; const std::vector& radii = ap.getRadii(); options.radius_set.insert(radii.begin(), radii.end()); options.choice = ap.useChoice(); options.local = ap.useLocal(); options.fulloutput = ap.calculateRRA(); options.weighted_measure_col = -1; if(!ap.getAttribute().empty()) { const ShapeGraph& map = mGraph->getDisplayedShapeGraph(); const AttributeTable& table = map.getAttributeTable(); for (int i = 0; i < table.getNumColumns(); i++) { if(ap.getAttribute() == table.getColumnName(i).c_str()) { options.weighted_measure_col = i; } } if(options.weighted_measure_col == -1) { throw depthmapX::RuntimeException("Given attribute (" + ap.getAttribute() + ") does not exist in currently selected map"); } } DO_TIMED("Axial analysis", mGraph->analyseAxial(getCommunicator(clp).get(), options, clp.simpleMode())) std::cout << "ok\n" << std::flush; } std::cout << "Writing out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void runSegmentAnalysis(const CommandLineParser &clp, const SegmentParser &sp, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(), perfWriter); auto state = mGraph->getState(); std::cout << "Running segment analysis... " << std::flush; Options options; const std::vector& radii = sp.getRadii(); options.radius_set.insert(radii.begin(), radii.end()); options.choice = sp.includeChoice(); options.tulip_bins = sp.getTulipBins(); options.weighted_measure_col = -1; if(!sp.getAttribute().empty()) { const ShapeGraph& map = mGraph->getDisplayedShapeGraph(); const AttributeTable& table = map.getAttributeTable(); for (int i = 0; i < table.getNumColumns(); i++) { if(sp.getAttribute() == table.getColumnName(i).c_str()) { options.weighted_measure_col = i; } } if(options.weighted_measure_col == -1) { throw depthmapX::RuntimeException("Given attribute (" + sp.getAttribute() + ") does not exist in currently selected map"); } } switch(sp.getRadiusType()) { case SegmentParser::RadiusType::SEGMENT_STEPS: { options.radius_type = Options::RADIUS_STEPS; break; } case SegmentParser::RadiusType::METRIC: { options.radius_type = Options::RADIUS_METRIC; break; } case SegmentParser::RadiusType::ANGULAR: { options.radius_type = Options::RADIUS_ANGULAR; break; } case SegmentParser::RadiusType::NONE: break; } switch(sp.getAnalysisType()) { case SegmentParser::AnalysisType::ANGULAR_TULIP: { DO_TIMED("Segment tulip analysis", mGraph->analyseSegmentsTulip(getCommunicator(clp).get(), options)) break; } case SegmentParser::AnalysisType::ANGULAR_FULL: { DO_TIMED("Segment angular analysis", mGraph->analyseSegmentsAngular(getCommunicator(clp).get(), options)) break; } case SegmentParser::AnalysisType::TOPOLOGICAL: { options.output_type = 0; DO_TIMED("Segment topological", mGraph->analyseTopoMetMultipleRadii(getCommunicator(clp).get(), options)) break; } case SegmentParser::AnalysisType::METRIC: { options.output_type = 1; DO_TIMED("Segment metric", mGraph->analyseTopoMetMultipleRadii(getCommunicator(clp).get(), options)) break; } case SegmentParser::AnalysisType::NONE: throw depthmapX::RuntimeException("No segment analysis type given"); } std::cout << "ok\n" << std::flush; std::cout << "Writing out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void runAgentAnalysis(const CommandLineParser &cmdP, const AgentParser &agentP, IPerformanceSink &perfWriter) { auto mgraph = loadGraph(cmdP.getFileName().c_str(), perfWriter); PointMap& currentMap = mgraph->getDisplayedPointMap(); AgentEngine& eng = mgraph->getAgentEngine(); // set up eng here... if (!eng.agentSets.size()) { eng.agentSets.push_back(AgentSet()); } eng.m_timesteps = agentP.totalSystemTimestemps(); eng.agentSets.back().m_release_rate = agentP.releaseRate(); eng.agentSets.back().m_lifetime = agentP.agentLifeTimesteps(); if (agentP.agentFOV() == 32) { eng.agentSets.back().m_vbin = -1; } else { eng.agentSets.back().m_vbin = (agentP.agentFOV() - 1) / 2; } eng.agentSets.back().m_steps = agentP.agentStepsBeforeTurnDecision(); switch(agentP.getAgentMode()) { case AgentParser::NONE: case AgentParser::STANDARD: eng.agentSets.back().m_sel_type = AgentProgram::SEL_STANDARD; break; case AgentParser::LOS_LENGTH: eng.agentSets.back().m_sel_type = AgentProgram::SEL_LOS; break; case AgentParser::OCC_LENGTH: eng.agentSets.back().m_sel_type = AgentProgram::SEL_LOS_OCC; break; case AgentParser::OCC_ANY: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_ALL; break; case AgentParser::OCC_GROUP_45: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_BIN45; break; case AgentParser::OCC_GROUP_60: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_BIN60; break; case AgentParser::OCC_FURTHEST: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_STANDARD; break; case AgentParser::BIN_FAR_DIST: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_WEIGHT_DIST; break; case AgentParser::BIN_ANGLE: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_WEIGHT_ANG; break; case AgentParser::BIN_FAR_DIST_ANGLE: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_WEIGHT_DIST_ANG; break; case AgentParser::BIN_MEMORY: eng.agentSets.back().m_sel_type = AgentProgram::SEL_OCC_MEMORY; break; } // if the m_release_locations is not set the locations are // set later by picking random pixels if(agentP.randomReleaseLocationSeed() >= 0) { eng.agentSets.back().m_release_locations_seed = agentP.randomReleaseLocationSeed(); } else { eng.agentSets.back().m_release_locations.clear(); for_each(agentP.getReleasePoints().begin(), agentP.getReleasePoints().end(), [&eng, ¤tMap](const Point2f &point) ->void{eng.agentSets.back().m_release_locations.push_back(currentMap.pixelate(point, false));}); } // the ui and code suggest that the results can be put on a separate // 'data map', but the functionality does not seem to actually be // there thus it is skipped for now // eng.m_gatelayer = m_gatelayer; // note, trails currently per run, but output per engine if (agentP.recordTrailsForAgents() == 0) { eng.m_record_trails = true; } else if (agentP.recordTrailsForAgents() > 0) { eng.m_record_trails = true; eng.m_trail_count = agentP.recordTrailsForAgents(); } std::cout << "ok\nRunning agent analysis... " << std::flush; DO_TIMED("Running agent analysis", eng.run(getCommunicator(cmdP).get(), ¤tMap)) std::cout << " ok\nWriting out result..." << std::flush; std::vector resultTypes = agentP.outputTypes(); if(resultTypes.size() == 0) { // if no choice was made for an output type assume the user just // wants a graph file DO_TIMED("Writing graph", mgraph->write(cmdP.getOuputFile().c_str(),METAGRAPH_VERSION, false)) } else if(resultTypes.size() == 1) { // if only one type of output is given, assume that the user has // correctly entered a name with the correct extension and export // exactly with that name and extension switch(resultTypes[0]) { case AgentParser::OutputType::GRAPH: { DO_TIMED("Writing graph", mgraph->write(cmdP.getOuputFile().c_str(),METAGRAPH_VERSION, false)) break; } case AgentParser::OutputType::GATECOUNTS: { std::ofstream gatecountStream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing gatecounts", currentMap.outputSummary(gatecountStream, ',')) break; } case AgentParser::OutputType::TRAILS: { std::ofstream trailStream(cmdP.getOuputFile().c_str()); ShapeMap trailMap("Agent Trails"); eng.insertTrailsInMap(trailMap); DO_TIMED("Writing trails", mgraph->writeMapShapesAsCat(trailMap, trailStream)) break; } } } else { // if more than one output type is given assume the user has given // a filename without an extension and thus the new file must have // an extension. Also to avoid name clashes in cases where the user // asked for outputs that would yield the same extension also add // a related suffix if(std::find(resultTypes.begin(), resultTypes.end(), AgentParser::OutputType::GRAPH) != resultTypes.end()) { std::string outFile = cmdP.getOuputFile() + ".graph"; DO_TIMED("Writing graph", mgraph->write(outFile.c_str(),METAGRAPH_VERSION, false)) } if(std::find(resultTypes.begin(), resultTypes.end(), AgentParser::OutputType::GATECOUNTS) != resultTypes.end()) { std::string outFile = cmdP.getOuputFile() + "_gatecounts.csv"; std::ofstream gatecountStream(outFile.c_str()); DO_TIMED("Writing gatecounts", currentMap.outputSummary(gatecountStream, ',')) } if(std::find(resultTypes.begin(), resultTypes.end(), AgentParser::OutputType::TRAILS) != resultTypes.end()) { std::string outFile = cmdP.getOuputFile() + "_trails.cat"; std::ofstream trailStream(outFile.c_str()); ShapeMap trailMap("Agent Trails"); eng.insertTrailsInMap(trailMap); DO_TIMED("Writing trails", mgraph->writeMapShapesAsCat(trailMap, trailStream)) } } } void runIsovists(const CommandLineParser &clp, const std::vector &isovists, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(),perfWriter); std::cout << "Making " << isovists.size() << " isovists... " << std::flush; DO_TIMED("Make isovists", std::for_each(isovists.begin(), isovists.end(), [&mGraph, &clp](const IsovistDefinition &isovist)->void{ mGraph->makeIsovist(getCommunicator(clp).get(), isovist.getLocation(), isovist.getLeftAngle(), isovist.getRightAngle(), clp.simpleMode()); })) std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void exportData(const CommandLineParser &cmdP, const ExportParser &exportP, IPerformanceSink &perfWriter ) { auto mgraph = loadGraph(cmdP.getFileName().c_str(), perfWriter); switch(exportP.getExportMode()) { case ExportParser::POINTMAP_DATA_CSV: { PointMap& currentMap = mgraph->getDisplayedPointMap(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing pointmap data", currentMap.outputSummary(stream, ',')) stream.close(); break; } case ExportParser::POINTMAP_CONNECTIONS_CSV: { PointMap& currentMap = mgraph->getDisplayedPointMap(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing pointmap connections", currentMap.outputConnectionsAsCSV(stream, ",")) stream.close(); break; } case ExportParser::POINTMAP_LINKS_CSV: { PointMap& currentMap = mgraph->getDisplayedPointMap(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing pointmap connections", currentMap.outputLinksAsCSV(stream, ",")) stream.close(); break; } case ExportParser::SHAPEGRAPH_MAP_CSV: { ShapeGraph& currentMap = mgraph->getDisplayedShapeGraph(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing pointmap connections", currentMap.output(stream, ',')) stream.close(); break; } case ExportParser::SHAPEGRAPH_MAP_MIF: { ShapeGraph& currentMap = mgraph->getDisplayedShapeGraph(); std::string fileName = cmdP.getOuputFile().c_str(); std::string mifFile = fileName + ".mif"; std::string midFile = fileName + ".mid"; if (0 == fileName.compare(fileName.length() - 4, 4, ".mif")) { // we are given the .mif mifFile = fileName; midFile = fileName.substr(0, fileName.length() - 4) + ".mid"; } else if (0 == fileName.compare(fileName.length() - 4, 4, ".mid")) { // we are given the .mid mifFile = fileName.substr(0, fileName.length() - 4) + ".mif"; midFile = fileName; } std::ofstream mifStream(mifFile); std::ofstream midStream(midFile); DO_TIMED("Writing pointmap connections", currentMap.outputMifMap(mifStream, midStream)) mifStream.close(); midStream.close(); break; } case ExportParser::SHAPEGRAPH_CONNECTIONS_CSV: { ShapeGraph& currentMap = mgraph->getDisplayedShapeGraph(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing shapegraph connections", currentMap.isAxialMap() ? currentMap.writeAxialConnectionsAsPairsCSV(stream) : currentMap.writeSegmentConnectionsAsPairsCSV(stream)) stream.close(); break; } case ExportParser::SHAPEGRAPH_LINKS_UNLINKS_CSV: { ShapeGraph& currentMap = mgraph->getDisplayedShapeGraph(); std::ofstream stream(cmdP.getOuputFile().c_str()); DO_TIMED("Writing shapegraph links and unlinks", currentMap.writeLinksUnlinksAsPairsCSV(stream)) stream.close(); break; } default: { throw depthmapX::SetupCheckException("Error, unsupported export mode"); } } } void runStepDepth( const CommandLineParser &clp, const StepDepthParser::StepType &stepType, const std::vector &stepDepthPoints, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(),perfWriter); std::cout << "ok\nSelecting cells... " << std::flush; for( auto & point : stepDepthPoints ) { auto graphRegion = mGraph->getRegion(); if (!graphRegion.contains(point)) { throw depthmapX::RuntimeException("Point outside of target region"); } QtRegion r(point, point); mGraph->setCurSel(r, true); } std::cout << "ok\nCalculating step-depth... " << std::flush; Options options; options.global = 0; switch (stepType) { case StepDepthParser::StepType::ANGULAR: options.point_depth_selection = 3; break; case StepDepthParser::StepType::METRIC: options.point_depth_selection = 2; break; case StepDepthParser::StepType::VISUAL: options.point_depth_selection = 1; break; default: { throw depthmapX::SetupCheckException("Error, unsupported step type"); } } DO_TIMED("Calculating step-depth", mGraph->analyseGraph( getCommunicator(clp).get(), options, false)) std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } void runMapConversion(const CommandLineParser &clp, const MapConvertParser &mcp, IPerformanceSink &perfWriter) { auto mGraph = loadGraph(clp.getFileName().c_str(), perfWriter); int currentMapType = mGraph->getDisplayedMapType(); if (currentMapType == ShapeMap::EMPTYMAP) { if(mGraph->hasVisibleDrawingLayers()) { currentMapType = ShapeMap::DRAWINGMAP; } else { throw depthmapX::RuntimeException("No currently available map to convert from"); } } if (mcp.copyAttributes()) { if(currentMapType != ShapeMap::DATAMAP && currentMapType != ShapeMap::AXIALMAP && currentMapType != ShapeMap::SEGMENTMAP) { throw depthmapX::RuntimeException("Copying attributes is only available when "\ "converting between Data, Axial and Segment maps "\ "(current map type is not of those types)"); } if(mcp.outputMapType() != ShapeMap::DATAMAP && mcp.outputMapType() != ShapeMap::AXIALMAP && mcp.outputMapType() != ShapeMap::SEGMENTMAP) { throw depthmapX::RuntimeException("Copying attributes is only available when "\ "converting between Data, Axial and Segment maps "\ "(selected output map type is not of those types)"); } } if (mcp.removeStubLength() > 0) { if(currentMapType != ShapeMap::AXIALMAP) { throw depthmapX::RuntimeException("Removing stubs (-crsl) is only available when"\ "converting from Axial to Segment maps"\ "(current map type is not Axial)"); } if(mcp.outputMapType() != ShapeMap::SEGMENTMAP) { throw depthmapX::RuntimeException("Removing stubs (-crsl) is only available when"\ "converting from Axial to Segment maps"\ "(selected output map type is not Segment)"); } } switch(mcp.outputMapType()) { case ShapeMap::DRAWINGMAP: { DO_TIMED("Converting to drawing", mGraph->convertToDrawing(getCommunicator(clp).get(), mcp.outputMapName(), currentMapType == ShapeMap::DATAMAP)); break; } case ShapeMap::AXIALMAP: { switch(currentMapType) { case ShapeMap::DRAWINGMAP: { DO_TIMED("Converting from drawing to axial", mGraph->convertDrawingToAxial(getCommunicator(clp).get(), mcp.outputMapName())); break; } case ShapeMap::DATAMAP: { DO_TIMED("Converting from data to axial", mGraph->convertDataToAxial(getCommunicator(clp).get(), mcp.outputMapName(), !mcp.removeInputMap(), mcp.copyAttributes())); break; } default: { throw depthmapX::RuntimeException("Unsupported conversion to axial"); } } break; } case ShapeMap::SEGMENTMAP: { switch(currentMapType) { case ShapeMap::DRAWINGMAP: { DO_TIMED("Converting from drawing to segment", mGraph->convertDrawingToSegment(getCommunicator(clp).get(), mcp.outputMapName())); break; } case ShapeMap::AXIALMAP: { DO_TIMED("Converting from axial to segment", mGraph->convertAxialToSegment(getCommunicator(clp).get(), mcp.outputMapName(), !mcp.removeInputMap(), mcp.copyAttributes(), mcp.removeStubLength() / 100.0)); break; } case ShapeMap::DATAMAP: { DO_TIMED("Converting from data to segment", mGraph->convertDataToSegment(getCommunicator(clp).get(), mcp.outputMapName(), !mcp.removeInputMap(), mcp.copyAttributes())); break; } default: { throw depthmapX::RuntimeException("Unsupported conversion to segment"); } } break; } case ShapeMap::DATAMAP: { DO_TIMED("Converting to data", mGraph->convertToData(getCommunicator(clp).get(), mcp.outputMapName(), !mcp.removeInputMap(), currentMapType, mcp.copyAttributes())); break; } case ShapeMap::CONVEXMAP: { DO_TIMED("Converting to convex", mGraph->convertToConvex(getCommunicator(clp).get(), mcp.outputMapName(), !mcp.removeInputMap(), currentMapType, mcp.copyAttributes())); break; } default: { throw depthmapX::RuntimeException("Unsupported conversion"); } } std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(),METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } } ================================================ FILE: depthmapXcli/runmethods.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include "commandlineparser.h" #include "radiusconverter.h" #include "performancesink.h" #include "vgaparser.h" #include "axialparser.h" #include "mapconvertparser.h" #include "segmentparser.h" #include "agentparser.h" #include "exportparser.h" #include "linkparser.h" #include "importparser.h" #include "stepdepthparser.h" #include "salalib/isovistdef.h" #include #define CONCAT_(x,y) x##y #define CONCAT(x,y) CONCAT_(x,y) #define DO_TIMED(message, code)\ SimpleTimer CONCAT(t_, __LINE__); \ code; \ perfWriter.addData(message, CONCAT(t_, __LINE__).getTimeInSeconds()); class Line; class Point2f; namespace dm_runmethods{ std::unique_ptr loadGraph(const std::string& filename, IPerformanceSink &perfWriter); void importFiles(const CommandLineParser &cmdP, const ImportParser &parser, IPerformanceSink &perfWriter); void linkGraph(const CommandLineParser &cmdP, const LinkParser &parser, IPerformanceSink &perfWriter ); void runVga(const CommandLineParser &cmdP, const VgaParser &vgaP, const IRadiusConverter &converter, IPerformanceSink &perfWriter ); void runVisualPrep(const CommandLineParser &clp, double gridSize, const std::vector &fillPoints, double maxVisibility, bool boundaryGraph, bool makeGraph, bool unmakeGraph, bool removeLinksWhenUnmaking, IPerformanceSink &perfWriter); void runAxialAnalysis(const CommandLineParser& clp, const AxialParser &ap, IPerformanceSink &perfWriter); void runSegmentAnalysis(const CommandLineParser& clp, const SegmentParser &sp, IPerformanceSink &perfWriter); void runAgentAnalysis(const CommandLineParser &cmdP, const AgentParser &agentP, IPerformanceSink &perfWriter ); void runIsovists(const CommandLineParser &cmdP, const std::vector &isovists, IPerformanceSink &perfWriter ); void exportData(const CommandLineParser &cmdP, const ExportParser &exportP, IPerformanceSink &perfWriter ); void runStepDepth(const CommandLineParser &clp, const StepDepthParser::StepType &stepType, const std::vector &stepDepthPoints, IPerformanceSink &perfWriter); void runMapConversion(const CommandLineParser& clp, const MapConvertParser &mcp, IPerformanceSink &perfWriter); } ================================================ FILE: depthmapXcli/segmentparser.cpp ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmentparser.h" #include "parsingutils.h" #include "exceptions.h" #include "salalib/entityparsing.h" #include "runmethods.h" #include using namespace depthmapX; SegmentParser::SegmentParser() : m_analysisType(AnalysisType::NONE), m_radiusType(RadiusType::NONE), m_includeChoice(false), m_tulipBins(0) { } std::string SegmentParser::getModeName() const { return "SEGMENT"; } std::string SegmentParser::getHelp() const { return "Mode options for Segment Analysis:\n"\ " -st one of:\n" " tulip (Angular Tulip - Faster)\n"\ " angular (Angular Full - Slower)\n"\ " topological\n"\ " metric\n"\ " -sr \n"\ " -srt (only for Tulip) one of:\n"\ " steps\n"\ " metric\n"\ " angular\n"\ " -sic to include choice (only for Tulip)\n"\ " -stb (4 to 1024, 1024 approximates full angular)\n"\ " -swa perform weighted analysis using this attribute (only for Tulip)\n"; } void SegmentParser::parse(int argc, char **argv) { for (int i = 1; i < argc; ++i) { if ( std::strcmp ("-st", argv[i]) == 0) { if (m_analysisType != AnalysisType::NONE) { throw CommandLineException("-st can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-st", i) if ( std::strcmp(argv[i], "tulip") == 0 ) { m_analysisType = AnalysisType::ANGULAR_TULIP; } else if ( std::strcmp(argv[i], "angular") == 0 ) { m_analysisType = AnalysisType::ANGULAR_FULL; } else if ( std::strcmp(argv[i], "topological") == 0 ) { m_analysisType = AnalysisType::TOPOLOGICAL; } else if ( std::strcmp(argv[i], "metric") == 0 ) { m_analysisType = AnalysisType::METRIC; } else { throw CommandLineException(std::string("Invalid SEGMENT mode: ") + argv[i]); } } else if (std::strcmp(argv[i], "-srt") == 0) { if (m_radiusType != RadiusType::NONE) { throw CommandLineException("-srt can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-srt", i) if ( std::strcmp(argv[i], "steps") == 0 ) { m_radiusType = RadiusType::SEGMENT_STEPS; } else if ( std::strcmp(argv[i], "angular") == 0 ) { m_radiusType = RadiusType::ANGULAR; } else if ( std::strcmp(argv[i], "metric") == 0 ) { m_radiusType = RadiusType::METRIC; } else { throw CommandLineException(std::string("Invalid SEGMENT radius type: ") + argv[i]); } } else if(std::strcmp(argv[i], "-sic") == 0) { m_includeChoice = true; } else if (std::strcmp(argv[i], "-sr") == 0) { ENFORCE_ARGUMENT("-sr", i) m_radii = depthmapX::parseRadiusList(argv[i]); } else if (std::strcmp(argv[i], "-stb") == 0) { ENFORCE_ARGUMENT("-stb", i) if (!has_only_digits(argv[i])) { throw CommandLineException(std::string("-stb must be a number between 4 and 1024, got ") + argv[i]); } m_tulipBins = std::atoi(argv[i]); if (m_tulipBins < 4 || m_tulipBins > 1024) { throw CommandLineException(std::string("-stb must be a number between 4 and 1024, got ") + argv[i]); } } else if (std::strcmp(argv[i], "-swa") == 0) { ENFORCE_ARGUMENT("-swa", i) m_attribute = argv[i]; } } if (getAnalysisType() == AnalysisType::NONE) { throw CommandLineException("No analysis type given"); } if (getRadii().empty()) { throw CommandLineException("At least one radius must be provided"); } if (getAnalysisType() == AnalysisType::ANGULAR_TULIP && getRadiusType() == RadiusType::NONE) { throw CommandLineException("Radius type is required for tulip analysis"); } if (getAnalysisType() == AnalysisType::ANGULAR_TULIP && getTulipBins() == 0) { throw CommandLineException("Tulip bins are required for tulip analysis"); } if (getAnalysisType() != AnalysisType::ANGULAR_TULIP && (getTulipBins() != 0 || getRadiusType() != RadiusType::NONE || m_includeChoice)) { throw CommandLineException("-stb, -srt and -sic can only be used with tulip analysis"); } } void SegmentParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runSegmentAnalysis(clp, *this, perfWriter); } ================================================ FILE: depthmapXcli/segmentparser.h ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "genlib/p2dpoly.h" class SegmentParser : public IModeParser { public: SegmentParser(); // IModeParser interface public: std::string getModeName() const; std::string getHelp() const; void parse(int argc, char **argv); void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; enum class AnalysisType { NONE, ANGULAR_TULIP, ANGULAR_FULL, TOPOLOGICAL, METRIC }; enum class RadiusType { NONE, SEGMENT_STEPS, ANGULAR, METRIC }; AnalysisType getAnalysisType() const { return m_analysisType; } RadiusType getRadiusType() const { return m_radiusType; } bool includeChoice() const { return m_includeChoice; } int getTulipBins() const { return m_tulipBins; } const std::vector getRadii() const { return m_radii;} const std::string getAttribute() const { return m_attribute;} private: AnalysisType m_analysisType; RadiusType m_radiusType; bool m_includeChoice; int m_tulipBins; std::vector m_radii; std::string m_attribute; }; ================================================ FILE: depthmapXcli/simpletimer.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include class SimpleTimer { public: SimpleTimer() : m_startTime(std::chrono::high_resolution_clock::now()) { } double getTimeInSeconds() const { auto t2 = std::chrono::high_resolution_clock::now(); return static_cast(std::chrono::duration_cast(t2-m_startTime).count()) / 1000.0; } void reset() { m_startTime = std::chrono::high_resolution_clock::now(); } private: std::chrono::time_point m_startTime; }; ================================================ FILE: depthmapXcli/stepdepthparser.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "stepdepthparser.h" #include "exceptions.h" #include "parsingutils.h" #include "salalib/entityparsing.h" #include "runmethods.h" #include #include using namespace depthmapX; void StepDepthParser::parse(int argc, char ** argv) { std::vector points; std::string pointFile; for ( int i = 1; i < argc; ++i ) { if ( std::strcmp ("-sdp", argv[i]) == 0) { if (!pointFile.empty()) { throw CommandLineException("-sdp cannot be used together with -sdf"); } ENFORCE_ARGUMENT("-sdp", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid step depth point provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } points.push_back(argv[i]); } else if ( std::strcmp("-sdf", argv[i]) == 0 ) { if (!points.empty()) { throw CommandLineException("-sdf cannot be used together with -sdp"); } ENFORCE_ARGUMENT("-sdf", i) pointFile = argv[i]; } else if ( std::strcmp ("-sdt", argv[i]) == 0) { ENFORCE_ARGUMENT("-sdt", i) if ( std::strcmp(argv[i], "angular") == 0 ) { m_stepType = StepType::ANGULAR; } else if ( std::strcmp(argv[i], "metric") == 0 ) { m_stepType = StepType::METRIC; } else if ( std::strcmp(argv[i], "visual") == 0 ) { m_stepType = StepType::VISUAL; } else { throw CommandLineException(std::string("Invalid step type: ") + argv[i]); } } } if (pointFile.empty() && points.empty()) { throw CommandLineException("Either -sdp or -sdf must be given"); } if(!pointFile.empty()) { std::ifstream pointsStream(pointFile); if (!pointsStream) { std::stringstream message; message << "Failed to load file " << pointFile << ", error " << std::strerror(errno) << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } std::vector parsed = EntityParsing::parsePoints(pointsStream, '\t'); m_stepDepthPoints.insert(std::end(m_stepDepthPoints), std::begin(parsed), std::end(parsed)); } else if(!points.empty()) { std::stringstream pointsStream; pointsStream << "x,y"; std::vector::iterator iter = points.begin(), end = points.end(); for ( ; iter != end; ++iter ) { pointsStream << "\n" << *iter; } std::vector parsed = EntityParsing::parsePoints(pointsStream, ','); m_stepDepthPoints.insert(std::end(m_stepDepthPoints), std::begin(parsed), std::end(parsed)); } if (m_stepType == StepType::NONE) { throw CommandLineException("Step depth type (-sdt) must be provided"); } } void StepDepthParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runStepDepth(clp, m_stepType, m_stepDepthPoints, perfWriter); } ================================================ FILE: depthmapXcli/stepdepthparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "genlib/p2dpoly.h" #include class StepDepthParser : public IModeParser { public: StepDepthParser() : m_stepType(StepType::NONE) {} virtual std::string getModeName() const { return "STEPDEPTH"; } virtual std::string getHelp() const { return "Mode options for pointmap STEPDEPTH are:\n" \ " -sdp point where to calculate step depth from. Can be repeated\n" \ " -sdf a file with a point per line to calculate step depth from\n" \ " -sdt step type. One of metric, angular or visual\n"; } enum class StepType { NONE, ANGULAR, METRIC, VISUAL }; virtual void parse(int argc, char** argv); virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; std::vector getStepDepthPoints() const { return m_stepDepthPoints; } StepType getStepType() const { return m_stepType; } private: std::vector m_stepDepthPoints; StepType m_stepType; }; ================================================ FILE: depthmapXcli/vgaparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "vgaparser.h" #include "exceptions.h" #include #include "radiusconverter.h" #include "runmethods.h" #include "parsingutils.h" using namespace depthmapX; VgaParser::VgaParser() : m_vgaMode(VgaMode::NONE), m_localMeasures(false), m_globalMeasures(false) {} void VgaParser::parse(int argc, char *argv[]) { for ( int i = 1; i < argc; ) { if ( std::strcmp ("-vm", argv[i]) == 0) { if (m_vgaMode != VgaMode::NONE) { throw CommandLineException("-vm can only be used once, modes are mutually exclusive"); } ENFORCE_ARGUMENT("-vm", i) if ( std::strcmp(argv[i], "isovist") == 0 ) { m_vgaMode = VgaMode::ISOVIST; } else if ( std::strcmp(argv[i], "visibility") == 0 ) { m_vgaMode = VgaMode::VISBILITY; } else if ( std::strcmp(argv[i], "metric") == 0 ) { m_vgaMode = VgaMode::METRIC; } else if ( std::strcmp(argv[i], "angular") == 0 ) { m_vgaMode = VgaMode::ANGULAR; } else if ( std::strcmp(argv[i], "thruvision") == 0) { m_vgaMode = VgaMode::THRU_VISION; } else { throw CommandLineException(std::string("Invalid VGA mode: ") + argv[i]); } } else if ( std::strcmp(argv[i], "-vg") == 0 ) { m_globalMeasures = true; } else if ( std::strcmp(argv[i], "-vl") == 0 ) { m_localMeasures = true; } else if (std::strcmp(argv[i], "-vr") == 0) { ENFORCE_ARGUMENT("-vr", i) m_radius = argv[i]; } ++i; } if(m_vgaMode == VgaMode::NONE) { m_vgaMode = VgaMode::ISOVIST; } if (m_vgaMode == VgaMode::VISBILITY && m_globalMeasures) { if (m_radius.empty()) { throw CommandLineException("Global measures in VGA/visibility analysis require a radius, use -vr "); } if (m_radius != "n" && !has_only_digits(m_radius)) { throw CommandLineException(std::string("Radius must be a positive integer number or n, got ") + m_radius); } } else if (m_vgaMode == VgaMode::METRIC) { if (m_radius.empty()) { throw CommandLineException("Metric vga requires a radius, use -vr "); } } } void VgaParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { RadiusConverter radiusConverter; dm_runmethods::runVga(clp, *this, radiusConverter, perfWriter); } ================================================ FILE: depthmapXcli/vgaparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include "imodeparser.h" #include "commandlineparser.h" class VgaParser : public IModeParser { public: virtual std::string getModeName() const { return "VGA"; } virtual std::string getHelp() const { return "Mode options for VGA:\n"\ "-vm one of isovist, visiblity, metric, angular, thruvision\n"\ "-vg turn on global measures for visibility, requires radius between 1 and 99 or n\n"\ "-vl turn on local measures for visibility\n"\ "-vr set visibility radius\n"; } public: VgaParser(); virtual void parse(int argc, char *argv[]); virtual void run(const CommandLineParser &clp, IPerformanceSink& perfWriter) const; enum VgaMode{ NONE, ISOVIST, VISBILITY, METRIC, ANGULAR, THRU_VISION }; // vga options VgaMode getVgaMode() const { return m_vgaMode; } bool localMeasures() const { return m_localMeasures; } bool globalMeasures() const { return m_globalMeasures; } const std::string & getRadius() const { return m_radius; } private: // vga options VgaMode m_vgaMode; bool m_localMeasures; bool m_globalMeasures; std::string m_radius; }; ================================================ FILE: depthmapXcli/visprepparser.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "visprepparser.h" #include "exceptions.h" #include "parsingutils.h" #include "salalib/entityparsing.h" #include "runmethods.h" #include #include using namespace depthmapX; void VisPrepParser::parse(int argc, char ** argv) { // All options: // Create grid (m_grid > 0) // Fill grid (pointFile or points not empty) // Make graph // Unmake graph // All possible combinations: // Create Grid + Fill Grid // Create Grid + Fill Grid + Make graph // Fill Grid // Fill Grid + Make graph // Make Graph // Unmake Graph // Bad combinations: // Create Grid + Make graph = Creates empty graph // Unmake graph + Anything else = Pointless action std::vector points; std::string pointFile; for ( int i = 1; i < argc; ++i ) { if ( std::strcmp ("-pg", argv[i]) == 0) { if (m_grid >= 0) { throw CommandLineException("-pg can only be used once"); } ENFORCE_ARGUMENT("-pg", i) m_grid = std::atof(argv[i]); if (m_grid <= 0) { throw CommandLineException(std::string("-pg must be a number >0, got ") + argv[i]); } } else if ( std::strcmp ("-pp", argv[i]) == 0) { if (!pointFile.empty()) { throw CommandLineException("-pp cannot be used together with -pf"); } ENFORCE_ARGUMENT("-pp", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid fill point provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } points.push_back(argv[i]); } else if ( std::strcmp("-pf", argv[i]) == 0 ) { if (!points.empty()) { throw CommandLineException("-pf cannot be used together with -pp"); } ENFORCE_ARGUMENT("-pf", i) pointFile = argv[i]; } else if ( std::strcmp("-pr", argv[i]) == 0) { ENFORCE_ARGUMENT("-pr", i); m_maxVisibility = std::atof(argv[i]); if ( m_maxVisibility == 0.0) { std::stringstream message; message << "Restricted visibility of '" << argv[i] << "' makes no sense, use a positive number or -1 for unrestricted"; throw CommandLineException(message.str()); } } else if ( std::strcmp("-pb", argv[i]) == 0 ) { m_boundaryGraph = true; } else if ( std::strcmp("-pm", argv[i]) == 0 ) { if (getUnmakeGraph()) { throw CommandLineException("-pm cannot be used together with -pu"); } m_makeGraph = true; } else if ( std::strcmp("-pu", argv[i]) == 0 ) { if (getMakeGraph()) { throw CommandLineException("-pu cannot be used together with -pm"); } m_unmakeGraph = true; } else if ( std::strcmp("-pl", argv[i]) == 0 ) { m_removeLinksWhenUnmaking = true; } } if(!getMakeGraph() && !getUnmakeGraph() && m_grid <= 0 && pointFile.empty() && points.empty()) { throw CommandLineException("Nothing to do"); } if(m_grid > 0 && getMakeGraph() && pointFile.empty() && points.empty()) { throw CommandLineException("Creating a graph for an unfilled grid is not possible. " \ "Either -pp or -pf must be given"); } if(!pointFile.empty()) { std::ifstream pointsStream(pointFile); if (!pointsStream) { std::stringstream message; message << "Failed to load file " << pointFile << ", error " << std::strerror(errno) << std::flush; throw depthmapX::RuntimeException(message.str().c_str()); } std::vector parsed = EntityParsing::parsePoints(pointsStream, '\t'); m_fillPoints.insert(std::end(m_fillPoints), std::begin(parsed), std::end(parsed)); } else if(!points.empty()) { std::stringstream pointsStream; pointsStream << "x,y"; std::vector::iterator iter = points.begin(), end = points.end(); for ( ; iter != end; ++iter ) { pointsStream << "\n" << *iter; } std::vector parsed = EntityParsing::parsePoints(pointsStream, ','); m_fillPoints.insert(std::end(m_fillPoints), std::begin(parsed), std::end(parsed)); } if(getUnmakeGraph() && (m_grid > 0 || !m_fillPoints.empty())) { throw CommandLineException("-pu can not be used with any other option apart from -pl"); } if(m_removeLinksWhenUnmaking && !m_unmakeGraph) { throw CommandLineException("-pl can only be used together with -pu"); } } void VisPrepParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { dm_runmethods::runVisualPrep(clp, m_grid, m_fillPoints, m_maxVisibility, m_boundaryGraph, m_makeGraph, m_unmakeGraph, m_removeLinksWhenUnmaking, perfWriter); } ================================================ FILE: depthmapXcli/visprepparser.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "imodeparser.h" #include "genlib/p2dpoly.h" #include class VisPrepParser : public IModeParser { public: VisPrepParser() : m_grid(-1.0), m_maxVisibility(-1.0), m_boundaryGraph(false), m_makeGraph(false), m_unmakeGraph(false), m_removeLinksWhenUnmaking(false) {} virtual std::string getModeName() const { return "VISPREP"; } virtual std::string getHelp() const { return "Mode options for VISPREP (visual analysis preparation) are:\n" \ " -pg floating point number defining the grid spacing. If this\n" \ " is provided it will create a new map\n" \ " -pp point where to fill. Can be repeated\n" \ " -pf a file with a point per line to fill\n" \ " -pr restrict visibility (-1 is unrestricted, default)\n" \ " -pb Make boundary graph\n" \ " -pm Make graph\n" \ " -pu Unmake graph\n" \ " -pl Remove links when unmaking\n"; } virtual void parse(int argc, char** argv); virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; double getGrid() const { return m_grid; } std::vector getFillPoints() const { return m_fillPoints; } bool getBoundaryGraph() const { return m_boundaryGraph; } double getMaxVisibility() const { return m_maxVisibility; } bool getMakeGraph() const { return m_makeGraph; } bool getUnmakeGraph() const { return m_unmakeGraph; } bool getRemoveLinksWhenUnmaking() const { return m_removeLinksWhenUnmaking; } private: double m_grid; std::vector m_fillPoints; double m_maxVisibility; bool m_boundaryGraph; bool m_makeGraph; bool m_unmakeGraph; bool m_removeLinksWhenUnmaking; }; ================================================ FILE: docs/about.md ================================================ ## About depthmapX depthmapX is a multi-platform software platform to perform a set of spatial network analyses designed to understand social processes within the built environment. It works at a variety of scales from building through small urban to whole cities or states. At each scale, the aim of the software is to produce a map of open space elements, connect them via some relationship (for example, intervisibility or overlap) and then perform graph analysis of the resulting network. The objective of the analysis is to derive variables which may have social or experiential significance. At the building or small urban scale, depthmapX can be used to assess the visual accessibility in a number of ways. It can produce point isovists, that is, polygons representing the visually accessible area from a location, along with measures of those polygons (such as perimeter, area and so on), or it can further join a dense grid of isovists into a visibility graph of intervisible points (with graphs of up to about 1000000 point locations). The visibility graph may then be analysed directly using graph measures, or used as the core of an agent-based analysis. In the agent-based analysis a number of software agents representing pedestrians are released into the environment. Each software agent is able to access the visual accessibility information for its current location from the visibility graph, and this informs its choice of next destination. The numbers of agents passing through gates can be counted, and compared to actual numbers of pedestrians passing through gates. At the small to medium urban scale, depthmapX can be used to derive an ‘axial map’ of a layout. That is, derive a reduced straight-line network of the open space in an environment. The axial map has been the staple of space syntax research for many years, but the mathematical derivation of it is novel. The automatic derivation allows an objective map for research into city form and function. Once the map has been generated, it may be analysed using graph measures, and the measures may be transferred to gate layers in order to compare with indicators of pedestrian or social behaviour. For larger systems where the derivation algorithm becomes cumbersome, pre-drawn axial maps may be imported. Axial maps may be broken into segment maps, or segment maps, such as road-centre line maps, may be imported directly. These may be analysed using a variety of techniques, such as according to angular separation, road distance, or segment steps. For example, number of shortest angular paths through a segment may be calculated, or the average road distance from each segment to all others may be calculated. The analyses described so far are fairly fixed, however depthmapX also offers the capability of extension through two levels of interface. The first level, a scripting interface based on the Python language, allows researchers to calculate new derived measures as well as to add graph measures, such as circuit lengths, for each of the graph types. It also allows the ability to select groups of nodes according to value or according to simple algorithms. The second level, the Software Developers’ Kit (SDK) allows programmers the ability to write new forms of analysis. For example, researchers at the West Japan Railway Company have used the software developers’ kit to add new agent-based analysis where agents are directed through a station layout including ticket barriers and signposting. depthmapX can display information as coloured maps, tables and scattergrams that comparing measures against other measures or observed data, as well as a three-dimensional view of agents walking. Data for plans can be imported from AutoCAD’s DXF format, or from Ordnance Survey NTF files or US Tiger Line maps, as well as from GIS through MapInfo’s MIF/MID format. Export may also be to MIF/MID, or to text files which may be analysed further using statistical analysis packages. Additionally, maps may be exported as vector graphics EPS files, or by copying and pasting into other software such as Microsoft Word. ================================================ FILE: docs/building.md ================================================ # Building depthmapX ## Building natively To build depthmapX on your machine, you need the following dependencies: - A C++ compiler that supports C++-11 or later. Tested compilers are - MSVC 2015 or later (on Windows) - Clang (on MacOS and Linux) - g++ (on Linux) - Qt 5.7 or later - cmake 3.13 or later - this is a fairly recent version If these dependencies are available, then building depthmapX should be ``` mkdir build cd build cmake .. make ``` ## Building in docker depthmapX can be built in a docker container that provides an image including all the required dependencies. It will build depthmapX on Unbuntu 18.04, i.e. it will produce a linux executable. The docker image can also be used to run the command line app interactively. In order to use the docker build image, docker must be running on the computer in use - please refer to the docker documentation at www.docker.com. ### Windows To run the docker build on windows, use this command line: ``` docker run -v \depthmapX:/mnt/code/ -it blackseamonster/depthmapx-buildenv:0.3 bash -c ci/build.sh ``` To run the build environment interactively, use ``` docker run -v \depthmapX:/mnt/code/ -it blackseamonster/depthmapx-buildenv:0.3 bash ``` ### Mac/Linux To run the docker build on a Unix based system, use this command line: ``` docker run --security-opt seccomp:unconfined --user $UID -v $PWD:/mnt/code blackseamonster/depthmapx-buildenv:0.3 bash -c ci/build.sh ``` To run the build environment interactively, use: ``` docker run --security-opt seccomp:unconfined --user $UID -v $PWD:/mnt/code blackseamonster/depthmapx-buildenv:0.3 bash ``` ## Using an IDE As depthmapX uses cmake as build toolchain, any IDE that supports cmake should be usable. ================================================ FILE: docs/commandline.md ================================================ # depthmapX Command Line Interface ## Overview The depthmapX command line interface allows to run steps that are traditionally executed by loading a file into the GUI and clicking buttons/menu entries by running a command from a command line/shell. The command line interface is especially useful in cases where a similar kind of analysis needs to be repeated regularly, as the steps can be written into a script and run automatically or semi-automatically, do not require user input via mouse/GUI and can be parallelised into multiple processes or on multiple machines. The general idea is that each call to the command line interface reads in a depthmapX graph file, then applies some transformation/analysis to it and saves the result into a different file. Thus, a pipeline of operations can be created where each step reads in the input of the previous step, and in the end we have the end result and all intermediate steps. This is particularly helpful if something has gone wrong, as we can go back, figure out which step went wrong and rerun this and all subsequent steps. The command line interface also supports importing of data from DXF and csv formats and export to csv so that a whole pipeline from plan to statistical output can be run programmatically. ## The Command Line The functionality in the depthmapX cli is split up into execution modes - each mode roughly represents a class of functionalities in the UI. The overall commandline looks like: Mac/Linux: `./depthmapXcli -f -o -m [mode options]` Windows: `depthmapXcli.exe -f -o -m [mode options]` ### Global option These are command line parameters that can be used for any run of the application, no matter what the used mode is. - `-m ` This chooses the mode (what depthmapX operation to execute). Available modes are - `VGA` run visual graph analysis - `LINK` create extra links between pixels - `VISPREP` various operations to prepare a blank map for VGA or agent analysis - `AXIAL` run axial analysis - `AGENTS` run an agent analysis - `ISOVIST` calculate isovists - `EXPORT` export data from the given graph file - `IMPORT` import data into a graph file - `-f ` input graph file to base the operation on - `-o ` graph file the result of the operation will be written to - `-h` print a help text and exit - `-s` enable simple mode (off by default) - `-t ` enables dumping of the time used for various steps of the processing into the specified file. Each mode has a set of suboptions to tailor what exactly will we done. ### Mode options for `VGA` - `-vm` Sets the VGA mode. This option must be set when using `VGA`. These reflect the options from the VGA submenu in the depthmap UI. Possible options are - `isovist` - `visibility` - `metric` - `angular` - `thruvision` - `-vg` Turn on global measures (optional). When set, `-vr` must be used to set a visibility radius. - `-vl` Turn on local measures (optional). - `-vr ` Set the visibility radius to a number between 1 and 99 steps. ### Mode options for `LINK` Use this mode to add links to a grid before running a `VGA` analysis. It takes tuples of coordinates and links the two closes pixels (as if using the link tool in the graphical user interface - the coordinates represent the mouse positions when clicking). This mode either takes a list of tuples on the command line, or it reads it in from a file - `-lf ` Reads in the link coordinates from a file. - `-lnk Defines one link to be made in the format `x1,y1,x2,y2` - e.g. to link from 0.0,0.0 to 1.0,2.3, specify 0.0,0.0,1.0,2.3. The file format for the links file is 4 tabulator separated columns with headers x1, x2, y1, and y2. So the file for the example above would be: ``` x1 y1 x2 y2 0.0 0.0 1.0 2.3 ``` ### Mode options for `VISPREP` This mode can be used to run the preparation steps required after a map (dxf) has been imported into depthmapX, but before a VGA or agent analysis can be run. It will define a grid, fill the graph, and run the connectivity calculation. It takes the following options - `-pg ` defines the grid size in units of your drawing - `-pp ` Defines a point where the fill algorithm starts in `x,y` format. This option can be repeated if separate parts of the plan need to be filled. - `-pf ` Reads the points for filling from the specified file (tab separated, headers `X` and `Y`). This option cannot be combined with `-pp` - `-pr ` This restricts the visiblity in the connectivity calculation to the given value. The default value is unrestricted (`-1`) - `-pb` Enables creating a boundary graph. Example: `./depthmapXcli_macos -f gallery.graph -o gallery_prep.graph -m VISPREP -pg 0.4 -pf 3.0,4.0 -pr 5` ### Mode options for `AXIAL` This modes runs the various things that depthmapX can do around axial analysis. It has two different kinds of options: command options that specify what to run, and modifiers that impact how these are run. Each command options expects an input file that has the required inputs for these options (e.g. an axial analysis expects the graph file to contain an axial map). The command options are - `-xl ` Calculate an all lines map starting at the point given in `x,y` format. - `-xf` reduce an all lines map to a fewest lines map. Expects an axial map that can be reduced to be in the graph file. - `-xu` Process unlink data (not yet supported on the command line) - `-xa` run the actual axial analysis. Expects an axial map to be present in the graph file. These command flags can be combined within one run, they will always run in the order `-xl -xf -xu -xa` and each step can produce the input for the next. In addition to these flags, the following modifiers are available - `-xac` Include choice (betweenness) calculations - `-xal` Include local measures - `-xar` Include RA, RRA and total depth calculations ### Mode options for `AGENTS` - `-am ` one of - `standard` - `los-length` (Line of Sight length) - `occ-length` (Occluded length) - `occ-any` (Any occlusions) - `occ-group-45` (Occlusion group bins - 45 degrees) - `occ-group-60` (Occlusion group bins - 60 degrees) - `occ-furthest` (Furthest occlusion per bin) - `bin-far-dist` (Per bin far distance weighted) - `bin-angle` (Per bin angle weighted) - `bin-far-dist-angle` (Per bin far-distance and angle weighted) - `bin-memory` (Per bin memory) - `-ats ` set total system timesteps to be run - `-arr ` set agent release rate (likelyhood of release per timestep) - `-atrails ` record trails for this amount of agents (set to 0 to record all, with max possible currently = 50) - `-afov ` set agent field-of-view (bins) - `-asteps ` set agent steps before turn decision - `-alife ` set agent total lifetime (in timesteps) - `-alocseed ` set agents to start at random locations with specific seed (0 to 10) - `-alocfile ` - `-aloc ` provide the single agent starting point in format `x1,y1` for example `-aloc 0.1,0.2`. - `-ot ` available output types (may use more than one - `graph` (graph file, default) - `gatecounts` (csv with cells of grid with gate counts) - `trails` (csv with lines showing path traversed by each agent) ### Mode options for `ISOVIST` - `-ii ` Define an isoivist at position x,y with optional direction angle and view angle for partial isovists - `-if ` load isovist definitions from a file (csv) the relevant headers must be called x, y, angle and viewangle the latter two are optional. Those two arguments cannot be mixed Angles for partial isovists are in degrees, counted anti-clockwise with 0 pointing to the right. ### Mode options for `EXPORT` This mode exports data from a graph file to a csv for further analysis in other tools, e.g. Excel or a statistics package. Thus, the output file (`-o` argument) should be a csv file, not a graph file in this mode. - `-em ` one of - `pointmap-data-csv` - `pointmap-connections-csv` ### Mode options for `IMPORT` The file provided by -f here will be used as the base. If that fileis not a graph, a new graph will be created and the file will be imported. - `-if ` one or more files to import Example for importing a dxf: `./depthmapXcli -f in.dxf -o out.graph` ================================================ FILE: docs/formatting.md ================================================ Formatting is done with ClangFormat with the following options: - IndentWidth: 4 - ColumnLimit: 119 - NamespaceIndentation: All ================================================ FILE: docs/gui.md ================================================ # depthmapX Graphical User Interface The graphical user interface is the standard way of interacting with depthmapX. It allows to load files, import plans, runs analyses and explore the data in an interactive way. A lot of the available functionality has been described in the [Depthmap Manual for Dummies](./DepthmapManualForDummies-v13.pdf) by Akkie van Nes, which is slightly outdated but still worth a read to get an idea how things work in the GUI. ================================================ FILE: docs/howdoi.md ================================================ Calculate NACh and NAIn --- NACh (Normalised Angular Choice) and NAIn (Normalised Angular Integration) were introduced in Hillier et al. (2012). To create them first calculate Choice and Total depth (Tools -> Segment -> Run Angular Segment Analysis..., include choice), create the two new attributes/columns (Attributes -> Add Column) and finally set their formulas (Attribute -> Update Column). According to Hillier et al. (2012) the equation for NACh is: **`NACh = log( ACH + 1) / log( ATD + 3)`** where `ACH = Angular Choice` and `ATD = Angular Total Depth`. Thus the formula in depthmapX needs to be: **`log(value("T1024 Choice") + 1) / log(value("T1024 Total Depth") + 3)`**, assuming that the analysis carried out was Angular Tulip analysis with 1024 bins and no radius limit. The equivalent for NAIn is: **`NAIn = NC ^ 1.2 / ATD`** where `NC = Node Count` and `ATD = Angular Total Depth`. Thus the formula for depthmapX needs to be: **`value("T1024 Node Count")^1.2 / value("T1024 Total Depth")`** References: - Hillier, W. R. G., Yang, T., & Turner, A. (2012). Normalising least angle choice in Depthmap - And how it opens up new perspectives on the global and local analysis of city space. Journal of Space Syntax, 3(2), 155–193. ================================================ FILE: docs/index.md ================================================ # depthmapX Documentation depthmapX is a tool for spatial analysis, originally written as a research project by Alasdair Turner (targeting the Windows platform only), then later ported to Qt and made available cross platform by Tasos Varoudis, and is now under active development by a small team of members of Bartlett School of Architecture at UCL and volunteers. ## Table of Contents - [About](./about.md) - [Using the Graphical User Interface (GUI)](./gui.md) - [The command line interface](./commandline.md) - [Building depthmapX yourself](./building.md) ================================================ FILE: genlib/CMakeLists.txt ================================================ set(genlib genlib) set(genlib_SRCS bsptree.cpp p2dpoly.cpp pafmath.cpp stringutils.cpp xmlparse.cpp) add_compile_definitions(GENLIB_LIBRARY) add_library(${genlib} STATIC ${genlib_SRCS}) ================================================ FILE: genlib/bsptree.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010 University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "bsptree.h" #include // Binary Space Partition /* Takes a set of lines and creates a binary-space-partition tree by starting from a * root node, setting its left and right nodes and recursively doing the same process * over those. Through this process the set of lines is split in two (one set for each * left and right nodes) and those are split and passed again further down the recursion. * While the original implementation was actually recursive it was hitting the recursion * limit when the input was a large number of lines that fell on the same side (i.e. an * arc divided in 500 pieces). It has been refactored here to an iterative solution, where * the current node (left or right) is pushed to a stack along with the relevant set of lines. */ void BSPTree::make(Communicator *communicator, time_t atime, const std::vector &lines, BSPNode *root) { typedef std::pair, std::vector> TagLineVecPair; std::stack nodeStack; std::stack lineStack; nodeStack.push(root); lineStack.push(makeLines(communicator, atime, lines, root)); int progress = 0; while (!nodeStack.empty()) { progress++; // might need to increase by 2 because it was one for each left/right in the previous iteration if (communicator) { if (communicator->IsCancelled()) { throw Communicator::CancelledException(); } if (qtimer(atime, 500)) { communicator->CommPostMessage(Communicator::CURRENT_RECORD, progress); } } BSPNode *currNode = nodeStack.top(); nodeStack.pop(); TagLineVecPair currLines = lineStack.top(); lineStack.pop(); if (!currLines.first.empty()) { currNode->m_left = std::unique_ptr(new BSPNode(currNode)); nodeStack.push(currNode->m_left.get()); lineStack.push(makeLines(communicator, atime, currLines.first, currNode->m_left.get())); } if (!currLines.second.empty()) { currNode->m_right = std::unique_ptr(new BSPNode(currNode)); nodeStack.push(currNode->m_right.get()); lineStack.push(makeLines(communicator, atime, currLines.second, currNode->m_right.get())); } } } /* Finds the midpoint from all the lines given and returns the index of the line * closest to it. */ int BSPTree::pickMidpointLine(const std::vector &lines, BSPNode *par) { int chosen = -1; Point2f midpoint; for (size_t i = 0; i < lines.size(); i++) { midpoint += lines[i].line.start() + lines[i].line.end(); } midpoint /= 2.0 * lines.size(); bool ver = true; if (par && par->getLine().height() > par->getLine().width()) { ver = false; } double chosendist = -1.0; for (size_t i = 0; i < lines.size(); i++) { const Line &line = lines[i].line; if (ver) { if (line.height() > line.width() && (chosen == -1 || dist(line.midpoint(), midpoint) < chosendist)) { chosen = static_cast(i); chosendist = dist(line.midpoint(), midpoint); } } else { if (line.width() > line.height() && (chosen == -1 || dist(line.midpoint(), midpoint) < chosendist)) { chosen = static_cast(i); chosendist = dist(line.midpoint(), midpoint); } } } // argh... and again... there weren't any hoz / ver: if (chosen == -1) { for (size_t i = 0; i < lines.size(); i++) { if (chosen == -1 || dist(lines[i].line.midpoint(), midpoint) < chosendist) { chosen = static_cast(i); chosendist = dist(lines[i].line.midpoint(), midpoint); } } } return chosen; } /* Breaks a set of lines in two (left-right). First chooses a line closest to the midpoint * of the set ("chosen") and then classifies lines left or right depending on whether they * lie clockwise or anti-clockwise of the chosen one (with chosen start as centre, angles * from the chosen end up to 180 are clockwise, down to -180 anti-clockwise). Lines that cross * from one side of the chosen to the other are split in two and each part goes to the relevant set. */ std::pair, std::vector> BSPTree::makeLines(Communicator *, time_t, const std::vector &lines, BSPNode *base) { std::vector leftlines; std::vector rightlines; // for optimization of the tree (this reduced a six-minute gen time to a 38 second gen time) int chosen = -1; if (lines.size() > 3) { chosen = BSPTree::pickMidpointLine(lines, base->m_parent); } else { chosen = pafrand() % lines.size(); } Line chosenLine = lines[chosen].line; int chosenTag = lines[chosen].tag; base->setLine(chosenLine); base->setTag(chosenTag); Point2f v0 = chosenLine.end() - chosenLine.start(); v0.normalise(); for (size_t i = 0; i < lines.size(); i++) { if (i == static_cast(chosen)) { continue; } const Line &testline = lines[i].line; int tag = lines[i].tag; Point2f v1 = testline.start() - chosenLine.start(); v1.normalise(); Point2f v2 = testline.end() - chosenLine.start(); v2.normalise(); // should use approxeq here: double a = testline.start() == chosenLine.start() ? 0 : det(v0, v1); double b = testline.end() == chosenLine.start() ? 0 : det(v0, v2); // note sure what to do if a == 0 and b == 0 (i.e., it's parallel... this test at least ensures on the line is // one or the other side) if (a >= 0 && b >= 0) { leftlines.push_back(TaggedLine(testline, tag)); } else if (a <= 0 && b <= 0) { rightlines.push_back(TaggedLine(testline, tag)); } else { Point2f p = intersection_point(chosenLine, testline); Line x = Line(testline.start(), p); Line y = Line(p, testline.end()); if (a >= 0) { if (x.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(y, tag)); } else { if (x.length() > 0.0) // should use a tolerance here too rightlines.push_back(TaggedLine(x, tag)); if (y.length() > 0.0) // should use a tolerance here too leftlines.push_back(TaggedLine(y, tag)); } } } return std::make_pair(leftlines, rightlines); } ================================================ FILE: genlib/bsptree.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010 University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include // Binary Space Partition struct BSPNode { private: Line m_line; int m_tag; public: enum { BSPLEFT, BSPRIGHT }; std::unique_ptr m_left; std::unique_ptr m_right; BSPNode *m_parent; BSPNode(BSPNode *parent = NULL) : m_left(nullptr), m_right(nullptr) { m_parent = parent; m_tag = -1; } bool isLeaf() { return m_left == nullptr && m_right == nullptr; } int classify(const Point2f &p) { Point2f v0 = m_line.end() - m_line.start(); v0.normalise(); Point2f v1 = p - m_line.start(); v1.normalise(); if (det(v0, v1) >= 0) { return BSPLEFT; } else { return BSPRIGHT; } } const Line &getLine() const { return m_line; } void setLine(const Line &line) { m_line = line; } int getTag() const { return m_tag; } void setTag(const int tag) { m_tag = tag; } }; namespace BSPTree { void make(Communicator *communicator, time_t atime, const std::vector &lines, BSPNode *root); int pickMidpointLine(const std::vector &lines, BSPNode *par); std::pair, std::vector> makeLines(Communicator *communicator, time_t atime, const std::vector &lines, BSPNode *base); } // namespace BSPTree ================================================ FILE: genlib/comm.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once //#include #include #include #include #include #include #ifdef _WIN32 // Quick mod - TV #pragma warning(disable : 4244) #pragma warning(disable : 4100) #else #endif const char *const g_default_file_set = "File set"; struct FilePath { std::string m_path; std::string m_name; std::string m_ext; FilePath(const std::string &pathname) { size_t dot = pathname.find_last_of('.'); #ifdef _WIN32 size_t slash = pathname.find_last_of('\\'); // WIN32 #else size_t slash = pathname.find_last_of('/'); // Other #endif if (slash != std::string::npos) { m_path = pathname.substr(0, slash + 1); } if (dot != std::string::npos) { m_name = pathname.substr(slash + 1, dot - slash - 1); m_ext = pathname.substr(dot + 1); } else { m_name = pathname.substr(slash + 1); } } }; class Communicator { public: class CancelledException // throw from your class { public: CancelledException() { ; } }; enum { NUM_STEPS, CURRENT_STEP, NUM_RECORDS, CURRENT_RECORD }; protected: bool m_cancelled; bool m_delete_flag; // nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11) std::string m_infilename; std::ifstream *m_infile; std::ifstream *m_infile2; // <- MapInfo MIF files come in two parts std::ofstream *m_outfile; // nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11) std::vector m_fileset; // <- sometimes you want to load a whole set of files public: Communicator() { m_infile = NULL; m_infile2 = NULL; m_outfile = NULL; m_cancelled = false; m_delete_flag = false; } // bool GetDeleteFlag() // used by ICommunicator and IComm together { return m_delete_flag; } // virtual ~Communicator() { if (m_infile) delete m_infile; m_infile = NULL; if (m_infile2) delete m_infile2; m_infile2 = NULL; if (m_outfile) delete m_outfile; m_outfile = NULL; } // void SetInfile(const char *filename) { m_infile = new std::ifstream(filename); FilePath fp(filename); m_infilename = fp.m_name; } void SetInfile2(const char *filename) { m_infile2 = new std::ifstream(filename); } std::string GetInfileName() { return m_fileset.size() ? std::string(g_default_file_set) : m_infilename; } std::string GetMBInfileName() { std::string ret; if (m_fileset.size()) { ret = "File set"; } else { ret = std::string(m_infilename.c_str()); } return ret; } size_t GetInfileSize() { if (m_infile) { m_infile->seekg(0, std::ios::beg); size_t begin_pos = m_infile->tellg(); m_infile->seekg(0, std::ios::end); size_t end_pos = m_infile->tellg(); m_infile->seekg(0, std::ios::beg); return size_t(end_pos - begin_pos); } return 0; } void SetOutfile(const char *filename) { m_outfile = new std::ofstream(filename); } // bool IsCancelled() const { return m_cancelled; } void Cancel() { m_cancelled = true; } // std::ifstream &getInFileStream() { return *m_infile; } std::ifstream &GetInfile2() { return *m_infile2; } // const std::vector &GetFileSet() const { return m_fileset; } // virtual void CommPostMessage(int m, int x) const = 0; // Override for specific operating system }; // this is a simple version of the Communicator which can be used for // an interface class ICommunicator : public Communicator { friend class IComm; // IComm is found in idepthmap.h // protected: mutable int num_steps; mutable int num_records; mutable int step; mutable int record; // public: ICommunicator() { m_delete_flag = true; } // note: an ICommunicator lets IComm know that it should delete it virtual ~ICommunicator() { ; } virtual void CommPostMessage(int m, int x) const; }; inline void ICommunicator::CommPostMessage(int m, int x) const { switch (m) { case Communicator::NUM_STEPS: num_steps = x; break; case Communicator::CURRENT_STEP: step = x; break; case Communicator::NUM_RECORDS: num_records = x; break; case Communicator::CURRENT_RECORD: record = x; break; default: break; } } // a helpful little function... // This function is used exclusively to update the communicators at specific intervals (set in milliseconds // by the timeout argument). Typical usage: Create a time_t t1 and pass to this function with timeout = 0, // setting thus t1 to the current time in milliseconds. Then continuously pass the same t1 to this function // along with an interval timeout (in most cases 500ms). The function only synchronises t1 to the current // time if its difference to the current time is longer than the interval (i.e. more than 500 milliseconds // have passed since the last synchronisation). If a synchronisation occurs then the communicator is // updated along with the equivalent user interface element. // TODO: All time handling in the application uses time_t and stores milliseconds in it, though time_t // is supposed to only store seconds. Replace with std::chrono::time_point everywhere inline bool qtimer(time_t &t1, time_t timeout) { auto time2 = std::chrono::system_clock::now().time_since_epoch(); time_t t2 = std::chrono::duration_cast(time2).count(); if ((t2 - t1) > timeout || (t2 - t1) < 0) { // also catch a loop t1 = t2; return true; } return false; } ================================================ FILE: genlib/containerutils.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include namespace depthmapX { template void findAndErase(std::vector &vec, T element) { auto it = std::find(vec.begin(), vec.end(), element); if (it != vec.end()) vec.erase(it); } template bool addIfNotExists(std::vector &vec, T element) { auto it = std::find(vec.begin(), vec.end(), element); if (it == vec.end()) { vec.push_back(element); return true; } return false; } template bool addIfNotExists(std::map &map, const K &key, const V &value) { auto it = map.find(key); if (it == map.end()) { map[key] = value; return true; } return false; } template typename std::map::const_iterator getMapAtIndex(const std::map &m, size_t idx) { auto iter = m.begin(); std::advance(iter, idx); return iter; } template typename std::map::iterator getMapAtIndex(std::map &m, size_t idx) { auto iter = m.begin(); std::advance(iter, idx); return iter; } template int findIndexFromKey(const std::map &m, K key) { auto iter = m.find(key); return iter == m.end() ? -1 : std::distance(m.begin(), iter); } template typename TContainer::iterator findBinary(TContainer &container, const TValue val) { auto res = std::lower_bound(container.begin(), container.end(), val); if (res == container.end() || val < *res) { return container.end(); } return res; } template typename TContainer::const_iterator findBinary(const TContainer &container, const TValue val) { auto res = std::lower_bound(container.begin(), container.end(), val); if (res == container.end() || val < *res) { return container.end(); } return res; } template typename std::vector::iterator insert_sorted(std::vector &vec, T const &item) { return vec.insert(std::upper_bound(vec.begin(), vec.end(), item), item); } } // namespace depthmapX ================================================ FILE: genlib/exceptions.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include namespace depthmapX { class BaseException : public std::exception { public: BaseException() {} BaseException(std::string message) : _message(message) {} virtual const char *what() const noexcept { return _message.c_str(); } private: std::string _message; }; class RuntimeException : public BaseException { public: RuntimeException(std::string message) : BaseException(message) {} }; } // namespace depthmapX ================================================ FILE: genlib/lgpl.txt ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ================================================ FILE: genlib/linreg.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010 University College London, Alasdair Turner // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" // linear regression // T should be int, float or double template struct LinReg { double S_x; double S_y; double S_xx; double S_yy; double S_xy; double n; // bool cached; double ca; double cb; // LinReg() { S_x = 0; S_y = 0; S_xx = 0; S_yy = 0; S_xy = 0; n = 0; cached = false; } void clear() { S_x = 0; S_y = 0; S_xx = 0; S_yy = 0; S_xy = 0; n = 0; cached = false; } void add(T x, T y) { n++; S_x += double(x); S_y += double(y); S_xx += sqr(double(x)); S_yy += sqr(double(y)); S_xy += double(x) * double(y); cached = false; } void makecache() { cb = (n * S_xy - S_x * S_y) / (n * S_xx - S_x * S_x); ca = (S_y - cb * S_x) / n; cached = true; } // Y = bX + a double a() { if (!cached) makecache(); return ca; } double b() { if (!cached) makecache(); return cb; } double r() { return (n * S_xy - S_x * S_y) / sqrt((n * S_xx - sqr(S_x)) * (n * S_yy - sqr(S_y))); } double mu_x() { return S_x / n; } double mu_y() { return S_y / n; } // note you will need to keep the vectors if you need // to calculate the residuals: e[i] = y[i] - b() * x[i] - a(); double model(double x) { if (!cached) makecache(); return cb * x + ca; } double invmodel(double y) { if (!cached) makecache(); return (y - ca) / cb; } }; ================================================ FILE: genlib/p2dpoly.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // 2d polygons (and line sets too...) #include "p2dpoly.h" #include "genlib/comm.h" // used in BSP construction #include #include ////////////////////////////////////////////////////////////////////////////////////// // gps2os: function to convert long-lat GPS coordinates to OS national grid // n.b.: approximation only // This algorithm is taken from: // "A guide to coordinate systems in Great Britain" // http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/index.html // (v1.9 Mar 2008 D00659, Crown Copyright) // Sourced: 21-Mar-08 // It's truly ick... and nuts... there must be an easier way... // Outline: // 1. take long-lat on ETRS89 ellipsoid and convert to 3d cartesian coordinates // 2. shift 3d cartesian coordinates from ETRS89 ellipsoid to OSGB36 ellipsoid // 3. convert 3d cartesian coordinates to long-lat on OSGB36 ellipsoid // 4. project onto OSFB36 2d grid using a transverse Mercator projection // According to OS, accurate to within about 5 metres Point2f gps2os(const Point2f &pt) { // *first*, we have ETRS89 data... // Convert it to 3D Cartesian Coordinates double lambda = M_PI * pt.x / 180.0; double phi = M_PI * pt.y / 180.0; // GRS80 ellipsoid double a = 6378137.0000; double b = 6356752.3141; double e_sq = (sqr(a) - sqr(b)) / sqr(a); double nu = a / sqrt(1.0 - e_sq * sqr(sin(phi))); double x = nu * cos(phi) * cos(lambda); double y = nu * cos(phi) * sin(lambda); double z = (1 - e_sq) * nu * sin(phi); // Now we have the ETRS89 location, convert it to a rough OSGB36 location: // rough conversion chart // t_x (m) t_y (m) t_z (m) s (ppm) r_x (sec) r_y (sec) r_z (sec) // -446.448 +125.157 -542.060 +20.4894 -0.1502 -0.2470 -0.8421 = (in radians: ) // nb, seconds converted to radians: double r_x = -0.7281901490265230623720509817416e-6; double r_y = -1.1974897923405539041670878328241e-6; double r_z = -4.0826160086234026020206666559563e-6; x = -446.448 + (1.0 + 2.04894e-5) * x - r_z * y + r_y * z; y = +125.157 + r_z * x + (1.0 + 2.04894e-5) * y - r_x * z; z = -542.060 - r_y * x + r_x * y + (1.0 + 2.04894e-5) * z; double p = sqrt(sqr(x) + sqr(y)); // now place it back in long lat on the OSGB36 ellipsoid: // Airy 1830 (OSGB36) ellipsoid a = 6377563.396; b = 6356256.910; e_sq = (sqr(a) - sqr(b)) / sqr(a); lambda = atan(y / x); phi = atan(z / (p * (1.0 - e_sq))); double lastphi = phi; nu = a / sqrt(1.0 - e_sq * sqr(sin(phi))); do { phi = atan((z + e_sq * nu * sin(phi)) / p); } while (fabs(lastphi - phi) > 1e-6); // now, it's on the ellipsoid, project it onto the OSGB36 grid: // E_0 easting of true origin 400 000m double E_0 = 400000; // N_0 northing of true origin -100 000m double N_0 = -100000; // F_0 scaling factor on central meridian 0.9996012717 double F_0 = 0.9996012717; // lambda_0 longitude of true origin -2.0 radians: -0.034906585039886591538473815369772 double lambda_0 = -0.034906585039886591538473815369772; // phi_0 latitude of true origin 49.0 radians: double phi_0 = 0.85521133347722149269260847655942; nu = a * F_0 * pow((1 - e_sq * sqr(sin(phi))), -0.5); double n = (a - b) / (a + b); double rho = a * F_0 * (1.0 - e_sq) * pow((1 - e_sq * sqr(sin(phi))), -1.5); double eta_sq = nu / rho - 1; double n_sq = pow(n, 2); double n_cubed = pow(n, 3); double M = b * F_0 * ((1.0 + n + 0.25 * 5 * (n_sq + n_cubed)) * (phi - phi_0) - (3.0 * (n + n_sq + 0.125 * 7 * n_cubed)) * sin(phi - phi_0) * cos(phi + phi_0) + (0.125 * 15.0 * (n_sq + n_cubed)) * sin(2.0 * (phi - phi_0)) * cos(2.0 * (phi + phi_0)) - (35.0 / 24.0 * n_cubed) * sin(3.0 * (phi - phi_0)) * cos(3.0 * (phi + phi_0))); double I = M + N_0; double II = 0.5 * nu * sin(phi) * cos(phi); double tanphi = tan(phi); double III = nu * sin(phi) * pow(cos(phi), 3.0) * (5.0 - sqr(tanphi) + 9.0 * eta_sq) / 24.0; double IIIA = nu * sin(phi) * pow(cos(phi), 5.0) * (61.0 - 58.0 * sqr(tanphi) + pow(tanphi, 4.0)) / 720.0; double IV = nu * cos(phi); double V = nu * pow(cos(phi), 3.0) * (nu / rho - sqr(tanphi)) / 6.0; double VI = nu * pow(cos(phi), 5.0) * (5.0 - 18.0 * sqr(tanphi) + pow(tanphi, 4) + 14.0 * eta_sq - 58.0 * sqr(tanphi) * eta_sq) / 120.0; double E = E_0 + IV * (lambda - lambda_0) + V * pow((lambda - lambda_0), 3) + VI * pow((lambda - lambda_0), 5); double N = I + II * pow((lambda - lambda_0), 2) + III * pow((lambda - lambda_0), 4) + IIIA * pow((lambda - lambda_0), 6); return Point2f(E, N); } ////////////////////////////////////////////////////////////////////////////////////// static long g_count = 0L; int bitcount(int a) { int ret = 0; while (a != 0) { ret += (a & 1) ? 1 : 0; a = a >> 1; } return ret; } //////////////////////////////////////////////////////////////////////////////////////// // EdgeU is used for polygon clipping to viewports // are a,b,c in ccw order (true) or cw order (false) bool ccwEdgeU(const EdgeU &a, const EdgeU &b, const EdgeU &c) { bool ccw = false; if (c.edge > a.edge || (c.edge == a.edge && c.u > a.u)) { if (b.edge > a.edge || (b.edge == a.edge && b.u > a.u)) { if (b.edge < c.edge || (b.edge == c.edge && b.u < c.u)) { ccw = true; } } } else { if (b.edge > a.edge || (b.edge == a.edge && b.u > a.u)) { ccw = true; } else if (b.edge < c.edge || (b.edge == c.edge && b.u < c.u)) { ccw = true; } } return ccw; } // EdgeU is used for polygon clipping to viewports // get the actual point from an EdgeU Point2f QtRegion::getEdgeUPoint(const EdgeU &eu) { switch (eu.edge) { case 0: return Point2f(bottom_left.x + (eu.u * width()), bottom_left.y); case 1: return Point2f(top_right.x, bottom_left.y + (eu.u * height())); case 2: return Point2f(top_right.x - (eu.u * width()), top_right.y); case 3: return Point2f(bottom_left.x, top_right.y - (eu.u * height())); } return Point2f(); } // EdgeU is used for polygon clipping to viewports // get where the polygon exits the viewport EdgeU QtRegion::getCutEdgeU(const Point2f &inside, const Point2f &outside) { EdgeU eu; if (outside.x < bottom_left.x) { double y = outside.y + (inside.y - outside.y) * (bottom_left.x - outside.x) / (inside.x - outside.x); if (y >= bottom_left.y && y <= top_right.y) { eu.edge = 3; eu.u = (top_right.y - y) / height(); } } if (eu.edge == -1 && outside.x > top_right.x) { double y = inside.y + (outside.y - inside.y) * (top_right.x - inside.x) / (outside.x - inside.x); if (y >= bottom_left.y && y <= top_right.y) { eu.edge = 1; eu.u = (y - bottom_left.y) / height(); } } if (eu.edge == -1 && outside.y < bottom_left.y) { double x = outside.x + (inside.x - outside.x) * (bottom_left.y - outside.y) / (inside.y - outside.y); if (x >= bottom_left.x && x <= top_right.x) { eu.edge = 0; eu.u = (x - bottom_left.x) / width(); } } if (eu.edge == -1 && outside.y > top_right.y) { double x = inside.x + (outside.x - inside.x) * (top_right.y - inside.y) / (outside.y - inside.y); if (x >= bottom_left.x && x <= top_right.x) { eu.edge = 2; eu.u = (top_right.x - x) / width(); } } // if at this stage eu.edge is still -1 there's a problem! return eu; } ////////////////////////////////////////////////////////////////////////// // union of two regions QtRegion runion(const QtRegion &a, const QtRegion &b) { QtRegion n; n.bottom_left.x = a.bottom_left.x < b.bottom_left.x ? a.bottom_left.x : b.bottom_left.x; n.bottom_left.y = a.bottom_left.y < b.bottom_left.y ? a.bottom_left.y : b.bottom_left.y; n.top_right.x = a.top_right.x > b.top_right.x ? a.top_right.x : b.top_right.x; n.top_right.y = a.top_right.y > b.top_right.y ? a.top_right.y : b.top_right.y; return n; } // test intersecting regions, touching counts bool intersect_region(const QtRegion &a, const QtRegion &b, double tolerance) { if (overlap_x(a, b, tolerance) && overlap_y(a, b, tolerance)) { return true; } else { return false; } } bool overlap_x(const QtRegion &a, const QtRegion &b, double tolerance) { if (a.bottom_left.x > b.bottom_left.x) { if (b.top_right.x >= a.bottom_left.x - tolerance) { return true; } } else { if (a.top_right.x >= b.bottom_left.x - tolerance) { return true; } } return false; } bool overlap_y(const QtRegion &a, const QtRegion &b, double tolerance) { if (a.bottom_left.y > b.bottom_left.y) { if (b.top_right.y >= a.bottom_left.y - tolerance) { return true; } } else { if (a.top_right.y >= b.bottom_left.y - tolerance) { return true; } } return false; } // line set up // default: nothing: Line::Line() { bits.parity = 0; bits.direction = 0; // Points automatically assigned to 0,0 } Line::Line(const Point2f &a, const Point2f &b) { if (a.x == b.x) { bottom_left.x = a.x; top_right.x = b.x; // vertical lines stored consistently as parity 1 if (a.y <= b.y) { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 1; bits.direction = 1; } else { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 1; bits.direction = 0; } } else if (a.x < b.x) { bottom_left.x = a.x; top_right.x = b.x; if (a.y <= b.y) { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 1; bits.direction = 1; } else { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 0; // -1 bits.direction = 1; } } else { bottom_left.x = b.x; top_right.x = a.x; if (b.y <= a.y) { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 1; bits.direction = 0; } else { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 0; // -1 bits.direction = 0; } } } ////////////////////////////////////////////////////////////////////////////// double dot(const Line &a, const Line &b) { return (a.bx() - a.ax()) * (b.bx() - b.ax()) + (a.by() - a.ay()) * (b.by() - b.ay()); } // intersection test: touching counts as an intersection // (uses dot product comparison) // NB You must MUST check that line *regions do not intersect* before using this test // By this test, *all parallel lines intersect* bool intersect_line(const Line &a, const Line &b, double tolerance) { g_count++; if (((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())) <= tolerance && ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())) <= tolerance) { return true; } return false; } // intersection test: touching does not count as an intersection // (uses dot product comparison) bool intersect_line_no_touch(const Line &a, const Line &b, double tolerance) { g_count++; if (((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())) < -tolerance && ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())) < -tolerance) { return true; } return false; } // returns 0 for no intersect, 1 for touching and 2 for crossing int intersect_line_distinguish(const Line &a, const Line &b, double tolerance) { g_count++; double alpha = ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())); double beta = ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())); if (alpha <= tolerance && beta <= tolerance) { if (alpha < -tolerance && beta < -tolerance) { return 2; } else { return 1; } } return 0; } // returns 0 for no intersect, 1 for touching and 2 for crossing // n.b. only used by polygon contains -- throws if the first point of line b is touching line a // (first point of line b is the point to be tested) -- i.e., throws if point touches polygon int intersect_line_b(const Line &a, const Line &b, double tolerance) { g_count++; double alpha = ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())); double beta = ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())); double gamma = ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())); if (alpha * beta <= tolerance && gamma <= tolerance) { if (alpha * beta < -tolerance && gamma < -tolerance) { return 2; } else { // this function is only used for poly contains point, // the throw is defined if the point is *on* the polygon edge // (within the tolerance) if (fabs(alpha) <= tolerance) { throw 1; } return 1; } } return 0; } double Line::intersection_point(const Line &l, int axis, double tolerance) const { // use axis = XAXIS for width() > height() double loc; if (axis == XAXIS) { if (l.width() == 0.0) { loc = l.bottom_left.x; } else { double lg = l.grad(YAXIS); double g = grad(YAXIS); if (fabs(lg - g) <= tolerance) { // these have almost the same gradient, so it's impossible to tell where they intersect: going for // midpoint Point2f p = l.midpoint(); loc = (p.x > top_right.x) ? top_right.x : ((p.x < bottom_left.x) ? bottom_left.x : p.x); } else { // this is the same as: constant(YAXIS) - l.constant(YAXIS)) / (l.grad(YAXIS) - grad(YAXIS)); loc = ((ay() - g * ax()) - (l.ay() - lg * l.ax())) / (lg - g); } } } else { if (l.height() == 0.0) { loc = l.bottom_left.y; } else { double lg = l.grad(XAXIS); double g = grad(XAXIS); if (fabs(lg - g) <= tolerance) { // these have almost the same gradient, so it's impossible to tell where they intersect: going for // midpoint Point2f p = l.midpoint(); loc = (p.y > top_right.y) ? top_right.y : ((p.y < bottom_left.y) ? bottom_left.y : p.y); } else { // this is the same as: constant(XAXIS) - l.constant(XAXIS)) / (l.grad(XAXIS) - grad(XAXIS)); loc = ((ax() - g * ay()) - (l.ax() - lg * l.ay())) / (lg - g); } } } return loc; } // intersecting line segments, touching counts // (uses intersection point comparison) bool Line::intersect_line(const Line &l, int axis, double &loc) const { // please be intelligent when passing the axis... if (axis == XAXIS) { if (l.width() == 0.0) { // Special case: double y = ay() + sign() * (l.ax() - ax()) * height() / width(); if (y >= bottom_left.y && y <= l.top_right.y) { // <- you must have checked loc = l.bottom_left.x; // the regions overlap first return true; } } else { // Standard: (note: if m1 == m2, loc is NaN) loc = (constant(YAXIS) - l.constant(YAXIS)) / (l.grad(YAXIS) - grad(YAXIS)); if (std::isnan(loc)) { // lines are parallel --- are they coincident? // you must have checked the regions overlap first if (constant(YAXIS) == l.constant(YAXIS)) { return true; } } else if (loc >= l.bottom_left.x && loc <= l.top_right.x) { return true; } } } else { if (l.height() == 0.0) { // Special case: double x = ax() + sign() * (l.ay() - ay()) * width() / height(); if (x >= bottom_left.x && x <= top_right.x) { // <- you must have checked loc = l.bottom_left.y; // the regions overlap first return true; } } else { // Standard: (note: if m1 == m2, loc is NaN) loc = (constant(XAXIS) - l.constant(XAXIS)) / (l.grad(XAXIS) - grad(XAXIS)); if (std::isnan(loc)) { // lines are parallel --- are they coincident? // you must have checked the regions overlap first if (constant(XAXIS) == l.constant(XAXIS)) { return true; } } else if (loc >= l.bottom_left.y && loc <= l.top_right.y) { return true; } } } return false; } // this converts the loc back into a point: Point2f Line::point_on_line(double loc, int axis) const { Point2f p; if (axis == XAXIS) { p = Point2f(loc, grad(YAXIS) * loc + constant(YAXIS)); } else { p = Point2f(grad(XAXIS) * loc + constant(XAXIS), loc); } return p; } ////////////////////////////////////////////////////////////////////////////// // distance from a point to a line segment double dist(const Point2f &point, const Line &line) { double d = 0.0; Point2f alpha = line.end() - line.start(); Point2f beta = point - line.end(); Point2f gamma = line.start() - line.end(); Point2f delta = point - line.start(); if (dot(alpha, beta) > 0) { d = beta.length(); } else if (dot(gamma, delta) > 0) { d = delta.length(); } else { if (alpha.length() < 1e-9 * beta.length()) { // should actually be a user-specified tolerance test d = beta.length(); } else { d = fabs(det(alpha, beta)) / alpha.length(); } } return d; } /* // for infinite line rather than line segment return fabs((line.bx() - line.ax()) * (line.ay() - point.y) - (line.ax() - point.x) * (line.by() - line.ay())) / line.length(); */ ////////////////////////////////////////////////////////////////////////////// // intersection test bool intersect(const RegionTree &a, const RegionTree &b) { if (a.is_leaf() && b.is_leaf()) { if (intersect_region(QtRegion(a), QtRegion(b))) { return intersect_line((const Line &)QtRegion(a), (const Line &)QtRegion(b)); } else { return false; } } else { if (intersect_region(QtRegion(a), QtRegion(b))) { return subintersect(a, b); } else { return false; } } } bool subintersect(const RegionTree &a, const RegionTree &b) { if (intersect(a.left(), b.left())) { return true; } else if (intersect(a.right(), b.right())) { return true; } else if (intersect(a.left(), b.right())) { return true; } else if (intersect(a.right(), b.left())) { return true; } return false; } // Intersection count int intersections(const RegionTree &a, const Line &b) { int n = 0; if (!a.is_leaf()) { if (intersect_region(QtRegion(a), QtRegion(b))) { n += intersections(a.left(), b); n += intersections(a.right(), b); } } else { // Note: touching lines count 1, non-touching lines count 2, this allows through // vertex lines (where it touches both vertices) n += intersect_line_b((const Line &)a, (const Line &)b); } return n; } ////////////////////////////////////////////////////////////////////////////// // crop a line to fit within bounds of region // if line lies outside region, returns false bool Line::crop(const QtRegion &r) { if (bx() >= r.bottom_left.x) { if (ax() < r.bottom_left.x) { // crop! ay() += sign() * (height() * (r.bottom_left.x - ax()) / width()); ax() = r.bottom_left.x; } if (ax() <= r.top_right.x) { if (bx() > r.top_right.x) { // crop! by() -= sign() * height() * (bx() - r.top_right.x) / width(); bx() = r.top_right.x; } if (top_right.y >= r.bottom_left.y) { if (bottom_left.y < r.bottom_left.y) { // crop! if (bits.parity) { ax() += width() * (r.bottom_left.y - bottom_left.y) / height(); } else { bx() -= width() * (r.bottom_left.y - bottom_left.y) / height(); } bottom_left.y = r.bottom_left.y; } if (bottom_left.y <= r.top_right.y) { if (top_right.y > r.top_right.y) { // crop! if (bits.parity) { bx() -= width() * (top_right.y - r.top_right.y) / height(); } else { ax() += width() * (top_right.y - r.top_right.y) / height(); } top_right.y = r.top_right.y; } // if we got this far, well done, it's in the region: return true; } } } } // returns false if the entire line is outside the region: return false; } // cast a ray to the edge of a box void Line::ray(short dir, const QtRegion &r) { if (dir == bits.direction) { if (width() >= height()) { by() = ay() + sign() * height() * (r.top_right.x - ax()) / width(); bx() = r.top_right.x; } else if (bits.parity) { bx() = ax() + width() * (r.top_right.y - ay()) / height(); by() = r.top_right.y; } else { bx() = ax() + width() * (ay() - r.bottom_left.y) / height(); by() = r.bottom_left.y; } } else { if (width() >= height()) { ay() = by() - sign() * height() * (bx() - r.bottom_left.x) / width(); ax() = r.bottom_left.x; } else if (bits.parity) { ax() = bx() - width() * (by() - r.bottom_left.y) / height(); ay() = r.bottom_left.y; } else { ax() = bx() - width() * (r.top_right.y - by()) / height(); ay() = r.top_right.y; } } // now fit within bounds... crop(r); } ////////////////////////////////////////////////////////////////////////////// // Polygon set up (the hard bit!) void Poly::add_line_segment(const Line &l) { m_line_segments++; RegionTreeLeaf *leaf = new RegionTreeLeaf(l); if (m_p_root == NULL) { // first ever node m_p_root = (RegionTree *)leaf; } else { // traverse the tree to the insertion point // you'll just have to take my word for it that the next line // gives you the correct position to insert int cut_level = bitcount(m_line_segments - 1) - 2; if (cut_level < 0) { // replace the root node QtRegion new_region = runion(QtRegion(*m_p_root), QtRegion(*leaf)); RegionTree *new_root = new RegionTreeBranch(new_region, *m_p_root, *leaf); m_p_root = new_root; } else { RegionTree *here = m_p_root; for (int i = 0; i < cut_level; i++) { here = here->m_p_right; } // cut and insert RegionTree &insertion_point = here->right(); QtRegion new_region = runion(QtRegion(insertion_point), QtRegion(*leaf)); RegionTree *new_node = new RegionTreeBranch(new_region, insertion_point, *leaf); here->m_p_right = new_node; // traverse up tree unioning regions // (saving data by not recording parents!) // Note must be '>=' to catch current root node --- I really stuffed up earlier with '>'! while (cut_level >= 0) { here = m_p_root; for (int j = 0; j < cut_level; j++) { here = here->m_p_right; } here->m_p_region = new Line(runion(QtRegion(here->left()), QtRegion(here->right()))); cut_level--; } } } } // ...and after all the efficient stuff, we have a really // inefficient polygon copy... hmm RegionTree *Poly::copy_region_tree(const RegionTree *tree) { if (!tree) { return NULL; } RegionTree *newtree; if (tree->is_leaf()) { newtree = new RegionTreeLeaf(); newtree->m_p_region = new Line(*(tree->m_p_region)); return newtree; } else { newtree = new RegionTreeBranch(); } std::vector newlist; std::vector oldlist; oldlist.push_back((RegionTree *)tree); newlist.push_back((RegionTree *)newtree); do { RegionTree *oldnode = oldlist.back(); oldlist.pop_back(); RegionTree *newnode = newlist.back(); newlist.pop_back(); newnode->m_p_region = new Line(*oldnode->m_p_region); if (oldnode->m_p_left) { if (oldnode->m_p_left->is_leaf()) { newnode->m_p_left = new RegionTreeLeaf(); newnode->m_p_left->m_p_region = new Line(*(oldnode->m_p_left->m_p_region)); } else { oldlist.push_back(oldnode->m_p_left); newnode->m_p_left = new RegionTreeBranch(); newlist.push_back(newnode->m_p_left); } } if (oldnode->m_p_right) { if (oldnode->m_p_right->is_leaf()) { newnode->m_p_right = new RegionTreeLeaf(); newnode->m_p_right->m_p_region = new Line(*(oldnode->m_p_right->m_p_region)); } else { oldlist.push_back(oldnode->m_p_right); newnode->m_p_right = new RegionTreeBranch(); newlist.push_back(newnode->m_p_right); } } } while (oldlist.size() > 0); return newtree; } // polygon destruction void Poly::destroy_region_tree() { if (!m_p_root) { return; } std::vector del_node_list; std::vector del_node_dir; del_node_list.push_back(m_p_root); do { RegionTree *current_node = del_node_list.back(); if (current_node->m_p_left == current_node && current_node->m_p_right == current_node) { delete current_node; del_node_list.pop_back(); if (del_node_list.size() > 0) { if (del_node_dir.back() == 0) { del_node_list.back()->m_p_left = del_node_list.back(); del_node_dir.pop_back(); } else { del_node_list.back()->m_p_right = del_node_list.back(); del_node_dir.pop_back(); } } } else { if (current_node->m_p_right == NULL) { current_node->m_p_right = current_node; } else if (current_node->m_p_right != current_node) { del_node_list.push_back(current_node->m_p_right); del_node_dir.push_back(1); } else { del_node_list.push_back(current_node->m_p_left); del_node_dir.push_back(0); } } } while (del_node_list.size() > 0); m_p_root = NULL; } // contains? intersects?? // Here they are! bool Poly::contains(const Point2f &p) { // n.b., intersections throws on some accidental alignments -- // we must use a point outside the polygon to extend our test // line from to prevent them Line l(p, Point2f(get_bounding_box().top_right.x + get_bounding_box().width(), get_bounding_box().top_right.y + get_bounding_box().height())); int double_n; // note, touching intersections count 1/2 try { double_n = intersections(*(m_p_root), l); } catch (int) { throw 1; // throws if on edge } if (double_n % 2 == 0 && double_n % 4 != 0) { return true; } return false; } bool intersect(const Poly &a, const Poly &b) { if (intersect(*(a.m_p_root), *(b.m_p_root))) { return true; } return false; } ================================================ FILE: genlib/p2dpoly.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // 2d poly (own format, adapted from the original Sala libraries // The idea is that from this format, // we can read into Cosmo3d as well as Sala based applications #pragma once // Using doubles right the way through can really eat memory for isovist // polygon files, thus we use a defined type, change as appropriate: #include "genlib/comm.h" // communicator used in BSP tree construction #include "genlib/pafmath.h" #include // Note: code depends on XAXIS being 0 and YAXIS being 1 --- do not change enum { NOAXIS = -1, XAXIS = 0, YAXIS = 1 }; class Point2f; bool approxeq(const Point2f &p1, const Point2f &p2, double tolerance = 0.0); class QtRegion; bool intersect_region(const QtRegion &a, const QtRegion &b, double tolerance = 0.0); bool overlap_x(const QtRegion &a, const QtRegion &b, double tolerance = 0.0); bool overlap_y(const QtRegion &a, const QtRegion &b, double tolerance = 0.0); class Line; bool intersect_line(const Line &a, const Line &b, double tolerance = 0.0); bool intersect_line_no_touch(const Line &a, const Line &b, double tolerance = 0.0); int intersect_line_distinguish(const Line &a, const Line &b, double tolerance = 0.0); int intersect_line_b(const Line &a, const Line &b, double tolerance = 0.0); Point2f intersection_point(const Line &a, const Line &b, double tolerance = 0.0); // NaN on Intel: // Quick mod - TV // const double P2DNULL = (const double)0xFFFFFFFF7FF7FFFF; // for non-Intel: 0x7FF7FFFFFFFFFFFF // Point class Point2f { public: double x; double y; Point2f() // { x = P2DNULL; y = P2DNULL; } { x = 0.0; y = 0.0; } Point2f(double a, double b) { x = a; y = b; } bool atZero() const // { return x == P2DNULL || y == P2DNULL; } { return x == 0.0 && y == 0.0; } void normalScale(const QtRegion &); // inline function: below region void denormalScale(const QtRegion &); void operator+=(const Point2f &p) { x += p.x; y += p.y; } void operator-=(const Point2f &p) { x -= p.x; y -= p.y; } void operator*=(const double s) { x *= s; y *= s; } void operator/=(const double s) { x /= s; y /= s; } double &operator[](int i) { return (i == XAXIS) ? x : y; } const double &operator[](int i) const { return (i == XAXIS) ? x : y; } friend Point2f operator-(Point2f &p); friend Point2f operator+(const Point2f &p1, const Point2f &p2); friend Point2f operator-(const Point2f &p1, const Point2f &p2); friend bool operator==(const Point2f &p1, const Point2f &p2); friend bool operator!=(const Point2f &p1, const Point2f &p2); friend bool operator>(const Point2f &a, const Point2f &b); friend bool operator<(const Point2f &a, const Point2f &b); friend Point2f operator*(const double s, const Point2f &p); friend Point2f operator/(const Point2f &p, const double s); friend double dot(const Point2f &p1, const Point2f &p2); friend double det(const Point2f &p1, const Point2f &p2); friend double dist(const Point2f &p1, const Point2f &p2); friend double dist(const Point2f &point, const Line &line); friend double angle(const Point2f &p1, const Point2f &p2, const Point2f &p3); friend bool approxeq(const Point2f &p1, const Point2f &p2, double tolerance); friend Point2f pointfromangle(double angle); // a couple of useful tests bool intriangle(const Point2f &p1, const Point2f &p2, const Point2f &p3); bool insegment(const Point2f &key, const Point2f &p2, const Point2f &p3, double tolerance = 0.0); // for OS transformation (note: accurate only to 5 metres according to OS) Point2f longlat2os(const Point2f &p); public: // A few simple vector ops: double length() const { return (double)sqrt(x * x + y * y); } Point2f &scale(const double scalar) { x *= scalar; y *= scalar; return *this; } Point2f &scale(const Point2f &scalevec) { x *= scalevec.x; y *= scalevec.y; return *this; } Point2f &normalise() { return scale(1.0 / length()); } Point2f &rotate(const double angle) { double t = x; x = x * cos(angle) - y * sin(angle); y = y * cos(angle) + t * sin(angle); return *this; } double angle() const { return (y < 0) ? (2.0 * M_PI - acos(x)) : acos(x); } }; inline Point2f operator-(Point2f &p) { return Point2f(-p.x, -p.y); } inline Point2f operator+(const Point2f &p1, const Point2f &p2) { return Point2f(p1.x + p2.x, p1.y + p2.y); } inline Point2f operator-(const Point2f &p1, const Point2f &p2) { return Point2f(p1.x - p2.x, p1.y - p2.y); } inline bool operator==(const Point2f &p1, const Point2f &p2) { return (p1.x == p2.x && p1.y == p2.y); } inline bool operator!=(const Point2f &p1, const Point2f &p2) { return (p1.x != p2.x || p1.y != p2.y); } inline bool operator>(const Point2f &p1, const Point2f &p2) { return (p1.x > p2.x || (p1.x == p2.x && p1.y > p2.y)); } inline bool operator<(const Point2f &p1, const Point2f &p2) { return (p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y)); } inline Point2f operator*(const double s, const Point2f &p) { return Point2f(s * p.x, s * p.y); } inline Point2f operator/(const Point2f &p, const double s) { return Point2f(p.x / s, p.y / s); } inline double dot(const Point2f &p1, const Point2f &p2) { return (p1.x * p2.x + p1.y * p2.y); } // greater than 0 => p2 left (anticlockwise) of p1, less than 0 => p2 right (clockwise) of p1 inline double det(const Point2f &p1, const Point2f &p2) { return (p1.x * p2.y - p1.y * p2.x); } inline double dist(const Point2f &p1, const Point2f &p2) { return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y)); } inline double angle(const Point2f &p1, const Point2f &p2, const Point2f &p3) { Point2f a = p1 - p2; Point2f b = p3 - p2; a.normalise(); b.normalise(); // ensure in range (f.p. error can throw out) double d = std::min(std::max(dot(a, b), -1.0), 1.0); return (sgn(det(a, b)) == 1) ? acos(d) : 2.0 * M_PI - acos(d); } inline bool approxeq(const Point2f &p1, const Point2f &p2, double tolerance) { return (fabs(p1.x - p2.x) <= tolerance && fabs(p1.y - p2.y) <= tolerance); } inline bool Point2f::insegment(const Point2f &key, const Point2f &p2, const Point2f &p3, double tolerance) { Point2f va = p2 - key; Point2f vb = p3 - key; Point2f vp = *this - key; double ap = det(va, vp); double bp = det(vb, vp); if ((dot(va, vp) > 0 && dot(vb, vp) > 0) && (sgn(ap) != sgn(bp) || fabs(ap) < tolerance || fabs(bp) < tolerance)) { return true; } return false; } inline bool Point2f::intriangle(const Point2f &p1, const Point2f &p2, const Point2f &p3) { // touching counts int test = sgn(det(p2 - p1, *this - p1)); if (test == sgn(det(p3 - p2, *this - p2)) && test == sgn(det(p1 - p3, *this - p3))) { return true; } return false; } inline Point2f pointfromangle(double angle) { Point2f p; p.x = cos(angle); p.y = sin(angle); return p; } Point2f gps2os(const Point2f &p); // an event is a point plus time (as in spacetime technical language) class Event2f : public Point2f { public: double t; // time in seconds Event2f() : Point2f() { t = 0.0; } Event2f(double _x, double _y, double _t) : Point2f(_x, _y) { t = _t; } Event2f(Point2f &_p) : Point2f(_p) { t = 0.0; } Event2f(Point2f &_p, double _t) : Point2f(_p) { t = _t; } }; /////////////////////////////////////////////////////////////////////////////////////////// class Point3f { public: double x; double y; double z; Point3f(double a = 0.0, double b = 0.0, double c = 0.0) { x = a; y = b; z = c; } Point3f(const Point2f &p) { x = p.x; y = 0.0; z = p.y; } // Note! not z = -y (due to an incosistency earlier...) bool inside(const Point3f &bl, const Point3f &tr) // now inclusive (...) { return (x >= bl.x && y >= bl.y && z >= bl.z && x <= tr.x && y <= tr.y && z <= tr.z); } operator Point2f() { return Point2f(x, z); } // Note! not x, -z (due to an inconsistency earlier...) Point2f xy() { return Point2f(x, y); } // From the x, y plane // A few simple vector ops: double length() const { return (double)sqrt(x * x + y * y + z * z); } Point3f &scale(const double scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; } Point3f &normalise() { return scale(1.0 / length()); } Point3f &rotate(double theta, double phi) { double t = x; x = t * cos(theta) - y * sin(theta); y = y * cos(theta) + t * sin(theta); t = x; x = t * cos(phi) - z * sin(phi); z = z * cos(phi) - t * sin(phi); return *this; } // friend double dot(const Point3f &a, const Point3f &b); friend Point3f cross(const Point3f &a, const Point3f &b); }; inline double dot(const Point3f &a, const Point3f &b) { return (a.x * b.x + a.y * b.y + a.z * b.z); } inline Point3f cross(const Point3f &a, const Point3f &b) { return Point3f(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y); } // ////////////////////////////////////////////////////////////////////////////// // used for clipping of polygons to regions struct EdgeU { int edge; double u; EdgeU(int e = -1, double _u = 0.0) { edge = e; u = _u; } EdgeU(const EdgeU &eu) { edge = eu.edge; u = eu.u; } friend bool ccwEdgeU(const EdgeU &a, const EdgeU &b, const EdgeU &c); }; // QtRegion class QtRegion { public: Point2f bottom_left; Point2f top_right; QtRegion(const Point2f &bl = Point2f(), const Point2f &tr = Point2f()) { bottom_left = bl; top_right = tr; } QtRegion(const QtRegion &r) { bottom_left = r.bottom_left; top_right = r.top_right; } QtRegion &operator=(const QtRegion &r) { bottom_left = r.bottom_left; top_right = r.top_right; return *this; } // double height() const { return fabs(top_right.y - bottom_left.y); } double width() const // The assumption that top_right.x is always > bottom_left.x is not always true. // Returning a negative value here causes an infinite loop at axialmap.cpp line 3106 // after overlapdist is assigned a negative value at axialmap.cpp line 3084. // height() above could also be changed for this reason, but this is a band-aid // fix for the real problem, which is why the top_right > bottom_left assumption // is assumed to be 100% valid but is, in some instances, not valid. // { return top_right.x - bottom_left.x; } { return fabs(top_right.x - bottom_left.x); } double area() const { return height() * width(); } void normalScale(const QtRegion &r) { top_right.normalScale(r); bottom_left.normalScale(r); } void denormalScale(const QtRegion &r) { top_right.denormalScale(r); bottom_left.denormalScale(r); } void scale(const Point2f &scalevec) { top_right.scale(scalevec); bottom_left.scale(scalevec); } void offset(const Point2f &offset) { top_right += offset; bottom_left += offset; } Point2f getCentre() const { return Point2f((bottom_left.x + top_right.x) / 2.0, (bottom_left.y + top_right.y) / 2.0); } // bool contains(const Point2f &p) const { return (p.x > bottom_left.x && p.x < top_right.x && p.y > bottom_left.y && p.y < top_right.y); } bool contains_touch(const Point2f &p) const { return (p.x >= bottom_left.x && p.x <= top_right.x && p.y >= bottom_left.y && p.y <= top_right.y); } void encompass(const Point2f &p) { if (p.x < bottom_left.x) bottom_left.x = p.x; if (p.x > top_right.x) top_right.x = p.x; if (p.y < bottom_left.y) bottom_left.y = p.y; if (p.y > top_right.y) top_right.y = p.y; } // bool atZero() const { return bottom_left.atZero() || top_right.atZero(); } // Point2f getEdgeUPoint(const EdgeU &eu); EdgeU getCutEdgeU(const Point2f &inside, const Point2f &outside); // friend bool intersect_region(const QtRegion &a, const QtRegion &b, double tolerance); friend bool overlap_x(const QtRegion &a, const QtRegion &b, double tolerance); friend bool overlap_y(const QtRegion &a, const QtRegion &b, double tolerance); // // set functions friend QtRegion runion(const QtRegion &a, const QtRegion &b); friend QtRegion rintersect(const QtRegion &a, const QtRegion &b); // undefined? // void grow(const double scalar) { Point2f dim = top_right - bottom_left; dim.scale(scalar - 1.0); top_right += dim; bottom_left -= dim; } }; // First time we have a region available to use... inline void Point2f::normalScale(const QtRegion &r) { if (r.width()) x = (x - r.bottom_left.x) / r.width(); else x = 0.0; if (r.height()) y = (y - r.bottom_left.y) / r.height(); else y = 0.0; } inline void Point2f::denormalScale(const QtRegion &r) { x = x * r.width() + r.bottom_left.x; y = y * r.height() + r.bottom_left.y; } // Lines are stored left to right as regions, // the parity tells us whether the region should be inverted // top to bottom to get the line class Line : public QtRegion { protected: struct Bits { Bits() : x_dummy(0), y_dummy(0), z_dummy(0) {} char parity : 8; // 1 ... positive, 0 ... negative char direction : 8; // 1 ... positive, 0 ... negative // dummy variables as it seems to be necessary that the width of this struct is 8 bytes // and I don't want any uninitialised memory that gets written to file accidentally char x_dummy : 8; char y_dummy : 8; int z_dummy : 32; }; Bits bits; public: Line(); Line(const Point2f &a, const Point2f &b); Line(const QtRegion &r) : QtRegion(r) { bits.parity = 1; bits.direction = 1; } Line(const Line &l) : QtRegion(l) { bits = l.bits; } Line &operator=(const Line &l) { this->QtRegion::operator=(l); bits = l.bits; return *this; } // friend bool intersect_line(const Line &a, const Line &b, double tolerance); friend bool intersect_line_no_touch(const Line &a, const Line &b, double tolerance); friend int intersect_line_distinguish(const Line &a, const Line &b, double tolerance); friend int intersect_line_b(const Line &a, const Line &b, double tolerance); // // fills in the location along the axis where the intersection happens bool intersect_line(const Line &l, int axis, double &loc) const; double intersection_point(const Line &l, int axis, double tolerance = 0.0) const; // this converts a loc retrieved from intersect line or intersection point back into a point: Point2f point_on_line(double loc, int axis) const; // ...and a quick do it all in one go: friend Point2f intersection_point(const Line &a, const Line &b, double tolerance); // bool crop(const QtRegion &r); void ray(short dir, const QtRegion &r); // friend double dot(const Line &a, const Line &b); // double ax() const { return bottom_left.x; } double &ax() { return bottom_left.x; } double bx() const { return top_right.x; } double &bx() { return top_right.x; } double ay() const { return bits.parity ? bottom_left.y : top_right.y; } double &ay() { return bits.parity ? bottom_left.y : top_right.y; } double by() const { return bits.parity ? top_right.y : bottom_left.y; } double &by() { return bits.parity ? top_right.y : bottom_left.y; } // const Point2f start() const { return Point2f(bottom_left.x, (bits.parity ? bottom_left.y : top_right.y)); } const Point2f end() const { return Point2f(top_right.x, (bits.parity ? top_right.y : bottom_left.y)); } const Point2f midpoint() const { return Point2f((start() + end()) / 2); } // // helpful to have a user friendly indication of direction: bool rightward() const { return bits.direction == 1; } bool upward() const { return bits.direction == bits.parity; } // const Point2f t_start() const { return Point2f((rightward() ? bottom_left.x : top_right.x), (upward() ? bottom_left.y : top_right.y)); } const Point2f t_end() const { return Point2f((rightward() ? top_right.x : bottom_left.x), (upward() ? top_right.y : bottom_left.y)); } // short sign() const { return bits.parity ? 1 : -1; } // double grad(int axis) const { return (axis == YAXIS) ? sign() * height() / width() : sign() * width() / height(); } double constant(int axis) const { return (axis == YAXIS) ? ay() - grad(axis) * ax() : ax() - grad(axis) * ay(); } // double length() const { return (double)sqrt((top_right.x - bottom_left.x) * (top_right.x - bottom_left.x) + (top_right.y - bottom_left.y) * (top_right.y - bottom_left.y)); } // short direction() const { return bits.direction; } Point2f vector() const { return t_end() - t_start(); } }; inline Point2f intersection_point(const Line &a, const Line &b, double tolerance) { int axis = (a.width() >= a.height()) ? XAXIS : YAXIS; return a.point_on_line(a.intersection_point(b, axis, tolerance), axis); } //////////////////////////////////////////////////////////////////////////////////////// struct TaggedLine { Line line; int tag; TaggedLine(const Line &l = Line(), int t = -1) { line = l; tag = t; } }; // plain 2-point line without regions struct SimpleLine { public: SimpleLine(const Line &line) { m_start.x = line.t_start().x; m_start.y = line.t_start().y; m_end.x = line.t_end().x; m_end.y = line.t_end().y; } SimpleLine(const Point2f &a, const Point2f &b) { m_start.x = a.x; m_start.y = a.y; m_end.x = b.x; m_end.y = b.y; } SimpleLine(double x1, double y1, double x2, double y2) { m_start.x = x1; m_start.y = y1; m_end.x = x2; m_end.y = y2; } const Point2f &start() const { return m_start; } const Point2f &end() const { return m_end; } private: Point2f m_start; Point2f m_end; }; //////////////////////////////////////////////////////////////////////////////////////// // not sure if this code is used any more: // Now the difficult bit: making the line segments into polygons... // The polygons are stored in a tree format so that intersection testing is easier class RegionTree { friend class Poly; protected: Line *m_p_region; RegionTree *m_p_left; RegionTree *m_p_right; public: RegionTree() { m_p_region = NULL; m_p_left = this; m_p_right = this; } virtual ~RegionTree() { if (m_p_region) delete m_p_region; } // virtual bool is_leaf() const = 0; // RegionTree &left() const { return *m_p_left; } RegionTree &right() const { return *m_p_right; } // operator QtRegion() const { return *(QtRegion *)m_p_region; } operator Line() const { return *(Line *)m_p_region; } // friend bool intersect(const RegionTree &a, const RegionTree &b); friend bool subintersect(const RegionTree &a, const RegionTree &b); friend int intersections(const RegionTree &a, const Line &b); }; // Branch on a region tree... class RegionTreeBranch : public RegionTree { public: RegionTreeBranch() : RegionTree() { ; } RegionTreeBranch(const Line &r, const RegionTree &a, const RegionTree &b) { m_p_left = (RegionTree *)&a; m_p_right = (RegionTree *)&b; m_p_region = new Line(r); // copy } virtual bool is_leaf() const { return false; } }; // Leaf on a region tree... class RegionTreeLeaf : public RegionTree { public: RegionTreeLeaf() : RegionTree() { ; } RegionTreeLeaf(const Line &l) { // no subnodes (but nice recursive properties) m_p_left = this; m_p_right = this; m_p_region = new Line(l); } virtual bool is_leaf() const { return true; } }; class Poly { protected: int m_line_segments; RegionTree *m_p_root; public: Poly() { m_p_root = NULL; m_line_segments = 0; } Poly(const Poly &p) { m_line_segments = p.m_line_segments; m_p_root = copy_region_tree(p.m_p_root); } Poly &operator=(const Poly &p) { if (this != &p) { m_line_segments = p.m_line_segments; m_p_root = copy_region_tree(p.m_p_root); } return *this; } virtual ~Poly() { destroy_region_tree(); } // essentially, the copy constructor... RegionTree *copy_region_tree(const RegionTree *tree); // essentially, the destructor... void destroy_region_tree(); // RegionTree &get_region_tree() const { return *m_p_root; } // void add_line_segment(const Line &l); // int get_line_segments() { return m_line_segments; } QtRegion get_bounding_box() { return *(QtRegion *)(m_p_root->m_p_region); } // bool contains(const Point2f &p); friend bool intersect(const Poly &a, const Poly &b); }; ================================================ FILE: genlib/pafmath.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // a collection of math functions #include "pafmath.h" #include #include uint64_t g_rand[11] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29}; // 25-Jul-2007: changed the g_mult and g_const used for random number generation // for some reason, there appeared to be a pattern to the numbers // Quick mod - TV const uint64_t g_mult = /*(0xF9561B2E << 32) + */ 0x71A7FA85; const uint64_t g_const = /*(0x9BB3920E << 32) + */ 0xF5E958B9; void pafsrand(unsigned int seed, int set) // = 0 { g_rand[set] = seed; } // Pafrand is a Linear Congruential Generator // After the 25-Jul-2007 changes: // The current version seems to meet standard randomness conditions // Tested using Diehard, the 32 bit version ((g_rand[set] >> 32) & 0xffffffff) // passes all tests for at least the first 5 seeds above // it is also independent in at least 20 dimensions // It should not be used for "serious" randomness, but should be fine // for most things (agents in depthmapX, genetic algorithms, etc) // 25-Jul-2007: moved up to take top 32 bits unsigned int pafrand(int set) // = 0 { g_rand[set] = g_mult * g_rand[set] + g_const; return (unsigned int)((g_rand[set] >> 32) & PAF_RAND_MAX); } /////////////////////////////////////////////////////////////////////////////// double poisson(int x, double lambda) { double f = exp(-lambda); for (int i = 1; i <= x; i++) { f *= lambda / double(i); } return f; } double cumpoisson(int x, double lambda) { double f = exp(-lambda); double c = f; for (int i = 1; i <= x; i++) { f *= lambda / double(i); c += f; } return c; } int invcumpoisson(double p, double lambda) { if (p <= 0) { return 0; } if (p >= 1) { // passing this 1 will cause an infinite loop, try this instead: p = 1 - 1e-9; } double f = exp(-lambda); int i = 0; for (double c = f; c < p; c += f) { i++; f *= lambda / double(i); } return i; } ================================================ FILE: genlib/pafmath.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Paf Template Library --- a set of useful C++ templates // // Copyright (c) 1996-2011 Alasdair Turner (a.turner@ucl.ac.uk) // //----------------------------------------------------------------------------- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See the lgpl.txt file for details //----------------------------------------------------------------------------- // a collection of math functions #pragma once #include #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif inline double sqr(double a) { return (a * a); } inline int sgn(double a) { return (a < 0) ? -1 : 1; } #ifndef M_ROOT_1_2 #define M_ROOT_1_2 0.70710678118654752440084436210485 #endif #ifndef M_1_LN2 #define M_1_LN2 1.4426950408889634073599246810019 #endif const unsigned int PAF_RAND_MAX = 0x0FFFFFFF; void pafsrand(unsigned int seed, int set = 0); unsigned int pafrand(int set = 0); // a random number from 0 to 1 inline double prandom(int set = 0) { return double(pafrand(set)) / double(PAF_RAND_MAX); } // a random number from 0 to just less than 1 inline double prandomr(int set = 0) { return double(pafrand(set)) / double(PAF_RAND_MAX + 1); } // note, in order to stop confusing myself I have ln defined: #define ln(X) log(X) inline double log2(double a) { return (ln(a) * M_1_LN2); } // Hillier Hanson dvalue /* inline double dvalue(double k) { return 2.0 * (3.3231 * k * log10(k+2) - 2.5863 * k + 1.0) / ((k - 1.0) * (k - 2.0)); } */ // Hillier Hanson dvalue (from Kruger 1989 -- see Teklenburg et al) inline double dvalue(double k) { return 2.0 * (k * (log2((k + 2.0) / 3.0) - 1.0) + 1.0) / ((k - 1.0) * (k - 2.0)); } // Hillier Hanson pvalue inline double pvalue(double k) { return 2.0 * (k - log2(k) - 1.0) / ((k - 1.0) * (k - 2.0)); } // Teklenburg integration (correction 31.01.11 due to Ulrich Thaler inline double teklinteg(double nodecount, double totaldepth) { return ln(0.5 * (nodecount - 2.0)) / ln(double(totaldepth - nodecount + 1)); } // Penn palmtree inline double palmtree(double n, double r) { if (n > r) { return r * (n - 0.5 * (r + 1)); } else { return 0.5 * n * (n - 1); } } double poisson(int x, double lambda); double cumpoisson(int x, double lambda); int invcumpoisson(double p, double lambda); ================================================ FILE: genlib/pflipper.h ================================================ // Copyright (c) 1996-2011 Alasdair Turner (a.turner@ucl.ac.uk) // //----------------------------------------------------------------------------- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See the lgpl.txt file for details //----------------------------------------------------------------------------- #pragma once template class pflipper { protected: T m_contents[2]; short parity; public: pflipper() { parity = 0; } pflipper(const T &a, const T &b) { parity = 0; m_contents[0] = a; m_contents[1] = b; } pflipper(const pflipper &f) { parity = f.parity; m_contents[0] = f.m_contents[0]; m_contents[1] = f.m_contents[1]; } virtual ~pflipper() {} pflipper &operator=(const pflipper &f) { if (this != &f) { parity = f.parity; m_contents[0] = f.m_contents[0]; m_contents[1] = f.m_contents[1]; } return *this; } void flip() { parity = (parity == 0) ? 1 : 0; } T &a() { return m_contents[parity]; } T &b() { return m_contents[(parity == 0) ? 1 : 0]; } const T &a() const { return m_contents[parity]; } const T &b() const { return m_contents[(parity == 0) ? 1 : 0]; } }; ================================================ FILE: genlib/readwritehelpers.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/exceptions.h" #include #include #include namespace dXreadwrite { // The read/write methods can only be used for vectors of stack allocated types (basic data, POD) // read in vector data and write to an existing vector (overwriting its previous contents) template size_t readIntoVector(std::istream &stream, std::vector &vec) { vec.clear(); unsigned int size; stream.read(reinterpret_cast(&size), sizeof(size)); if (size > 0) { vec.resize(size); stream.read(reinterpret_cast(vec.data()), sizeof(T) * std::streamsize(size)); } return size; } // read in a vector into a new vector template std::vector readVector(std::istream &stream) { std::vector vec; readIntoVector(stream, vec); return vec; } template void writeVector(std::ostream &stream, const std::vector &vec) { // READ / WRITE USES 32-bit LENGTHS (number of elements) for compatibility reasons if (vec.size() > size_t(static_cast(-1))) { throw new depthmapX::RuntimeException("Vector exceeded max size for streaming"); } const unsigned int length = static_cast(vec.size()); stream.write(reinterpret_cast(&length), sizeof(length)); if (length > 0) { stream.write(reinterpret_cast(vec.data()), sizeof(T) * std::streamsize(length)); } } // read in map data and write to an existing map (overwriting its previous contents) template size_t readIntoMap(std::istream &stream, std::map &map) { map.clear(); unsigned int size; stream.read(reinterpret_cast(&size), sizeof(size)); for (size_t i = 0; i < size; ++i) { K key; V value; stream.read(reinterpret_cast(&key), sizeof(K)); stream.read(reinterpret_cast(&value), sizeof(V)); map.insert(std::make_pair(key, value)); } return size; } // read in a map into a new map template std::map readMap(std::istream &stream) { std::map map; readIntoMap(stream, map); return map; } template void writeMap(std::ostream &stream, const std::map &map) { // READ / WRITE USES 32-bit LENGTHS (number of elements) for compatibility reasons if (map.size() > size_t(static_cast(-1))) { throw new depthmapX::RuntimeException("Map exceeded max size for streaming"); } const unsigned int length = static_cast(map.size()); stream.write(reinterpret_cast(&length), sizeof(length)); for (auto &pair : map) { stream.write(reinterpret_cast(&pair.first), sizeof(K)); stream.write(reinterpret_cast(&pair.second), sizeof(V)); } } } // namespace dXreadwrite ================================================ FILE: genlib/simplematrix.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2018, Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include namespace depthmapX { /** * Base class for 2 dimensional matrices. This can be used as reference/pointer, but you cannot * create this directly - you need to create either a row or a column matrix (the difference * being the memory layout either, contiguous rows, or contiguous columns. * Which layout to choose depends on the underlying data - if the data layout is given, it should be * simple to find the matching implementation. To choose a new data layout, think about access patterns. * If it is more likely to process several values from one row in one got, choose a row matrix. If processing * is more likely to be by column, choose a column matrix. If access is truly random, it makes no difference. */ template class BaseMatrix { protected: BaseMatrix(size_t rows, size_t columns) { m_data = new T[rows * columns]; m_rows = rows; m_columns = columns; } BaseMatrix(const BaseMatrix &other) : BaseMatrix(other.m_rows, other.m_columns) { std::copy(other.begin(), other.end(), m_data); } BaseMatrix(BaseMatrix &&other) : m_data(other.m_data), m_rows(other.m_rows), m_columns(other.m_columns) { other.m_data = nullptr; other.m_rows = 0; other.m_columns = 0; } public: virtual ~BaseMatrix() { delete[] m_data; } /** * @brief Fill all values of the matrix with a default value * @param value default value */ virtual void initialiseValues(T const &value) { std::fill(begin(), end(), value); } /** * @brief Resets the matrix to a new size - this deletes all contents. * This method provides a strong exception guarantee - if the new statement throws, * the old state will be preserved. * @param rows new number of rows * @param columns new number of columns */ virtual void reset(size_t rows, size_t columns) { // allocate new memory first - if this throws, the old matrix is still intact. T *tmp = new T[rows * columns]; delete[] m_data; m_data = tmp; m_rows = rows; m_columns = columns; } /** * @brief operator () access operator uses () instead of [] to allow giving two coordinates * @param row row to access * @param column column to access * @return non-const reference to the data */ virtual T &operator()(size_t row, size_t column) = 0; /** * @brief operator () access operator uses () instead of [] to allow giving two coordinates * @param row row to access * @param column column to access * @return const reference to the data */ virtual T const &operator()(size_t row, size_t column) const = 0; /** * @brief begin get a pointer to the data array (complies with std::iterator definitions) * @return pointer to the first element */ T *begin() { return m_data; } /** * @brief end pointer marking the end of the data array * @return pointer behind the last element of the data array */ T *end() { return m_data + size(); } /** * @brief begin get a pointer to the data array (complies with std::iterator definitions) * @return const pointer to the first element */ T const *begin() const { return m_data; } /** * @brief end pointer marking the end of the data array * @return const pointer behind the last element of the data array */ T const *end() const { return m_data + size(); } /** * @brief size * @return size of the data array in elements */ size_t size() const { return m_rows * m_columns; } /** * @brief rows * @return number of rows */ size_t rows() const { return m_rows; } /** * @brief columns * @return number of columns */ size_t columns() const { return m_columns; } protected: T *m_data; size_t m_rows; size_t m_columns; void access_check(size_t row, size_t column) const { if (row >= m_rows) { throw std::out_of_range("row out of range"); } if (column >= m_columns) { throw std::out_of_range("column out of range"); } } void swap(BaseMatrix &other) { std::swap(m_data, other.m_data); std::swap(m_rows, other.m_rows); std::swap(m_columns, other.m_columns); } }; /** * Row matrix implementation - the data for each row is contiguous in memory, columns jump by the * number of rows. */ template class RowMatrix : public BaseMatrix { public: RowMatrix(size_t rows, size_t columns) : BaseMatrix(rows, columns) {} RowMatrix(RowMatrix const &other) : BaseMatrix(other) {} RowMatrix(RowMatrix &&other) : BaseMatrix(std::move(other)) {} RowMatrix &operator=(RowMatrix const &other) { RowMatrix tmp(other); this->swap(tmp); return *this; } RowMatrix &operator=(RowMatrix &&other) { RowMatrix tmp(std::move(other)); this->swap(tmp); return *this; } T &operator()(size_t row, size_t column) { this->access_check(row, column); return this->m_data[column + row * this->m_columns]; } T const &operator()(size_t row, size_t column) const { this->access_check(row, column); return this->m_data[column + row * this->m_columns]; } }; /** * Column matrix implementation - the data for each column is contiguous in memory, rows jump by the * number of columns. */ template class ColumnMatrix : public BaseMatrix { public: ColumnMatrix(size_t rows, size_t columns) : BaseMatrix(rows, columns) {} ColumnMatrix(ColumnMatrix const &other) : BaseMatrix(other) {} ColumnMatrix(ColumnMatrix &&other) : BaseMatrix(std::move(other)) {} ColumnMatrix &operator=(ColumnMatrix const &other) { ColumnMatrix tmp(other); this->swap(tmp); return *this; } ColumnMatrix &operator=(ColumnMatrix &&other) { ColumnMatrix tmp(std::move(other)); this->swap(tmp); return *this; } T &operator()(size_t row, size_t column) { this->access_check(row, column); return this->m_data[row + column * this->m_rows]; } T const &operator()(size_t row, size_t column) const { this->access_check(row, column); return this->m_data[row + column * this->m_rows]; } }; } // namespace depthmapX ================================================ FILE: genlib/stringutils.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "stringutils.h" #include #include #include #include #include namespace dXstring { std::vector split(const std::string &s, char delim, bool skipEmptyTokens) { std::vector elems; std::stringstream ss; ss.str(s); std::string item; while (std::getline(ss, item, delim)) { if (skipEmptyTokens && item.empty()) { continue; } elems.push_back(item); } return elems; } std::string readString(std::istream &stream) { unsigned int length; stream.read(reinterpret_cast(&length), sizeof(length)); if (length == 0) { return std::string(); } std::string result(length, '\0'); char *ptr = &result[0]; stream.read(ptr, length); return result; } void writeString(std::ostream &stream, const std::string &s) { unsigned int length = static_cast(s.length()); stream.write(reinterpret_cast(&length), sizeof(unsigned int)); if (length > 0) { stream.write(s.data(), length); } } std::string formatString(double value, const std::string &format) { size_t bufferLength = 24 + format.length(); std::vector buffer(bufferLength, '\0'); snprintf(&buffer[0], bufferLength, format.c_str(), value); return std::string(&buffer[0]); } std::string formatString(int value, const std::string &format) { size_t bufferLength = 24 + format.length(); std::vector buffer(bufferLength, '\0'); snprintf(&buffer[0], bufferLength, format.c_str(), value); return std::string(&buffer[0]); } std::string &toLower(std::string &str) { std::transform(str.begin(), str.end(), str.begin(), tolower); return str; } // trim from start (in place) void ltrim(std::string &s, char c) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [&c](int ch) { return ch != c; })); } // trim from end (in place) void rtrim(std::string &s, char c) { s.erase(std::find_if(s.rbegin(), s.rend(), [&c](int ch) { return ch != c; }).base(), s.end()); } void makeInitCaps(std::string &s) { bool literal = false; bool reset = true; for (auto &c : s) { if (!isalpha(c)) { if (c == '"') { literal = !literal; } reset = true; } else { if (!literal) { if (reset) { c = static_cast(toupper(c)); } else { c = static_cast(tolower(c)); } } reset = false; } } } bool isDouble(const std::string &s) { // nasty const cast to satisfy the function signature - we will not change the value of endPtr char *endPtr = const_cast(&s[0]); strtod(s.c_str(), &endPtr); return endPtr != &s[0]; } // handles all three line endings ("\r", "\n" and "\r\n"). taken from: // https://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf std::istream &safeGetline(std::istream &is, std::string &t) { t.clear(); // The characters in the stream are read one-by-one using a std::streambuf. // That is faster than reading them one-by-one using the std::istream. // Code that uses streambuf this way must be guarded by a sentry object. // The sentry object performs various tasks, // such as thread synchronization and updating the stream state. std::istream::sentry se(is, true); std::streambuf *sb = is.rdbuf(); for (;;) { int c = sb->sbumpc(); switch (c) { case '\n': return is; case '\r': if (sb->sgetc() == '\n') sb->sbumpc(); return is; case std::streambuf::traits_type::eof(): // Also handle the case when the last line has no line ending if (t.empty()) is.setstate(std::ios::eofbit); return is; default: t += (char)c; } } } } // namespace dXstring ================================================ FILE: genlib/stringutils.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Collection of utility functions that are required to add pstring functionality // to std::strings (i.e. splitting and compatible serialisation/deserialisation) #pragma once #include #include #include #include namespace dXstring { std::vector split(const std::string &s, char delim, bool skipEmptyTokens = false); std::string readString(std::istream &stream); void writeString(std::ostream &stream, const std::string &s); std::string formatString(double value, const std::string &format = "%+.16le"); std::string formatString(int value, const std::string &format = "% 16d"); /// Inplace conversion to lower case std::string &toLower(std::string &str); void ltrim(std::string &s, char c = ' '); void rtrim(std::string &s, char c = ' '); void makeInitCaps(std::string &s); bool isDouble(const std::string &s); template bool beginsWith(const T &input, const T match) { return input.size() >= match.size() && equal(match.begin(), match.end(), input.begin()); } std::istream &safeGetline(std::istream &is, std::string &t); } // namespace dXstring ================================================ FILE: genlib/xmlparse.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "xmlparse.h" enum { STEP_START, STEP_ELEMENT_NAME, STEP_ATTRIBUTE_NAME, STEP_START_ATTRIBUTE_VALUE, STEP_ATTRIBUTE_VALUE, STEP_CLOSING }; bool iscrlf(char c) { // \n is MAC = 13, UNIX = 10, MS = 13,10 return (c == 10 || c == 13); } bool xmlelement::parse(std::ifstream &stream, bool parsesubelements) { bool closed = false; bool complete = false; int step = STEP_START; std::string buffer; std::string attribute; std::string value; while (!complete && stream) { char c = static_cast(stream.get()); if (stream) { switch (step) { case STEP_START: if (c == '<') { step = 1; buffer.clear(); } break; case STEP_ELEMENT_NAME: if (isspace(c) || iscrlf(c)) { name = buffer; buffer.clear(); step = STEP_ATTRIBUTE_NAME; } else if (c == '/') { if (buffer.empty()) { closetag = true; } else { name = buffer; buffer.clear(); step = STEP_CLOSING; } } else if (c == '>') { if (buffer.empty()) { throw xmlerror("No element name"); } else { name = buffer; buffer.clear(); complete = true; if (closetag) { closed = true; } else { if (parsesubelements) { closed = subparse(stream); } } } } else if (isalnum(c) || ispunct(c)) { buffer += c; } else { badcharacter(c, "parsing element name"); } break; case STEP_CLOSING: if (c == '>') { // only get here if midway through tag closed = true; complete = true; } else if (!isspace(c) && !iscrlf(c)) { badcharacter(c, "closing element tag"); } break; case STEP_ATTRIBUTE_NAME: if (isspace(c) || iscrlf(c)) { if (attribute.empty()) { attribute = buffer; buffer.clear(); } } else if (c == '=') { if (attribute.empty()) { attribute = buffer; if (attribute.empty()) { throw xmlerror("No attribute name"); } } buffer.clear(); step = STEP_START_ATTRIBUTE_VALUE; } else if (c == '/') { // could be closing a tag without specifying attribute value, but we'll be okay: step = STEP_CLOSING; } else if (c == '>') { complete = true; // could be closing a tag without specifying attribute value, but we'll be okay: if (parsesubelements) { closed = subparse(stream); } } else if (isalnum(c) || ispunct(c)) { buffer += c; } else { badcharacter(c, "reading attribute name"); } break; case STEP_START_ATTRIBUTE_VALUE: if (c == '\"') { step = STEP_ATTRIBUTE_VALUE; } else if (!isspace(c) && !iscrlf(c)) { badcharacter(c, "expecting opening '\"'"); } break; case STEP_ATTRIBUTE_VALUE: if (c == '\"') { attributes[attribute] = buffer; buffer.clear(); attribute.clear(); step = STEP_ATTRIBUTE_NAME; } else { // there was a bad char test for 'isprint(c)', but it didn't like certain characters! buffer += c; } break; } } } if (!complete && step != STEP_START) { throw xmlerror(std::string("Unexpected end of element ") + name); } return closed; } void xmlelement::badcharacter(char c, const std::string &location) { if (isprint(c)) { throw(std::string("Found '") + c + std::string("' while ") + location); } else { std::stringstream s; s << "Found character " << int(c) << " while " << location; throw(s.str()); } } bool xmlelement::subparse(std::ifstream &stream) { bool complete = false; while (!complete && stream) { subelements.push_back(xmlelement()); if (!subelements.back().parse(stream, true)) { throw xmlerror(std::string("Unexplained error")); } if (subelements.back().closetag) { if (subelements.back().name == name) { subelements.pop_back(); complete = true; } else { throw xmlerror(std::string("Element <") + name + std::string("> closed with ")); } } } if (!complete) { throw xmlerror(std::string("Unexpected end of element ") + name); } return true; } std::ostream &operator<<(std::ostream &stream, const xmlelement &elem) { stream << "<" << elem.name; std::map::const_iterator it; for (it = elem.attributes.begin(); it != elem.attributes.end(); it++) { stream << " " << it->first << "=\"" << it->second << "\" "; } if (elem.subelements.size() == 0) { stream << " />" << std::endl; } else { stream << ">" << std::endl; for (size_t i = 0; i < elem.subelements.size(); i++) { stream << elem.subelements[i]; } stream << "" << std::endl; } return stream; } ================================================ FILE: genlib/xmlparse.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __XMLPARSE_H__ #define __XMLPARSE_H__ #include #include #include #include #include #include struct xmlelement { std::string name; bool closetag; std::map attributes; std::vector subelements; xmlelement() { closetag = false; } bool parse(std::ifstream &stream, bool parsesubelements = false); friend std::ostream &operator<<(std::ostream &stream, const xmlelement &elem); protected: bool subparse(std::ifstream &stream); void badcharacter(char c, const std::string &location); }; struct xmlerror { std::string error; xmlerror(const std::string &e = std::string()) { error = e; } }; #endif ================================================ FILE: genlibTest/CMakeLists.txt ================================================ set(genlibtest genlibTest) set(genlibTest_SRCS testreadwritehelpers.cpp main.cpp testsimplematrix.cpp testbspnode.cpp teststringutils.cpp testcontainerutils.cpp) set(LINK_LIBS genlib) include_directories("../ThirdParty/Catch") add_executable(${genlibtest} ${genlibTest_SRCS}) target_link_libraries(${genlibtest} ${LINK_LIBS}) ================================================ FILE: genlibTest/main.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: genlibTest/testbspnode.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "genlib/comm.h" #include "genlib/p2dpoly.h" #include "genlib/bsptree.h" TEST_CASE("BSPTree::pickMidpointLine") { std::vector lines; lines.push_back(TaggedLine(Line(Point2f(1, 2), Point2f(2, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(2, 2), Point2f(3, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(3, 2), Point2f(4, 2)), 0)); BSPNode node; REQUIRE(BSPTree::pickMidpointLine(lines, 0) == 1); SECTION("Additional lines") { lines.push_back(TaggedLine(Line(Point2f(4, 2), Point2f(5, 2)), 0)); REQUIRE(BSPTree::pickMidpointLine(lines, 0) == 1); lines.push_back(TaggedLine(Line(Point2f(5, 1), Point2f(6, 1)), 0)); REQUIRE(BSPTree::pickMidpointLine(lines, 0) == 2); // the only line with height > width becomes chosen lines.push_back(TaggedLine(Line(Point2f(15, 4), Point2f(15, 0)), 0)); REQUIRE(BSPTree::pickMidpointLine(lines, 0) == 5); } SECTION("rotated middle") { // height > width, rotated, close to midpoint lines.push_back(TaggedLine(Line(Point2f(4.5, 1), Point2f(4.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(5, 2), Point2f(6, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(6, 2), Point2f(7, 2)), 0)); // height > width, rotated, not close to midpoint lines.push_back(TaggedLine(Line(Point2f(6.5, 1), Point2f(6.5, 3)), 0)); REQUIRE(BSPTree::pickMidpointLine(lines, 0) == 3); } } void compareLines(Line l1, Line l2, float EPSILON) { REQUIRE(l1.start().x == Approx(l2.start().x).epsilon(EPSILON)); REQUIRE(l1.start().y == Approx(l2.start().y).epsilon(EPSILON)); REQUIRE(l1.end().x == Approx(l2.end().x).epsilon(EPSILON)); REQUIRE(l1.end().y == Approx(l2.end().y).epsilon(EPSILON)); } TEST_CASE("BSPTree::makeLines") { const float EPSILON = 0.001f; typedef std::pair, std::vector > TagLineVecPair; std::vector lines; lines.push_back(TaggedLine(Line(Point2f(1, 2), Point2f(2, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(2, 2), Point2f(3, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(3, 2), Point2f(4, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(4, 2), Point2f(5, 2)), 0)); std::unique_ptr node(new BSPNode()); TagLineVecPair result = BSPTree::makeLines(0, 0, lines, node.get()); REQUIRE(result.first.size() == 3); REQUIRE(result.second.size() == 0); compareLines(result.first[0].line, lines[0].line, EPSILON); compareLines(result.first[1].line, lines[2].line, EPSILON); compareLines(result.first[2].line, lines[3].line, EPSILON); SECTION("One on the right") { lines.push_back(TaggedLine(Line(Point2f(5, 1), Point2f(6, 1)), 0)); result = BSPTree::makeLines(0, 0, lines, node.get()); REQUIRE(result.first.size() == 3); REQUIRE(result.second.size() == 1); compareLines(result.second[0].line, lines[4].line, EPSILON); } SECTION("One line with height > width becomes chosen") { // height > width, rotated, not close to midpoint lines.push_back(TaggedLine(Line(Point2f(5.5, 1), Point2f(5.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(6, 2), Point2f(7, 2)), 0)); result = BSPTree::makeLines(0, 0, lines, node.get()); REQUIRE(result.first.size() == 4); REQUIRE(result.second.size() == 1); compareLines(result.first[0].line, lines[0].line, EPSILON); compareLines(result.first[1].line, lines[1].line, EPSILON); compareLines(result.first[2].line, lines[2].line, EPSILON); compareLines(result.first[3].line, lines[3].line, EPSILON); compareLines(result.second[0].line, lines[5].line, EPSILON); } SECTION("One broken between") { // height > width, rotated, close to midpoint lines.push_back(TaggedLine(Line(Point2f(5.5, 1), Point2f(5.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(6, 2), Point2f(7, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(7, 2), Point2f(8, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(8, 2), Point2f(9, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(9, 2), Point2f(10, 2)), 0)); // line with two points at different sides of chosen lines.push_back(TaggedLine(Line(Point2f(3, -2), Point2f(6, -2)), 0)); result = BSPTree::makeLines(0, 0, lines, node.get()); // adds one on each side REQUIRE(result.first.size() == 5); REQUIRE(result.second.size() == 5); compareLines(result.first[0].line, lines[0].line, EPSILON); compareLines(result.first[1].line, lines[1].line, EPSILON); compareLines(result.first[2].line, lines[2].line, EPSILON); compareLines(result.first[3].line, lines[3].line, EPSILON); compareLines(result.second[0].line, lines[5].line, EPSILON); compareLines(result.second[1].line, lines[6].line, EPSILON); compareLines(result.second[2].line, lines[7].line, EPSILON); compareLines(result.second[3].line, lines[8].line, EPSILON); compareLines(result.first[4].line, Line(Point2f(3, -2), Point2f(5.5, -2)), EPSILON); compareLines(result.second[4].line, Line(Point2f(5.5, -2), Point2f(6, -2)), EPSILON); } } TEST_CASE("BSPTree::make (all horizontal lines)", "all-left tree") { const float EPSILON = 0.001f; std::vector lines; lines.push_back(TaggedLine(Line(Point2f(1, 2), Point2f(2, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(2, 2), Point2f(3, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(3, 2), Point2f(4, 2)), 0)); lines.push_back(TaggedLine(Line(Point2f(4, 2), Point2f(5, 2)), 0)); std::unique_ptr node(new BSPNode()); BSPTree::make(0, 0, lines, node.get()); compareLines(node->getLine(), lines[1].line, EPSILON); REQUIRE(node->m_left != nullptr); REQUIRE(node->m_right == nullptr); compareLines(node->m_left->getLine(), lines[2].line, EPSILON); REQUIRE(node->m_left->m_left != nullptr); REQUIRE(node->m_left->m_right == nullptr); compareLines(node->m_left->m_left->getLine(), lines[3].line, EPSILON); REQUIRE(node->m_left->m_left->m_left != nullptr); REQUIRE(node->m_left->m_left->m_right == nullptr); compareLines(node->m_left->m_left->m_left->getLine(), lines[0].line, EPSILON); REQUIRE(node->m_left->m_left->m_left->m_left == nullptr); REQUIRE(node->m_left->m_left->m_left->m_right == nullptr); } TEST_CASE("BSPTree::make (all vertical lines)", "split tree") { const float EPSILON = 0.001f; std::vector lines; lines.push_back(TaggedLine(Line(Point2f(1.5, 1), Point2f(1.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(2.5, 1), Point2f(2.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(3.5, 1), Point2f(3.5, 3)), 0)); lines.push_back(TaggedLine(Line(Point2f(4.5, 1), Point2f(4.5, 3)), 0)); std::unique_ptr node(new BSPNode()); BSPTree::make(0, 0, lines, node.get()); compareLines(node->getLine(), lines[1].line, EPSILON); REQUIRE(node->m_left != nullptr); REQUIRE(node->m_right != nullptr); compareLines(node->m_left->getLine(), lines[0].line, EPSILON); compareLines(node->m_right->getLine(), lines[3].line, EPSILON); REQUIRE(node->m_left->m_left == nullptr); REQUIRE(node->m_left->m_right == nullptr); REQUIRE(node->m_right->m_left != nullptr); REQUIRE(node->m_right->m_right == nullptr); compareLines(node->m_right->m_left->getLine(), lines[2].line, EPSILON); REQUIRE(node->m_right->m_left->m_left == nullptr); REQUIRE(node->m_right->m_left->m_right == nullptr); } ================================================ FILE: genlibTest/testcontainerutils.cpp ================================================ // Copyright (C) 2018 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include #include TEST_CASE("Test binary search helper with container", ""){ std::vector testVec{ 1, 2, 4, 5}; REQUIRE(*depthmapX::findBinary(testVec, 2) == 2); REQUIRE(depthmapX::findBinary(testVec, 3) == testVec.end()); REQUIRE(depthmapX::findBinary(testVec, 6) == testVec.end()); auto iter = depthmapX::findBinary(testVec, 2); *iter = 3; REQUIRE(*depthmapX::findBinary(testVec, 3) == 3); const std::vector& constVec = testVec; REQUIRE(*depthmapX::findBinary(constVec, 3) == 3); REQUIRE(depthmapX::findBinary(constVec, 2) == testVec.end()); REQUIRE(depthmapX::findBinary(constVec, 6) == testVec.end()); } ================================================ FILE: genlibTest/testreadwritehelpers.cpp ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "cliTest/selfcleaningfile.h" #include "genlib/readwritehelpers.h" #include "genlib/containerutils.h" #include TEST_CASE("vector reading and writing") { using namespace dXreadwrite; std::vector intVec{1, 5, 34, -2, 5}; SelfCleaningFile intFile("integers.bin"); { std::ofstream outfile(intFile.Filename()); writeVector(outfile, intVec); } { std::ifstream infile(intFile.Filename()); auto copy = readVector(infile); REQUIRE(copy == intVec); } std::vector intCopy; { std::ifstream infile(intFile.Filename()); readIntoVector(infile, intCopy); } REQUIRE(intCopy == intVec); } TEST_CASE("map reading and writing") { using namespace dXreadwrite; std::map intFloatMap; intFloatMap.insert(std::make_pair(1,0.1f)); intFloatMap.insert(std::make_pair(5,5000.0f)); intFloatMap.insert(std::make_pair(34,-3.4f)); intFloatMap.insert(std::make_pair(-2,0.2f)); intFloatMap.insert(std::make_pair(6,0.6f)); SelfCleaningFile intFloatFile("intFloatMap.bin"); { std::ofstream outfile(intFloatFile.Filename()); writeMap(outfile, intFloatMap); } { std::ifstream infile(intFloatFile.Filename()); auto copy = readMap(infile); REQUIRE(copy == intFloatMap); } std::map intCopy; { std::ifstream infile(intFloatFile.Filename()); readIntoMap(infile, intCopy); } REQUIRE(intCopy == intFloatMap); } ================================================ FILE: genlibTest/testsimplematrix.cpp ================================================ // Copyright (C) 2018 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../genlib/simplematrix.h" #include #include template void compareMatrixContent( depthmapX::BaseMatrix const & matrix, std::vector const & expected ){ REQUIRE(matrix.size() == expected.size()); std::vector result(matrix.size()); std::copy(matrix.begin(), matrix.end(), result.begin()); REQUIRE(result == expected); } TEST_CASE("Row matrix test assignemnt copy and move"){ depthmapX::RowMatrix matrix(2,3); matrix(0,0) = "0,0"; matrix(1,0) = "1,0"; matrix(0,1) = "0,1"; matrix(1,1) = "1,1"; matrix(1,2) = "1,2"; matrix(0,2) = "0,2"; std::vector expected{"0,0", "0,1", "0,2", "1,0", "1,1", "1,2"}; compareMatrixContent(matrix, expected); depthmapX::RowMatrix copy(matrix); compareMatrixContent(matrix, expected); compareMatrixContent(copy, expected); depthmapX::RowMatrix clone(std::move(copy)); compareMatrixContent(clone, expected); REQUIRE(copy.size() == 0); copy = clone; compareMatrixContent(copy, expected); REQUIRE(copy.columns() == 3); REQUIRE(copy.rows() == 2); compareMatrixContent(clone, expected); depthmapX::RowMatrix assignMove(1,1); assignMove = std::move(copy); compareMatrixContent(assignMove, expected); REQUIRE(copy.size() == 0); } TEST_CASE("Row matrix test exceptions"){ depthmapX::RowMatrix matrix(2, 3); matrix(0,0) = 1; matrix(1,2) = -1; matrix(0,1) = 2; matrix(0,2) = 3; matrix(1,0) = -23; matrix(1,1) = 0; REQUIRE(matrix(1,2) == -1); compareMatrixContent(matrix, std::vector{1, 2, 3, -23, 0, -1}); REQUIRE_THROWS_WITH(matrix(5, 0), Catch::Contains("row out of range")); REQUIRE_THROWS_WITH(matrix(0, 5), Catch::Contains("column out of range")); } TEST_CASE("Column matrix test assignemnt copy and move"){ depthmapX::ColumnMatrix matrix(2,3); matrix(0,0) = "0,0"; matrix(1,0) = "1,0"; matrix(0,1) = "0,1"; matrix(1,1) = "1,1"; matrix(1,2) = "1,2"; matrix(0,2) = "0,2"; std::vector expected{"0,0", "1,0", "0,1", "1,1", "0,2", "1,2"}; compareMatrixContent(matrix, expected); depthmapX::ColumnMatrix copy(matrix); compareMatrixContent(matrix, expected); compareMatrixContent(copy, expected); depthmapX::ColumnMatrix clone(std::move(copy)); compareMatrixContent(clone, expected); REQUIRE(copy.size() == 0); copy = clone; compareMatrixContent(copy, expected); REQUIRE(copy.columns() == 3); REQUIRE(copy.rows() == 2); compareMatrixContent(clone, expected); depthmapX::ColumnMatrix assignMove(1,1); assignMove = std::move(copy); compareMatrixContent(assignMove, expected); REQUIRE(copy.size() == 0); } TEST_CASE("Column matrix test exceptions"){ depthmapX::ColumnMatrix matrix(2, 3); matrix(0,0) = 1; matrix(1,2) = -1; matrix(0,1) = 2; matrix(0,2) = 3; matrix(1,0) = -23; matrix(1,1) = 0; REQUIRE(matrix(1,2) == -1); compareMatrixContent(matrix, std::vector{1, -23, 2, 0, 3, -1}); REQUIRE_THROWS_WITH(matrix(5, 0), Catch::Contains("row out of range")); REQUIRE_THROWS_WITH(matrix(0, 5), Catch::Contains("column out of range")); } TEST_CASE("Fill and reset"){ depthmapX::ColumnMatrix matrix(2,3); matrix.initialiseValues(-42); compareMatrixContent(matrix, std::vector(6, -42)); matrix.reset(3,4); REQUIRE(matrix.rows() == 3); REQUIRE(matrix.columns() == 4); matrix.initialiseValues(12); compareMatrixContent(matrix, std::vector(12, 12)); } ================================================ FILE: genlibTest/teststringutils.cpp ================================================ // Copyright (C) 2017-2018 Christian Sailer // Copyright (C) 2017-2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../genlib/stringutils.h" #include "../cliTest/selfcleaningfile.h" #include TEST_CASE("Tests for split function", "") { { std::vector stringParts = dXstring::split("foo,bar",','); REQUIRE(stringParts.size() == 2); REQUIRE(stringParts[0] == "foo"); REQUIRE(stringParts[1] == "bar"); } { std::vector stringParts = dXstring::split("0.5,1.2",','); REQUIRE(stringParts.size() == 2); REQUIRE(stringParts[0] == "0.5"); REQUIRE(stringParts[1] == "1.2"); } { std::vector stringParts = dXstring::split("0.5\t1.2",'\t'); REQUIRE(stringParts.size() == 2); REQUIRE(stringParts[0] == "0.5"); REQUIRE(stringParts[1] == "1.2"); } { std::vector stringParts = dXstring::split("0.5\t1.2\tfoo",'\t'); REQUIRE(stringParts.size() == 3); REQUIRE(stringParts[0] == "0.5"); REQUIRE(stringParts[1] == "1.2"); REQUIRE(stringParts[2] == "foo"); } { // skip last blank element std::vector stringParts = dXstring::split("foo,bar,",','); REQUIRE(stringParts.size() == 2); } { // do not skip middle blank element std::vector stringParts = dXstring::split("foo,,bar",','); REQUIRE(stringParts.size() == 3); } { // do skip any empty elements when flag is set // do not skip middle blank element std::vector stringParts = dXstring::split("foo,,bar",',', true); REQUIRE(stringParts.size() == 2); } } TEST_CASE("Read String") { { // case empty string - just read 0 length and return new string object SelfCleaningFile f("test.bin"); { std::ofstream fs(f.Filename()); unsigned int length = 0; fs.write(reinterpret_cast(&length), sizeof(unsigned int)); } std::ifstream fs(f.Filename()); auto result = dXstring::readString(fs); REQUIRE(result.empty()); } // case non empty string - read length and then beam data into the string { SelfCleaningFile f("test.bin"); { std::ofstream fs(f.Filename()); unsigned int length = 5; const char *payload = "abcde"; fs.write(reinterpret_cast(&length), sizeof(unsigned int)); fs.write(payload, 5); } std::ifstream fs(f.Filename()); std::string result = dXstring::readString(fs); REQUIRE(result == "abcde"); } } TEST_CASE("Write String") { { // case empty string - just write 0 length std::string testString; SelfCleaningFile f("test.bin"); { std::ofstream fs(f.Filename()); dXstring::writeString(fs, testString); } std::ifstream fs(f.Filename()); unsigned int length; fs.read(reinterpret_cast(&length), sizeof(unsigned int)); REQUIRE(length == 0); char dummy[1]; REQUIRE_FALSE(fs.read(dummy, 1)); REQUIRE(fs.eof()); } { // case non empty string - just write length plus content std::string testString("cdfe"); SelfCleaningFile f("test.bin"); { std::ofstream fs(f.Filename()); dXstring::writeString(fs, testString); } std::ifstream fs(f.Filename()); unsigned int length; fs.read(reinterpret_cast(&length), sizeof(unsigned int)); REQUIRE(length == testString.length()); char buffer[5]; buffer[4] = '\0'; fs.read(buffer, length); REQUIRE(testString == buffer); char dummy[1]; REQUIRE_FALSE(fs.read(dummy, 1)); REQUIRE(fs.eof()); } } TEST_CASE("test string format") { REQUIRE(dXstring::formatString(1.0, "foo") == "foo"); REQUIRE(dXstring::formatString(1.0, "%+.16le") == "+1.0000000000000000e+00"); REQUIRE(dXstring::formatString(1.0) == "+1.0000000000000000e+00"); REQUIRE(dXstring::formatString(1.0, "%+.8le") == "+1.00000000e+00"); REQUIRE(dXstring::formatString(1 ) == " 1"); } TEST_CASE("test tolower") { std::string tstr = "AbdUgs24*hHÜ"; auto result = dXstring::toLower(tstr); REQUIRE(tstr == "abdugs24*hhÜ"); REQUIRE(result == "abdugs24*hhÜ"); } TEST_CASE("test ltrim") { std::string normal = " fo o "; dXstring::ltrim(normal); REQUIRE( normal == "fo o "); std::string empty = ""; dXstring::ltrim(empty); REQUIRE( empty == "" ); std::string justBlanks = " "; dXstring::ltrim(justBlanks); REQUIRE( justBlanks == ""); std::string noBlanks = "foo "; dXstring::ltrim(noBlanks); REQUIRE(noBlanks == "foo "); } TEST_CASE("test rtrim") { std::string normal = " fo o "; dXstring::rtrim(normal); REQUIRE( normal == " fo o"); std::string empty = ""; dXstring::rtrim(empty); REQUIRE( empty == "" ); std::string justBlanks = " "; dXstring::rtrim(justBlanks); REQUIRE( justBlanks == ""); std::string noBlanks = "foo "; dXstring::rtrim(noBlanks); REQUIRE(noBlanks == "foo"); } TEST_CASE("test makeInitCaps") { std::string tstr = "abC DEf dEf \"fOO Bar\" blah bLuB"; dXstring::makeInitCaps(tstr); REQUIRE(tstr == "Abc Def Def \"fOO Bar\" Blah Blub"); } TEST_CASE("test isDouble") { REQUIRE(dXstring::isDouble("0")); REQUIRE(dXstring::isDouble(" 1.345e23.1")); REQUIRE_FALSE(dXstring::isDouble("")); REQUIRE_FALSE(dXstring::isDouble("foo1234")); } TEST_CASE("test begins with") { REQUIRE(dXstring::beginsWith("abcd", "abcd")); REQUIRE(dXstring::beginsWith("abcde", "abcd")); REQUIRE_FALSE(dXstring::beginsWith("abcd", "abcde")); REQUIRE_FALSE(dXstring::beginsWith("abcd", "ef")); REQUIRE_FALSE(dXstring::beginsWith("abcd", "aec")); } TEST_CASE("test safeGetline") { std::stringstream stream; std::string out; SECTION("Windows") { stream << "Test\r"; } SECTION("Unix") { stream << "Test\n"; } SECTION("Mixed") { stream << "Test\r\n"; } dXstring::safeGetline(stream, out); REQUIRE(out == "Test"); } ================================================ FILE: mgraph440/CMakeLists.txt ================================================ set(mgraph440 mgraph440) set(mgraph440_SRCS pafcolor.cpp attr.cpp ngraph.cpp datalayer.cpp pointmap.cpp attributes.cpp connector.cpp mgraph.cpp axialmap.cpp shapemap.cpp pixelbase.cpp spacepix.cpp point.cpp stringutils.cpp p2dpoly.cpp salaprogram.cpp pafmath.cpp) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(warnings "-Wnone") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(warnings "/W0 /EHsc /wd4800") endif() add_compile_definitions(MGRAPH440_LIBRARY) add_library(${mgraph440} ${mgraph440_SRCS}) ================================================ FILE: mgraph440/attr.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #include "mgraph440/attr.h" #include #include // _finite support ////////////////////////////////////////////////////////////////////////////// namespace mgraph440 { void AttrHeader::reset(AttrVal attributes[]) { attributes[NEIGHBOURHOOD_SIZE].intval = -1; attributes[GRAPH_SIZE].intval = -1; attributes[KERNEL_SIZE].intval = -1; attributes[CLIQUE_SIZE].intval = -1; attributes[TOTAL_DEPTH].intval = -1; attributes[ENTROPY].floatval = -1.0f; attributes[REL_ENTROPY].floatval = -1.0f; attributes[CLUSTER].floatval = -1.0f; attributes[UNUSED].floatval = -1.0f; attributes[POINT_DEPTH].intval = -1; attributes[CONTROL_HILL].floatval = -1.0f; attributes[CONTROL_TURN].floatval = -1.0f; attributes[MEDIAN_ANGLE].floatval = -1.0f; attributes[FAR_NODE].intval = -1; attributes[FAR_DIST].floatval = -1.0f; attributes[TOTAL_DIST].floatval = -1.0f; attributes[AGENT_COUNT].intval = -1; attributes[AGENT_COLL_COUNT].intval = -1; attributes[TOTAL_METRIC_DEPTH].floatval = -1.0f; attributes[METRIC_GRAPH_SIZE].intval = -1; attributes[METRIC_POINT_DEPTH].floatval = -1.0f; attributes[TOTAL_EUCLID_DIST].floatval = -1.0f; attributes[POINT_EUCLID_DIST].floatval = -1.0f; attributes[TOTAL_METRIC_ANGLE].floatval = -1.0f; attributes[METRIC_POINT_ANGLE].floatval = -1.0f; } #define QUICK_MD (double(attributes[TOTAL_DEPTH].intval) / double(attributes[GRAPH_SIZE].intval - 1)) #define QUICK_METRIC_MD (double(attributes[TOTAL_METRIC_DEPTH].floatval) / double(attributes[METRIC_GRAPH_SIZE].intval - 1)) #define QUICK_METRIC_AMD (double(attributes[TOTAL_METRIC_ANGLE].floatval) / double(attributes[METRIC_GRAPH_SIZE].intval - 1)) double AttrHeader::getAttr(int attr, const AttrVal attributes[]) const { double val; // will eventually put the attributes in a table switch (attr) { case NEIGHBOURHOOD_SIZE: val = double(attributes[NEIGHBOURHOOD_SIZE].intval); break; case GRAPH_SIZE: val = double(attributes[GRAPH_SIZE].intval); break; case MEAN_DEPTH: if (attributes[GRAPH_SIZE].intval > 1) { val = QUICK_MD; } else { val = -1.0; } break; case INTEGRATION_RA: if (attributes[GRAPH_SIZE].intval > 2) { val = 2.0 * (QUICK_MD - 1.0) / double(attributes[GRAPH_SIZE].intval - 2); } else { val = -1.0; } break; case INTEGRATION_RRA: if (attributes[GRAPH_SIZE].intval > 2) { val = (2.0 * (QUICK_MD - 1.0)) / (double(attributes[GRAPH_SIZE].intval - 2) * dvalue(attributes[GRAPH_SIZE].intval)); } else { val = -1.0; } break; case INTEGRATION_HILL: if (attributes[GRAPH_SIZE].intval > 2 && attributes[TOTAL_DEPTH].intval > attributes[GRAPH_SIZE].intval) { val = (double(attributes[GRAPH_SIZE].intval - 2) * dvalue(attributes[GRAPH_SIZE].intval)) / (2.0 * (QUICK_MD - 1.0)); } else { val = -1.0; } break; case INTEGRATION_TEKL: if (attributes[GRAPH_SIZE].intval > 2 && attributes[TOTAL_DEPTH].intval > attributes[GRAPH_SIZE].intval) { val = ln(double(attributes[GRAPH_SIZE].intval - 2)/2.0) / ln(double(attributes[TOTAL_DEPTH].intval - attributes[GRAPH_SIZE].intval + 1)); } else { val = -1.0; } break; case POINT_DEPTH: val = attributes[POINT_DEPTH].intval; break; case AVG_DIST: if (attributes[NEIGHBOURHOOD_SIZE].intval > 0) { val = attributes[TOTAL_DIST].floatval / double(attributes[NEIGHBOURHOOD_SIZE].intval); } else { val = -1.0; } break; case AGENT_COUNT: val = attributes[attr].intval; break; case AGENT_COLL_COUNT: val = attributes[attr].intval; break; case METRIC_MEAN_DEPTH: if (attributes[METRIC_GRAPH_SIZE].intval > 1) { val = QUICK_METRIC_MD; } else { val = -1.0; } break; case METRIC_MEAN_ANGLE: if (attributes[METRIC_GRAPH_SIZE].intval > 1) { val = QUICK_METRIC_AMD; } else { val = -1.0; } break; case DECENTRAL_INTEG: if (attributes[TOTAL_METRIC_DEPTH].floatval >= 0.0 && attributes[TOTAL_DEPTH].intval > 0) { val = ln(attributes[TOTAL_METRIC_DEPTH].floatval+1.0) / double(attributes[TOTAL_DEPTH].intval); } else { val = -1.0; } break; case MEAN_PENN_DIST: if (attributes[METRIC_GRAPH_SIZE].intval > 1) { if (attributes[TOTAL_METRIC_DEPTH].floatval > attributes[TOTAL_EUCLID_DIST].floatval) { val = double(attributes[TOTAL_METRIC_DEPTH].floatval - attributes[TOTAL_EUCLID_DIST].floatval) / double(attributes[METRIC_GRAPH_SIZE].intval); } else { val = 0.0f; } } else { val = -1.0f; } break; case POINT_PENN_DIST: if (attributes[METRIC_POINT_DEPTH].floatval >= 0.0) { if (attributes[METRIC_POINT_DEPTH].floatval > attributes[POINT_EUCLID_DIST].floatval) { val = attributes[METRIC_POINT_DEPTH].floatval - attributes[POINT_EUCLID_DIST].floatval; } else { val = 0.0f; } } else { val = -1.0f; } break; default: val = attributes[attr].floatval; break; } return val; } /////////////////////////////////////////////////////////////////////////////////// AttrBody::AttrBody( std::streampos p, const AttrHeader& h ) { pos = p; ref = -1; header = (AttrHeader *) &h; color = 0.5; highlight = false; myagent = NULL; attributes = new AttrVal[header->m_attr_count]; header->reset(attributes); } AttrBody::AttrBody(const AttrBody& attr) { pos = attr.pos; ref = attr.ref; origin = attr.origin; header = attr.header; color = attr.color; highlight = attr.highlight; myagent = attr.myagent; if (attr.attributes) { attributes = new AttrVal[header->m_attr_count]; // fill in with original attributes: for (int i = 0; i < header->m_attr_count; i++) { attributes[i] = attr.attributes[i]; } } } AttrBody::~AttrBody() { if (attributes) { delete [] attributes; attributes = NULL; } } std::ostream& operator << (std::ostream& stream, const AttrBody& attr) { stream << attr.ref << "\t"; stream << attr.origin.x << "\t" << attr.origin.y << "\t" << attr.origin.z; for (int i = 0; i < NUM_SUMMARISABLE_ATTRIBUTES; i++) { if (g_attr_summary_map[i].usable()) { if (g_attr_summary_map[i].intval()) { stream << "\t" << attr.attributes[g_attr_summary_map[i].ref].intval; } else { stream << "\t" << attr.attributes[g_attr_summary_map[i].ref].floatval; } } } return stream; } void AttrBody::write( std::ostream& stream ) const { stream.write( (char *) &pos, sizeof(pos) ); stream.write( (char *) &ref, sizeof(ref) ); stream.write( (char *) &origin, sizeof(origin) ); if (attributes) { stream.write( (char *) attributes, sizeof(AttrVal) * (header->m_attr_count) ); } } void AttrBody::read( std::ifstream& stream, int attr_count ) { stream.read( (char *) &pos, sizeof(pos) ); stream.read( (char *) &ref, sizeof(ref) ); stream.read( (char *) &origin, sizeof(origin) ); if (attributes) { stream.read( (char *) attributes, sizeof(AttrVal) * attr_count ); } } /////////////////////////////////////////////////////////////////////////////////// bool ArVertexList::openwrite( int nodes ) { #ifdef _WIN32 m_stream = new std::fstream( m_filename.c_str(), std::ios::binary | std::ios::out | std::ios::trunc ); #else m_stream = new std::fstream( m_filename.c_str(), std::ios::out | std::ios::trunc ); #endif if (m_stream->fail()) { if (m_stream->rdbuf()->is_open()) { remove(); } if (m_stream) { delete m_stream; m_stream = NULL; } return false; } m_stream->write( "grf", 3 ); int version = METAGRAPH_VERSION; m_stream->write( (char *) &version, sizeof(int) ); m_stream->write( "v", 1 ); // <- signifies virtual memory section m_stream->write( (char *) &nodes, sizeof(nodes) ); return true; } void ArVertexList::openread() { #ifdef _WIN32 m_stream = new std::fstream( m_filename.c_str(), std::ios::binary | std::ios::in ); #else m_stream = new std::fstream( m_filename.c_str(), std::ios::in ); #endif } void ArVertexList::close() { if (m_stream) { if (m_stream->rdbuf()->is_open()) { m_stream->close(); } delete m_stream; m_stream = NULL; } } void ArVertexList::remove() { close(); if (!m_filename.empty()) { // Quick mod - TV #if defined(_MSC_VER) _unlink(m_filename.c_str()); #else unlink(m_filename.c_str()); #endif m_filename = ""; } } void ArVertexList::add( int ref, const ArVertex& node ) { m_cache_ref = ref; m_cache_data = node; } void ArVertexList::commit() // Copy { if (m_cache_ref != -1) { std::streampos pos = m_stream->tellp(); m_attributes[m_cache_ref].pos = pos; m_cache_data.write( (std::ofstream&) *m_stream ); m_cache_data.clear(); m_stream->flush(); } m_cache_ref = -1; } void ArVertexList::commit(const Point2f& p, int far_node, float far_dist, float total_dist) // Add { if (m_cache_ref != -1) { std::streampos pos = m_stream->tellp(); AttrBody attr(pos, m_attr_header); { // a few values we know attr.ref = m_cache_ref; attr.origin.x = p.x; attr.origin.y = p.y; attr.intval(AttrHeader::NEIGHBOURHOOD_SIZE) = m_cache_data.size(); attr.intval(AttrHeader::FAR_NODE) = far_node; attr.floatval(AttrHeader::FAR_DIST) = far_dist; attr.floatval(AttrHeader::TOTAL_DIST) = total_dist; } m_attributes.push_back( attr ); m_cache_data.write( (std::ofstream&) *m_stream ); m_cache_data.clear(); m_stream->flush(); } m_cache_ref = -1; } // NOTE: ONLY READ AND WRITE ATTRIBUTES! // (At the moment, complex virtual mem stuff is handled at the meta graph level) bool ArVertexList::read( std::ifstream& stream, int metagraph_version ) { m_metagraph_version = metagraph_version; int attr_count; stream.read( (char *) &m_which_attributes, sizeof(m_which_attributes) ); stream.read( (char *) &attr_count, sizeof(int) ); int size; stream.read( (char *) &size, sizeof(int) ); m_attributes.clear(); for (int i = 0; i < size; i++) { AttrBody attr(-1, m_attr_header); attr.read(stream, attr_count); // <- only write in saved attributes m_attributes.push_back( attr ); } m_cache_ref = -1; // just in case... should really set this with virtual mem stuff... return true; } bool ArVertexList::write( std::ostream& stream ) { stream.write( (char *) &m_which_attributes, sizeof(m_which_attributes) ); // I'm phasing this out again for now (attribute header), // I'm thinking the map should really be stored rather than the header, // in any case, the only important think about the header is the number of // attributes... stream.write( (char *) &m_attr_header.m_attr_count, sizeof(int) ); int size = m_attributes.size(); stream.write( (char *) &size, sizeof(int) ); for (size_t i = 0; i < m_attributes.size(); i++) { m_attributes[i].write( stream ); } return true; } } ================================================ FILE: mgraph440/attr.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Modifed by Dream #if defined(_MSC_VER) #include #else #include #endif #include #include "mgraph440/paftl.h" #include "mgraph440/p2dpoly.h" #include "mgraph440/mgraph_consts.h" namespace mgraph440 { // Pretty much all of this is now deprecated... // the attrs will be replaced by the easier to use AttributeTables in the future... // ...and so it now is: union AttrVal { int intval; float floatval; }; const int NUM_PHYSICAL_ATTRIBUTES = 25; // 25 physical attributes: see below // Note: also see AttrMap at bottom of file. // THIS ENTIRE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD struct AttrHeader { enum { NEIGHBOURHOOD_SIZE = 0, GRAPH_SIZE = 1, KERNEL_SIZE = 2, CLIQUE_SIZE = 3, TOTAL_DEPTH = 4, MEAN_DEPTH = 101, INTEGRATION_RA = 102, INTEGRATION_RRA = 103, INTEGRATION_HILL = 104, INTEGRATION_TEKL = 105, ENTROPY = 5, REL_ENTROPY = 6, CLUSTER = 7, UNUSED = 8, POINT_DEPTH = 9, CONTROL_HILL = 10, CONTROL_TURN = 11, MEDIAN_ANGLE = 12, FAR_NODE = 13, // not output in text file FAR_DIST = 14, AGENT_COUNT = 15, AGENT_COLL_COUNT = 16, // collisions TOTAL_DIST = 17, AVG_DIST = 107, // derived TOTAL_METRIC_DEPTH = 18, METRIC_GRAPH_SIZE = 19, METRIC_MEAN_DEPTH = 108, // derived DECENTRAL_INTEG = 109, // derived METRIC_POINT_DEPTH = 20, TOTAL_EUCLID_DIST = 21, POINT_EUCLID_DIST = 22, MEAN_PENN_DIST = 110, // derived POINT_PENN_DIST = 111, // derived TOTAL_METRIC_ANGLE = 23, METRIC_POINT_ANGLE = 24, METRIC_MEAN_ANGLE = 112 // derived }; int m_attr_count; // number of attributes: for storage AttrHeader(int n = NUM_PHYSICAL_ATTRIBUTES) { m_attr_count = n; } void reset(AttrVal attributes[]); double getAttr(int attr, const AttrVal attributes[]) const; }; const AttrHeader g_attr_header; class PafAgent; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD struct AttrBody { // // stored values int pos; int ref; Point3f origin; // storing origin unnecessary, may revise later AttrHeader *header; AttrVal *attributes; // colour and highlight are not stored float color; bool highlight; // // you can have agents *in* the graph too (helps with looking them up!) PafAgent *myagent; // AttrBody(std::streampos p = -1, const AttrHeader& h = AttrHeader() ); AttrBody(const AttrBody& attr); ~AttrBody(); void reset(); // double getAttr(int attr) const { return header->getAttr(attr, attributes); } // void write(std::ostream &stream ) const; void read( std::ifstream& stream, int attr_count ); // // Save a bit of memory, use integer / floating as appropriate int& intval(int i) { return attributes[i].intval; } float& floatval(int i) { return attributes[i].floatval; } // friend std::ostream& operator << (std::ostream& stream, const AttrBody& attr); // friend bool operator == (const AttrBody& a, const AttrBody& b); friend bool operator != (const AttrBody& a, const AttrBody& b); friend bool operator < (const AttrBody& a, const AttrBody& b); friend bool operator > (const AttrBody& a, const AttrBody& b); }; // These allow an order list of attributes (used by the conversion routine) inline bool operator == (const AttrBody& a, const AttrBody& b) { return a.ref == b.ref; } inline bool operator != (const AttrBody& a, const AttrBody& b) { return a.ref != b.ref; } inline bool operator > (const AttrBody& a, const AttrBody& b) { return a.ref > b.ref; } inline bool operator < (const AttrBody& a, const AttrBody& b) { return a.ref < b.ref; } /////////////////////////////////////////////////////////////////////////////// // a graph vertex /* class GraphVertex { friend class ArVertexList; protected: pvecint m_connections; public: GraphVertex() {} ~GraphVertex() {} public: pvecint& get_connections() { return m_connections; } int count_connections() { return m_connections.size(); } int& operator [] (int index) { return m_connections[index]; } void add_connection(int index) { #ifdef _DEBUG if (m_connections.findindex(index) != paftl::npos) { cerr << "oops" << endl; } #endif m_connections.push_back(index); } }; */ /////////////////////////////////////////////////////////////////////////////// // new angular member // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD inline short& loword(int& a) {return (short&) *((short *)&a);} inline short& hiword(int& a) {return (short&) *((short *)&a + 1); } class ArVertex { friend class ArVertexList; protected: pvecint m_nodes; pvecint m_bins; public: class Iterator { protected: ArVertex *m_vertex; short m_current; short m_last; short m_top; public: Iterator() { m_vertex = NULL; } Iterator(ArVertex *vertex, int bin) { m_vertex = vertex; m_current = loword(m_vertex->m_bins[bin]); m_last = hiword(m_vertex->m_bins[bin]); m_top = (short)m_vertex->m_nodes.size(); if (m_current == m_last) m_current = -1; } Iterator(ArVertex *vertex, short current, short last) { m_vertex = vertex; m_current = current; m_last = last; m_top = (short)m_vertex->m_nodes.size(); if (m_current == m_last) m_current = -1; else if (m_current == m_top) m_current = 0; } int& operator *() { return m_vertex->m_nodes[m_current]; } operator short() { return m_current; } virtual Iterator& operator ++(int) { if ((++m_current) - m_last == 0) // <- might jump, and then whoops m_current = -1; else if (m_current >= m_top) // <- although this just loops back m_current = 0; return *this; } }; friend class Iterator; Iterator fovealView(int bin) { Iterator i( this, loword(m_bins[(bin+30)%32]), hiword(m_bins[(bin+2)%32]) ); return i; } Iterator peripheralViewFemale(int bin) { // a fudge follows... // essentially, the iterator can't determine the difference between 6,6 and 6,7...5,6 bool found = false; for (int i = bin - 8; i <= bin + 8; i++) { if (loword(m_bins[(i+32)%32]) != hiword(m_bins[(i+32)%32])) found = true; } if (loword(m_bins[(bin+24)%32]) == hiword(m_bins[(bin+8)%32]) && found) return Iterator( this, 0, (short)m_nodes.size() ); else return Iterator( this, loword(m_bins[(bin+24)%32]), hiword(m_bins[(bin+8)%32]) ); } Iterator peripheralViewMale(int bin) { Iterator i( this, loword(m_bins[(bin+25)%32]), hiword(m_bins[(bin+7)%32]) ); return i; } public: enum { bin_count = 32 }; ArVertex( const pvecint& nodes = pvecint(), const pvecint& bins = pvecint() ) { m_nodes = nodes; m_bins = bins; } ArVertex( const ArVertex& v ) { m_nodes = v.m_nodes; m_bins = v.m_bins; } ArVertex& operator = (const ArVertex& v ) { if (&v != this) { m_nodes = v.m_nodes; m_bins = v.m_bins; } return *this; } void make( pvecint *bin_list ) { // If you're a clever bunny using the sparkGraph algorithm, the bins come presorted // ...this code is the same as the one below... tidy at some point! int bin_marker; loword(bin_marker) = 0; hiword(bin_marker) = 0; for (int i = 0; i < bin_count; i++) { for (size_t j = 0; j < bin_list[i].size(); j++) { m_nodes.push_back( bin_list[i][j] ); } hiword(bin_marker) += (short)bin_list[i].size(); m_bins.push_back( bin_marker ); loword(bin_marker) = hiword(bin_marker); bin_list[i].clear(); // <- NOTE: useful to clear this here } } void make( pqmap *bin_list ) { // Same as above int bin_marker; loword(bin_marker) = 0; hiword(bin_marker) = 0; for (int i = 0; i < bin_count; i++) { for (size_t j = 0; j < bin_list[i].size(); j++) { m_nodes.push_back( bin_list[i][j] ); } hiword(bin_marker) += (short)bin_list[i].size(); m_bins.push_back( bin_marker ); loword(bin_marker) = hiword(bin_marker); bin_list[i].clear(); // <- NOTE: useful to clear this here } } void clear() { m_nodes.clear(); m_bins.clear(); } // Old version compatibility: int& operator [] (int i) { return m_nodes[i]; } int size() const { return (int)m_nodes.size(); } // // All connected vertices pvecint& edgeset() { return m_nodes; } // Edges from a particular bin Iterator binset(int binnum) { return Iterator( this, binnum ); } int binsize(int bin) { // NB --- bin with all nodes will give erroneous zero! return (int)((m_nodes.size() + hiword(m_bins[bin]) - loword(m_bins[bin])) % m_nodes.size()); } // std::ifstream& read( std::ifstream& stream, std::streampos offset, int metagraph_version ) { if (metagraph_version >= mgraph440::VERSION_BINS_INTROD) { m_nodes.read(stream,offset); // read from offset... m_bins.read(stream); // <- and now read bins straight away } else { m_nodes.read(stream,offset); // no angular before version 30 } return stream; } std::ofstream& write(std::ofstream& stream ) { m_nodes.write(stream); m_bins.write(stream); return stream; } }; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD class ArVertexList { public: enum { NONE = 0x0000, BASIC = 0x0001, LOCAL = 0x0002, GLOBAL = 0x0004, POINTDEPTH = 0x0008, ANGULAR = 0x0010, METRIC = 0x0020, METRICPOINTDEPTH = 0x0040, ANGULARPOINTDEPTH = 0x0080 // for historical reasons (which was implemented when) these are in a strange order }; // which attributes have been calculated protected: // stored here for ease of use int m_metagraph_version; ::std::string m_filename; std::fstream *m_stream; AttrHeader m_attr_header; prefvec m_attributes; int m_cache_ref; ArVertex m_cache_data; // either cached... bool m_mem_loaded; prefvec m_mem_data; // ...or all in memory int m_which_attributes; public: ArVertexList( const ::std::string& filename = ::std::string() ) { m_metagraph_version = mgraph440::METAGRAPH_VERSION; m_filename = filename; m_stream = NULL; m_cache_ref = -1; m_mem_loaded = false; m_which_attributes = ArVertexList::NONE; } virtual ~ArVertexList() { close(); // <-- used to be remove: ensure MetaGraph removes if a temporary file } int size() const { return (int)m_attributes.size(); } ArVertex& operator [] (int i) { if (m_mem_loaded) { return m_mem_data[i]; } else if (i != m_cache_ref && m_stream) { // <- just make sure this doesn't crash m_cache_data.read( (std::ifstream&) *m_stream, m_attributes[i].pos, m_metagraph_version ); m_cache_ref = i; } return m_cache_data; } // long memsize() const { return (m_attributes.tail().pos ); // roughly right : excludes final node } // file must be open to do this void loadmem() { for (size_t i = 0; i < m_attributes.size(); i++) { m_mem_data.push_back( ArVertex() ); m_mem_data.tail().read( (std::ifstream&) *m_stream, m_attributes[i].pos, m_metagraph_version ); } m_mem_loaded = true; } void unloadmem() { m_mem_data.clear(); m_mem_loaded = false; } // void setFilename( const std::string& filename ) { m_filename = filename; } const std::string& getFilename() const { return m_filename; } // void setWhichAttributes(int which_attributes) { m_which_attributes |= which_attributes; } int getWhichAttributes() const { return m_which_attributes; } void clearAttributes() { m_attributes.clear(); m_which_attributes = ArVertexList::NONE; } // bool openwrite(int nodes); void openread(); void close(); void remove(); void add( int ref, const ArVertex& node ); void commit(); // when copying void commit( const Point2f& p, int far_node, float far_dist, float total_dist ); // when creating new node // bool read( std::ifstream& stream, int metagraph_version ); bool write(std::ostream &stream ); // const AttrBody& getAttributes(int i) const { return m_attributes[i]; } AttrBody& getAttributes(int i) { return m_attributes[i]; } }; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD /////////////////////////////////////////////////////////////////////////////// // depthmap: file based graph vertex lists: typedef ArVertex GraphVertex; typedef ArVertexList GraphVertexList; // standard: memory resident graph vertex lists: // typedef Vertex GraphVertex; // typedef pqmap GraphVertexList; // --- now sadly dead and buried /////////////////////////////////////////////////////////////////////////////// // Exception to be thrown if the thread is cancelled /* class thread_cancelled_exception { public: thread_cancelled_exception() {;} }; */ // Attribute map is for choosing attributes by description // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD struct AttrMap { enum { ATTR_INT, ATTR_FLOAT }; int ref; char *desc; int attr_set; int modules_req; int type; AttrMap(int r, char *d, int a, int m, int t) { ref = r; desc = d; attr_set = a; modules_req = m; type = t; } int usable() const {return true; } bool intval() const {return type == ATTR_INT;} bool floatval() const {return type == ATTR_FLOAT;} }; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD // This *must* match number of attributes listed below! const int NUM_DISPLAYABLE_ATTRIBUTES = 26; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD const AttrMap g_attr_display_map[] = { // 0 AttrMap(AttrHeader::NEIGHBOURHOOD_SIZE, (char *)"Neighbourhood Size", GraphVertexList::BASIC, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::MEAN_DEPTH, (char *)"Mean Depth", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::INTEGRATION_RA, (char *)"Relative Asymmetry", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::INTEGRATION_RRA, (char *)"Real Relative Asymmetry*", GraphVertexList::GLOBAL,0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::INTEGRATION_HILL, (char *)"Integration (Hillier/Hanson)*", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), // 5 AttrMap(AttrHeader::INTEGRATION_TEKL, (char *)"Integration (Teklenburg et al.)", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::GRAPH_SIZE, (char *)"Graph Size", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::ENTROPY, (char *)"Entropy", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::REL_ENTROPY, (char *)"Relativised Entropy", GraphVertexList::GLOBAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::CLUSTER, (char *)"Clustering Coefficient", GraphVertexList::LOCAL, 0, AttrMap::ATTR_FLOAT), // 10 AttrMap(AttrHeader::CONTROL_HILL, (char *)"Control (Hillier/Hanson)", GraphVertexList::LOCAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::CONTROL_TURN, (char *)"Control (Turner)", GraphVertexList::LOCAL, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::POINT_DEPTH, (char *)"Point Depth", GraphVertexList::POINTDEPTH, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::MEDIAN_ANGLE, (char *)"Mean Angle", GraphVertexList::ANGULAR, 0,AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::FAR_DIST, (char *)"Far Neighbour Distance", GraphVertexList::BASIC, 0, AttrMap::ATTR_FLOAT), // 15 AttrMap(AttrHeader::TOTAL_DIST, (char *)"Total Neighbour Distance", GraphVertexList::BASIC, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::AVG_DIST, (char *)"Average Neighbour Distance", GraphVertexList::BASIC, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::AGENT_COUNT, (char *)"Agent Trails", GraphVertexList::BASIC, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::AGENT_COLL_COUNT, (char *)"Agent Collisions", GraphVertexList::BASIC, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::METRIC_MEAN_DEPTH, (char *)"Metric Mean Depth", GraphVertexList::METRIC, 0, AttrMap::ATTR_FLOAT), // 20 AttrMap(AttrHeader::METRIC_MEAN_ANGLE, (char *)"Metric Mean Angle", GraphVertexList::METRIC, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::MEAN_PENN_DIST, (char *)"Mean Penn Distance", GraphVertexList::METRIC, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::DECENTRAL_INTEG, (char *)"Decentralised Integration", GraphVertexList::METRIC, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::METRIC_POINT_DEPTH, (char *)"Metric Point Depth", GraphVertexList::METRICPOINTDEPTH, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::METRIC_POINT_ANGLE, (char *)"Metric Point Angle", GraphVertexList::METRICPOINTDEPTH, 0, AttrMap::ATTR_FLOAT), // 25 AttrMap(AttrHeader::POINT_PENN_DIST, (char *)"Point Penn Distance", GraphVertexList::METRICPOINTDEPTH, 0, AttrMap::ATTR_FLOAT) }; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD // This *must* match number of attributes listed below! const int NUM_SUMMARISABLE_ATTRIBUTES = 23; // THIS PART OF THE FILE IS DEPRECATED // ATTRIBUTE TABLES ARE USED INSTEAD const AttrMap g_attr_summary_map[] = { // 0 AttrMap(AttrHeader::NEIGHBOURHOOD_SIZE, (char *)"Neighbourhood Size", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::FAR_DIST, (char *)"Far Neighbour Distance", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::TOTAL_DIST, (char *)"Total Neighbour Distance", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::GRAPH_SIZE, (char *)"Graph Size", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::KERNEL_SIZE, (char *)"Kernel Size", 1, 0, AttrMap::ATTR_INT), // 5 AttrMap(AttrHeader::CLIQUE_SIZE, (char *)"Clique Size", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::TOTAL_DEPTH, (char *)"Total Visual Depth", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::ENTROPY, (char *)"Entropy", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::REL_ENTROPY, (char *)"Relativised Entropy", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::CLUSTER, (char *)"Clustering Coefficient", 1, 0, AttrMap::ATTR_FLOAT), // 10 AttrMap(AttrHeader::POINT_DEPTH, (char *)"Point Depth", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::CONTROL_HILL, (char *)"Control (Hillier/Hanson)", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::CONTROL_TURN, (char *)"Control (Turner)", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::MEDIAN_ANGLE, (char *)"Mean Angle", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::AGENT_COUNT, (char *)"Agent Trails", 1, 0, AttrMap::ATTR_INT), // 15 AttrMap(AttrHeader::AGENT_COLL_COUNT, (char *)"Agent Collisions", 1, 0, AttrMap::ATTR_INT), AttrMap(AttrHeader::TOTAL_METRIC_DEPTH, (char *)"Total Metric Depth", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::TOTAL_METRIC_ANGLE, (char *)"Total Metric Angle", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::TOTAL_EUCLID_DIST, (char *)"Total Euclidean Distance", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::METRIC_GRAPH_SIZE, (char *)"Metric Graph Size", 1, 0, AttrMap::ATTR_INT), // 20 AttrMap(AttrHeader::METRIC_POINT_DEPTH, (char *)"Metric Point Depth", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::METRIC_POINT_ANGLE, (char *)"Metric Point Angle", 1, 0, AttrMap::ATTR_FLOAT), AttrMap(AttrHeader::POINT_EUCLID_DIST, (char *)"Euclidean Point Depth", 1, 0, AttrMap::ATTR_FLOAT) }; } ================================================ FILE: mgraph440/attributes.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include "mgraph440/stringutils.h" #include namespace mgraph440 { //////////////////////////////////////////////////////////////////////////////////// // helpers: local sorting routines int compareValuePair(const void *p1, const void *p2) { double v = (((ValuePair *)p1)->value - ((ValuePair *)p2)->value); return (v > 0.0 ? 1 : v < 0.0 ? -1 : 0); } //////////////////////////////////////////////////////////////////////////////////// AttributeTable::AttributeTable(const std::string& name) { // need memory initialised somewhere for these... g_ref_number_name = std::string("Ref Number"); g_ref_number_formula = std::string(); // m_name = name; // initially not showing any column: m_display_column = -2; // initially no selection: m_sel_count = 0; m_sel_value = 0.0; // // everything apart from the default layer is available for use: // Quick mod - TV m_available_layers = 0xffffffff << (32 + 0xfffffffe); // display the default layer only (everything): m_visible_layers = 0x1; m_layers.add(1,"Everything"); m_visible_size = 0; } int AttributeTable::insertColumn(const std::string& name) { size_t index = m_columns.searchindex(AttributeColumn(name)); if (index != paftl::npos) { m_columns[index].reset(); int phys_col = m_columns[index].m_physical_col; for (size_t i = 0; i < size(); i++) { at(i)[phys_col] = -1.0f; } } else { index = m_columns.add(AttributeColumn(name)); for (size_t i = 0; i < size(); i++) { at(i).push_back(-1.0f); } m_columns[index].m_physical_col = m_columns.size() - 1; } return index; } int AttributeTable::insertRow(int key) { int index = add(key,AttributeRow()); value(index).init(m_columns.size()); return index; } void AttributeTable::deselectAll() const { m_sel_count = 0; m_sel_value = 0.0; for (size_t i = 0; i < size(); i++) { value(i).m_selected = false; } } ////////////////////////////////////////////////////////////////////////////////////// void AttributeTable::setDisplayColumn(int col, bool override) const { if (col != m_display_column || override) { if (col != -2) { m_sel_value = 0.0; // reset selection total for new column // note, visible size is actually picked up by the display index m_visible_size = m_display_index.makeIndex(*this, col, true); if (col == -1) m_display_params = m_ref_display_params; else m_display_params = m_columns[col].getDisplayParams(); } m_display_column = col; } } ////////////////////////////////////////////////////////////////////////////////////// bool AttributeTable::read( std::ifstream& stream, int version ) { if (version >= VERSION_MAP_LAYERS) { m_layers.clear(); stream.read((char *)&m_available_layers,sizeof(int64)); stream.read((char *)&m_visible_layers,sizeof(int64)); int count; stream.read((char *)&count,sizeof(int)); for (int i = 0; i < count; i++) { int64 key; stream.read((char *)&key,sizeof(key)); m_layers.add(key,dXstring440::readString(stream)); } } int colcount; stream.read((char *)&colcount, sizeof(colcount)); for (int j = 0; j < colcount; j++) { m_columns.push_back(AttributeColumn()); m_columns.tail().read(stream, version); // this may need a bit of reordering, as the reader can chop up names: m_columns.sort(); } int rowcount, rowkey; stream.read((char *)&rowcount, sizeof(rowcount)); for (int i = 0; i < rowcount; i++) { stream.read((char *)&rowkey, sizeof(rowkey)); int index = add(rowkey,AttributeRow()); if (version >= VERSION_MAP_LAYERS) { stream.read((char *)&(value(index).m_layers),sizeof(int64)); } value(index).read(stream); } if (version >= VERSION_GATE_MAPS) { // ref column display params stream.read((char *)&m_display_params,sizeof(m_display_params)); } return true; } //////////////////////////////////////////////////////////////////////// void AttributeRow::init(size_t length) { if (m_data) { delete [] m_data; m_data = NULL; } while (length >= storage_size()) m_shift++; m_data = new float [storage_size()]; m_length = length; for (size_t i = 0; i < m_length; i++) { at(i) = -1.0; } } //////////////////////////////////////////////////////////////////////// void AttributeColumn::reset() { m_min = -1.0; m_max = 0.0; m_tot = 0.0; m_visible_min = -1.0; m_visible_max = 0.0; m_visible_tot = 0.0; } bool AttributeColumn::read( std::ifstream& stream, int version ) { m_updated = false; m_name = dXstring440::readString(stream); float min, max; stream.read((char *)&min, sizeof(min)); stream.read((char *)&max, sizeof(max)); m_min = min; m_max = max; if (version >= VERSION_ATTRIBUTES_TABLE) // m_tot has always been a double stream.read((char *)&m_tot, sizeof(m_tot)); else m_tot = 0.0; stream.read((char *)&m_physical_col, sizeof(m_physical_col)); stream.read((char *)&m_hidden, sizeof(m_hidden)); if (version >= VERSION_ATTRIBUTE_LOCKING) { stream.read((char *)&m_locked, sizeof(m_locked)); } else { if (m_name == "Connectivity" || m_name == "Connectivity (Degree)" || m_name == "Axial Line Ref" || m_name == "Segment Length" || m_name == "Line Length") { m_locked = true; } else { m_locked = false; } } if (version >= VERSION_STORE_COLOR) { stream.read((char*)&m_display_params,sizeof(m_display_params)); } if (version >= VERSION_STORE_FORMULA) { m_formula = dXstring440::readString(stream); } if (version >= VERSION_STORE_COLUMN_CREATOR && version < VERSION_FORGET_COLUMN_CREATOR) { std::string dummy_creator = dXstring440::readString(stream); } return true; } //////////////////////////////////////////////////////////////////////// AttributeIndex::AttributeIndex() { m_col = -1; m_data = NULL; } void AttributeIndex::clear() { m_col = -1; pvector::clear(); } int AttributeIndex::makeIndex(const AttributeTable& table, int col, bool setdisplayinfo) { // clear contents: clear(); // local copy since this will be reused a lot size_t rowcount = table.getRowCount(); // preallocate vector: while (rowcount >= storage_size()) m_shift++; m_data = new ValuePair[storage_size()]; m_length = rowcount; // m_col = col; // double min = -1.0f, max = -1.0f, vismin = -1.0f, vismax = -1.0f; double total = 0.0f, vistotal = 0.0; // note that, for safety, *everything* is always indexed, // viscount is simply a count of everything that is visible int viscount = 0; // n.b., attributes, axial lines and line refs must match size_t i; for (i = 0; i < rowcount; i++) { at(i).index = i; if (col != -1) { at(i).value = double(table.getValue(i,col)); if (at(i).value != -1) { if (min == -1.0f || at(i).value < min) { min = (double) at(i).value; } if (max == -1.0f || at(i).value > max) { max = (double) at(i).value; } total += at(i).value; if (table.isVisible(i)) { // note, this may be useful -- the visible count does not include nulls viscount++; if (vismin == -1.0f || at(i).value < vismin) { vismin = (double) at(i).value; } if (vismax == -1.0f || at(i).value > vismax) { vismax = (double) at(i).value; } vistotal += at(i).value; } } // note: qsort is slow when many values are the same -- so these values are perturbed // -> perturbation used to be random, but now sub sort by ref number // note: value needs to be double to work out in large tables // (note also, max may build up through table, causing some disturbance to order) at(i).value += (max * 1e-9 * double(i)) / table.getRowCount(); } else { if (table.isVisible(i)) { // note, viscount is used by scatterplots at least viscount++; // eventually there should be a colour override on the ref column as well as any other) vismax = i; if (vismin == -1) { vismin = i; } } at(i).value = double(table.getRowKey(i))/table.getMaxRowKey(); } } // mutable override: if (col != -1) { table.setColumnInfo(col,min,max,total,vismin,vismax,vistotal); } qsort(m_data,rowcount,sizeof(ValuePair),compareValuePair); for (i = 0; i < rowcount; i++) { // note: this is to ensure we have save settings for the table ranges where data has been overwritten: if (setdisplayinfo) { at(i).value = (col != -1) ? table.getNormValue(at(i).index,col) : double(table.getRowKey(at(i).index))/table.getMaxRowKey(); // be able to lookup index pos from row: ValuePair vp2; vp2.index = i; vp2.value = at(i).value; table.setDisplayInfo(at(i).index,vp2); } else { // don't normalise: you want the exact value for this row at(i).value = (col != -1) ? table.getValue(at(i).index,col) : double(table.getRowKey(at(i).index)); } } return viscount; } bool AttributeTable::write( std::ostream& stream, int version ) { stream.write((char *)&m_available_layers,sizeof(int64)); stream.write((char *)&m_visible_layers,sizeof(int64)); int count = m_layers.size(); stream.write((char *)&count,sizeof(int)); for (size_t i = 0; i < m_layers.size(); i++) { int64 key = m_layers.key(i); stream.write((char *)&key,sizeof(key)); dXstring440::writeString(stream ,m_layers.value(i)); } int colcount = m_columns.size(); stream.write((char *)&colcount, sizeof(colcount)); for (int j = 0; j < colcount; j++) { m_columns[j].write(stream,version); } int rowcount = size(), rowkey; stream.write((char *)&rowcount, sizeof(rowcount)); for (int i = 0; i < rowcount; i++) { rowkey = key(i); stream.write((char *)&rowkey, sizeof(rowkey)); stream.write((char *)&(value(i).m_layers),sizeof(int64)); value(i).write(stream); } // ref column display params stream.write((char *)&m_display_params,sizeof(m_display_params)); return true; } bool AttributeColumn::write( std::ostream& stream, int version ) { m_updated = false; dXstring440::writeString(stream, m_name); float min = (float) m_min; float max = (float) m_max; stream.write((char *)&min, sizeof(min)); stream.write((char *)&max, sizeof(max)); stream.write((char *)&m_tot, sizeof(m_tot)); stream.write((char *)&m_physical_col, sizeof(m_physical_col)); stream.write((char *)&m_hidden, sizeof(m_hidden)); stream.write((char *)&m_locked, sizeof(m_locked)); stream.write((char *)&m_display_params,sizeof(m_display_params)); dXstring440::writeString(stream, m_formula); return true; } } ================================================ FILE: mgraph440/attributes.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __ATTRIBUTES_H__ #define __ATTRIBUTES_H__ #include "mgraph440/attr.h" #include "mgraph440/displayparams.h" #include "mgraph440/pafcolor.h" #include // for scripting object #include namespace mgraph440 { // yet another way to do attributes, but one that is easily expandable // it's slow to look for a column, since you have to find the column // by name, but other than that it's fairly easy // helpers... local sorting routines //////////////////////////////////////////////////////////////////////////////// struct ValuePair { double value; // needs to be double for sorting in index at higher resolution than the stored data int index; ValuePair(int i = -1, double v = -1.0) { index = i; value = v; } friend bool operator < (const ValuePair& vp1, const ValuePair& vp2); friend bool operator > (const ValuePair& vp1, const ValuePair& vp2); friend bool operator == (const ValuePair& vp1, const ValuePair& vp2); }; inline bool operator < (const ValuePair& vp1, const ValuePair& vp2) { return (vp1.value < vp2.value); } inline bool operator > (const ValuePair& vp1, const ValuePair& vp2) { return (vp1.value > vp2.value); } inline bool operator == (const ValuePair& vp1, const ValuePair& vp2) { return (vp1.value == vp2.value); } int compareValuePair(const void *p1, const void *p2); //////////////////////////////////////////////////////////////////////////////// // These aren't really to do with attributes per se, but helpful to have // them around ValuePair definition // note! unsorted struct IntPair { int a; int b; IntPair(int x = -1, int y = -1) { a = x; b = y; } // inlined at end of file friend bool operator == (const IntPair& x, const IntPair& y); friend bool operator != (const IntPair& x, const IntPair& y); friend bool operator < (const IntPair& x, const IntPair& y); friend bool operator > (const IntPair& x, const IntPair& y); }; // note! sorted struct OrderedIntPair { int a; int b; OrderedIntPair(int x = -1, int y = -1) { a = (int) x < y ? x : y; b = (int) x < y ? y : x; } // inlined at end of file friend bool operator == (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator != (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator < (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator > (const OrderedIntPair& x, const OrderedIntPair& y); }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class AttributeRow : public pvector { friend class AttributeTable; protected: mutable bool m_selected; mutable ValuePair m_display_info; // this is for salascripting to allow "checking" a searched node: mutable SalaObj m_sala_mark; // this is for recording layers (up to 64 are possible) int64 m_layers; public: AttributeRow() { m_selected = false; m_layers = 1; } void init(size_t length); // // For SalaScript void setMark(SalaObj& mark) { m_sala_mark = mark; } const SalaObj& getMark() const { return m_sala_mark; } }; // note pvector: this is stored in order, reorder by qsort class AttributeIndex : public pvector { friend class AttributeTable; protected: int m_col; public: AttributeIndex(); void clear(); int makeIndex(const AttributeTable& table, int col, bool setdisplayinfo); }; class AttributeColumn { public: std::string m_name; bool m_updated; // <- this flag is not saved, and indicates new data in the column (set on insert column etc) int m_physical_col; mutable double m_min; mutable double m_max; mutable double m_tot; mutable double m_visible_min; mutable double m_visible_max; mutable double m_visible_tot; bool m_hidden; bool m_locked; // display parameters DisplayParams m_display_params; // retain formula used to create column std::string m_formula; AttributeColumn(const std::string& name = std::string(), int physical_col = -1) { m_name = name; m_min = -1.0f; m_max = 0.0f; m_tot = 0.0; m_visible_min = -1.0f; m_visible_max = 0.0f; m_visible_tot = 0.0; m_physical_col = physical_col; m_hidden = false; m_locked = false; m_updated = false; } float makeNormValue(float value) const { return (m_min == m_max) ? 0.5f : (value == -1.0f) ? -1.0f : (float)((value - m_min) / (m_max - m_min)); } void setValue(float value) { m_updated = true; m_tot += value; if (m_min == -1.0f || value < m_min) m_min = value; if (value > m_max) m_max = value; } void changeValue(float oldval, float newval) { m_updated = true; if (oldval != -1.0f) m_tot -= oldval; if (newval != -1.0f) setValue(newval); } void setInfo(double min, double max, double tot, double vismin, double vismax, double vistot) const { m_min = min; m_max = max; m_tot = tot; m_visible_min = vismin; m_visible_max = vismax; m_visible_tot = vistot; } const DisplayParams& getDisplayParams() const { return m_display_params; } void reset(); void setLock(bool lock = true) { m_locked = lock; } bool read( std::ifstream& stream, int version ); bool write(std::ostream &stream, int version ); friend bool operator == (const AttributeColumn& a, const AttributeColumn& b); friend bool operator < (const AttributeColumn& a, const AttributeColumn& b); friend bool operator > (const AttributeColumn& a, const AttributeColumn& b); }; inline bool operator == (const AttributeColumn& a, const AttributeColumn& b) { return a.m_name == b.m_name; } inline bool operator < (const AttributeColumn& a, const AttributeColumn& b) { return a.m_name < b.m_name; } inline bool operator > (const AttributeColumn& a, const AttributeColumn& b) { return a.m_name > b.m_name; } class AttributeTable : protected pqmap { public: std::string m_name; pqvector m_columns; mutable int m_sel_count; mutable double m_sel_value; // pqmap m_data; // // display parameters for the reference id column DisplayParams m_ref_display_params; int64 m_available_layers; pqmap m_layers; mutable int64 m_visible_layers; mutable int m_visible_size; mutable int m_display_column; mutable DisplayParams m_display_params; // Display: mutable AttributeIndex m_display_index; std::string g_ref_number_name; // = std::string("Ref Number"); std::string g_ref_number_formula; // = std::string(""); AttributeTable(const std::string& name = std::string()); int insertColumn(const std::string& name = std::string()); int insertRow(int key); int getColumnIndex(const std::string& name) const { size_t index = m_columns.searchindex(name); return (index == paftl::npos) ? -1 : int(index);} // note use -1 rather than paftl::npos for return value int getOrInsertColumnIndex(const std::string& name) { size_t col = m_columns.searchindex(name); if (col == paftl::npos) return insertColumn(name); else return (int) col; } int getOrInsertLockedColumnIndex(const std::string& name) { size_t col = m_columns.searchindex(name); if (col == paftl::npos) return insertLockedColumn(name); else return (int) col; } int getRowKey(int index) const { return key(index); } int getRowid(const int key) const { size_t i = searchindex(key); return (i == paftl::npos) ? -1 : int(i);} // note use -1 rather than paftl::npos for return value int getRowCount() const { return (int) size(); } int getMaxRowKey() const { return key(size()-1); } // this version uses known row and col indices float getValue(int row, int col) const { return col != -1 ? value(row).at(m_columns[col].m_physical_col) : key(row); } // this version is meant to use row key and col name float getValue(int row, const std::string& name) const { int col = getColumnIndex(name); return col != -1 ? value(row).at(m_columns[col].m_physical_col) : key(row); } float getNormValue(int row, int col) const { return col != -1 ? m_columns[col].makeNormValue(value(row).at(m_columns[col].m_physical_col)) : (float) (double(getRowKey(row))/double(getRowKey(int(size()-1)))); } void setValue(int row, int col, float val) { value(row).at(m_columns[col].m_physical_col) = val; m_columns[col].setValue(val); } void setValue(int row, const std::string& name, float val) { int col = getColumnIndex(name); if (col != -1) setValue(row,col,val); } void changeValue(int row, int col, float val) { float& theval = value(row).at(m_columns[col].m_physical_col); m_columns[col].changeValue(theval,val); theval = val; } void changeValue(int row, const std::string& name, float val) { int col = getColumnIndex(name); if (col != -1) changeValue(row,col,val); } void changeSelValues(int col, float val) { for (size_t i = 0; i < size(); i++) { if (value(i).m_selected) changeValue((int)i,col,val);} } void incrValue(int row, int col, float amount = 1.0f) { float& v = value(row).at(m_columns[col].m_physical_col); v = (v == -1.0f) ? amount : v+amount ; m_columns[col].changeValue(v-amount,v); } void incrValue(int row, const std::string& name, float amount = 1.0f) { int col = getColumnIndex(name); if (col != -1) incrValue(row,col,amount); } void setColumnInfo(int col, double min, double max, double tot, double vismin, double vismax, double vistot) const { m_columns[col].setInfo(min,max,tot,vismin,vismax,vistot); } void setColumnLock(int col, bool lock = true) { m_columns[col].setLock(lock); } int insertLockedColumn(const std::string& name = std::string()) { int col = insertColumn(name); setColumnLock(col); return col; } // For SalaScript: void setMark(int row, SalaObj& mark) { value(row).setMark(mark); } const SalaObj& getMark(int row) const { return value(row).getMark(); } void deselectAll() const; void addSelValue(double value) const { m_sel_value += (value != -1.0f) ? value : 0.0; } bool isSelected(int index) const { return value(index).m_selected; } bool isVisible(int row) const { return (m_visible_layers & (at(row).m_layers)) != 0; } void setDisplayColumn(int col, bool override = false) const; int getDisplayColumn() const { return m_display_column; } void setDisplayInfo(int row, ValuePair vp) const { at(row).m_display_info = vp; if (at(row).m_selected) addSelValue((double)vp.value); } const DisplayParams& getDisplayParams() const { return m_display_params; } void clear() // <- totally destroy, not just clear values { m_columns.clear(); pqmap::clear(); } bool read( std::ifstream& stream, int version ); bool write(std::ostream &stream, int version ); }; } #endif ================================================ FILE: mgraph440/axialmap.cpp ================================================ #include "mgraph440/mgraph_consts.h" #include "mgraph440/axialmap.h" #include "mgraph440/stringutils.h" namespace mgraph440 { bool ShapeGraph::read( std::ifstream& stream, int version ) { m_attributes.clear(); m_connectors.clear(); m_selection = false; m_map_type = ShapeMap::EMPTYMAP; // the old version used SpacePixel as base class // actually easiest to read and translate, rather than try to use new method if (version < VERSION_AXIAL_SHAPES) { readold(stream, version); } else { bool segmentmap = false; if (version < VERSION_MAP_TYPES) { // axial specific reads -- segment map flag and keyvertices (part of all line map functionality) // note, now stored in the "map_type", and read / written with shape map char segmentmapc = stream.get(); if (segmentmapc == '1') { segmentmap = true; } } // note that keyvertexcount and keyvertices are different things! (length keyvertices not the same as keyvertexcount!) stream.read((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); int size; stream.read((char *)&size,sizeof(size)); for (int i = 0; i < size; i++) { m_keyvertices.push_back(pvecint()); m_keyvertices[i].read(stream); } // now base class read: ShapeMap::read(stream,version); // // override shapemap map type designation if necessary: if (version < VERSION_MAP_TYPES) { if (segmentmap) { m_map_type = ShapeMap::SEGMENTMAP; } else { m_map_type = ShapeMap::AXIALMAP; } } } return true; } bool ShapeGraph::readold( std::ifstream& stream, int version ) { // read in from old base class SpacePixel linemap; linemap.read(stream, version); const pmap& lines = linemap.getAllLines(); m_name = linemap.getName(); // now copy to new base class: init(lines.size(),linemap.getRegion()); for (size_t i = 0; i < lines.size(); i++) { makeLineShape(lines[i].line); } // n.b., we now have to reclear attributes! m_attributes.clear(); // continue old read: int pushmap = -1; if (version >= VERSION_SEGMENT_MAPS) { char segmentmapc = stream.get(); if (segmentmapc == '1') { m_map_type = ShapeMap::SEGMENTMAP; } else { m_map_type = ShapeMap::AXIALMAP; } } if (version >= VERSION_GATE_MAPS) { char gatemapc = stream.get(); if (gatemapc == '1') { m_map_type = ShapeMap::DATAMAP; } stream.read((char *)&pushmap,sizeof(pushmap)); } int displayed_attribute; // n.b., temp variable necessary to force recalc below stream.read((char *)&displayed_attribute,sizeof(displayed_attribute)); m_attributes.read(stream,version); int size; stream.read((char *)&size,sizeof(size)); for (int j = 0; j < size; j++) { m_keyvertices.push_back(pvecint()); // <- these were stored with the connector int key; stream.read((char *)&key,sizeof(key)); // <- key deprecated m_connectors.push_back(Connector()); m_connectors[j].read(stream,version,&(m_keyvertices[j])); } stream.read((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); if (version >= VERSION_AXIAL_LINKS) { m_links.read(stream); m_unlinks.read(stream); } // some miscellaneous extra data for mapinfo files if (m_mapinfodata) { delete m_mapinfodata; m_mapinfodata = NULL; } if (version >= VERSION_MAPINFO_DATA) { char x = stream.get(); if (x == 'm') { m_mapinfodata = new MapInfoData; m_mapinfodata->read(stream,version); } } // now, as soon as loaded, must recalculate our screen display: // note m_displayed_attribute should be -2 in order to force recalc... m_displayed_attribute = -2; setDisplayedAttribute(displayed_attribute); return true; } bool ShapeGraphs::read( std::ifstream& stream, int version ) { // base class read if (version >= VERSION_AXIAL_SHAPES) { ShapeMaps::read(stream,version); } else { readold(stream,version); } // these are additional essentially for all line axial maps // should probably be kept *with* the all line axial map... m_poly_connections.clear(); m_poly_connections.read(stream); m_radial_lines.clear(); m_radial_lines.read(stream); // this is an index to look up the all line map, used by UI to determine if can make fewest line map // note: it is not saved for historical reasons // will get confused by more than one all line map m_all_line_map = getMapRef("All-Line Map"); if (m_all_line_map == -1) { // used to be called All Line Map m_all_line_map = getMapRef("All Line Map"); } if (m_all_line_map != -1) { at(m_all_line_map).m_map_type = ShapeMap::ALLLINEMAP; } // VERSION_AXIAL_REGION_FIX -- this fix is now deprecated // some awful things could have gone wrong in the past, but the shapemap read should fix automatically return true; } // for backward compatibility only: bool ShapeGraphs::readold( std::ifstream& stream, int version ) { // this read is based on SpacePixelGroup::read(stream, version); dXstring440::readString(stream); QtRegion dummyregion; stream.read( (char *) &dummyregion, sizeof(dummyregion) ); int count; stream.read( (char *) &count, sizeof(count) ); for (int i = 0; i < count; i++) { push_back(ShapeGraph()); tail().read(stream,version); } stream.read((char *)&m_displayed_map,sizeof(m_displayed_map)); return true; } bool ShapeGraphs::write(std::ostream &stream, int version, bool displayedmaponly ) { // base class write ShapeMaps::write(stream, version, displayedmaponly); m_poly_connections.write(stream); m_radial_lines.write(stream); return true; } bool ShapeGraph::write( std::ostream& stream, int version ) { // note keyvertexcount and keyvertices are different things! (length keyvertices not the same as keyvertexcount!) stream.write((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); int size = m_keyvertices.size(); stream.write((char *)&size,sizeof(size)); for (size_t i = 0; i < m_keyvertices.size(); i++) { m_keyvertices[i].write(stream); } // now simply run base class write: ShapeMap::write(stream,version); return true; } AxialPolygons::AxialPolygons() { m_pixel_polys = NULL; } AxialPolygons::~AxialPolygons() { if (m_pixel_polys) { for (int i = 0; i < m_cols; i++) { delete [] m_pixel_polys[i]; } delete [] m_pixel_polys; m_pixel_polys = NULL; } } ShapeGraph::ShapeGraph(const std::string& name, int type) : ShapeMap(name,type) { m_keyvertexcount = 0; m_hasgraph = true; } } ================================================ FILE: mgraph440/axialmap.h ================================================ #pragma once #include "mgraph440/spacepix.h" #include "mgraph440/shapemap.h" #include "mgraph440/connector.h" namespace mgraph440 { struct AxialVertexKey { int m_ref_key; short m_ref_a; short m_ref_b; AxialVertexKey(int ref = -1, short a = -1, short b = -1) { m_ref_key = ref; m_ref_a = a; m_ref_b = b; } friend bool operator == (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator != (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator > (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator < (const AxialVertexKey& a, const AxialVertexKey& b); }; inline bool operator == (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key == b.m_ref_key && a.m_ref_a == b.m_ref_a && a.m_ref_b == b.m_ref_b); } inline bool operator != (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key != b.m_ref_key || a.m_ref_a != b.m_ref_a || a.m_ref_b != b.m_ref_b); } inline bool operator > (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key > b.m_ref_key || (a.m_ref_key == b.m_ref_key && (a.m_ref_a > b.m_ref_a || (a.m_ref_a == b.m_ref_a && a.m_ref_b > b.m_ref_b)))); } inline bool operator < (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key < b.m_ref_key || (a.m_ref_key == b.m_ref_key && (a.m_ref_a < b.m_ref_a || (a.m_ref_a == b.m_ref_a && a.m_ref_b < b.m_ref_b)))); } const AxialVertexKey NoVertex(-1,-1,-1); struct RadialKey { AxialVertexKey vertex; float ang; bool segend; // padding the remaining three bytes behind the bool - don't use int : 24 as this will grab the next 4 byte block char pad1 : 8; short pad2 : 16; RadialKey(const AxialVertexKey& v = NoVertex, float a = -1.0f, bool se = false) : pad1(0), pad2(0) { vertex = v; ang = a; segend = se; } RadialKey(const RadialKey& rk) : pad1(0), pad2(0) { vertex = rk.vertex; ang = rk.ang; segend = rk.segend; } friend bool operator < (const RadialKey& a, const RadialKey& b); friend bool operator > (const RadialKey& a, const RadialKey& b); friend bool operator == (const RadialKey& a, const RadialKey& b); }; inline bool operator < (const RadialKey& a, const RadialKey& b) { return a.vertex < b.vertex || (a.vertex == b.vertex && (a.ang < b.ang || (a.ang == b.ang && a.segend < b.segend))); } inline bool operator > (const RadialKey& a, const RadialKey& b) { return a.vertex > b.vertex || (a.vertex == b.vertex && (a.ang > b.ang || (a.ang == b.ang && a.segend > b.segend))); } inline bool operator == (const RadialKey& a, const RadialKey& b) { return a.vertex == b.vertex && a.ang == b.ang && a.segend == b.segend; } struct RadialLine : public RadialKey { Point2f openspace; Point2f keyvertex; Point2f nextvertex; RadialLine(const RadialKey& rk = RadialKey()) : RadialKey(rk) {;} RadialLine(const AxialVertexKey& v, bool se, const Point2f& o, const Point2f& k, const Point2f& n) { vertex = v; ang = (float) angle(o,k,n); segend = se; openspace = o; keyvertex = k; nextvertex = n; } RadialLine(const RadialLine& rl) : RadialKey(rl) { openspace = rl.openspace; keyvertex = rl.keyvertex; nextvertex = rl.nextvertex; } bool cuts(const Line& l) const; }; struct PolyConnector { Line line; RadialKey key; PolyConnector(const Line& l = Line(), const RadialKey& k = RadialKey()) { line = l; key = k; } }; struct AxialVertex : public AxialVertexKey { Point2f m_point; Point2f m_openspace; Point2f m_a; Point2f m_b; bool m_clockwise; bool m_convex; bool m_initialised; bool m_axial; AxialVertex(const AxialVertexKey& vertex_key = NoVertex, const Point2f& point = Point2f(), const Point2f& openspace = Point2f()) : AxialVertexKey(vertex_key) { m_point = point; m_openspace = openspace; m_initialised = false; m_axial = false; } }; class AxialPolygons : public SpacePixel { friend class ShapeGraphs; public: pqmap> m_vertex_possibles; pvecint m_vertex_polys; pvecint **m_pixel_polys; pqvector m_handled_list; AxialPolygons(); virtual ~AxialPolygons(); void clear(); void init(prefvec& lines, const QtRegion& region); void makeVertexPossibles(const prefvec& lines, const prefvec& connectionset); void makePixelPolys(); // AxialVertex makeVertex(const AxialVertexKey& vertexkey, const Point2f& openspace); // find a polygon corner visible from seed: AxialVertexKey seedVertex(const Point2f& seed); // make axial lines from corner vertices, visible from openspace void makeAxialLines(pqvector& openvertices, prefvec& lines, prefvec& keyvertices, prefvec& poly_connections, pqvector& radial_lines); // extra: make all the polygons possible from the set of m_vertex_possibles void makePolygons(prefvec>& polygons); }; class ShapeGraph : public ShapeMap { friend class ShapeGraphs; friend class AxialMinimiser; friend class MapInfoData; public: ShapeGraph(const std::string& name = "", int type = ShapeMap::AXIALMAP); virtual ~ShapeGraph() {;} prefvec m_keyvertices; // but still need to return keyvertices here int m_keyvertexcount; bool outputMifPolygons(std::ostream& miffile, std::ostream& midfile) const; void outputNet(std::ostream& netfile) const; virtual bool read( std::ifstream& stream, int version ); bool readold( std::ifstream& stream, int version ); virtual bool write(std::ostream &stream, int version ); }; class ShapeGraphs : public ShapeMaps { public: // helpful to know this for creating fewest line maps, although has to be reread at input int m_all_line_map; // For all line map work: AxialPolygons m_polygons; prefvec m_poly_connections; pqvector m_radial_lines; ShapeGraphs() { m_all_line_map = -1; } virtual ~ShapeGraphs() {;} bool read( std::ifstream& stream, int version ); bool readold( std::ifstream& stream, int version ); bool write( std::ostream& stream, int version, bool displayedmaponly = false ); }; } ================================================ FILE: mgraph440/bspnode.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010 University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "mgraph440/paftl.h" #include "mgraph440/p2dpoly.h" // Binary Space Partition namespace mgraph440 { struct BSPNode { public: enum { BSPLEFT, BSPRIGHT }; BSPNode *left; BSPNode *right; BSPNode *parent; Line line; int m_tag; int m_count; // public: BSPNode() { left = NULL; right = NULL; parent = NULL; m_count = 0; m_tag = -1; } virtual ~BSPNode() { if (left) delete left; left = NULL; if (right) delete right; right = NULL; } // bool isLeaf() { return left == NULL && right == NULL; } void make(Communicator *communicator, time_t atime, const prefvec& lines, BSPNode *par); int classify(const Point2f& p); const Line& getLine() const { return line; } int getTag() const { return m_tag; } }; } ================================================ FILE: mgraph440/comm.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __COMM_H__ #define __COMM_H__ //#include #include #include #include #include #include #ifdef _WIN32 // Quick mod - TV #pragma warning (disable: 4244) #pragma warning (disable: 4100) #else #endif namespace mgraph440 { const char *const g_default_file_set = "File set"; struct FilePath { std::string m_path; std::string m_name; std::string m_ext; FilePath(const std::string& pathname) { size_t dot = pathname.find_last_of('.'); #ifdef _WIN32 size_t slash = pathname.find_last_of('\\'); // WIN32 #else size_t slash = pathname.find_last_of('/'); // Other #endif if (slash != std::string::npos) { m_path = pathname.substr(0,slash+1); } if (dot != std::string::npos) { m_name = pathname.substr(slash+1,dot-slash-1); m_ext = pathname.substr(dot+1); } else { m_name = pathname.substr(slash+1); } } }; class Communicator { public: class CancelledException // throw from your class { public: CancelledException() {;} }; enum { NUM_STEPS, CURRENT_STEP, NUM_RECORDS, CURRENT_RECORD }; protected: bool m_cancelled; bool m_delete_flag; // nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11) std::string m_infilename; std::ifstream *m_infile; std::ifstream *m_infile2; // <- MapInfo MIF files come in two parts std::ofstream *m_outfile; // nb. converted to Win32 UTF-16 Unicode path (AT 31.01.11) Linux, MacOS use UTF-8 (AT 29.04.11) std::vector m_fileset; // <- sometimes you want to load a whole set of files public: Communicator() { m_infile = NULL; m_infile2 = NULL; m_outfile = NULL; m_cancelled = false; m_delete_flag = false; } // bool GetDeleteFlag() // used by ICommunicator and IComm together { return m_delete_flag; } // virtual ~Communicator() { if (m_infile) delete m_infile; m_infile = NULL; if (m_infile2) delete m_infile2; m_infile2 = NULL; if (m_outfile) delete m_outfile; m_outfile = NULL; } // void SetInfile( const char* filename ) { m_infile = new std::ifstream( filename ); FilePath fp(filename); m_infilename = fp.m_name; } void SetInfile2( const char* filename ) { m_infile2 = new std::ifstream( filename ); } std::string GetInfileName() { return m_fileset.size() ? std::string(g_default_file_set) : m_infilename; } std::string GetMBInfileName() { std::string ret; if (m_fileset.size()) { ret = "File set"; } else { ret = std::string(m_infilename.c_str()); } return ret; } size_t GetInfileSize() { if (m_infile) { m_infile->seekg(0, std::ios::beg); size_t begin_pos = m_infile->tellg(); m_infile->seekg(0, std::ios::end); size_t end_pos = m_infile->tellg(); m_infile->seekg(0, std::ios::beg); return size_t(end_pos - begin_pos); } return 0; } void SetOutfile( const char *filename ) { m_outfile = new std::ofstream( filename ); } // bool IsCancelled() const { return m_cancelled; } void Cancel() { m_cancelled = true; } // operator std::ofstream& () { return *m_outfile; } operator std::ifstream& () { return *m_infile; } std::ifstream& GetInfile2() { return *m_infile2; } // const std::vector& GetFileSet() const { return m_fileset; } // virtual void CommPostMessage(int m, int x, int y = 0) const = 0; // Override for specific operating system }; // this is a simple version of the Communicator which can be used for // an interface class ICommunicator : public Communicator { friend class IComm; // IComm is found in idepthmap.h // protected: mutable int num_steps; mutable int num_records; mutable int step; mutable int record; // public: ICommunicator() { m_delete_flag = true; } // note: an ICommunicator lets IComm know that it should delete it virtual ~ICommunicator() {;} virtual void CommPostMessage(int m, int x) const; }; inline void ICommunicator::CommPostMessage(int m, int x) const { switch (m) { case Communicator::NUM_STEPS: num_steps = x; break; case Communicator::CURRENT_STEP: step = x; break; case Communicator::NUM_RECORDS: num_records = x; break; case Communicator::CURRENT_RECORD: record = x; break; default: break; } } } #endif ================================================ FILE: mgraph440/connector.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include "mgraph440/mgraph_consts.h" #include #include #include #include namespace mgraph440 { bool Connector::read( ::std::ifstream& stream, int version, pvecint *keyvertices ) { m_connections.clear(); m_forward_segconns.clear(); m_back_segconns.clear(); // n.b., must set displayed attribute as soon as loaded... m_connections.read(stream); // keyvertices now stored with axial map itself, but need this read for backward compatibility if (version < VERSION_AXIAL_SHAPES && keyvertices != NULL) { keyvertices->read(stream); } if (version >= VERSION_SEGMENT_MAPS) { stream.read((char *)&m_segment_axialref, sizeof(m_segment_axialref)); m_forward_segconns.read(stream); } if (version >= VERSION_SEGMENT_MAPS_FIX) { m_back_segconns.read(stream); } return true; } bool Connector::write( ::std::ostream& stream ) { // n.b., must set displayed attribute as soon as loaded... m_connections.write(stream); // m_keyvertices.write(stream); stream.write((char *)&m_segment_axialref, sizeof(m_segment_axialref)); m_forward_segconns.write(stream); m_back_segconns.write(stream); return true; } ///////////////////////////////////////////////////////////////////////////////// // Cursor extras int Connector::count(int mode) const { int c = 0; switch (mode) { case CONN_ALL: c = m_connections.size(); break; case SEG_CONN_ALL: c = m_back_segconns.size() + m_forward_segconns.size(); break; case SEG_CONN_FW: c = m_forward_segconns.size(); break; case SEG_CONN_BK: c = m_back_segconns.size(); break; } return c; } int Connector::cursor(int mode) const { int cur = -1; if (m_cursor != -1) { switch (mode) { case CONN_ALL: if (m_cursor < (int)m_connections.size()) { cur = m_connections[m_cursor]; } break; case SEG_CONN_ALL: if (m_cursor < (int)m_back_segconns.size()) { cur = m_back_segconns.key(m_cursor).ref; } else if (m_cursor - m_back_segconns.size() < m_forward_segconns.size()) { cur = m_forward_segconns.key(m_cursor - m_back_segconns.size()).ref; } break; case SEG_CONN_FW: if (m_cursor < (int)m_forward_segconns.size()) { cur = m_forward_segconns.key(m_cursor).ref; } break; case SEG_CONN_BK: if (m_cursor < (int)m_back_segconns.size()) { cur = m_back_segconns.key(m_cursor).ref; } break; } } if (cur == -1) { m_cursor = -1; } return cur; } int Connector::direction(int mode) const { int direction = 0; if (m_cursor != -1) { switch (mode) { case SEG_CONN_ALL: if (m_cursor < (int)m_back_segconns.size()) { direction = m_back_segconns.key(m_cursor).dir; } else if (m_cursor - m_back_segconns.size() < m_forward_segconns.size()) { direction = m_forward_segconns.key(m_cursor - m_back_segconns.size()).dir; } break; case SEG_CONN_FW: direction = m_forward_segconns.key(m_cursor).dir; break; case SEG_CONN_BK: direction = m_back_segconns.key(m_cursor).dir; break; } } return direction; } float Connector::weight(int mode) const { float weight = 0.0f; if (m_cursor != -1) { switch (mode) { case SEG_CONN_ALL: if (m_cursor < (int)m_back_segconns.size()) { weight = m_back_segconns.value(m_cursor); } else if (m_cursor - m_back_segconns.size() < m_forward_segconns.size()) { weight = m_forward_segconns.value(m_cursor - m_back_segconns.size()); } break; case SEG_CONN_FW: weight = m_forward_segconns.value(m_cursor); break; case SEG_CONN_BK: weight = m_back_segconns.value(m_cursor); break; } } return weight; } } ================================================ FILE: mgraph440/connector.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __CONNECTOR_H__ #define __CONNECTOR_H__ #include "mgraph440/paftl.h" ///////////////////////////////////////////////////////////////////////////// // Additional for segment analysis namespace mgraph440 { struct SegmentRef { char dir; int ref; SegmentRef(char d = 0, int r = -1) { dir = d; ref = r; } friend bool operator < (SegmentRef a, SegmentRef b); friend bool operator > (SegmentRef a, SegmentRef b); friend bool operator == (SegmentRef a, SegmentRef b); friend bool operator != (SegmentRef a, SegmentRef b); }; // note, the dir is only a direction indicator, the ref should always be unique inline bool operator < (SegmentRef a, SegmentRef b) { return a.ref < b.ref; } inline bool operator > (SegmentRef a, SegmentRef b) { return a.ref > b.ref; } inline bool operator == (SegmentRef a, SegmentRef b) { return a.ref == b.ref; } inline bool operator != (SegmentRef a, SegmentRef b) { return a.ref != b.ref; } // used during angular analysis struct SegmentData : public SegmentRef { SegmentRef previous; int segdepth; float metricdepth; unsigned int coverage; SegmentData(char d = 0, int r = -1, SegmentRef p = SegmentRef(), int sd = 0, float md = 0.0f, unsigned int cv = 0xffffffff) { dir = d; ref = r; previous = p; segdepth = sd; metricdepth = md; coverage = cv; } SegmentData(SegmentRef ref, SegmentRef p = SegmentRef(), int sd = 0, float md = 0.0f, unsigned int cv = 0xffffffff) : SegmentRef(ref) { previous = p; segdepth = sd; metricdepth = md; coverage = cv; } friend bool operator < (SegmentData a, SegmentData b); friend bool operator > (SegmentData a, SegmentData b); friend bool operator == (SegmentData a, SegmentData b); friend bool operator != (SegmentData a, SegmentData b); }; // note, these are stored in reverse metric depth order (i.e., metric shorter paths are taken off the end of the list first) inline bool operator < (SegmentData a, SegmentData b) { return a.metricdepth > b.metricdepth; } inline bool operator > (SegmentData a, SegmentData b) { return a.metricdepth < b.metricdepth; } inline bool operator == (SegmentData a, SegmentData b) { return a.metricdepth == b.metricdepth; } inline bool operator != (SegmentData a, SegmentData b) { return a.metricdepth != b.metricdepth; } /////////////////////////////////////////////////////////////////////////// // Main connector class for segments, convex spaces or axial lines struct Connector { // cursor included purely to make this compatible with DLL functionality mutable int m_cursor; // if this is a segment, this is the key for the axial line: int m_segment_axialref; // use one or other of these pvecint m_connections; // pmap m_back_segconns; pmap m_forward_segconns; // Connector(int axialref = -1) { m_segment_axialref = axialref; m_cursor = -1; } void clear() { m_connections.clear(); m_back_segconns.clear(); m_forward_segconns.clear(); } // bool read( ::std::ifstream& stream, int version, pvecint *keyvertices = NULL ); bool write(std::ostream &stream ); // // Cursor extras enum { CONN_ALL, SEG_CONN_ALL, SEG_CONN_FW, SEG_CONN_BK }; int count(int mode = CONN_ALL) const; int cursor(int mode = CONN_ALL) const; int direction(int mode = SEG_CONN_ALL) const; float weight(int mode = SEG_CONN_ALL) const; void first() const { m_cursor = 0; } void next() const { m_cursor++; } }; } #endif ================================================ FILE: mgraph440/containerutils.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2017, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once namespace depthmapX440 { template void findAndErase(std::vector &vec, T element) { auto it = std::find(vec.begin(), vec.end(), element); if(it != vec.end()) vec.erase(it); } template void addIfNotExists(std::vector &vec, T element) { auto it = std::find(vec.begin(), vec.end(), element); if(it == vec.end()) vec.push_back(element); } } ================================================ FILE: mgraph440/datalayer.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // THIS CODE IS DEPRECATED DO NOT USE: USE SHAPE MAPS INSTEAD 21.08.05 // INCLUDED ONLY TO ALLOW COMPATIBILITY WITH OLD VERSIONS // DataLayer.cpp: implementation of the DataLayer class. // ////////////////////////////////////////////////////////////////////// #include #include #include #include "mgraph440/stringutils.h" namespace mgraph440 { bool DataLayers::read(std::ifstream& stream, int version) { m_layers.clear(); stream.read( (char *) &m_current_layer_index, sizeof(int) ); int size; stream.read( (char *) &size, sizeof(int) ); for (int i = 0; i < size; i++) { DataLayer data; m_layers.push_back(data); m_layers.tail().read(stream, version); } return true; } //////////////////////////////////////////////////////// void DataLayer::setDisplayColumn(int i) { if (i == 0) { for (size_t j = 0; j < m_data_objects.size(); j++) { m_data_objects[j].m_color = float(j + 1) / m_data_objects.size(); } m_display_min = 0; m_display_max = m_data_objects.size(); } else if (m_data_objects.size()) { double max = m_data_objects[0][i-1], min = m_data_objects[0][i-1]; for (size_t j = 1; j < m_data_objects.size(); j++) { if (m_data_objects[j][i-1] < min) { min = m_data_objects[j][i-1]; } else if (m_data_objects[j][i-1] > max) { max = m_data_objects[j][i-1]; } } for (size_t k = 0; k < m_data_objects.size(); k++) { m_data_objects[k].m_color = (float) ((m_data_objects[k][i-1] - min) / (max - min)); } m_display_min = min; m_display_max = max; } m_display_column = i; } bool DataLayer::read(std::ifstream& stream, int version) { m_data_objects.clear(); m_column_titles.clear(); stream.read( (char *) &m_layer_ref, sizeof(int) ); m_layer_name = dXstring440::readString(stream); stream.read( (char *) &m_next_object_ref, sizeof(int) ); int rows_size; stream.read( (char *) &rows_size, sizeof(int) ); for (int i = 0; i < rows_size; i++) { DataObject object; m_data_objects.push_back(object); m_data_objects.tail().read(stream,version); } int columns_size; stream.read( (char *) &columns_size, sizeof(int) ); for (int j = 0; j < columns_size; j++) { m_column_titles.push_back(dXstring440::readString(stream)); } // Since it doesn't seem to be recorded, just display the initial column setDisplayColumn(0); return true; } bool DataLayer::output(std::ofstream& stream) { stream << "Ref" << "\t" << "x" << "\t" << "y" << "\t"; for (size_t i = 0; i < m_column_titles.size(); i++) { stream << m_column_titles[i] << "\t"; } stream << std::endl; for (size_t j = 0; j < m_data_objects.size(); j++) { stream.precision(12); stream << j << "\t" << m_data_objects[j].getCentroid().x << "\t" << m_data_objects[j].getCentroid().y << "\t"; stream.precision(7); for (size_t k = 0; k < m_column_titles.size(); k++) { stream << m_data_objects[j].m_data_cols[k] << "\t"; } stream << std::endl; } return true; } ////////////////////////////////////////////////////////////// bool DataObject::read(std::ifstream& stream, int version) { stream.read( (char *) &m_object_ref, sizeof(int) ); m_object_name = dXstring440::readString(stream); m_data_cols.read(stream); if (version >= VERSION_LAYERS_CENTROID_INTROD) { stream.read( (char *) &m_centroid, sizeof(Point2f) ); } // default values for selection / output color m_selected = false; m_color = 0.0f; return true; } bool DataObject::write(std::ostream& stream) { stream.write( (char *) &m_object_ref, sizeof(int) ); dXstring440::writeString(stream, m_object_name); m_data_cols.write(stream); stream.write( (char *) &m_centroid, sizeof(Point2f) ); return true; } } ================================================ FILE: mgraph440/datalayer.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // THIS CODE IS DEPRECATED DO NOT USE: USE SHAPE MAPS INSTEAD 21.08.05 // INCLUDED ONLY TO ALLOW COMPATIBILITY WITH OLD VERSIONS // DataLayer.h: interface for the DataLayer class. // ////////////////////////////////////////////////////////////////////// #ifndef __DATA_LAYER_H__ #define __DATA_LAYER_H__ namespace mgraph440 { // a layer object, e.g., a gate or a room class DataException { public: enum {UNDEFINED, LAYER_HAS_COLUMNS}; protected: int m_exception; public: DataException(int e = 0) { m_exception = e; } int errorCode() { return m_exception; } }; class DataObject { friend class DataLayer; protected: int m_object_ref; std::string m_object_name; Point2f m_centroid; pvecdouble m_data_cols; float m_color; bool m_selected; public: DataObject(int ref = 0, const std::string& name = std::string()) { m_object_ref = ref; m_object_name = name; m_selected = false; m_color = 0.0f; } double& operator [] (int i) { return m_data_cols[i]; } const double& operator [] (int i) const { return m_data_cols[i]; } int size() const { return (int) m_data_cols.size(); } void setCentroid(const Point2f& p) { m_centroid = p; } const Point2f& getCentroid() const { return m_centroid; } float getColor() const { return m_color; } bool isSelected() const { return m_selected; } void setSelected(bool on = true) { m_selected = on; } // friend bool operator == (const DataObject& a, const DataObject& b); friend bool operator != (const DataObject& a, const DataObject& b); friend bool operator < (const DataObject& a, const DataObject& b); friend bool operator > (const DataObject& a, const DataObject& b); // bool read( std::ifstream& stream, int version ); bool write(std::ostream &stream ); }; inline bool operator == (const DataObject& a, const DataObject& b) { return a.m_object_ref == b.m_object_ref; } inline bool operator != (const DataObject& a, const DataObject& b) { return a.m_object_ref != b.m_object_ref; } inline bool operator < (const DataObject& a, const DataObject& b) { return a.m_object_ref < b.m_object_ref; } inline bool operator > (const DataObject& a, const DataObject& b) { return a.m_object_ref > b.m_object_ref; } class DataLayer { protected: int m_layer_ref; std::string m_layer_name; int m_next_object_ref; pqvector m_data_objects; std::vector m_column_titles; int m_display_column; public: DataLayer(int ref = -1, const std::string& name = std::string()) { m_layer_ref = ref; m_layer_name = name; m_next_object_ref = -1; m_display_column = 0; // n.b. display column 0 is ref... always present } // Display column used to just set a column to display: // now it recalculates the colours too void setDisplayColumn(int i); // int addObject() { m_data_objects.push_back(DataObject(++m_next_object_ref)); for (size_t i = 0; i < m_column_titles.size(); i++) { // this used to be a problem so I was throwing an exception // throw LayerException(LayerException::LAYER_HAS_COLUMNS); // but I decided just to fill the object with blanks instead: m_data_objects.tail().m_data_cols.push_back(0.0); m_data_objects.tail().m_color = 0.0; // <- range 0 to 1 } setDisplayColumn(m_display_column); return m_next_object_ref; } void clear() { m_data_objects.clear(); m_next_object_ref = -1; m_display_column = 0; m_column_titles.clear(); } void clearSel() { for (size_t i = 0; i < m_data_objects.size(); i++) { m_data_objects[i].setSelected(false); } } DataObject& operator [] (size_t i) { return m_data_objects[i]; } const DataObject& operator [] (size_t i) const { return m_data_objects[i]; } int getLayerRef() const { return m_layer_ref; } void setLayerName(const std::string& name) { m_layer_name = name; } const std::string& getLayerName() const { return m_layer_name; } // int addColumn(std::string title) { // probably ought to insert -1.0 to be consistent with -1.0 nulls in attributes tables // but for the time being it's easier to set to 0.0 // -- and helps as agent trace / collision counts should default to 0.0 // -- and helps for push column to layer auto iter = std::find(m_column_titles.begin(), m_column_titles.end(), title); if (iter != m_column_titles.end()) { size_t index = iter - m_column_titles.begin(); for (size_t i = 0; i < m_data_objects.size(); i++) { m_data_objects[i][index] = 0.0; } return (int) index; } m_column_titles.push_back(title); for (size_t i = 0; i < m_data_objects.size(); i++) { m_data_objects[i].m_data_cols.push_back(0.0); } return (int) m_column_titles.size() - 1; } void delColumn(int col) { m_column_titles.erase(m_column_titles.begin() + col); for (size_t i = 0; i < m_data_objects.size(); i++) { m_data_objects[i].m_data_cols.remove_at(col); } } void setColumnTitle(int i, std::string& name) { m_column_titles[i] = name; } std::string& getColumnTitle(int i) { return m_column_titles[i]; } int getColumnIndex(const std::string& title) { auto iter = std::find(m_column_titles.begin(), m_column_titles.end(), title); return (iter == m_column_titles.end() ? -1 : int(iter - m_column_titles.begin())); // note: must convert to -1 } int getColumnCount() { return (int) m_column_titles.size(); } int getObjectCount() { return (int) m_data_objects.size(); } public: // temporarily public! // min and max values displayed: double m_display_min; double m_display_max; // and the average value displayed: double m_display_avg; public: int getDisplayColumn() { return m_display_column; // nb, 0 is used for ref... always present } float getObjectValue(int object_ref) { if (m_display_column == 0) return (float)object_ref; else return (float)m_data_objects[object_ref].m_data_cols[m_display_column-1]; } std::string getObjectText(int object_ref) { char val[16]; if (m_display_column == 0) sprintf(val,"%d",object_ref); else sprintf(val,"%g",m_data_objects[object_ref].m_data_cols[m_display_column-1]); return val; } PafColor getObjectColor(int object_ref) { PafColor color; return color.makeColor(m_data_objects[object_ref].m_color, DisplayParams()); } // friend bool operator == (const DataLayer& a, const DataLayer& b); friend bool operator != (const DataLayer& a, const DataLayer& b); friend bool operator < (const DataLayer& a, const DataLayer& b); friend bool operator > (const DataLayer& a, const DataLayer& b); // bool read( std::ifstream& stream, int version ); bool write( std::ofstream& stream ); bool output( std::ofstream& stream ); }; inline bool operator == (const DataLayer& a, const DataLayer& b) { return a.m_layer_ref == b.m_layer_ref; } inline bool operator != (const DataLayer& a, const DataLayer& b) { return a.m_layer_ref != b.m_layer_ref; } inline bool operator < (const DataLayer& a, const DataLayer& b) { return a.m_layer_ref < b.m_layer_ref; } inline bool operator > (const DataLayer& a, const DataLayer& b) { return a.m_layer_ref > b.m_layer_ref; } class DataLayers { public: // standard types I've thought of so far // Note that BOUNDARIES comprise blocked locations (which may or may not be visibility graph members) enum { GATES = 0, ATTRACTORS = 1, GENERATORS = 2, BOUNDARIES = 3 }; protected: int m_current_layer_index; pqvector m_layers; public: DataLayers() {;} bool addLayer(int layer_ref, const std::string& layer_name) { size_t index = m_layers.searchindex(layer_ref); if (index != paftl::npos) { m_layers.remove_at(index); } m_current_layer_index = (int) m_layers.add(DataLayer(layer_ref,layer_name)); return true; } bool layerExists(int layer_ref) { size_t index = m_layers.searchindex(layer_ref); return (index != paftl::npos); } bool setCurrentLayerRef(int ref) { size_t index = m_layers.searchindex(ref); if (index == paftl::npos) { return false; } m_current_layer_index = (int) index; return true; } int getCurrentLayerRef() const { return m_layers[m_current_layer_index].getLayerRef(); } int getLayerRef(int i) const { return m_layers[i].getLayerRef(); } DataLayer& getLayer(int layer_ref) { return m_layers.search(layer_ref); } const DataLayer& getLayer(int layer_ref) const { return m_layers.search(layer_ref); } DataLayer& operator [] (int i) { return m_layers[i]; } const DataLayer& operator [] (int i) const { return m_layers[i]; } DataLayer& getCurrentLayer() { return m_layers[m_current_layer_index]; } const DataLayer& getCurrentLayer() const { return m_layers[m_current_layer_index]; } int getLayerCount() const { return (int) m_layers.size(); } // bool read( std::ifstream& stream, int version ); bool write( std::ofstream& stream ); }; } #endif ================================================ FILE: mgraph440/displayparams.h ================================================ #pragma once // For my colour scheme... some parameters to pass, and my own colour class namespace mgraph440 { struct DisplayParams { enum { AXMANESQUE = 0, GREYSCALE = 1, MONOCHROME = 2, DEPTHMAPCLASSIC = 3, PURPLEORANGE = 4, BLUERED = 5 }; float blue; float red; int colorscale; DisplayParams() { blue = 0.0f; red = 1.0f; colorscale = 0; } }; } ================================================ FILE: mgraph440/exceptions.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef EXCEPTIONS_H #define EXCEPTIONS_H #include namespace depthmapX440 { class BaseException : public std::exception { public: BaseException(){} BaseException(std::string message) : _message(message) {} virtual const char * what() const noexcept { return _message.c_str(); } private: std::string _message; }; class RuntimeException: public BaseException { public: RuntimeException(std::string message) : BaseException(message) {} }; } #endif // EXCEPTIONS_H ================================================ FILE: mgraph440/fileproperties.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __FILEPROPERTIES_H__ #define __FILEPROPERTIES_H__ #include "mgraph440/stringutils.h" namespace mgraph440 { class FileProperties { protected: std::string m_create_person; std::string m_create_organization; std::string m_create_date; std::string m_create_program; std::string m_title; std::string m_location; std::string m_description; public: FileProperties() {;} virtual ~FileProperties() {;} // void setProperties(const std::string& person, const std::string& organization, const std::string& date, const std::string& program) { m_create_person = person; m_create_organization = organization; m_create_date = date; m_create_program = program; } void setTitle(const std::string& title) { m_title = title; } void setLocation(const std::string& location) { m_location = location; } void setDescription(const std::string& description) { m_description = description; } // const std::string& getPerson() const { return m_create_person; } const std::string& getOrganization() const { return m_create_organization; } const std::string& getDate() const { return m_create_date; } const std::string& getProgram() const { return m_create_program; } const std::string& getTitle() const { return m_title; } const std::string& getLocation() const { return m_location; } const std::string& getDescription() const { return m_description; } // bool read( std::ifstream& stream, int version ); bool write(std::ostream &stream ); }; inline bool FileProperties::read(std::ifstream& stream, int version) { m_create_person=dXstring440::readString(stream); m_create_organization=dXstring440::readString(stream); m_create_date=dXstring440::readString(stream); m_create_program=dXstring440::readString(stream); m_title=dXstring440::readString(stream); m_location=dXstring440::readString(stream); m_description=dXstring440::readString(stream); return true; } inline bool FileProperties::write(std::ostream& stream) { dXstring440::writeString(stream, m_create_person); dXstring440::writeString(stream, m_create_organization); dXstring440::writeString(stream, m_create_date); dXstring440::writeString(stream, m_create_program); dXstring440::writeString(stream, m_title); dXstring440::writeString(stream, m_location); dXstring440::writeString(stream, m_description); return true; } } #endif ================================================ FILE: mgraph440/legacyconverters.h ================================================ // Copyright (C) 2017 Christian Sailer // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "mgraph440/paftl.h" #include #include #include namespace genshim440 { using namespace mgraph440; /** * Convert a std::vector to a pvec (preserving the order of elements) * This is expensive as it copies every single element */ template pvector toPVector(const std::vector &vec) { pvector pvec; std::for_each(vec.begin(), vec.end(), [&pvec](const T &val) -> void { pvec.push_back(val); }); return pvec; } /** * Convert a pvec to a std::vector (preserving the order of elements) * This is expensive as it copies every single element */ template std::vector toSTLVector(pvector &pvec) { std::vector vec; for (int i = 0; i < pvec.size(); i++) { vec.push_back(pvec[i]); } return vec; } /** * Convert a std::vector to a pqvector (preserving the order of elements) * This is expensive as it copies every single element */ template pqvector toPQVector(const std::vector &vec) { pqvector pvec; std::for_each(vec.begin(), vec.end(), [&pvec](const T &val) -> void { pvec.push_back(val); }); return pvec; } /** * Convert a std::vector to a pqvec (preserving the order of elements) * This is expensive as it copies every single element */ template std::vector toSTLVector(pqvector &pqvec) { std::vector vec; for (int i = 0; i < pqvec.size(); i++) { vec.push_back(pqvec[i]); } return vec; } /** * Convert a pmap to a std::map * This is expensive as it copies every single element */ template std::map toSTLMap(pmap &pm) { std::map m; for (int i = 0; i < pm.size(); i++) { m.insert(std::make_pair(pm.key(i), pm.value(i))); } return m; } /** * Convert a std::map to a pmap (preserving the order of elements) * This is expensive as it copies every single element */ template pmap toPMap(const std::map &m) { pmap pm; for (auto pair : m) { pm.add(pair.first, pair.second); } return pm; } } // namespace genshim440 ================================================ FILE: mgraph440/mapinfodata.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __MAPINFODATA_H__ #define __MAPINFODATA_H__ #include "mgraph440/mgraph_consts.h" #include "mgraph440/stringutils.h" namespace mgraph440 { // imported and exported data // note: this is very basic and designed for axial line import / export only // MapInfoData is stored with axial map data class MapInfoData { friend class ShapeGraph; friend class ShapeGraphs; friend class ShapeMap; public: std::string m_version; std::string m_charset; char m_delimiter; std::string m_index; std::string m_coordsys; std::string m_bounds; std::istream& read(std::istream& stream, int version) { m_version = dXstring440::readString(stream); m_charset = dXstring440::readString(stream); m_delimiter = stream.get(); m_index = dXstring440::readString(stream); m_coordsys = dXstring440::readString(stream); m_bounds = dXstring440::readString(stream); // // this is no longer used: just a dummy read: if (version < mgraph440::VERSION_MAPINFO_SHAPES) { int columns, rows; std::vector columnheads; std::vector table; stream.read((char *) &columns, sizeof(int)); for (int i = 0; i < columns; i++) { columnheads.push_back(dXstring440::readString(stream)); } stream.read((char *) &rows, sizeof(int)); for (int j = 0; j < rows; j++) { table.push_back(dXstring440::readString(stream)); } } return stream; } std::ostream& write(std::ostream& stream) { dXstring440::writeString(stream, m_version); dXstring440::writeString(stream, m_charset); stream.put(m_delimiter); dXstring440::writeString(stream, m_index); dXstring440::writeString(stream, m_coordsys); dXstring440::writeString(stream, m_bounds); /* // No longer used as of VERSION_MAPINFO_SHAPES int columns = m_columnheads.size(); int rows = m_table.size(); stream.write((char *)&columns, sizeof(columns)); for (int i = 0; i < m_columnheads.size(); i++) { m_columnheads[i].write(stream); } stream.write((char *)&rows, sizeof(rows)); for (int j = 0; j < m_table.size(); j++) { m_table[j].write(stream); } */ return stream; } }; } #endif ================================================ FILE: mgraph440/mgraph.cpp ================================================ #include "mgraph440/mgraph.h" namespace mgraph440 { MetaGraph::MetaGraph() { m_state = 0; m_view_class = VIEWNONE; m_file_version = -1; // <- if unsaved, file version is -1 // Standard layers no longer added: the gates layer will be initialised with the first push to layer, // or when made from axial lines. m_attr_conv_table = NULL; // whether or not showing text / grid saved with file: m_showtext = false; m_showgrid = false; } MetaGraph::~MetaGraph() { } int MetaGraph::convertAttributes( std::ifstream& stream, int version ) { int ret = 1; // This is adapted from original ArVertexList code: int attr_count, which_attributes; stream.read( (char *) &which_attributes, sizeof(int) ); stream.read( (char *) &attr_count, sizeof(int) ); int size; stream.read( (char *) &size, sizeof(int) ); if (m_attr_conv_table) delete m_attr_conv_table; m_attr_conv_table = new pqvector; pqvector& attrs = *m_attr_conv_table; size_t i; for (i = 0; i < size_t(size); i++) { AttrBody attr(-1, g_attr_header); attr.read(stream, attr_count); // <- only write in saved attributes if (attr.ref != -1) { attrs.add( attr ); } } for (size_t ii = 0; ii < attrs.size(); ii++) { // Check these are numbered 0 to n, and set the pos to be used later: if (attrs[ii].ref != ii) { ret = 0; break; } attrs[ii].pos = -1; } if (ret == 0) { delete m_attr_conv_table; m_attr_conv_table = NULL; return 0; } for (i = 0; i < PointMaps::size(); i++) { PointMap& map = PointMaps::at(i); for (int j = 0; j < map.m_cols; j++) { for (int k = 0; k < map.m_rows; k++) { // Note: block used to be the noderef if (map.m_points[j][k].filled() && map.m_points[j][k].m_block != -1) { AttrBody test(-1,g_attr_header); test.ref = map.m_points[j][k].m_block; size_t pos = attrs.searchindex(test); if (pos != paftl::npos) { map.m_points[j][k].setAttributes(attrs[pos]); attrs[pos].pos = (int) PixelRef(j,k); // <- note this can be used to convert the virtual mem quickly } else { // oops ret = 0; } } } } } return ret; } int MetaGraph::convertVirtualMem( std::ifstream& stream, int version ) { if (!m_attr_conv_table) { return 0; } if (~m_state & ANGULARGRAPH) { // can't convert non-angular graphs: if (m_attr_conv_table) delete m_attr_conv_table; m_attr_conv_table = NULL; return DEPRECATED_VERSION; } // The attr conv table can help us quickly convert: pqvector& attrs = *m_attr_conv_table; pvecint nodes; pvecint bins; PixelRefVector bins_b[32]; static float far_bin_dists[32]; for (int ii = 0; ii < 32; ii++) { far_bin_dists[ii] = 0.0f; } char header[3]; stream.read( header, 3 ); // 'grf' stream.read( (char *) &version, sizeof( version ) ); // version char type; stream.read( (char *) &type, sizeof( type ) ); // 'v' int size; stream.read( (char *) &size, sizeof( size ) ); PointMap& map = PointMaps::tail(); for (int i = 0; i < size; i++) { nodes.read(stream); bins.read(stream); if (attrs[i].pos != -1) { PixelRef curs = (PixelRef) attrs[i].pos; for (int j = 0; j < 32; j++) { for (int k = loword(bins[j]); k < hiword(bins[j]); k++) { int next = attrs[nodes[k]].pos; if (next != -1) { bins_b[j].push_back( (PixelRef) next ); } } } Point& pt = map.getPoint( curs ); pt.m_node = new Node; pt.m_node->make( curs, bins_b, far_bin_dists, 0x00FF ); } nodes.clear(); bins.clear(); } delete m_attr_conv_table; m_attr_conv_table = NULL; return WARN_CONVERTED; } int MetaGraph::read( const std::string& filename ) { m_state = 0; // <- clear the state out if (filename.empty()) { return NOT_A_GRAPH; } #ifdef _WIN32 std::ifstream stream( filename.c_str(), std::ios::binary | std::ios::in ); #else std::ifstream stream( filename.c_str(), std::ios::in ); #endif char header[3]; stream.read( header, 3 ); if (stream.fail() || header[0] != 'g' || header[1] != 'r' || header[2] != 'f') { stream.close(); return NOT_A_GRAPH; } int version; stream.read( (char *) &version, sizeof( version ) ); m_file_version = version; // <- recorded for easy debugging if (version > METAGRAPH_VERSION) { stream.close(); return NEWER_VERSION; } if (version == VERSION_VIEW_CLASS_ADDED) { stream.close(); return DEPRECATED_VERSION; // trial version no longer supported } // have to use temporary state here as redraw attempt may come too early: int temp_state = 0; if (version >= VERSION_STATE_RECORDED) { stream.read( (char *) &temp_state, sizeof( temp_state ) ); } if (version >= VERSION_VIEW_CLASS_ADDED) { stream.read( (char *) &m_view_class, sizeof(m_view_class) ); } if (version >= VERSION_STORE_GRIDTEXTINFO) { stream.read( (char *) &m_showgrid, sizeof(m_showgrid) ); stream.read( (char *) &m_showtext, sizeof(m_showtext) ); } // type codes: x --- properties // v --- virtual graph (from versions below 70) // n --- ngraph format // l --- layer data // p --- point data // d --- data summary layers bool conversion_required = false; char type; stream.read( &type, 1 ); if (type == 'x') { FileProperties::read(stream,version); if (stream.eof()) { // erk... this shouldn't happen stream.close(); return DAMAGED_FILE; } else if (!stream.eof()) { stream.read( &type, 1 ); } } else { FileProperties::setProperties("","","",""); } if (stream.eof()) { // file is still ok, just empty stream.close(); return OK; } if (type == 'v') { conversion_required = true; skipVirtualMem(stream,version); // and set our filename: // Graph::m_nodes.setFilename( filename ); // and tell everyone it's been archived // temp_state |= GRAPHARCHIVED; if (stream.eof()) { // erk... this shouldn't happen stream.close(); return DAMAGED_FILE; } else if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'l') { try { SuperSpacePixel::read( stream, version ); temp_state |= LINEDATA; if (!stream.eof()) { stream.read( &type, 1 ); } } catch (pexception) { // erk... this shouldn't happen stream.close(); return DAMAGED_FILE; } } if (type == 'p') { if (version < VERSION_NGRAPH_INTROD) { // This hasn't been coded yet stream.close(); return DEPRECATED_VERSION; } if (version < VERSION_POINT_MAPS) { PointMaps::push_back(PointMap()); if (temp_state & 0x0001) { // 0x0001 was "GRAPH" PointMaps::tail().m_processed = true; temp_state &= ~0x0001; } if (temp_state & 0x0080) { // 0x0080 was "BOUNDARYGRAPH" PointMaps::tail().m_boundarygraph = true; temp_state &= ~0x0080; } PointMaps::tail().read( stream, version ); setDisplayedPointMapRef(0); } else { PointMaps::read( stream, version ); } PointMaps::setSpacePixel( (SuperSpacePixel *) this ); temp_state |= POINTMAPS; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'g') { // Note the older version stored its attributes in a different location... // ...well, actually, now it's been rearranged, pretty similar to the original... // hasn't been coded yet, though (see above) if (version < VERSION_NGRAPH_INTROD) { if (!convertAttributes( stream, version )) { stream.close(); return DAMAGED_FILE; } } // record on state of actual point map: PointMaps::tail().m_processed = true; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'a') { temp_state |= ANGULARGRAPH; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'd') { // data layers are deprecated: data layers have been replaced by shape maps // so: first read data layers: DataLayers dl; dl.read( stream, version ); // now replace with shape maps, but only if layer exists: temp_state &= ~DATAMAPS; // converter requires a point map to work on: if (PointMaps::size()) { // returns 0 if there are actually no objects in the shapemaps to convert, int conv_ok = convertDataLayersToShapeMap(dl,getDisplayedPointMap()); if (conv_ok == 1) { // read objects in: temp_state |= DATAMAPS; } else if (conv_ok == -1) { // read objects in, but had trouble converting them: temp_state |= DATAMAPS; temp_state |= WARN_CONVERTED; } } if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'x') { m_shape_graphs.read( stream, version ); temp_state |= SHAPEGRAPHS; /* // THIS CODE IS NO LONGER REQUIRED AS AXIAL MAPS *ARE* SHAPE MAPS -- can just be switched to shape map layer if (version < VERSION_SHAPE_MAPS && m_shape_graphs.m_gate_map != -1) { // check for a gate map: convertShapeGraphToShapeMap(m_shape_graphs.at(m_shape_graphs.m_gate_map)); // delete the gate map: m_shape_graphs.remove_at(m_shape_graphs.m_gate_map); if (m_shape_graphs.m_displayed_map >= m_shape_graphs.m_gate_map) { int map = m_shape_graphs.m_displayed_map; m_shape_graphs.m_displayed_map = -1; // <- have to do this as setDisplayedShapeGraph clearSels a map that may not exist anymore setDisplayedShapeGraph(map-1); } m_shape_graphs.m_gate_map = -1; if (m_shape_graphs.size() == 0) { temp_state &= ~SHAPEGRAPHS; } // assume objects read in okay: temp_state |= DATAMAPS; } */ if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 's') { m_data_maps.read( stream, version ); temp_state |= DATAMAPS; if (!stream.eof()) { stream.read( &type, 1 ); } } stream.close(); m_state = temp_state; if (version < VERSION_VIEW_CLASS_ADDED) { if (m_state & POINTMAPS) { m_view_class = VIEWVGA; } else { m_view_class = VIEWNONE; } } // Note, below version 70, the graph data must be reread: if (version < VERSION_NGRAPH_INTROD && conversion_required) { // reopen the stream and convert stream.open(filename.c_str(), std::ios::binary | std::ios::in ); int ok = convertVirtualMem(stream, version); stream.close(); return ok; } if (version == VERSION_EXTRA_POINT_DATA_INTROD || version == VERSION_NGRAPH_INTROD || version == VERSION_SEGMENT_MAPS) { m_state |= BUGGY; return WARN_BUGGY_VERSION; } return OK; } std::streampos MetaGraph::skipVirtualMem(std::ifstream& stream, int version) { // it's graph virtual memory: skip it int nodes = -1; stream.read( (char *) &nodes, sizeof(nodes) ); // in angular version, have to skip two pvectors for each node: if (version >= 30) nodes *= 2; for (int i = 0; i < nodes; i++) { int connections; stream.read( (char *) &connections, sizeof(connections) ); // This relies on the pvecint storage... hope it don't change! stream.seekg( stream.tellg() + std::streamoff(connections * sizeof(connections)) ); } return (stream.tellg()); } int MetaGraph::convertDataLayersToShapeMap(DataLayers& datalayers, PointMap& pointmap) { int retvar = 1; // check for existence of data: pmap conversion_lookup; size_t i; for (i = 0; i < size_t(datalayers.getLayerCount()); i++) { if (datalayers[i].getObjectCount()) { int x = m_data_maps.addMap(datalayers[i].getLayerName(),ShapeMap::DATAMAP); conversion_lookup.add(i,x); } } // nothing to convert: if (!conversion_lookup.size()) { return 0; } for (i = 0; i < conversion_lookup.size(); i++) { ShapeMap& shapemap = m_data_maps.getMap(conversion_lookup.value(i)); int layer_ref = datalayers.getLayerRef(conversion_lookup.key(i)); pvecint *shape_pixel_lists = new pvecint [datalayers[i].getObjectCount()]; int j; for (j = 0; j < pointmap.getAttributeTable().getRowCount(); j++) { PixelRef pix = pointmap.getAttributeTable().getRowKey(j); int z = pointmap.getPoint(pix).getDataObject(layer_ref); if (z != -1) { shape_pixel_lists[z].push_back(pix); } } // add shapes: pvecint row_lookup; for (j = 0; j < datalayers[i].getObjectCount(); j++) { for (size_t k = 0; k < shape_pixel_lists[j].size(); k++) { pointmap.overrideSelPixel(shape_pixel_lists[j][k]); } row_lookup.push_back(shapemap.makeShapeFromPointSet(pointmap)); pointmap.clearSel(); } delete [] shape_pixel_lists; // now add attributes: AttributeTable& table = shapemap.getAttributeTable(); // add columns, note, we'll have to add and then have lookups because not necessarily in alphabetical order: for (j = 0; j < datalayers[i].getColumnCount(); j++) { table.insertColumn(datalayers[i].getColumnTitle(j)); } pvecint column_lookup; for (j = 0; j < datalayers[i].getColumnCount(); j++) { column_lookup.push_back(table.getColumnIndex(datalayers[i].getColumnTitle(j))); } // now we can add the data for this horrible matrix: for (j = 0; j < datalayers[i].getObjectCount(); j++) { for (int k = 0; k < datalayers[i].getColumnCount(); k++) { if (row_lookup[j] != -1) { int row = table.getRowid(row_lookup[j]); // row lookup should equal j since this is a new shape map, but for safety looked up table.setValue(row,column_lookup[k],float(datalayers[i][j][k])); } else { // conversion error occurred: retvar = -1; } } } // set the displayed attribute ready for first draw: shapemap.overrideDisplayedAttribute(-2); shapemap.setDisplayedAttribute(-1); } // the horror is over: return retvar; } int MetaGraph::writeToFile( const std::string& filename, int version, bool currentlayer ) { std::ofstream stream; int oldstate = m_state; m_state = 0; // <- temporarily clear out state, avoids any potential read / write errors // As of MetaGraph version 70 the disk caching has been removed stream.open( filename.c_str(), std::ios::binary | std::ios::out | std::ios::trunc ); if (stream.fail()) { if (stream.rdbuf()->is_open()) { stream.close(); } m_state = oldstate; return DISK_ERROR; } m_state = oldstate; int result = writeToStream(stream, version, currentlayer); stream.close(); return result; } int MetaGraph::writeToStream(std::ostream &stream, int version, bool currentlayer) { int oldstate = m_state; char type; stream.write("grf", 3); m_file_version = version; // <- note, the file may now have an updated file version stream.write( (char *) &version, sizeof(version) ); if (currentlayer) { int tempstate, tempclass; if (m_view_class & VIEWVGA) { tempstate = POINTMAPS; tempclass = VIEWVGA; } else if (m_view_class & MetaGraph::VIEWAXIAL) { tempstate = SHAPEGRAPHS; tempclass = VIEWAXIAL; } else if (m_view_class & MetaGraph::VIEWDATA) { tempstate = DATAMAPS; tempclass = VIEWDATA; } stream.write( (char *) &tempstate, sizeof(tempstate) ); stream.write( (char *) &tempclass, sizeof(tempclass) ); } else { stream.write( (char *) &oldstate, sizeof(oldstate) ); stream.write( (char *) &m_view_class, sizeof(m_view_class) ); } stream.write( (char *) &m_showgrid, sizeof(m_showgrid) ); stream.write( (char *) &m_showtext, sizeof(m_showtext) ); type = 'x'; stream.write(&type, 1); FileProperties::write(stream); if (currentlayer) { if (m_view_class & MetaGraph::VIEWVGA) { type = 'p'; stream.write(&type, 1); PointMaps::write( stream, version, true ); } else if (m_view_class & MetaGraph::VIEWAXIAL) { type = 'x'; stream.write(&type, 1); m_shape_graphs.write( stream, version, true ); } else if (m_view_class & MetaGraph::VIEWDATA) { type = 's'; stream.write(&type, 1); m_data_maps.write( stream, version, true ); } } else { if (oldstate & LINEDATA) { type = 'l'; stream.write(&type, 1); SuperSpacePixel::write( stream, version ); } if (oldstate & POINTMAPS) { type = 'p'; stream.write(&type, 1); PointMaps::write( stream, version ); } if (oldstate & SHAPEGRAPHS) { type = 'x'; stream.write(&type, 1); m_shape_graphs.write( stream, version ); } if (oldstate & DATAMAPS) { type = 's'; stream.write(&type, 1); m_data_maps.write( stream, version ); } } m_state = oldstate; return OK; } } ================================================ FILE: mgraph440/mgraph.h ================================================ #pragma once #include "mgraph440/ngraph.h" // for conversion #include "mgraph440/pointmap.h" #include "mgraph440/axialmap.h" #include "mgraph440/shapemap.h" #include "mgraph440/spacepix.h" #include "mgraph440/datalayer.h" #include "mgraph440/fileproperties.h" #include "mgraph440/bspnode.h" #include "mgraph440/attr.h" namespace mgraph440 { class MetaGraph : public SuperSpacePixel, public PointMaps, public FileProperties { public: MetaGraph(); ~MetaGraph(); enum { ANGULARGRAPH = 0x0010, LINEDATA = 0x0004, POINTMAPS = 0x0002, DATAMAPS = 0x0020, SHAPEGRAPHS = 0x0100, BUGGY = 0x8000 }; enum { OK, WARN_BUGGY_VERSION, WARN_CONVERTED, NOT_A_GRAPH, DAMAGED_FILE, DISK_ERROR, NEWER_VERSION, DEPRECATED_VERSION }; enum { VIEWNONE = 0x00, VIEWVGA = 0x01, VIEWAXIAL = 0x04, VIEWDATA = 0x20 }; int m_state; int m_file_version; int m_view_class; bool m_showgrid; bool m_showtext; ShapeMaps m_data_maps; ShapeGraphs m_shape_graphs; // Standard layers no longer added: the gates layer will be initialised with the first push to layer, // or when made from axial lines. pqvector *m_attr_conv_table = NULL; std::streampos skipVirtualMem(std::ifstream& stream, int version); int convertDataLayersToShapeMap(DataLayers& datalayers, PointMap& pointmap); int convertAttributes(std::ifstream &stream, int version); int convertVirtualMem(std::ifstream &stream, int version); int read(const std::string &filename); int writeToFile( const std::string& filename, int version, bool currentlayer = false); int writeToStream(std::ostream &stream, int version, bool currentlayer = false); }; } ================================================ FILE: mgraph440/mgraph_consts.h ================================================ #pragma once namespace mgraph440 { const int METAGRAPH_VERSION = 440; // Human readable(ish) metagraph version changes const int VERSION_ALWAYS_RECORD_BINDISTANCES = 440; // 17-Aug-2010 Version stamp for Depthmap 10.08.00 const int VERSION_100800 = 430; // 12-Jul-2010 Version stamp for Depthmap 10.07.00 const int VERSION_100700 = 430; // 12-Jul-2010 Occlusion distances for agent control test const int VERSION_OCCDISTANCES = 430; // 07-Feb-2010 Axial lines no longer self-connect const int VERSION_NO_SELF_CONNECTION = 420; // 31-Jan-2009 Maps have sublayers const int VERSION_MAP_LAYERS = 410; // // 390 and 400 used only for testing // // 31-Jan-2009 this is simply a version stamp for Depthmap 8.14.00 and 8.15.00 // The idea is that I should start writing code that saves in version 380 format // as a benchmark "save for older version" const int VERSION_81500 = 380; const int VERSION_81400 = 380; // // 20-Apr-2008 The shape map name lookup could have been corrupted. In addition it's not that useful (never much to sort through, unique layer names not necessary) const int VERSION_NO_SHAPEMAP_NAME_LOOKUP = 380; // 15-Mar-2008 const int VERSION_SHAPE_AREA_PERIMETER = 370; const int VERSION_FORGET_COLUMN_CREATOR = 370; // 04-Oct-2007 const int VERSION_MAP_TYPES = 360; // 20-Sep-2007 const int VERSION_STORE_COLUMN_CREATOR = 350; const int VERSION_ATTRIBUTE_LOCKING = 350; // version 340 unused // 08-Jun-2007: Store all drawing layers as shape maps rather than spacepixels (continued) const int VERSION_DRAWING_SHAPES_B = 330; // 27-Nov-2006: Store all drawing layers as shape maps rather than spacepixels const int VERSION_DRAWING_SHAPES = 320; // 27-Nov-2006: Store axial maps as children of shape maps rather than spacepixels const int VERSION_AXIAL_SHAPES = 310; // 01-Sep-2006: Store formulae for columns const int VERSION_STORE_FORMULA = 300; // 14-May-2006: Occlusions with node const int VERSION_OCCLUSIONS = 290; // 28-Dec-2005: Polygon shapes have centroids const int VERSION_SHAPE_CENTROIDS = 280; // 18-Dec-2005: Mapinfo data read into shape maps instead of axial maps const int VERSION_MAPINFO_SHAPES = 270; // 14-Sep-2005: QtRegion bug with segment maps from imported axial maps fixed: const int VERSION_AXIAL_REGION_FIX = 263; // 01-Sep-2005: Now Pointmaps really ought to store their names: const int VERSION_POINT_MAP_NAMES = 262; // 25-Aug-2005: And an extension to shape maps to make them easier to use as lines or points const int VERSION_EXTENDED_SHAPE_MAPS = 261; // 23-Aug-2005: Although in test from 11-Aug-2005, useful to read the testing graphs created: const int VERSION_SHAPE_MAPS = 260; // 11-Aug-2005: Also, a set of PointMaps now replace a single instance of PointData const int VERSION_POINT_MAPS = 251; // 11-Aug-2005: Location stored with points, not depixelated on the fly const int VERSION_POINT_LOCATIONS = 250; // 01-Mar-2005: Quick grid connections const int VERSION_GRID_CONNECTIONS = 240; // 02-Dec-2004: Axial map gates const int VERSION_GATE_MAPS = 230; // 29-Oct-2004: Store the colour display settings with the graph data const int VERSION_STORE_GRIDTEXTINFO = 220; // 29-Oct-2004: Store the colour display settings with the graph data const int VERSION_STORE_COLOR = 210; // 16-Jun-2004: New boundary graph (now much simpler: nodes at edge of main graph) const int VERSION_NEWBOUNDARYGRAPH = 200; // 20-May-2004: Each segment must have forward and backward connections listed separately! const int VERSION_SEGMENT_MAPS_FIX = 191; // 17-May-2004: Axial maps can be either segment or axial maps. Affects ShapeGraph and AxialLine classes const int VERSION_SEGMENT_MAPS = 190; // 12-May-2004: Extra Mapinfo table data const int VERSION_MAPINFO_DATA = 180; // 06-May-2004: Explicit links and unlinks for axial lines const int VERSION_AXIAL_LINKS = 170; // 29-Feb-2004: Attributes table (already used for AxialLines) now used for PointData as well const int VERSION_ATTRIBUTES_TABLE = 160; // File compression introduced const int VERSION_FILE_COMPRESSION = 150; // Some minor modifications to the axial line format... won't load v.130 files const int VERSION_REVISED_AXIAL = 140; // View class specifies whether axial or vga currently viewed const int VERSION_VIEW_CLASS_ADDED = 130; // A distance stored in the bin const int VERSION_BINDISTANCES = 120; // A set of nodes on the boundaries of the isovist const int VERSION_BOUNDARYGRAPH = 110; // Dynamic lines (addable and removable) in the visibility graph const int VERSION_DYNAMICLINES = 100; // Line layers are coloured... const int VERSION_LAYERCOLORS = 91; // Blocked locations split into 4, replaces m_noderef const int VERSION_BLOCKEDQUAD = 90; // Space pixel groups have different space pixels for different layers (at their own resolution!) const int VERSION_SPACEPIXELGROUPS = 80; // The graph state is just recorded const int VERSION_STATE_RECORDED = 72; // The binsizes weren't included in the metagraph 70 const int VERSION_NGRAPH_BINCOUNT = 71; // Major, major changes to the graph format (from now on it will now be held in memory only) const int VERSION_NGRAPH_INTROD = 70; // Slight changes to PointData required for the actual implementation of the quick graph const int VERSION_SPARK_GRAPH_INTROD = 61; // Quick graph... add underlying info about lines into the pointdata structure const int VERSION_QUICK_GRAPH_INTROD = 60; // Layers const int VERSION_LAYERS_CENTROID_INTROD = 51; const int VERSION_LAYERS_INTROD = 50; // version 41 repairs VERSION_EXTRA_POINT_DATA_INTROD bug const int VERSION_EXTRA_POINT_DATA_INTROD = 40; const int VERSION_BINS_INTROD = 30; const unsigned int SALA_SELECTED_COLOR = 0x00FFFF77; const unsigned int SALA_HIGHLIGHTED_COLOR = 0x0077FFFF; } ================================================ FILE: mgraph440/ngraph.cpp ================================================ #include "mgraph440/ngraph.h" #include "mgraph440/mgraph_consts.h" #include "mgraph440/legacyconverters.h" namespace mgraph440 { inline int processoctant(int bin) { int q = -1; switch (bin) { case 0: case 1: case 2: case 3: case 4: q = 1; break; case 5: case 6: case 7: q = 7; break; case 8: case 9: case 10: case 11: q = 6; break; case 12: case 13: case 14: case 15: case 16: q = 0; break; case 17: case 18: case 19: case 20: q = 2; break; case 21: case 22: case 23: q = 4; break; case 24: case 25: case 26: case 27: q = 5; break; case 28: case 29: case 30: case 31: q = 3; break; } return (1 << q); } void Node::make(const PixelRef pix, PixelRefVector *bins, float *bin_far_dists, int q_octants) { m_pixel = pix; for (int i = 0; i < 32; i++) { if (q_octants != 0x00FF) { // now, an octant filter has been used... note that the exact q-octants that // will have been processed rely on adjacenies in the q_octants... if (!(q_octants & processoctant(i))) { continue; } } m_bins[i].m_distance = bin_far_dists[i]; if (i == 4 || i == 20) { m_bins[i].make(bins[i], PixelRef::POSDIAGONAL); } else if (i == 12 || i == 28) { m_bins[i].make(bins[i], PixelRef::NEGDIAGONAL); } else if ((i > 4 && i < 12) || (i > 20 && i < 28)) { m_bins[i].make(bins[i], PixelRef::VERTICAL); } else { m_bins[i].make(bins[i], PixelRef::HORIZONTAL); } // Now clear the bin! bins[i].clear(); } } void Bin::make(const PixelRefVector& pixels, char dir) { if (m_pixel_vecs) { delete [] m_pixel_vecs; m_pixel_vecs = NULL; } m_length = 0; m_node_count = 0; if (pixels.size()) { m_dir = dir; if (m_dir & PixelRef::DIAGONAL) { PixelVec cur( pixels[0], pixels[0] ); // Special, the diagonal should be pixels directly along the diagonal // Both posdiagonal and negdiagonal are positive in the x direction // Note that it is ordered anyway, so no need for anything too fancy: if (pixels.back().x < cur.start().x) { cur.m_start = pixels.back(); } if (pixels.back().x > cur.end().x) { cur.m_end = pixels.back(); } m_length = 1; m_pixel_vecs = new PixelVec[1]; m_pixel_vecs[0] = cur; m_node_count = pixels.size(); } else { prefvec pixel_vecs; // Reorder the pixels: if (m_dir == PixelRef::HORIZONTAL) { pvector pixels_h; for (size_t i = 0; i < pixels.size(); i++) { pixels_h.add(pixels[i]); } // this looks like a simple bubble sort pixel_vecs.push_back(PixelVec(pixels_h[0],pixels_h[0])); for (size_t j = 1; j < pixels_h.size(); j++) { if (pixels_h[j-1].y != pixels_h[j].y || pixels_h[j-1].x + 1 != pixels_h[j].x) { pixel_vecs.tail().m_end = pixels_h[j-1]; pixel_vecs.push_back(PixelVec(pixels_h[j],pixels_h[j])); } } pixel_vecs.tail().m_end = pixels_h.tail(); } if (m_dir == PixelRef::VERTICAL) { pvector pixels_v; for (size_t i = 0; i < pixels.size(); i++) { pixels_v.add(pixels[i]); } // this looks like a simple bubble sort pixel_vecs.push_back(PixelVec(pixels_v[0],pixels_v[0])); for (size_t j = 1; j < pixels_v.size(); j++) { if (pixels_v[j-1].x != pixels_v[j].x || pixels_v[j-1].y + 1 != pixels_v[j].y) { pixel_vecs.tail().m_end = pixels_v[j-1]; pixel_vecs.push_back(PixelVec(pixels_v[j],pixels_v[j])); } } pixel_vecs.tail().m_end = pixels_v.tail(); } // Now compact the representation: m_length = pixel_vecs.size(); m_pixel_vecs = new PixelVec[m_length]; for (int k = 0; k < m_length; k++) { m_pixel_vecs[k] = pixel_vecs[k]; } m_node_count = pixels.size(); } } } void Bin::first() const { m_curvec = 0; if (m_length) m_curpix = m_pixel_vecs[m_curvec].m_start; } void Bin::next() const { if (m_curpix.move(m_dir).col(m_dir) > m_pixel_vecs[m_curvec].end().col(m_dir)) { m_curvec++; if (m_curvec < m_length) m_curpix = m_pixel_vecs[m_curvec].m_start; } } bool Bin::is_tail() const { return m_curvec >= m_length; } PixelRef Bin::cursor() const { return (int) m_curpix; } ::std::ifstream& Node::read(::std::ifstream& stream, int version) { int i; for (i = 0; i < 32; i++) { m_bins[i].read(stream, version); } if (version >= VERSION_OCCLUSIONS) { for (i = 0; i < 32; i++) { pvector tempPvector; tempPvector.read(stream); m_occlusion_bins[i] = genshim440::toSTLVector(tempPvector); } } return stream; } std::ostream& Node::write(std::ostream& stream, int version) { int i; for (i = 0; i < 32; i++) { m_bins[i].write(stream,version); } for (i = 0; i < 32; i++) { pvector tempPvector = genshim440::toPVector(m_occlusion_bins[i]); tempPvector.write(stream); } return stream; } ::std::ifstream& Bin::read(::std::ifstream& stream, int version) { stream.read( (char *) &m_dir, sizeof(m_dir) ); stream.read( (char *) &m_node_count, sizeof(m_node_count) ); if (version >= VERSION_FILE_COMPRESSION) { if (version >= VERSION_ALWAYS_RECORD_BINDISTANCES) { stream.read( (char *) &m_distance, sizeof(m_distance) ); stream.read( (char *) &m_occ_distance, sizeof(m_occ_distance) ); } if (m_node_count) { if (version < VERSION_ALWAYS_RECORD_BINDISTANCES) { stream.read( (char *) &m_distance, sizeof(m_distance) ); } if (m_dir & PixelRef::DIAGONAL) { m_length = 1; m_pixel_vecs = new PixelVec [m_length]; m_pixel_vecs[0].read(stream, version, m_dir); } else { stream.read( (char *) &m_length, sizeof(m_length) ); m_pixel_vecs = new PixelVec [m_length]; m_pixel_vecs[0].read(stream, version, m_dir); for (int i = 1; i < m_length; i++) { m_pixel_vecs[i].read(stream, version, m_dir,m_pixel_vecs[i-1]); } } if (version < VERSION_ALWAYS_RECORD_BINDISTANCES) { if (version >= VERSION_OCCDISTANCES) { stream.read( (char *) &m_occ_distance, sizeof(m_occ_distance) ); } else { m_occ_distance = 0.0f; } } } else { m_pixel_vecs = NULL; m_length = 0; if (version < VERSION_ALWAYS_RECORD_BINDISTANCES) { m_distance = 0.0f; m_occ_distance = 0.0f; } } } else { stream.read( (char *) &m_length, sizeof(m_length) ); if (version >= VERSION_BINDISTANCES) { stream.read( (char *) &m_distance, sizeof(m_distance) ); } else { m_distance = 0.0f; } if (m_pixel_vecs) { delete m_pixel_vecs; m_pixel_vecs = NULL; } if (m_length) { m_pixel_vecs = new PixelVec [m_length]; stream.read( (char *) m_pixel_vecs, sizeof(PixelVec) * m_length); } } return stream; } std::ostream& Bin::write(std::ostream& stream, int version) { stream.write( (char *) &m_dir, sizeof(m_dir) ); stream.write( (char *) &m_node_count, sizeof(m_node_count) ); stream.write( (char *) &m_distance, sizeof(m_distance) ); stream.write( (char *) &m_occ_distance, sizeof(m_occ_distance) ); if (m_node_count) { if (m_dir & PixelRef::DIAGONAL) { m_pixel_vecs[0].write(stream,m_dir); } else { stream.write( (char *) &m_length, sizeof(m_length) ); m_pixel_vecs[0].write(stream,m_dir); for (int i = 1; i < m_length; i++) { m_pixel_vecs[i].write(stream,m_dir,m_pixel_vecs[i-1]); } } } return stream; } ::std::ifstream& PixelVec::read(::std::ifstream& stream, int version, const char dir) { unsigned short runlength; stream.read((char *) &m_start, sizeof(m_start)); stream.read((char *) &runlength, sizeof(runlength)); switch (dir) { case PixelRef::POSDIAGONAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y + runlength; break; case PixelRef::NEGDIAGONAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y - runlength; break; case PixelRef::HORIZONTAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y; break; case PixelRef::VERTICAL: m_end.x = m_start.x; m_end.y = m_start.y + runlength; break; } return stream; } struct ShiftLength { unsigned short shift : 4; unsigned short runlength : 12; }; ::std::ifstream& PixelVec::read(::std::ifstream& stream, int version, const char dir, const PixelVec& context) { short primary; ShiftLength shiftlength; stream.read((char *) &primary, sizeof(primary)); stream.read((char *) &shiftlength, sizeof(shiftlength)); switch (dir) { case PixelRef::HORIZONTAL: m_start.x = primary; m_start.y = context.m_start.y + shiftlength.shift; m_end.x = m_start.x + shiftlength.runlength; m_end.y = m_start.y; break; case PixelRef::VERTICAL: m_start.x = context.m_start.x + shiftlength.shift; m_start.y = primary; m_end.x = m_start.x; m_end.y = m_start.y + shiftlength.runlength; break; } return stream; } std::ostream& PixelVec::write(std::ostream& stream, const char dir) { stream.write((char *) &m_start, sizeof(m_start)); unsigned short runlength; switch (dir) { case PixelRef::HORIZONTAL: case PixelRef::POSDIAGONAL: case PixelRef::NEGDIAGONAL: runlength = m_end.x - m_start.x; break; case PixelRef::VERTICAL: runlength = m_end.y - m_start.y; break; } stream.write((char *) &runlength, sizeof(runlength)); return stream; } std::ostream& PixelVec::write(std::ostream& stream, const char dir, const PixelVec& context) { ShiftLength shiftlength; switch (dir) { case PixelRef::HORIZONTAL: stream.write((char *) &(m_start.x), sizeof(m_start.x)); shiftlength.runlength = m_end.x - m_start.x; shiftlength.shift = m_start.y - context.m_start.y; break; case PixelRef::VERTICAL: stream.write((char *) &(m_start.y), sizeof(m_start.y)); shiftlength.runlength = m_end.y - m_start.y; shiftlength.shift = m_start.x - context.m_start.x; break; } stream.write((char *) &shiftlength, sizeof(shiftlength)); return stream; } void Node::first() const { m_curbin = 0; do { m_bins[m_curbin].first(); } while (m_bins[m_curbin].is_tail() && ++m_curbin < 32); } void Node::next() const { m_bins[m_curbin].next(); while (m_bins[m_curbin].is_tail() && ++m_curbin < 32) { m_bins[m_curbin].first(); } } PixelRef Node::cursor() const { return m_bins[m_curbin].cursor(); } } ================================================ FILE: mgraph440/ngraph.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ngraph.h #ifndef __NGRAPH_H__ #define __NGRAPH_H__ #include "mgraph440/pixelref.h" #include "mgraph440/paftl.h" #include namespace mgraph440 { class PointMap; struct MetricPair; struct MetricTriple; struct PixelVec { PixelRef m_start; PixelRef m_end; PixelVec(const PixelRef start = NoPixel, const PixelRef end = NoPixel) { m_start = (int) start; m_end = (int) end; }; PixelRef start() const { return m_start; } PixelRef end() const { return m_end; } // std::ifstream& read(std::ifstream& stream, int version, const char dir); std::ifstream& read(std::ifstream& stream, int version, const char dir, const PixelVec& context); std::ostream &write(std::ostream &stream, const char dir); std::ostream& write(std::ostream& stream, const char dir, const PixelVec& context); }; class Bin { friend class Node; protected: char m_dir; unsigned short m_length; unsigned short m_node_count; float m_distance; float m_occ_distance; PixelVec *m_pixel_vecs; public: Bin() { m_dir = PixelRef::NODIR; m_length = 0; m_pixel_vecs = NULL; m_node_count = 0; m_distance = 0.0f; m_occ_distance = 0.0f; } Bin(const Bin&) { throw 1; } Bin& operator = (const Bin&) { throw 1; } ~Bin() { if (m_pixel_vecs) delete [] m_pixel_vecs; m_pixel_vecs = NULL; } // void make(const PixelRefVector& pixels, char m_dir); // int count() const { return m_node_count; } float distance() const { return m_distance; } float occdistance() const { return m_occ_distance; } // void setOccDistance(float d) { m_occ_distance = d; } // bool containsPoint(const PixelRef p) const; // // Iterator protected: // Conversion back to old fashioned schema: mutable int m_curvec; mutable PixelRef m_curpix; public: // void contents(PixelRefVector& hood); void first() const; void next() const; bool is_tail() const; PixelRef cursor() const; // std::ifstream& read(std::ifstream& stream, int version); std::ostream &write(std::ostream &stream, int version); }; class Node { protected: PixelRef m_pixel; Bin m_bins[32]; public: // testing some agent stuff: std::vector m_occlusion_bins[32]; public: Node() { ; } Node(const Node&) { throw 1; } Node& operator = (const Node&) { throw 1; } ~Node() { ; } // Conversion back to old fashioned schema: mutable int m_curbin; // Note: this function clears the bins as it goes void make(const PixelRef pix, PixelRefVector *bins, float *bin_far_dists, int q_octants); // void setPixel(const PixelRef& pixel) { m_pixel = pixel; } Bin& bin(int i) { return m_bins[i]; } float occdistance(int i) { return m_bins[i].occdistance(); } int count() { int c = 0; for (int i = 0; i < 32; i++) c += m_bins[i].count(); return c; } void first() const; void next() const; PixelRef cursor() const; std::ifstream& read(std::ifstream& stream, int version); std::ostream &write(std::ostream &stream, int version); }; // Two little helpers: class PixelRefH : public PixelRef { public: PixelRefH() : PixelRef() {;} PixelRefH(const PixelRef& p) : PixelRef(p) {;} friend bool operator > (const PixelRefH& a, const PixelRefH& b); friend bool operator < (const PixelRefH& a, const PixelRefH& b); }; inline bool operator > (const PixelRefH& a, const PixelRefH& b) { return (a.y > b.y || (a.y == b.y && a.x > b.x)); } inline bool operator < (const PixelRefH& a, const PixelRefH& b) { return (a.y < b.y || (a.y == b.y && a.x < b.x)); } class PixelRefV : public PixelRef { public: PixelRefV() : PixelRef() {;} PixelRefV(const PixelRef& p) : PixelRef(p) {;} friend bool operator > (const PixelRefV& a, const PixelRefV& b); friend bool operator < (const PixelRefV& a, const PixelRefV& b); }; inline bool operator > (const PixelRefV& a, const PixelRefV& b) { return (a.x > b.x || (a.x == b.x && a.y > b.y)); } inline bool operator < (const PixelRefV& a, const PixelRefV& b) { return (a.x < b.x || (a.x == b.x && a.y < b.y)); } } #endif ================================================ FILE: mgraph440/options.h ================================================ #pragma once namespace mgraph440 { // Options for mean depth calculations struct Options { enum output_t { OUTPUT_ISOVIST, OUTPUT_VISUAL, OUTPUT_METRIC, OUTPUT_ANGULAR, OUTPUT_THRU_VISION, OUTPUT_CLIQUE_GRAPH, OUTPUT_KERNEL_GRAPH, OUTPUT_MATRIX_REDUCTION }; // Output type, see above int output_type; // Options for the summary type: int local; int global; int cliques; // bool choice; // include measures that can be derived: RA, RRA and total depth bool fulloutput; // enum { RADIUS_STEPS, RADIUS_METRIC, RADIUS_ANGULAR }; int radius_type; double radius; // <- n.b. for metric integ radius is floating point // radius has to go up to a list (phase out radius as is) pvecdouble radius_list; // int point_depth_selection; int tulip_bins; bool process_in_memory; bool sel_only; bool gates_only; // for pushing to a gates layer int gatelayer; // a column to weight measures by: int weighted_measure_col; int weighted_measure_col2; //EFEF int routeweight_col; //EFEF std::string output_file; // To save an output graph (for example) // default values Options() { local = 0; global = 1; cliques = 0; choice = false; fulloutput = false; point_depth_selection = 0; tulip_bins = 1024; radius = -1; radius_type = 0; output_type = OUTPUT_ISOVIST; process_in_memory = false; gates_only = false; sel_only = false; gatelayer = -1; weighted_measure_col = -1;} }; } ================================================ FILE: mgraph440/p2dpoly.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // 2d polygons (and line sets too...) #include #include #include #include namespace mgraph440 { ////////////////////////////////////////////////////////////////////////////////////// // gps2os: function to convert long-lat GPS coordinates to OS national grid // n.b.: approximation only // This algorithm is taken from: // "A guide to coordinate systems in Great Britain" // http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/index.html // (v1.9 Mar 2008 D00659, Crown Copyright) // Sourced: 21-Mar-08 // It's truly ick... and nuts... there must be an easier way... // Outline: // 1. take long-lat on ETRS89 ellipsoid and convert to 3d cartesian coordinates // 2. shift 3d cartesian coordinates from ETRS89 ellipsoid to OSGB36 ellipsoid // 3. convert 3d cartesian coordinates to long-lat on OSGB36 ellipsoid // 4. project onto OSFB36 2d grid using a transverse Mercator projection // According to OS, accurate to within about 5 metres Point2f gps2os(const Point2f& pt) { // *first*, we have ETRS89 data... // Convert it to 3D Cartesian Coordinates double lambda = M_PI * pt.x / 180.0; double phi = M_PI * pt.y / 180.0; // GRS80 ellipsoid double a = 6378137.0000; double b = 6356752.3141; double e_sq = (sqr(a) - sqr(b)) / sqr(a); double nu = a / sqrt(1.0 - e_sq * sqr(sin(phi))); double x = nu * cos(phi) * cos(lambda); double y = nu * cos(phi) * sin(lambda); double z = (1 - e_sq) * nu * sin(phi); // Now we have the ETRS89 location, convert it to a rough OSGB36 location: // rough conversion chart // t_x (m) t_y (m) t_z (m) s (ppm) r_x (sec) r_y (sec) r_z (sec) // -446.448 +125.157 -542.060 +20.4894 -0.1502 -0.2470 -0.8421 = (in radians: ) // nb, seconds converted to radians: double r_x = -0.7281901490265230623720509817416e-6; double r_y = -1.1974897923405539041670878328241e-6; double r_z = -4.0826160086234026020206666559563e-6; x = -446.448 + (1.0 + 2.04894e-5) * x - r_z * y + r_y * z; y = +125.157 + r_z * x + (1.0 + 2.04894e-5) * y - r_x * z; z = -542.060 - r_y * x + r_x * y + (1.0 + 2.04894e-5) * z; double p = sqrt(sqr(x)+sqr(y)); // now place it back in long lat on the OSGB36 ellipsoid: // Airy 1830 (OSGB36) ellipsoid a = 6377563.396; b = 6356256.910; e_sq = (sqr(a) - sqr(b)) / sqr(a); lambda = atan( y / x ); phi = atan( z / (p * (1.0 - e_sq)) ); double lastphi = phi; nu = a / sqrt(1.0 - e_sq * sqr(sin(phi))); do { phi = atan( (z + e_sq * nu * sin(phi)) / p ); } while (fabs(lastphi - phi) > 1e-6); // now, it's on the ellipsoid, project it onto the OSGB36 grid: // E_0 easting of true origin 400 000m double E_0 = 400000; // N_0 northing of true origin -100 000m double N_0 = -100000; // F_0 scaling factor on central meridian 0.9996012717 double F_0 = 0.9996012717; // lambda_0 longitude of true origin -2.0 radians: -0.034906585039886591538473815369772 double lambda_0 = -0.034906585039886591538473815369772; // phi_0 latitude of true origin 49.0 radians: double phi_0 = 0.85521133347722149269260847655942; nu = a * F_0 * pow((1 - e_sq * sqr(sin(phi))),-0.5); double n = (a-b) / (a+b); double rho = a * F_0 * (1.0 - e_sq) * pow((1 - e_sq * sqr(sin(phi))),-1.5); double eta_sq = nu / rho - 1; double n_sq = pow(n,2); double n_cubed = pow(n,3); double M = b * F_0 * ( (1.0 + n + 0.25 * 5 * (n_sq + n_cubed)) * (phi - phi_0) -(3.0 * (n + n_sq + 0.125 * 7 * n_cubed)) * sin(phi - phi_0) * cos(phi + phi_0) +(0.125 * 15.0 * (n_sq + n_cubed)) * sin(2.0 * (phi - phi_0)) * cos(2.0 * (phi + phi_0)) -(35.0/24.0 * n_cubed) * sin(3.0 * (phi - phi_0)) * cos(3.0 * (phi + phi_0)) ); double I = M + N_0; double II = 0.5 * nu * sin(phi) * cos(phi); double tanphi = tan(phi); double III = nu * sin(phi) * pow(cos(phi),3.0) * (5.0 - sqr(tanphi)+ 9.0 * eta_sq) / 24.0; double IIIA = nu * sin(phi) * pow(cos(phi),5.0) * (61.0 - 58.0 * sqr(tanphi) + pow(tanphi,4.0)) / 720.0; double IV = nu * cos(phi); double V = nu * pow(cos(phi),3.0) * (nu/rho - sqr(tanphi)) / 6.0; double VI = nu * pow(cos(phi),5.0) * (5.0 - 18.0 * sqr(tanphi) + pow(tanphi,4) + 14.0 * eta_sq - 58.0 * sqr(tanphi) * eta_sq) / 120.0; double E = E_0 + IV * (lambda - lambda_0) + V * pow((lambda - lambda_0),3) + VI * pow((lambda - lambda_0),5); double N = I + II * pow((lambda - lambda_0),2) + III * pow((lambda - lambda_0),4) + IIIA * pow((lambda - lambda_0),6); return Point2f(E,N); } ////////////////////////////////////////////////////////////////////////////////////// static long g_count = 0L; int bitcount(int a) { int ret = 0; while (a != 0) { ret += (a & 1) ? 1 : 0; a = a >> 1; } return ret; } //////////////////////////////////////////////////////////////////////////////////////// // EdgeU is used for polygon clipping to viewports // are a,b,c in ccw order (true) or cw order (false) bool ccwEdgeU(const EdgeU& a, const EdgeU& b, const EdgeU& c) { bool ccw = false; if (c.edge > a.edge || (c.edge == a.edge && c.u > a.u)) { if (b.edge > a.edge || (b.edge == a.edge && b.u > a.u)) { if (b.edge < c.edge || (b.edge == c.edge && b.u < c.u)) { ccw = true; } } } else { if (b.edge > a.edge || (b.edge == a.edge && b.u > a.u)) { ccw = true; } else if (b.edge < c.edge || (b.edge == c.edge && b.u < c.u)) { ccw = true; } } return ccw; } // EdgeU is used for polygon clipping to viewports // get the actual point from an EdgeU Point2f QtRegion::getEdgeUPoint(const EdgeU& eu) { switch (eu.edge) { case 0: return Point2f(bottom_left.x + (eu.u * width()), bottom_left.y); case 1: return Point2f(top_right.x, bottom_left.y + (eu.u * height())); case 2: return Point2f(top_right.x - (eu.u * width()), top_right.y); case 3: return Point2f(bottom_left.x, top_right.y - (eu.u * height())); } return Point2f(); } // EdgeU is used for polygon clipping to viewports // get where the polygon exits the viewport EdgeU QtRegion::getCutEdgeU(const Point2f& inside, const Point2f& outside) { EdgeU eu; if (outside.x < bottom_left.x) { double y = outside.y + (inside.y - outside.y) * (bottom_left.x - outside.x) / (inside.x-outside.x); if (y >= bottom_left.y && y <= top_right.y) { eu.edge = 3; eu.u = (top_right.y - y) / height(); } } if (eu.edge == -1 && outside.x > top_right.x) { double y = inside.y + (outside.y - inside.y) * (top_right.x - inside.x) / (outside.x-inside.x); if (y >= bottom_left.y && y <= top_right.y) { eu.edge = 1; eu.u = (y - bottom_left.y) / height(); } } if (eu.edge == -1 && outside.y < bottom_left.y) { double x = outside.x + (inside.x - outside.x) * (bottom_left.y - outside.y) / (inside.y-outside.y); if (x >= bottom_left.x && x <= top_right.x) { eu.edge = 0; eu.u = (x - bottom_left.x) / width(); } } if (eu.edge == -1 && outside.y > top_right.y) { double x = inside.x + (outside.x - inside.x) * (top_right.y - inside.y) / (outside.y-inside.y); if (x >= bottom_left.x && x <= top_right.x) { eu.edge = 2; eu.u = (top_right.x - x) / width(); } } // if at this stage eu.edge is still -1 there's a problem! return eu; } ////////////////////////////////////////////////////////////////////////// // union of two regions QtRegion runion(const QtRegion& a, const QtRegion& b) { QtRegion n; n.bottom_left.x = a.bottom_left.x < b.bottom_left.x ? a.bottom_left.x : b.bottom_left.x; n.bottom_left.y = a.bottom_left.y < b.bottom_left.y ? a.bottom_left.y : b.bottom_left.y; n.top_right.x = a.top_right.x > b.top_right.x ? a.top_right.x : b.top_right.x; n.top_right.y = a.top_right.y > b.top_right.y ? a.top_right.y : b.top_right.y; return n; } // test intersecting regions, touching counts bool intersect_region(const QtRegion& a, const QtRegion& b, double tolerance) { if (overlap_x(a,b,tolerance) && overlap_y(a,b,tolerance)) { return true; } else { return false; } } bool overlap_x(const QtRegion& a, const QtRegion& b, double tolerance) { if (a.bottom_left.x > b.bottom_left.x) { if (b.top_right.x >= a.bottom_left.x - tolerance) { return true; } } else { if (a.top_right.x >= b.bottom_left.x - tolerance) { return true; } } return false; } bool overlap_y(const QtRegion& a, const QtRegion& b, double tolerance) { if (a.bottom_left.y > b.bottom_left.y) { if (b.top_right.y >= a.bottom_left.y - tolerance) { return true; } } else { if (a.top_right.y >= b.bottom_left.y - tolerance) { return true; } } return false; } // line set up // default: nothing: Line::Line() { bits.parity = 0; bits.direction = 0; // Points automatically assigned to 0,0 } Line::Line(const Point2f& a, const Point2f& b) { if (a.x == b.x) { bottom_left.x = a.x; top_right.x = b.x; // vertical lines stored consistently as parity 1 if (a.y <= b.y) { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 1; bits.direction = 1; } else { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 1; bits.direction = 0; } } else if (a.x < b.x) { bottom_left.x = a.x; top_right.x = b.x; if (a.y <= b.y) { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 1; bits.direction = 1; } else { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 0; // -1 bits.direction = 1; } } else { bottom_left.x = b.x; top_right.x = a.x; if (b.y <= a.y) { bottom_left.y = b.y; top_right.y = a.y; bits.parity = 1; bits.direction = 0; } else { bottom_left.y = a.y; top_right.y = b.y; bits.parity = 0; // -1 bits.direction = 0; } } } ////////////////////////////////////////////////////////////////////////////// double dot(const Line& a, const Line& b) { return (a.bx() - a.ax()) * (b.bx() - b.ax()) + (a.by() - a.ay()) * (b.by() - b.ay()); } // intersection test: touching counts as an intersection // (uses dot product comparison) // NB You must MUST check that line *regions do not intersect* before using this test // By this test, *all parallel lines intersect* bool intersect_line(const Line& a, const Line& b, double tolerance) { g_count++; if ( ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())) <= tolerance && ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())) <= tolerance) { return true; } return false; } // intersection test: touching does not count as an intersection // (uses dot product comparison) bool intersect_line_no_touch(const Line& a, const Line& b, double tolerance) { g_count++; if ( ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())) < -tolerance && ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())) < -tolerance) { return true; } return false; } // returns 0 for no intersect, 1 for touching and 2 for crossing int intersect_line_distinguish(const Line& a, const Line& b, double tolerance) { g_count++; double alpha = ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())) * ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())); double beta = ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())); if (alpha <= tolerance && beta <= tolerance) { if (alpha < -tolerance && beta < -tolerance) { return 2; } else { return 1; } } return 0; } // returns 0 for no intersect, 1 for touching and 2 for crossing // n.b. only used by polygon contains -- throws if the first point of line b is touching line a // (first point of line b is the point to be tested) -- i.e., throws if point touches polygon int intersect_line_b(const Line& a, const Line& b, double tolerance) { g_count++; double alpha = ((a.ay() - a.by()) * (b.ax() - a.ax()) + (a.bx() - a.ax()) * (b.ay() - a.ay())); double beta = ((a.ay() - a.by()) * (b.bx() - a.ax()) + (a.bx() - a.ax()) * (b.by() - a.ay())); double gamma = ((b.ay() - b.by()) * (a.ax() - b.ax()) + (b.bx() - b.ax()) * (a.ay() - b.ay())) * ((b.ay() - b.by()) * (a.bx() - b.ax()) + (b.bx() - b.ax()) * (a.by() - b.ay())); if (alpha * beta <= tolerance && gamma <= tolerance) { if (alpha * beta < -tolerance && gamma < -tolerance) { return 2; } else { // this function is only used for poly contains point, // the throw is defined if the point is *on* the polygon edge // (within the tolerance) if (fabs(alpha) <= tolerance) { throw 1; } return 1; } } return 0; } double Line::intersection_point(const Line& l, int axis, double tolerance) const { // use axis = XAXIS for width() > height() double loc; if (axis == XAXIS) { if (l.width() == 0.0) { loc = l.bottom_left.x; } else { double lg = l.grad(YAXIS); double g = grad(YAXIS); if (fabs(lg - g) <= tolerance) { // these have almost the same gradient, so it's impossible to tell where they intersect: going for midpoint Point2f p = l.midpoint(); loc = (p.x > top_right.x) ? top_right.x : ((p.x < bottom_left.x) ? bottom_left.x : p.x); } else { // this is the same as: constant(YAXIS) - l.constant(YAXIS)) / (l.grad(YAXIS) - grad(YAXIS)); loc = ((ay() - g * ax()) - (l.ay() - lg * l.ax())) / (lg - g); } } } else { if (l.height() == 0.0) { loc = l.bottom_left.y; } else { double lg = l.grad(XAXIS); double g = grad(XAXIS); if (fabs(lg - g) <= tolerance) { // these have almost the same gradient, so it's impossible to tell where they intersect: going for midpoint Point2f p = l.midpoint(); loc = (p.y > top_right.y) ? top_right.y : ((p.y < bottom_left.y) ? bottom_left.y : p.y); } else { // this is the same as: constant(XAXIS) - l.constant(XAXIS)) / (l.grad(XAXIS) - grad(XAXIS)); loc = ((ax() - g * ay()) - (l.ax() - lg * l.ay())) / (lg - g); } } } return loc; } // intersecting line segments, touching counts // (uses intersection point comparison) bool Line::intersect_line(const Line& l, int axis, double& loc) const { // please be intelligent when passing the axis... if (axis == XAXIS) { if (l.width() == 0.0) { // Special case: double y = ay() + sign() * (l.ax() - ax()) * height() / width(); if (y >= bottom_left.y && y <= l.top_right.y) { // <- you must have checked loc = l.bottom_left.x; // the regions overlap first return true; } return false; } else { // Standard: (note: if m1 == m2, loc is NaN) loc = (constant(YAXIS) - l.constant(YAXIS)) / (l.grad(YAXIS) - grad(YAXIS)); if (std::isnan(loc)) { // lines are parallel --- are they coincident? // you must have checked the regions overlap first if (constant(YAXIS) == l.constant(YAXIS)) { return true; } } else if (loc >= l.bottom_left.x && loc <= l.top_right.x) { return true; } return false; } } else { if (l.height() == 0.0) { // Special case: double x = ax() + sign() * (l.ay() - ay()) * width() / height(); if (x >= bottom_left.x && x <= top_right.x) { // <- you must have checked loc = l.bottom_left.y; // the regions overlap first return true; } return false; } else { // Standard: (note: if m1 == m2, loc is NaN) loc = (constant(XAXIS) - l.constant(XAXIS)) / (l.grad(XAXIS) - grad(XAXIS)); if (std::isnan(loc)) { // lines are parallel --- are they coincident? // you must have checked the regions overlap first if (constant(XAXIS) == l.constant(XAXIS)) { return true; } } else if (loc >= l.bottom_left.y && loc <= l.top_right.y) { return true; } return false; } } return false; } // this converts the loc back into a point: Point2f Line::point_on_line(double loc, int axis) const { Point2f p; if (axis == XAXIS) { p = Point2f(loc, grad(YAXIS) * loc + constant(YAXIS)); } else { p = Point2f(grad(XAXIS) * loc + constant(XAXIS), loc); } return p; } ////////////////////////////////////////////////////////////////////////////// // distance from a point to a line segment double dist(const Point2f& point, const Line& line) { double d = 0.0; Point2f alpha = line.end() - line.start(); Point2f beta = point - line.end(); Point2f gamma = line.start() - line.end(); Point2f delta = point - line.start(); if (dot(alpha,beta) > 0) { d = beta.length(); } else if (dot(gamma,delta) > 0) { d = delta.length(); } else { if (alpha.length() < 1e-9 * beta.length()) { // should actually be a user-specified tolerance test d = beta.length(); } else { d = fabs(det(alpha,beta)) / alpha.length(); } } return d; } /* // for infinite line rather than line segment return fabs((line.bx() - line.ax()) * (line.ay() - point.y) - (line.ax() - point.x) * (line.by() - line.ay())) / line.length(); */ ////////////////////////////////////////////////////////////////////////////// // intersection test bool intersect(const RegionTree& a, const RegionTree& b) { if (a.is_leaf() && b.is_leaf()) { if (intersect_region( QtRegion(a), QtRegion(b))) { return intersect_line( (const Line&) QtRegion(a), (const Line&) QtRegion(b) ); } else { return false; } } else { if (intersect_region( QtRegion(a), QtRegion(b))) { return subintersect(a, b); } else { return false; } } } bool subintersect(const RegionTree& a, const RegionTree& b) { if (intersect(a.left(),b.left())) { return true; } else if (intersect(a.right(),b.right())) { return true; } else if (intersect(a.left(),b.right())) { return true; } else if (intersect(a.right(),b.left())) { return true; } return false; } // Intersection count int intersections(const RegionTree& a, const Line& b) { int n = 0; if (!a.is_leaf()) { if (intersect_region( QtRegion(a), QtRegion(b))) { n += intersections(a.left(), b); n += intersections(a.right(), b); } } else { // Note: touching lines count 1, non-touching lines count 2, this allows through // vertex lines (where it touches both vertices) n += intersect_line_b( (const Line&) a, (const Line&) b ); } return n; } ////////////////////////////////////////////////////////////////////////////// // crop a line to fit within bounds of region // if line lies outside region, returns false bool Line::crop(const QtRegion& r) { if (bx() >= r.bottom_left.x) { if (ax() < r.bottom_left.x) { // crop! ay() += sign() * (height() * (r.bottom_left.x - ax()) / width()); ax() = r.bottom_left.x; } if (ax() <= r.top_right.x) { if (bx() > r.top_right.x) { // crop! by() -= sign() * height() * (bx() - r.top_right.x) / width(); bx() = r.top_right.x; } if (top_right.y >= r.bottom_left.y) { if (bottom_left.y < r.bottom_left.y) { // crop! if (bits.parity) { ax() += width() * (r.bottom_left.y - bottom_left.y) / height(); } else { bx() -= width() * (r.bottom_left.y - bottom_left.y) / height(); } bottom_left.y = r.bottom_left.y; } if (bottom_left.y <= r.top_right.y) { if (top_right.y > r.top_right.y) { // crop! if (bits.parity) { bx() -= width() * (top_right.y - r.top_right.y) / height(); } else { ax() += width() * (top_right.y - r.top_right.y) / height(); } top_right.y = r.top_right.y; } // if we got this far, well done, it's in the region: return true; } } } } // returns false if the entire line is outside the region: return false; } // cast a ray to the edge of a box void Line::ray(short dir, const QtRegion& r) { if (dir == bits.direction) { if (width() >= height()) { by() = ay() + sign() * height() * (r.top_right.x - ax()) / width(); bx() = r.top_right.x; } else if (bits.parity) { bx() = ax() + width() * (r.top_right.y - ay()) / height(); by() = r.top_right.y; } else { bx() = ax() + width() * (ay() - r.bottom_left.y) / height(); by() = r.bottom_left.y; } } else { if (width() >= height()) { ay() = by() - sign() * height() * (bx() - r.bottom_left.x) / width(); ax() = r.bottom_left.x; } else if (bits.parity) { ax() = bx() - width() * (by() - r.bottom_left.y) / height(); ay() = r.bottom_left.y; } else { ax() = bx() - width() * (r.top_right.y - by()) / height(); ay() = r.top_right.y; } } // now fit within bounds... crop(r); } ////////////////////////////////////////////////////////////////////////////// // Polygon set up (the hard bit!) void Poly::add_line_segment(const Line& l) { m_line_segments++; RegionTreeLeaf *leaf = new RegionTreeLeaf( l ); if (m_p_root == NULL) { // first ever node m_p_root = (RegionTree *) leaf; } else { // traverse the tree to the insertion point // you'll just have to take my word for it that the next line // gives you the correct position to insert int cut_level = bitcount(m_line_segments - 1) - 2; if (cut_level < 0) { // replace the root node QtRegion new_region = runion( QtRegion(*m_p_root), QtRegion(*leaf) ); RegionTree *new_root = new RegionTreeBranch( new_region, *m_p_root, *leaf ); m_p_root = new_root; } else { RegionTree *here = m_p_root; for (int i = 0; i < cut_level; i++) { here = here->m_p_right; } // cut and insert RegionTree& insertion_point = here->right(); QtRegion new_region = runion( QtRegion(insertion_point), QtRegion(*leaf) ); RegionTree *new_node = new RegionTreeBranch( new_region, insertion_point, *leaf ); here->m_p_right = new_node; // traverse up tree unioning regions // (saving data by not recording parents!) // Note must be '>=' to catch current root node --- I really stuffed up earlier with '>'! while (cut_level >= 0) { here = m_p_root; for (int j = 0; j < cut_level; j++) { here = here->m_p_right; } here->m_p_region = new Line( runion(QtRegion(here->left()), QtRegion(here->right())) ); cut_level--; } } } } // ...and after all the efficient stuff, we have a really // inefficient polygon copy... hmm RegionTree *Poly::copy_region_tree( const RegionTree* tree ) { if ( !tree ) { return NULL; } RegionTree *newtree; if (tree->is_leaf()) { newtree = new RegionTreeLeaf(); newtree->m_p_region = new Line( *(tree->m_p_region) ); return newtree; } else { newtree = new RegionTreeBranch(); } pvector newlist; pvector oldlist; oldlist.push_back( (RegionTree *) tree ); newlist.push_back( (RegionTree *) newtree ); do { RegionTree *oldnode = oldlist.tail(); oldlist.pop_back(); RegionTree *newnode = newlist.tail(); newlist.pop_back(); newnode->m_p_region = new Line( *oldnode->m_p_region ); if (oldnode->m_p_left) { if (oldnode->m_p_left->is_leaf()) { newnode->m_p_left = new RegionTreeLeaf(); newnode->m_p_left->m_p_region = new Line( *(oldnode->m_p_left->m_p_region) ); } else { oldlist.push_back( oldnode->m_p_left ); newnode->m_p_left = new RegionTreeBranch(); newlist.push_back( newnode->m_p_left ); } } if (oldnode->m_p_right) { if (oldnode->m_p_right->is_leaf()) { newnode->m_p_right = new RegionTreeLeaf(); newnode->m_p_right->m_p_region = new Line( *(oldnode->m_p_right->m_p_region) ); } else { oldlist.push_back( oldnode->m_p_right ); newnode->m_p_right = new RegionTreeBranch(); newlist.push_back( newnode->m_p_right ); } } } while (oldlist.size() > 0); return newtree; } // polygon destruction void Poly::destroy_region_tree() { if ( !m_p_root ) { return; } pvector del_node_list; pvector del_node_dir; del_node_list.push_back( m_p_root ); do { RegionTree *current_node = del_node_list.tail(); if (current_node->m_p_left == current_node && current_node->m_p_right == current_node) { delete current_node; del_node_list.pop_back(); if (del_node_list.size() > 0) { if (del_node_dir.tail() == 0) { del_node_list.tail()->m_p_left = del_node_list.tail(); del_node_dir.pop_back(); } else { del_node_list.tail()->m_p_right = del_node_list.tail(); del_node_dir.pop_back(); } } } else { if (current_node->m_p_right == NULL) { current_node->m_p_right = current_node; } else if (current_node->m_p_right != current_node) { del_node_list.push_back( current_node->m_p_right ); del_node_dir.push_back( 1 ); } else { del_node_list.push_back( current_node->m_p_left ); del_node_dir.push_back( 0 ); } } } while (del_node_list.size() > 0); m_p_root = NULL; } // contains? intersects?? // Here they are! bool Poly::contains( const Point2f& p ) { // n.b., intersections throws on some accidental alignments -- // we must use a point outside the polygon to extend our test // line from to prevent them Line l( p, Point2f( get_bounding_box().top_right.x + get_bounding_box().width(), get_bounding_box().top_right.y + get_bounding_box().height()) ); int double_n; // note, touching intersections count 1/2 try { double_n = intersections( *(m_p_root), l ); } catch (int) { throw 1; // throws if on edge } if (double_n % 2 == 0 && double_n % 4 != 0) { return true; } return false; } bool intersect( const Poly& a, const Poly& b ) { if ( intersect( *(a.m_p_root), *(b.m_p_root)) ) { return true; } return false; } } ================================================ FILE: mgraph440/p2dpoly.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // 2d poly (own format, adapted from the original Sala libraries // The idea is that from this format, // we can read into Cosmo3d as well as Sala based applications #pragma once // Using doubles right the way through can really eat memory for isovist // polygon files, thus we use a defined type, change as appropriate: #include #include #include // communicator used in BSP tree construction namespace mgraph440 { // Note: code depends on XAXIS being 0 and YAXIS being 1 --- do not change enum { NOAXIS = -1, XAXIS = 0, YAXIS = 1 }; class Point2f; bool approxeq(const Point2f& p1, const Point2f& p2, double tolerance = 0.0); class QtRegion; bool intersect_region(const QtRegion& a, const QtRegion& b, double tolerance = 0.0); bool overlap_x(const QtRegion& a, const QtRegion& b, double tolerance = 0.0); bool overlap_y(const QtRegion& a, const QtRegion& b, double tolerance = 0.0); class Line; bool intersect_line(const Line& a, const Line& b, double tolerance = 0.0); bool intersect_line_no_touch(const Line& a, const Line& b, double tolerance = 0.0); int intersect_line_distinguish(const Line& a, const Line& b, double tolerance = 0.0); int intersect_line_b(const Line& a, const Line& b, double tolerance = 0.0); Point2f intersection_point(const Line& a, const Line& b, double tolerance = 0.0); // NaN on Intel: // Quick mod - TV // const double P2DNULL = (const double)0xFFFFFFFF7FF7FFFF; // for non-Intel: 0x7FF7FFFFFFFFFFFF // Point class Point2f { public: double x; double y; Point2f() // { x = P2DNULL; y = P2DNULL; } { x = 0.0; y = 0.0; } Point2f(double a, double b) { x = a; y = b; } bool atZero() const // { return x == P2DNULL || y == P2DNULL; } { return x == 0.0 && y == 0.0; } void normalScale( const QtRegion& ); // inline function: below region void denormalScale( const QtRegion& ); void operator += (const Point2f& p) { x += p.x; y += p.y; } void operator -= (const Point2f& p) { x -= p.x; y -= p.y; } void operator *= (const double s) { x *= s; y *= s; } void operator /= (const double s) { x /= s; y /= s; } double& operator [] (int i) { return (i == XAXIS) ? x : y; } const double& operator [] (int i) const { return (i == XAXIS) ? x : y; } friend Point2f operator - (Point2f& p); friend Point2f operator + (const Point2f& p1, const Point2f& p2); friend Point2f operator - (const Point2f& p1, const Point2f& p2); friend bool operator == (const Point2f& p1, const Point2f& p2); friend bool operator != (const Point2f& p1, const Point2f& p2); friend bool operator > (const Point2f& a, const Point2f& b); friend bool operator < (const Point2f& a, const Point2f& b); friend Point2f operator * (const double s, const Point2f& p); friend Point2f operator / (const Point2f& p, const double s); friend double dot(const Point2f& p1, const Point2f& p2); friend double det(const Point2f& p1, const Point2f& p2); friend double dist(const Point2f& p1, const Point2f& p2); friend double dist(const Point2f& point, const Line& line); friend double angle(const Point2f& p1, const Point2f& p2, const Point2f& p3); friend bool approxeq(const Point2f& p1, const Point2f& p2, double tolerance); friend Point2f pointfromangle(double angle); // a couple of useful tests bool intriangle(const Point2f& p1, const Point2f& p2, const Point2f& p3); bool insegment(const Point2f& key, const Point2f& p2, const Point2f& p3, double tolerance = 0.0); // for OS transformation (note: accurate only to 5 metres according to OS) Point2f longlat2os(const Point2f& p); public: // A few simple vector ops: double length() const { return (double) sqrt(x * x + y * y); } Point2f& scale(const double scalar) { x *= scalar; y *= scalar; return *this; } Point2f& scale(const Point2f& scalevec) { x *= scalevec.x; y *= scalevec.y; return *this; } Point2f& normalise() { return scale( 1.0 / length() ); } Point2f& rotate(const double angle) { double t = x; x = x * cos(angle) - y * sin(angle); y = y * cos(angle) + t * sin(angle); return *this; } double angle() const { return (y < 0) ? (2.0 * M_PI - acos(x)) : acos(x); } }; inline Point2f operator - (Point2f& p) { return Point2f(-p.x, -p.y); } inline Point2f operator + (const Point2f& p1, const Point2f& p2) { return Point2f(p1.x + p2.x, p1.y + p2.y); } inline Point2f operator - (const Point2f& p1, const Point2f& p2) { return Point2f(p1.x - p2.x, p1.y - p2.y); } inline bool operator == (const Point2f& p1, const Point2f& p2) { return (p1.x == p2.x && p1.y == p2.y); } inline bool operator != (const Point2f& p1, const Point2f& p2) { return (p1.x != p2.x || p1.y != p2.y); } inline bool operator > (const Point2f& p1, const Point2f& p2) { return (p1.x > p2.x || (p1.x == p2.x && p1.y > p2.y)); } inline bool operator < (const Point2f& p1, const Point2f& p2) { return (p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y)); } inline Point2f operator * (const double s, const Point2f& p) { return Point2f(s * p.x, s * p.y); } inline Point2f operator / (const Point2f& p, const double s) { return Point2f(p.x / s, p.y / s); } inline double dot(const Point2f& p1, const Point2f& p2) { return (p1.x * p2.x + p1.y * p2.y); } // greater than 0 => p2 left (anticlockwise) of p1, less than 0 => p2 right (clockwise) of p1 inline double det(const Point2f& p1, const Point2f& p2) { return (p1.x * p2.y - p1.y * p2.x); } inline double dist(const Point2f& p1, const Point2f& p2) { return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y)); } inline double angle(const Point2f& p1, const Point2f& p2, const Point2f& p3) { Point2f a = p1 - p2; Point2f b = p3 - p2; a.normalise(); b.normalise(); // ensure in range (f.p. error can throw out) double d = std::min(std::max(dot(a,b),-1.0),1.0); return (sgn(det(a,b)) == 1) ? acos(d) : 2.0 * M_PI - acos(d); } inline bool approxeq(const Point2f& p1, const Point2f& p2, double tolerance) { return (fabs(p1.x - p2.x) <= tolerance && fabs(p1.y - p2.y) <= tolerance); } inline bool Point2f::insegment(const Point2f& key, const Point2f& p2, const Point2f& p3, double tolerance) { Point2f va = p2 - key; Point2f vb = p3 - key; Point2f vp = *this - key; double ap = det(va,vp); double bp = det(vb,vp); if ((dot(va,vp) > 0 && dot(vb,vp) > 0) && (sgn(ap) != sgn(bp) || fabs(ap) < tolerance || fabs(bp) < tolerance) ) { return true; } return false; } inline bool Point2f::intriangle(const Point2f& p1, const Point2f& p2, const Point2f& p3) { // touching counts int test = sgn(det(p2-p1,*this-p1)); if (test == sgn(det(p3-p2,*this-p2)) && test == sgn(det(p1-p3,*this-p3))) { return true; } return false; } inline Point2f pointfromangle(double angle) { Point2f p; p.x = cos(angle); p.y = sin(angle); return p; } Point2f gps2os(const Point2f& p); // an event is a point plus time (as in spacetime technical language) class Event2f : public Point2f { public: double t; // time in seconds Event2f() : Point2f() { t = 0.0; } Event2f(double _x, double _y, double _t) : Point2f(_x,_y) { t = _t; } Event2f(Point2f& _p) : Point2f(_p) { t = 0.0; } Event2f(Point2f& _p, double _t) : Point2f(_p) { t = _t; } }; /////////////////////////////////////////////////////////////////////////////////////////// class Point3f { public: double x; double y; double z; Point3f(double a = 0.0, double b = 0.0, double c = 0.0) { x = a; y = b; z = c;} Point3f(const Point2f& p) { x = p.x; y = 0.0; z = p.y; } // Note! not z = -y (due to an incosistency earlier...) bool inside( const Point3f& bl, const Point3f& tr ) // now inclusive (...) { return (x >= bl.x && y >= bl.y && z >= bl.z && x <= tr.x && y <= tr.y && z <= tr.z); } operator Point2f() { return Point2f( x, z ); } // Note! not x, -z (due to an inconsistency earlier...) Point2f xy() { return Point2f(x, y); } // From the x, y plane // A few simple vector ops: double length() const { return (double) sqrt(x * x + y * y + z * z); } Point3f& scale(const double scalar) { x *= scalar; y *= scalar; z *= scalar; return *this; } Point3f& normalise() { return scale( 1.0 / length() ); } Point3f& rotate(double theta, double phi) { double t = x; x = t * cos(theta) - y * sin(theta); y = y * cos(theta) + t * sin(theta); t = x; x = t * cos(phi) - z * sin(phi); z = z * cos(phi) - t * sin(phi); return *this; } // friend double dot(const Point3f& a, const Point3f& b); friend Point3f cross(const Point3f& a, const Point3f& b); }; inline double dot(const Point3f& a, const Point3f& b) { return (a.x * b.x + a.y * b.y + a.z * b.z); } inline Point3f cross(const Point3f& a, const Point3f& b) { return Point3f( a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y ); } // ////////////////////////////////////////////////////////////////////////////// // used for clipping of polygons to regions struct EdgeU { int edge; double u; EdgeU(int e = -1, double _u = 0.0) { edge = e; u = _u; } EdgeU(const EdgeU& eu) { edge = eu.edge; u = eu.u; } friend bool ccwEdgeU(const EdgeU& a, const EdgeU& b, const EdgeU& c); }; // QtRegion class QtRegion { public: Point2f bottom_left; Point2f top_right; QtRegion(const Point2f& bl = Point2f(), const Point2f& tr = Point2f()) { bottom_left = bl; top_right = tr; } QtRegion(const QtRegion& r) { bottom_left = r.bottom_left; top_right = r.top_right; } QtRegion& operator = (const QtRegion& r) { bottom_left = r.bottom_left; top_right = r.top_right; return *this; } // double height() const { return top_right.y - bottom_left.y; } double width() const // The assumption that top_right.x is always > bottom_left.x is not always true. // Returning a negative value here causes an infinite loop at axialmap.cpp line 3106 // after overlapdist is assigned a negative value at axialmap.cpp line 3084. // height() above could also be changed for this reason, but this is a band-aid // fix for the real problem, which is why the top_right > bottom_left assumption // is assumed to be 100% valid but is, in some instances, not valid. // { return top_right.x - bottom_left.x; } { return fabs(top_right.x - bottom_left.x); } double area() const { return height() * width(); } void normalScale( const QtRegion& r ) { top_right.normalScale(r); bottom_left.normalScale(r); } void denormalScale( const QtRegion& r ) { top_right.denormalScale(r); bottom_left.denormalScale(r); } void scale( const Point2f& scalevec ) { top_right.scale(scalevec); bottom_left.scale(scalevec); } void offset( const Point2f& offset ) { top_right += offset; bottom_left += offset; } Point2f getCentre() const { return Point2f( (bottom_left.x + top_right.x) / 2.0, (bottom_left.y + top_right.y) / 2.0 ); } // bool contains ( const Point2f& p ) const { return (p.x > bottom_left.x && p.x < top_right.x && p.y > bottom_left.y && p.y < top_right.y); } bool contains_touch ( const Point2f& p ) const { return (p.x >= bottom_left.x && p.x <= top_right.x && p.y >= bottom_left.y && p.y <= top_right.y); } void encompass( const Point2f& p ) { if (p.x < bottom_left.x) bottom_left.x = p.x; if (p.x > top_right.x) top_right.x = p.x; if (p.y < bottom_left.y) bottom_left.y = p.y; if (p.y > top_right.y) top_right.y = p.y; } // bool atZero() const { return bottom_left.atZero() || top_right.atZero(); } // Point2f getEdgeUPoint(const EdgeU& eu); EdgeU getCutEdgeU(const Point2f& inside, const Point2f& outside); // friend bool intersect_region(const QtRegion& a, const QtRegion& b, double tolerance); friend bool overlap_x(const QtRegion& a, const QtRegion& b, double tolerance); friend bool overlap_y(const QtRegion& a, const QtRegion& b, double tolerance); // // set functions friend QtRegion runion(const QtRegion& a, const QtRegion& b); friend QtRegion rintersect( const QtRegion& a, const QtRegion& b); // undefined? // void grow(const double scalar) { Point2f dim = top_right - bottom_left; dim.scale(scalar - 1.0); top_right += dim; bottom_left -= dim; } }; // First time we have a region available to use... inline void Point2f::normalScale( const QtRegion& r ) { if(r.width()) x = (x - r.bottom_left.x) / r.width(); else x = 0.0; if(r.height()) y = (y - r.bottom_left.y) / r.height(); else y = 0.0; } inline void Point2f::denormalScale( const QtRegion& r ) { x = x * r.width() + r.bottom_left.x; y = y * r.height() + r.bottom_left.y; } // Lines are stored left to right as regions, // the parity tells us whether the region should be inverted // top to bottom to get the line class Line : public QtRegion { protected: struct Bits { Bits() : x_dummy(0), y_dummy(0), z_dummy(0){} char parity : 8; // 1 ... positive, 0 ... negative char direction : 8; // 1 ... positive, 0 ... negative // dummy variables as it seems to be necessary that the width of this struct is 8 bytes // and I don't want any uninitialised memory that gets written to file accidentally char x_dummy : 8; char y_dummy : 8; int z_dummy : 32; }; Bits bits; public: Line(); Line(const Point2f& a, const Point2f& b); Line(const QtRegion& r) : QtRegion(r) { bits.parity = 1; bits.direction = 1; } Line(const Line& l) : QtRegion(l) { bits = l.bits; } Line& operator = (const Line& l) { this->QtRegion::operator = (l); bits = l.bits; return *this; } // friend bool intersect_line(const Line& a, const Line& b, double tolerance); friend bool intersect_line_no_touch(const Line& a, const Line& b, double tolerance); friend int intersect_line_distinguish(const Line& a, const Line& b, double tolerance); friend int intersect_line_b(const Line& a, const Line& b, double tolerance); // // fills in the location along the axis where the intersection happens bool intersect_line(const Line& l, int axis, double& loc) const; double intersection_point(const Line& l, int axis, double tolerance = 0.0) const; // this converts a loc retrieved from intersect line or intersection point back into a point: Point2f point_on_line(double loc, int axis) const; // ...and a quick do it all in one go: friend Point2f intersection_point(const Line& a, const Line& b, double tolerance); // bool crop(const QtRegion& r); void ray(short dir, const QtRegion& r); // friend double dot(const Line& a, const Line& b); // double ax() const { return bottom_left.x; } double& ax() { return bottom_left.x; } double bx() const { return top_right.x; } double& bx() { return top_right.x; } double ay() const { return bits.parity ? bottom_left.y : top_right.y; } double& ay() { return bits.parity ? bottom_left.y : top_right.y; } double by() const { return bits.parity ? top_right.y : bottom_left.y; } double& by() { return bits.parity ? top_right.y : bottom_left.y; } // const Point2f start() const { return Point2f( bottom_left.x, (bits.parity ? bottom_left.y : top_right.y) ); } const Point2f end() const { return Point2f( top_right.x, (bits.parity ? top_right.y : bottom_left.y) ); } const Point2f midpoint() const { return Point2f( (start() + end()) / 2); } // // helpful to have a user friendly indication of direction: bool rightward() const { return bits.direction == 1; } bool upward() const { return bits.direction == bits.parity; } // const Point2f t_start() const { return Point2f( (rightward() ? bottom_left.x : top_right.x), (upward() ? bottom_left.y : top_right.y) ); } const Point2f t_end() const { return Point2f( (rightward() ? top_right.x : bottom_left.x), (upward() ? top_right.y : bottom_left.y) ); } // short sign() const { return bits.parity ? 1 : -1; } // double grad(int axis) const { return (axis == YAXIS) ? sign() * height() / width() : sign() * width() / height(); } double constant(int axis) const { return (axis == YAXIS) ? ay() - grad(axis) * ax() : ax() - grad(axis) * ay(); } // double length() const { return (double) sqrt((top_right.x - bottom_left.x) * (top_right.x - bottom_left.x) + (top_right.y - bottom_left.y) * (top_right.y - bottom_left.y)); } // short direction() const { return bits.direction; } Point2f vector() const { return t_end() - t_start(); } }; inline Point2f intersection_point(const Line& a, const Line& b, double tolerance) { int axis = (a.width() >= a.height()) ? XAXIS : YAXIS; return a.point_on_line(a.intersection_point(b,axis,tolerance),axis); } //////////////////////////////////////////////////////////////////////////////////////// struct TaggedLine { Line line; int tag; TaggedLine(const Line& l = Line(),int t = -1) { line = l; tag = t; } }; // plain 2-point line without regions struct SimpleLine { public: SimpleLine(const Line& line) { m_start.x = line.start().x; m_start.y = line.start().y; m_end.x = line.end().x; m_end.y = line.end().y; } SimpleLine(const Point2f& a, const Point2f& b) { m_start.x = a.x; m_start.y = a.y; m_end.x = b.x; m_end.y = b.y; } SimpleLine(double x1, double y1, double x2, double y2) { m_start.x = x1; m_start.y = y1; m_end.x = x2; m_end.y = y2; } const Point2f& start() const { return m_start; } const Point2f& end() const { return m_end; } private: Point2f m_start; Point2f m_end; }; //////////////////////////////////////////////////////////////////////////////////////// // not sure if this code is used any more: // Now the difficult bit: making the line segments into polygons... // The polygons are stored in a tree format so that intersection testing is easier class Poly; class RegionTree { friend class mgraph440::Poly; protected: Line *m_p_region; RegionTree *m_p_left; RegionTree *m_p_right; public: RegionTree() { m_p_region = NULL; m_p_left = this; m_p_right = this; } virtual ~RegionTree() { if (m_p_region) delete m_p_region; } // virtual bool is_leaf() const = 0; // RegionTree& left() const { return *m_p_left; } RegionTree& right() const { return *m_p_right; } // operator QtRegion() const { return *(QtRegion *)m_p_region; } operator Line() const { return *(Line *)m_p_region; } // friend bool intersect(const RegionTree& a, const RegionTree& b); friend bool subintersect(const RegionTree& a, const RegionTree& b); friend int intersections(const RegionTree& a, const Line& b); }; // Branch on a region tree... class RegionTreeBranch : public RegionTree { public: RegionTreeBranch() : RegionTree() {;} RegionTreeBranch( const Line& r, const RegionTree& a, const RegionTree& b ) { m_p_left = (RegionTree *) &a; m_p_right = (RegionTree *) &b; m_p_region = new Line(r); // copy } virtual bool is_leaf() const { return false; } }; // Leaf on a region tree... class RegionTreeLeaf : public RegionTree { public: RegionTreeLeaf() : RegionTree() {;} RegionTreeLeaf(const Line &l) { // no subnodes (but nice recursive properties) m_p_left = this; m_p_right = this; m_p_region = new Line(l); } virtual bool is_leaf() const { return true; } }; class Poly { protected: int m_line_segments; RegionTree *m_p_root; public: Poly() { m_p_root = NULL; m_line_segments = 0; } Poly( const Poly& p ) { m_line_segments = p.m_line_segments; m_p_root = copy_region_tree( p.m_p_root ); } Poly& operator = (const Poly& p) { if (this != &p) { m_line_segments = p.m_line_segments; m_p_root = copy_region_tree( p.m_p_root ); } return *this; } virtual ~Poly() { destroy_region_tree(); } // essentially, the copy constructor... RegionTree *copy_region_tree( const RegionTree* tree ); // essentially, the destructor... void destroy_region_tree(); // RegionTree& get_region_tree() const { return *m_p_root; } // void add_line_segment(const Line& l); // int get_line_segments() { return m_line_segments; } QtRegion get_bounding_box() { return *(QtRegion *)(m_p_root->m_p_region); } // bool contains( const Point2f& p ); friend bool intersect( const Poly& a, const Poly& b ); }; } ================================================ FILE: mgraph440/pafcolor.cpp ================================================ #include "mgraph440/pafcolor.h" namespace mgraph440 { static unsigned int g_nicecolor[] = { 0x003333DD, // 0 blue 0x003388DD, // 1 0x0022CCDD, // 2 0x0022CCBB, // 3 0x0022DD88, // 4 0x0088DD22, // 5 0x00BBCC22, // 6 0x00DDCC22, // 7 0x00DD8833, // 8 0x00DD3333, // 9 red }; // Test a range designed to try to keep consitent saturation and brightness of g_nicecolor, and only move hue static unsigned int g_nicecolorhsb[] = { 0x003333DD, // 0 blue 0x003377DD, // 1 0x0033BBDD, // 2 0x0033DDBB, // 3 0x0033DD55, // 4 0x0055DD33, // 5 0x00BBDD33, // 6 0x00DDBB33, // 7 0x00DD7733, // 8 0x00DD3333, // 9 red }; static unsigned int g_hsbcolor[] = { 0x003333DD, // 0 blue 0x003388DD, // 1 0x0022CCDD, // 2 0x0022CCBB, // 3 0x0022DD88, // 4 0x0088DD22, // 5 0x00BBCC22, // 6 0x00DDCC22, // 7 0x00DD8833, // 8 0x00DD3333, // 9 red }; static unsigned int g_greyscale[] = { 0x00000000, // 0 black 0x00444444, // 1 0x00777777, // 2 0x00AAAAAA, // 3 0x00CCCCCC, // 4 0x00EEEEEE, // 5 0x00FFFFFF, // 6 white }; static unsigned int g_bluered[] = { 0x004575B4, // 0 blue 0x0091BFDB, 0x00E0F3F8, 0x00FFFFBF, 0x00FEE090, 0x00FC8D59, 0x00D73027 // 6 red }; static unsigned int g_purpleorange[] = { 0x00542788, // 0 purple 0x00998EC3, // 1 0x00D8DAEB, // 2 0x00F7F7F7, // 3 0x00FEE0B6, // 4 0x00F1A340, // 5 0x00B35806 // 6 orange }; // htmlByte converts a normalised number to an HTML safe byte unsigned char htmlByte440(double colorByte) { // Quick mod - TV #if defined(_MSC_VER) return (unsigned char((colorByte + 0.0333) * 15.0) * 0x11); #else return ((unsigned char)((colorByte + 0.0333) * 15.0) * 0x11); #endif } PafColor& PafColor::makeColor(double field, DisplayParams dp) { // Quick mod - TV if (field == -1.0 || std::isnan(field)) { // -1.0 is (currently) a nan value, set alpha channel to 0 (transparent) switch (dp.colorscale) { case DisplayParams::MONOCHROME: case DisplayParams::GREYSCALE: m_color = 0x00000000; // <- monochrome and greyscale, simply hide break; default: // if in colour, then show greyed out: m_color = 0x007f7f7f; // <- grey retained for visibility on certain values break; } return *this; } if (dp.blue > dp.red) { field = 1.0 - field; dp.blue = 1.0f - dp.blue; dp.red = 1.0f - dp.red; } if (dp.colorscale == DisplayParams::DEPTHMAPCLASSIC) { makeDepthmapClassic(field, dp.blue, dp.red); } else { field = (field - dp.blue) / (dp.red - dp.blue); // Quick mod - TV if (std::isnan(field)) { field = 0.5; } if (field > 1.0) { field = 1.0; } else if (field < 0.0) { field = 0.0; } switch(dp.colorscale) { case DisplayParams::AXMANESQUE: makeAxmanesque(field); break; case DisplayParams::PURPLEORANGE: makePurpleOrange(field); break; case DisplayParams::BLUERED: makeBlueRed(field); break; case DisplayParams::GREYSCALE: case DisplayParams::MONOCHROME: makeGreyScale(field); break; } } return *this; } // this makes an Axman-like colour range PafColor& PafColor::makeAxmanesque( double field ) { m_color = 0xff000000 | g_nicecolor[int((field - 1e-9) * 10.0)]; return *this; } // this makes a purple-orange scheme that is red-green colour-blind safe PafColor& PafColor::makePurpleOrange( double field ) { m_color = 0xff000000 | g_purpleorange[int((field - 1e-9) * 7.0)]; return *this; } // this makes a blue-red scheme that is red-green colour-blind safe PafColor& PafColor::makeBlueRed( double field ) { m_color = 0xff000000 | g_bluered[int((field - 1e-9) * 7.0)]; return *this; } // this makes a greyscale colour range PafColor& PafColor::makeGreyScale( double field ) { m_color = 0xff000000 | g_greyscale[int((field - 1e-9) * 7.0)]; return *this; } // note, makeDepthmapClassic converts to a safe HTML colour PafColor& PafColor::makeDepthmapClassic( double field, double blue, double red ) { m_color = 0xff000000; // set alpha to 255, solid colour double green = blue + (red-blue) / 10.0; // NB previously included colour muting: the 1.0 was originally 0.9 to mute the colours slightly if (field >= 0.0 && field < blue) { setr(htmlByte440(0.5 * (blue - field)/blue * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setb(unsigned char(0xFF)); #else setb((unsigned char)(0xFF)); #endif } else if (field >= blue && field < (green+blue)/2.0) { // Quick mod - TV #if defined(_MSC_VER) setb(unsigned char(0xFF)); #else setb((unsigned char)(0xFF)); #endif setg(htmlByte440((2.0*(field - blue)/(green-blue)) * 1.0)); } else if (field >= (green+blue)/2.0 && field < green) { setb(htmlByte440((2.0*(green - field)/(green-blue)) * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setg(unsigned char(0xFF)); #else setg((unsigned char)(0xFF)); #endif } else if (field >= green && field < (green+red)/2.0 ) { // Quick mod - TV #if defined(_MSC_VER) setg(unsigned char(0xFF)); #else setg((unsigned char)(0xFF)); #endif setr(htmlByte440((2.0*(field - green)/(red-green)) * 1.0)); } else if (field >= (green+red)/2.0 && field < red) { setg(htmlByte440((2.0*(red - field)/(red-green)) * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setr(unsigned char(0xFF)); #else setr((unsigned char)(0xFF)); #endif } else if (field >= red) { // Quick mod - TV #if defined(_MSC_VER) setr(unsigned char(0xFF)); #else setr((unsigned char)(0xFF)); #endif setb(htmlByte440(0.5 * (field - red)/(1.0 - red) * 1.0)); } return *this; } } ================================================ FILE: mgraph440/pafcolor.h ================================================ #pragma once #include "mgraph440/displayparams.h" #include "mgraph440/p2dpoly.h" // Converts everything to safe HTML colours namespace mgraph440 { struct PafColor { unsigned int m_color; unsigned char redb() const { return (unsigned char) (m_color >> 16); } unsigned char greenb() const { return (unsigned char) (m_color >> 8); } unsigned char blueb() const { return (unsigned char) (m_color); } unsigned char alphab() const { return (unsigned char) (m_color >> 24); } // Quick mod - TV void setr(unsigned char r) { m_color &= 0xff00ffff; m_color |= (((unsigned int)r) << 16);} // Quick mod - TV void setg(unsigned char g) { m_color &= 0xffff00ff; m_color |= (((unsigned int)g) << 8);} // Quick mod - TV void setb(unsigned char b) { m_color &= 0xffffff00; m_color |= ((unsigned int)b);} float redf() const { return float(redb()) / 255.0f; } float greenf() const { return float(greenb()) / 255.0f; } float bluef() const { return float(blueb()) / 255.0f; } PafColor() { m_color = 0x00000000; } PafColor(unsigned int rgb) // color in 0x00rrggbb format { m_color = 0xff000000 | rgb; } PafColor( double r, double g, double b, double a = 1.0 ) { m_color = 0x00000000 | (((unsigned char) (a * 255.0)) << 24) | (((unsigned char) (r * 255.0)) << 16) | (((unsigned char) (g * 255.0)) << 8) | (((unsigned char) (b * 255.0))); } PafColor( const Point2f& vec, double a = 1.0 ) { m_color = 0x00000000 | (((unsigned char) (a * 255.0)) << 24) | (((unsigned char) (dot(vec,Point2f(1.0, 0.0)) * 255.0)) << 16) | (((unsigned char) (dot(vec,Point2f(-0.5,0.86602540378443864676372317075294)) * 255.0)) << 8) | (((unsigned char) (dot(vec,Point2f(-0.5,-0.86602540378443864676372317075294)) * 255.0))); } operator unsigned int () { return m_color & 0x00ffffff; } friend bool operator == (const PafColor& a, const PafColor& b); friend bool operator != (const PafColor& a, const PafColor& b); PafColor& makeAxmanesque( double field); PafColor& makePurpleOrange( double field ); PafColor& makeBlueRed( double field ); PafColor& makeGreyScale( double field ); PafColor& makeMonochrome( double field ); PafColor& makeDepthmapClassic( double field, double blue, double red ); PafColor& makeColor(double field, DisplayParams dp); // <- note, make copy to play around with }; inline bool operator == (const PafColor& a, const PafColor& b) { return (a.m_color == b.m_color); } inline bool operator != (const PafColor& a, const PafColor& b) { return (a.m_color != b.m_color); } } ================================================ FILE: mgraph440/pafmath.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // a collection of math functions #include #include #include namespace mgraph440 { uint64_t g_rand[11] = {1,2,3,5,7,11,13,17,19,23,29}; // 25-Jul-2007: changed the g_mult and g_const used for random number generation // for some reason, there appeared to be a pattern to the numbers // Quick mod - TV const uint64_t g_mult = /*(0xF9561B2E << 32) + */0x71A7FA85; const uint64_t g_const = /*(0x9BB3920E << 32) + */0xF5E958B9; void pafsrand(unsigned int seed, int set) // = 0 { g_rand[set] = seed; } // Pafrand is a Linear Congruential Generator // After the 25-Jul-2007 changes: // The current version seems to meet standard randomness conditions // Tested using Diehard, the 32 bit version ((g_rand[set] >> 32) & 0xffffffff) // passes all tests for at least the first 5 seeds above // it is also independent in at least 20 dimensions // It should not be used for "serious" randomness, but should be fine // for most things (agents in depthmapX, genetic algorithms, etc) // 25-Jul-2007: moved up to take top 32 bits unsigned int pafrand(int set) // = 0 { g_rand[set] = g_mult * g_rand[set] + g_const; return (unsigned int)((g_rand[set] >> 32) & PAF_RAND_MAX); } /////////////////////////////////////////////////////////////////////////////// double poisson(int x, double lambda) { double f = exp(-lambda); for (int i = 1; i <= x; i++) { f *= lambda / double(i); } return f; } double cumpoisson(int x, double lambda) { double f = exp(-lambda); double c = f; for (int i = 1; i <= x; i++) { f *= lambda / double(i); c += f; } return c; } int invcumpoisson(double p, double lambda) { if (p <= 0) { return 0; } if (p >= 1) { // passing this 1 will cause an infinite loop, try this instead: p = 1-1e-9; } double f = exp(-lambda); int i = 0; for (double c = f; c < p; c += f) { i++; f *= lambda / double(i); } return i; } } ================================================ FILE: mgraph440/pafmath.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Paf Template Library --- a set of useful C++ templates // // Copyright (c) 1996-2011 Alasdair Turner (a.turner@ucl.ac.uk) // //----------------------------------------------------------------------------- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See the lgpl.txt file for details //----------------------------------------------------------------------------- // a collection of math functions #ifndef __PAFMATH_H__ #define __PAFMATH_H__ #include namespace mgraph440 { #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif inline double sqr(double a) { return (a*a); } inline int sgn(double a) { return (a < 0) ? -1 : 1; } #ifndef M_ROOT_1_2 #define M_ROOT_1_2 0.70710678118654752440084436210485 #endif #ifndef M_1_LN2 #define M_1_LN2 1.4426950408889634073599246810019 #endif const unsigned int PAF_RAND_MAX = 0x0FFFFFFF; void pafsrand(unsigned int seed, int set = 0); unsigned int pafrand(int set = 0); // a random number from 0 to 1 inline double prandom(int set = 0) { return double(pafrand(set)) / double(PAF_RAND_MAX); } // a random number from 0 to just less than 1 inline double prandomr(int set = 0) { return double(pafrand(set)) / double(PAF_RAND_MAX + 1); } // note, in order to stop confusing myself I have ln defined: #define ln(X) log(X) inline double log2(double a) { return (ln(a) * M_1_LN2); } // Hillier Hanson dvalue /* inline double dvalue(double k) { return 2.0 * (3.3231 * k * log10(k+2) - 2.5863 * k + 1.0) / ((k - 1.0) * (k - 2.0)); } */ // Hillier Hanson dvalue (from Kruger 1989 -- see Teklenburg et al) inline double dvalue(double k) { return 2.0 * (k * (log2((k+2.0)/3.0) - 1.0) + 1.0) / ((k - 1.0) * (k - 2.0)); } // Hillier Hanson pvalue inline double pvalue(double k) { return 2.0 * (k - log2(k) - 1.0) / ((k - 1.0) * (k - 2.0)); } // Teklenburg integration (correction 31.01.11 due to Ulrich Thaler inline double teklinteg(double nodecount, double totaldepth) { return ln(0.5 * (nodecount - 2.0)) / ln(double(totaldepth - nodecount + 1)); } // Penn palmtree inline double palmtree(double n, double r) { if (n > r) { return r * (n - 0.5 * (r+1)); } else { return 0.5 * n * (n - 1); } } double poisson(int x, double lambda); double cumpoisson(int x, double lambda); int invcumpoisson(double p, double lambda); } #endif ================================================ FILE: mgraph440/paftl.h ================================================ // Paf Template Library --- a set of useful C++ templates // // Copyright (c) 1996-2011 Alasdair Turner (a.turner@ucl.ac.uk) // //----------------------------------------------------------------------------- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // // See the lgpl.txt file for details //----------------------------------------------------------------------------- // // Paf's cross platform box of tricks // Everything you need to write any C++. All in one file! // // pmemvec base clase for pvector and prefvec // pvector similar to STL vector // prefvec pvector with a different allocator (vector of references) // pqvector searchable prefvec // pqmap a simple map class, based on a binary tree // ptree a simple tree template // pflipper used for flipping between two vectors (or anythings...) // pexception exception class, base for various exception types // // // A3 eliminates the double referencing used previously in the // vector classes #ifndef __PAFTL_MGRAPH440_H__ #define __PAFTL_MGRAPH440_H__ #include #include #include #include #include #include #ifdef _MSC_VER // MSVC compiler #else #include // not guaranteed to exist, but does in Mac / Ubuntu #endif namespace mgraph440 { #define PAFTL_DATE "01-FEB-2011" // 31-jan-2011: unicode constructor for pstring // 04-aug-2010: fix bug on quicksort to avoid sorting zero length array // 06-jun-2010: rewrite quicksort to avoid infinite loop // 31-aug-2009: change pstring constructors to align with STL string // 28-nov-2007: full implementation for ANSI standards // 28-nov-2007: minor bug on pvecsub construction: should be 2 << count rather than 1 << count // 30-aug-2007: make compatible with Unix / MacOS #ifdef _WIN32 // Quick mod - TV #pragma warning (disable: 4996 ) #pragma warning (disable: 4396 ) #else #endif #ifdef _MSC_VER // MSVC compiler typedef signed __int64 int64; typedef unsigned __int64 uint64; #else typedef int64_t int64; typedef uint64_t uint64; #endif #ifndef bool // #define bool int #endif #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif /////////////////////////////////////////////////////////////////////////////// // namespace paftl { class pexception; template class pvector; template class prefvec; template class pqvector; template class pqmap; template class ptree; template class pflipper; // a few basic types typedef pvector pvecint; typedef pvector pvecfloat; typedef pvector pvecdouble; /////////////////////////////////////////////////////////////////////////////// // miscellaneous enums (paftl used as namespace) namespace paftl { enum add_t {ADD_UNIQUE, ADD_REPLACE, ADD_DUPLICATE, ADD_HERE}; const size_t npos = size_t(-1); } /////////////////////////////////////////////////////////////////////////////// class pexception { public: enum exception_t { UNDEFINED = 0x0000, MEMORY_ALLOCATION = 0x0001, FILE_ERROR = 0x0002, MAX_ARRAY_EXCEEDED = 0x0003}; protected: int m_exception; size_t m_data; public: pexception(int n_exception = UNDEFINED, size_t data = 0) { m_exception = n_exception; m_data = data; } int error_code() { return m_exception; } size_t info() { return m_data; } }; /////////////////////////////////////////////////////////////////////////////// // pmemvec: base allocation for pvector and prefvec template class pmemvec { public: class exception : public pexception { public: enum exception_t { PVECTOR_UNDEFINED = 0x1000, EMPTY_VECTOR = 0x1001, UNASSIGNED_ITERATOR = 0x1002, OUT_OF_RANGE = 0x1003}; public: exception(int n_exception = PVECTOR_UNDEFINED, size_t data = 0) : pexception( n_exception, data ) {} }; protected: T *m_data; unsigned short m_shift; size_t m_length; public: // redefine pmemvec(size_t sz = 0); pmemvec(const pmemvec& ); virtual ~pmemvec(); pmemvec& operator = (const pmemvec& ); // virtual void push_back(const T& item); virtual void pop_back(); virtual void remove_at(size_t pos = 0); virtual void remove_at(const pvecint& list); virtual void insert_at(size_t pos, const T& item); // virtual void set(size_t count); virtual void set(const T& item, size_t count); // virtual void clear(); virtual void clearnofree(); protected: size_t storage_size() const { return m_shift ? (2 << m_shift) : 0; } void grow(size_t pos); void shrink(); public: size_t size() const { return m_length; } T& base_at(size_t pos) { return m_data[pos]; } const T& base_at(size_t pos) const { return m_data[pos]; } public: ::std::istream& read( ::std::istream& stream, ::std::streampos offset = ::std::streampos(-1) ); ::std::ostream& write( ::std::ostream& stream ); }; template pmemvec::pmemvec(size_t sz) { // note: uses same as grow / storage_size, but cannot rely on function existence when calling constructor if (sz == 0) { m_data = NULL; m_shift = 0; } else { do { m_shift++; } while ((size_t(2) << m_shift) < sz); m_data = new T [storage_size()]; if (m_data == NULL) { throw pexception(pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size()); } } m_length = 0; } template pmemvec::pmemvec(const pmemvec& v) { m_shift = v.m_shift; m_length = v.m_length; if (m_shift) { m_data = new T [storage_size()]; if (m_data == NULL) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); if (m_length) { for (size_t i = 0; i < m_length; i++) m_data[i] = v.m_data[i]; } } else { m_data = NULL; } } template pmemvec::~pmemvec() { if (m_data) { delete [] m_data; m_data = NULL; } } template pmemvec& pmemvec::operator = (const pmemvec& v) { if (m_shift < v.m_shift) { if (m_shift != 0) { delete [] m_data; } m_shift = v.m_shift; if (m_shift) { m_data = new T [storage_size()]; if (!m_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); } else { m_data = NULL; } } m_length = v.m_length; if (m_length) { for (size_t i = 0; i < m_length; i++) m_data[i] = v.m_data[i]; } return *this; } template void pmemvec::push_back(const T& item) { if (m_length >= storage_size()) { grow( m_length ); } m_data[m_length] = item; m_length++; } template void pmemvec::pop_back() { if (m_length == 0) throw exception( exception::EMPTY_VECTOR ); --m_length; // Preferably include shrink code here } template void pmemvec::insert_at(size_t pos, const T& item) { if (pos == paftl::npos || pos > m_length) { throw exception( exception::OUT_OF_RANGE ); } if (m_length >= storage_size()) { grow( pos ); } else { for (size_t i = m_length; i > pos; i--) { m_data[i] = m_data[i - 1]; } } m_data[pos] = item; m_length++; } template void pmemvec::remove_at(size_t pos) { // This is a simple but reliable remove item from vector if (m_length == 0) throw exception( exception::EMPTY_VECTOR ); else if (pos == paftl::npos || pos >= m_length) throw exception( exception::OUT_OF_RANGE ); for (size_t i = pos; i < m_length - 1; i++) { m_data[i] = m_data[i + 1]; } --m_length; // Preferably include shrink code here } template void pmemvec::set(size_t count) { clear(); do { m_shift++; } while ((size_t(2) << m_shift) < count); m_data = new T [storage_size()]; if (!m_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); m_length = count; } template void pmemvec::set(const T& item, size_t count) { clear(); do { m_shift++; } while ((size_t(2) << m_shift) < count); m_data = new T [storage_size()]; if (!m_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); m_length = count; for (size_t i = 0; i < m_length; i++) { m_data[i] = item; } } template void pmemvec::clear() { m_length = 0; m_shift = 0; if (m_data) { delete [] m_data; m_data = NULL; } } template void pmemvec::clearnofree() { m_length = 0; } template void pmemvec::grow(size_t pos) { m_shift++; T *new_data = new T [storage_size()]; if (!new_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); if (m_length) { for (size_t i = 0; i < m_length + 1; i++) new_data[i] = (i < pos) ? m_data[i] : m_data[i-1]; } if (m_data) { delete [] m_data; } m_data = new_data; } template void pmemvec::shrink() { } template ::std::istream& pmemvec::read( ::std::istream& stream, ::std::streampos offset ) { if (offset != ::std::streampos(-1)) { stream.seekg( offset ); } // READ / WRITE USES 32-bit LENGTHS (number of elements) // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length; stream.read( (char *) &length, sizeof(unsigned int) ); m_length = size_t(length); if (m_length >= storage_size()) { if (m_data) { delete [] m_data; m_data = NULL; } while (m_length >= storage_size()) m_shift++; m_data = new T [storage_size()]; if (!m_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); } if (m_length != 0) { stream.read( (char *) m_data, sizeof(T) * ::std::streamsize(m_length) ); } return stream; } template ::std::ostream& pmemvec::write( ::std::ostream& stream ) { // READ / WRITE USES 32-bit LENGTHS (number of elements) // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems // check for max unsigned int exceeded if (m_length > size_t((unsigned int)-1)) { throw pexception( pexception::MAX_ARRAY_EXCEEDED, m_length ); } // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length = (unsigned int)(m_length); stream.write( (char *) &length, sizeof(unsigned int) ); if (m_length != 0) { stream.write( (char *) m_data, sizeof(T) * ::std::streamsize(m_length) ); } return stream; } /////////////////////////////////////////////////////////////////////////////// template class pvector : public pmemvec { protected: mutable size_t m_current; public: pvector(size_t sz = 0) : pmemvec(sz) {m_current = paftl::npos;} pvector(const pvector& v) : pmemvec(v) {m_current = v.m_current;} pvector& operator = (const pvector& ); virtual ~pvector() {;} // T& at(size_t pos) { return pmemvec::m_data[pos]; } const T& at(size_t pos) const { return pmemvec::m_data[pos]; } T& operator[](size_t pos) { return at(pos); } const T& operator[](size_t pos) const { return at(pos); } // T& head() { return at(0); } const T& head() const { return at(0); } T& tail() { return at(pmemvec::m_length-1); } const T& tail() const { return at(pmemvec::m_length-1); } // standard operations (unordered vector) T& find(const T& item); const T& find(const T& item) const; size_t findindex(const T& item) const; // binary operations (ordered vector) size_t add(const T& item, int type = paftl::ADD_UNIQUE); // ignored if already exists T& search(const T& item); const T& search(const T& item) const; size_t searchindex(const T& item) const; size_t searchfloorindex(const T& item) const; size_t searchceilindex(const T& item) const; void remove(const T& item) { pmemvec::remove_at(searchindex(item)); } // set operations (ordered vector) void operator += (const pvector& v); // qsort algo: void sort(); void sort(size_t left, size_t right); // // Quick mod - TV #if defined(_MSC_VER) friend pvector intersect(const pvector& a, const pvector& b); #endif }; template pvector& pvector::operator = (const pvector& v) { if (&v != this) { pmemvec::operator = (v); } return *this; } template T& pvector::find(const T& item) { if (findindex(item) == paftl::npos) { throw pmemvec::exception::exception(pmemvec::exception::OUT_OF_RANGE); } return at(m_current); } template const T& pvector::find(const T& item) const { if (findindex(item) == paftl::npos) { throw pmemvec::exception(pmemvec::exception::OUT_OF_RANGE); } return at(m_current); } template size_t pvector::findindex(const T& item) const { for (size_t i = 0; i < pmemvec::m_length; i++) { if (at(i) == item) { m_current = i; return i; } } return paftl::npos; } // oops... we need an iterator... add use a current position marker. template T& pvector::search(const T& item) { if (searchindex(item) == paftl::npos) { throw pmemvec::exception(pmemvec::exception::OUT_OF_RANGE); // Not found } return at(m_current); } template const T& pvector::search(const T& item) const { if (searchindex(item) == paftl::npos) { throw pmemvec::exception(pmemvec::exception::OUT_OF_RANGE); // Not found } return at(m_current); } template size_t pvector::searchindex(const T& item) const { if (pmemvec::m_length != 0) { size_t ihere, ifloor = 0, itop = pmemvec::m_length - 1; while (itop != paftl::npos && ifloor <= itop) { m_current = ihere = (ifloor + itop) / 2; if (item == at(ihere)) { return m_current; } else if (item > at(ihere)) { ifloor = ihere + 1; } else { itop = ihere - 1; } } } return paftl::npos; } template size_t pvector::searchfloorindex(const T& item) const { searchindex(item); while (m_current != 0 && at(m_current) > item) { m_current--; } return m_current; } template size_t pvector::searchceilindex(const T& item) const { searchindex(item); while (m_current < pmemvec::m_length && at(m_current) < item) { m_current++; } return m_current; } // Note: uses m_current set by searchindex // Really need a list 'merge' function as well... will write this soon! template size_t pvector::add(const T& item, int type) // UNIQUE by default { size_t where = paftl::npos; if (pmemvec::m_length == 0 || item > pvector::tail()) { // often used for push_back, so handle quickly if so pmemvec::push_back( item ); where = pmemvec::m_length - 1; } else { // if you call with ADD_HERE, it is assumed you've just used search or searchindex // i.e., we don't need to go through the binary search again to find the insert position if (type != paftl::ADD_HERE) { searchindex(item); } if (item < at(m_current)) { pmemvec::insert_at( m_current, item ); where = m_current; } else if (item > at(m_current) || type == paftl::ADD_DUPLICATE) { pmemvec::insert_at( m_current + 1, item ); where = m_current + 1; } else if (type == paftl::ADD_REPLACE || type == paftl::ADD_HERE) { // relies on good assignment operator at(m_current) = item; } // n.b., type "UNIQUE" does not replace, returns -1 } return where; } template void pvector::operator += (const pvector& v) { if (this != &v && pmemvec::m_length + v.pmemvec::m_length > 0) { while (pmemvec::m_length + v.pmemvec::m_length >= pmemvec::storage_size()) pmemvec::m_shift++; T *new_data = new T [pmemvec::storage_size()]; if (!new_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * pmemvec::storage_size() ); size_t i = 0, j = 0, k = 0; while (i + j < pmemvec::m_length + v.pmemvec::m_length) { if ( i < pmemvec::m_length ) { if (j < v.pmemvec::m_length) { if (pmemvec::m_data[i] < v.pmemvec::m_data[j]) { new_data[k++] = pmemvec::m_data[i++]; } else if (pmemvec::the_data()[i] > v.pmemvec::the_data()[j]) { new_data[k++] = v.pmemvec::m_data[j++]; } else { new_data[k++] = pmemvec::m_data[i++]; j++; } } else { while (i < pmemvec::m_length) { new_data[k++] = pmemvec::m_data[i++]; } } } else { while (j < v.pmemvec::m_length) { new_data[k++] = v.pmemvec::m_data[j++]; } } } if (pmemvec::m_data) { delete [] pmemvec::m_data; } pmemvec::m_length = k; pmemvec::m_data = new_data; } } template void pvector::sort() { if (pmemvec::m_length != 0) { sort(0,pmemvec::m_length-1); } } // rewrite 6-jun-10 (was entering infinite loop, now appears to work properly) template void pvector::sort(size_t left, size_t right) { size_t i = left, j = right; const T& val = pmemvec::m_data[(left+right)/2]; while (j != paftl::npos && i <= j) { while (i <= j && pmemvec::m_data[i] < val) i++; while (j != paftl::npos && pmemvec::m_data[j] > val) j--; if (j != paftl::npos && i <= j) { // swap contents T temp = pmemvec::m_data[i]; pmemvec::m_data[i] = pmemvec::m_data[j]; pmemvec::m_data[j] = temp; i++; j--; } } if (j != paftl::npos && left < j) sort(left, j); if (i < right) sort(i, right); } // requires two sorted lists template inline pvector intersect(const pvector& a, const pvector& b) { pvector retvec; size_t i = 0; size_t j = 0; while (i < a.size() && j < b.size()) { if (a[i] == b[j]) { retvec.push_back(a[i]); i++; j++; } else { while (a[i] < b[j] && i < a.size()) { i++; } while (a[i] > b[j] && j < b.size()) { j++; } } } return retvec; } /////////////////////////////////////////////////////////////////////////////// // this version for bulk deletes: copies over entries to new list // (first requires pvector to have been defined) template void pmemvec::remove_at(const pvecint& list) { if (m_length == 0) throw exception( exception::EMPTY_VECTOR ); if (list.size() >= m_length) { // if the list does not contain duplicates, then this simply means delete all contents: clear(); return; } // shrink new vector: while ((m_length - list.size()) * 2 < storage_size()) { m_shift--; } size_t new_length = 0; T *new_data = new T [storage_size()]; bool *rem_flag = new bool [m_length]; if (!new_data) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() ); if (!rem_flag) throw pexception( pexception::MEMORY_ALLOCATION, sizeof(bool) * storage_size() ); size_t i; for (i = 0; i < m_length; i++) { rem_flag[i] = false; } for (i = 0; i < list.size(); i++) { if (size_t(list[i]) == paftl::npos || size_t(list[i]) >= m_length) throw exception( exception::OUT_OF_RANGE ); rem_flag[list[i]] = true; } for (i = 0; i < m_length; i++) { if (!rem_flag[i]) { new_data[new_length] = m_data[i]; new_length++; } } m_length = new_length; delete [] m_data; delete [] rem_flag; m_data = new_data; } /////////////////////////////////////////////////////////////////////////////// // prefvec: a vector of references (useful for larger objects) // should be able to use pqvector in most cases template class prefvec : public pmemvec { public: prefvec(size_t sz = 0) : pmemvec(sz) {;} prefvec(const prefvec& ); virtual ~prefvec(); prefvec& operator = (const prefvec& ); // void push_back(const T& item); void pop_back(); void remove_at(size_t pos = 0); void free_at(size_t pos = 0); void remove_at(const pvecint& list); void insert_at(size_t pos, const T& item); // void set(size_t count); void set(const T& item, size_t count); // void clear(); void clearnofree(); // T& at(size_t pos) { return *(pmemvec::m_data[pos]); } const T& at(size_t pos) const { return *(pmemvec::m_data[pos]); } T& operator[](size_t pos) { return at(pos); } const T& operator[](size_t pos) const { return at(pos); } // T& head() { return at(0); } const T& head() const { return at(0); } T& tail() { return at(pmemvec::m_length-1); } const T& tail() const { return at(pmemvec::m_length-1); } // // NOTE: no find (as often equivalence operator will not be defined) // // Override read and write ::std::istream& read( ::std::istream& stream ); ::std::ostream& write( ::std::ostream& stream ); }; template prefvec::prefvec(const prefvec& v) : pmemvec(v) { for (size_t i = 0; i < pmemvec::m_length; i++) { pmemvec::m_data[i] = new T(v.at(i)); if (pmemvec::m_data[i] == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } } } template prefvec& prefvec::operator = (const prefvec& v) { if (&v != this) { for (size_t i = 0; i < pmemvec::m_length; i++) { delete pmemvec::m_data[i]; } pmemvec::operator = (v); for (size_t j = 0; j < pmemvec::m_length; j++) { pmemvec::m_data[j] = new T(v.at(j)); if (pmemvec::m_data[j] == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } } } return *this; } template prefvec::~prefvec() { for (size_t i = 0; i < pmemvec::m_length; i++) { if (pmemvec::m_data[i]) delete pmemvec::m_data[i]; } // virtual destructor called for pmemvec } template void prefvec::push_back(const T& item) { T *p = new T(item); pmemvec::push_back( p ); } template void prefvec::pop_back() { if (pmemvec::m_data[pmemvec::m_length - 1]) { delete pmemvec::m_data[pmemvec::m_length - 1]; pmemvec::m_data[pmemvec::m_length - 1] = NULL; } pmemvec::pop_back(); } template void prefvec::remove_at(size_t pos) { if (pmemvec::m_length == 0) throw (typename pmemvec::exception)( pmemvec::exception::EMPTY_VECTOR ); else if (pos == paftl::npos || pos >= pmemvec::m_length) throw (typename pmemvec::exception)( pmemvec::exception::OUT_OF_RANGE ); if (pmemvec::m_data[pos]) { delete pmemvec::m_data[pos]; pmemvec::m_data[pos] = NULL; } pmemvec::remove_at( pos ); } // just frees the memory at position: does not manipulate vector template void prefvec::free_at(size_t pos) { if (pmemvec::m_length == 0) throw (typename pmemvec::exception)( pmemvec::exception::EMPTY_VECTOR ); else if (pos == paftl::npos || pos >= pmemvec::m_length) throw (typename pmemvec::exception)( pmemvec::exception::OUT_OF_RANGE ); delete pmemvec::m_data[pos]; pmemvec::m_data[pos] = NULL; } // this version for intended for bulk deletes (also retains previous ordering) template void prefvec::remove_at(const pvecint& list) { if (pmemvec::m_length == 0) throw (typename pmemvec::exception)( pmemvec::exception::EMPTY_VECTOR ); for (size_t i = 0; i < list.size(); i++) { if (size_t(list[i]) == paftl::npos || size_t(list[i]) >= pmemvec::m_length) throw (typename pmemvec::exception)( pmemvec::exception::OUT_OF_RANGE ); if (pmemvec::m_data[list[i]]) { delete pmemvec::m_data[list[i]]; pmemvec::m_data[list[i]] = NULL; } } pmemvec::remove_at( list ); } template void prefvec::insert_at(size_t pos, const T& item) { T *p = new T(item); if (p == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } pmemvec::insert_at(pos, p); } template void prefvec::set(size_t count) { pmemvec::set(count); for (size_t i = 0; i < pmemvec::m_length; i++) { pmemvec::m_data[i] = NULL; if (pmemvec::m_data[i] == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } } } template void prefvec::set(const T& item, size_t count) { pmemvec::set(count); for (size_t i = 0; i < pmemvec::m_length; i++) { pmemvec::m_data[i] = new T(item); if (pmemvec::m_data[i] == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } } } template void prefvec::clear() { for (size_t i = 0; i < pmemvec::m_length; i++) { if (pmemvec::m_data[i]) { delete pmemvec::m_data[i]; pmemvec::m_data[i] = NULL; } } pmemvec::clear(); } template void prefvec::clearnofree() { // still have to delete objects pointed to, just doesn't just clear the list of pointers: for (size_t i = 0; i < pmemvec::m_length; i++) { if (pmemvec::m_data[i]) { delete pmemvec::m_data[i]; pmemvec::m_data[i] = NULL; } } pmemvec::clearnofree(); } // Note: read and write only work for structures without pointers template ::std::istream& prefvec::read( ::std::istream& stream ) { for (size_t i = 0; i < pmemvec::m_length; i++) { if (pmemvec::m_data[i]) { delete pmemvec::m_data[i]; pmemvec::m_data[i] = NULL; } } // READ / WRITE USES 32-bit LENGTHS (number of elements) // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length; stream.read( (char *) &length, sizeof(unsigned int) ); if (stream.fail()) { throw pexception(pexception::FILE_ERROR); } pmemvec::m_length = size_t(length); if (pmemvec::m_length >= pmemvec::storage_size()) { if (pmemvec::m_data) { delete [] pmemvec::m_data; } while (pmemvec::m_length >= pmemvec::storage_size()) pmemvec::m_shift++; pmemvec::m_data = new T * [pmemvec::storage_size()]; if (pmemvec::m_data == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, pmemvec::storage_size() * sizeof(T) ); } } for (size_t j = 0; j < pmemvec::m_length; j++) { T *p = new T; if (p == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) ); } stream.read( (char *) p, sizeof(T) ); if (stream.fail()) { throw pexception(pexception::FILE_ERROR); } pmemvec::m_data[j] = p; } return stream; } template ::std::ostream& prefvec::write( ::std::ostream& stream ) { // READ / WRITE USES 32-bit LENGTHS (number of elements) // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems // check for max unsigned int exceeded if (pmemvec::m_length > size_t((unsigned int)-1)) { // Quick mod - TV #if 0 throw exception( pexception::MAX_ARRAY_EXCEEDED, pmemvec::m_length ); #else ; #endif } // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length = (unsigned int)(pmemvec::m_length); stream.write( (char *) &length, sizeof(unsigned int) ); for (size_t i = 0; i < pmemvec::m_length; i++) { stream.write( (char *) &at(i), sizeof(T) ); } return stream; } /////////////////////////////////////////////////////////////////////////////// // pqvector... prefvec with the binary addition routine... // (i.e., almost the hash table...) // (so... I think we might replace pqmap with an inherited form of this soon) // (if MS would oblige...) template class pqvector : public prefvec { protected: mutable size_t m_current; public: pqvector(size_t sz = 0) : prefvec(sz) {;} pqvector(const pqvector& v) : prefvec( v ) {;} virtual ~pqvector() {;} pqvector& operator = (const pqvector& v) { prefvec::operator = (v); return *this; } // // at, [] and so on as before // // standard operations (unordered vector) T& find(const T& item); const T& find(const T& item) const; size_t findindex(const T& item) const; // // binary operations (ordered vector) T& search(const T& item); const T& search(const T& item) const; size_t searchindex(const T& item) const; void remove(const T& item) { remove_at(searchindex(item)); } size_t add(const T& item, int type = paftl::ADD_UNIQUE); T& current() { return prefvec::at(m_current); } const T& current() const { return pmemvec::at(m_current); } // qsort algo: void sort(); void sort(size_t left, size_t right); }; template T& pqvector::find(const T& item) { if (findindex(item) == paftl::npos) { throw pmemvec::exception(pmemvec::exception::OUT_OF_RANGE); } return prefvec::at(m_current); } template const T& pqvector::find(const T& item) const { if (findindex(item) == paftl::npos) { throw pmemvec::exception(pmemvec::exception::OUT_OF_RANGE); } return prefvec::at(m_current); } template size_t pqvector::findindex(const T& item) const { for (size_t i = 0; i < pmemvec::m_length; i++) { if (prefvec::at(i) == item) { m_current = i; return i; } } return paftl::npos; } // oops... we need an iterator... add use a current position marker. template T& pqvector::search(const T& item) { if (searchindex(item) == paftl::npos) { throw (typename pmemvec::exception)(pmemvec::exception::OUT_OF_RANGE); // Not found } return prefvec::at(m_current); } template const T& pqvector::search(const T& item) const { if (searchindex(item) == paftl::npos) { throw (typename pmemvec::exception)(pmemvec::exception::OUT_OF_RANGE); // Not found } return prefvec::at(m_current); } template size_t pqvector::searchindex(const T& item) const { if (pmemvec::size() != 0) { size_t ihere, ifloor = 0, itop = pmemvec::size() - 1; while (itop != paftl::npos && ifloor <= itop) { m_current = ihere = (ifloor + itop) / 2; if (item == prefvec::at(ihere)) { return m_current; } else if (item > prefvec::at(ihere)) { ifloor = ihere + 1; } else { itop = ihere - 1; } } } return paftl::npos; } // Note: uses m_current set by searchindex // Really need a list 'merge' function as well... will write this soon! template size_t pqvector::add(const T& item, int type) // default type UNIQUE { size_t where = paftl::npos; if (pmemvec::size() == 0 || item > prefvec::tail()) { // often used for push_back, so handle quickly if so prefvec::push_back( item ); where = pmemvec::size() - 1; } else { // if you call with ADD_HERE, it is assumed you've just used search or searchindex // i.e., we don't need to go through the binary search again to find the insert position if (type != paftl::ADD_HERE) { searchindex(item); } if (item < prefvec::at(m_current)) { prefvec::insert_at( m_current, item ); where = m_current; } else if (item > prefvec::at(m_current) || type == paftl::ADD_DUPLICATE) { prefvec::insert_at( m_current + 1, item ); where = m_current + 1; } else if (type == paftl::ADD_REPLACE || type == paftl::ADD_HERE) { // relies on good assignment operator prefvec::at(m_current) = item; } // n.b., type "UNIQUE" does not replace, returns paftl::npos } return where; } template void pqvector::sort() { if (pmemvec::m_length != 0) { sort(0,pmemvec::m_length-1); } } // rewrite 6-jun-10 (was entering infinite loop, now appears to work properly) template void pqvector::sort(size_t left, size_t right) { size_t i = left, j = right; const T& val = prefvec::at((left+right)/2); while (j != paftl::npos && i <= j) { while (i <= j && prefvec::at(i) < val) i++; while (j != paftl::npos && prefvec::at(j) > val) j--; if (j != paftl::npos && i <= j) { // swap contents (using pointer) T* temp = pmemvec::m_data[i]; pmemvec::m_data[i] = pmemvec::m_data[j]; pmemvec::m_data[j] = temp; i++; j--; } } if (j != paftl::npos && left < j) sort(left, j); if (i < right) sort(i, right); } /////////////////////////////////////////////////////////////////////////////////////////////// // psubvec is based on pvector, designed for arrays of chars or shorts, it subsumes itself // so can be stored as a single pointer: useful if you have a lot of empty arrays template class psubvec { public: static const T npos = -1; protected: T *m_data; public: psubvec() { m_data = NULL; } psubvec(const psubvec& ); ~psubvec(); psubvec& operator = (const psubvec& ); // virtual void push_back(const T item); virtual void clear(); public: bool isEmpty() // isEmpty is provided in addition to size as is quicker to test { return m_data == NULL; } T size() const { return m_data ? m_data[0] : 0; } T& operator [] (T pos) { return m_data[pos+1]; } const T& operator [] (T pos) const { return m_data[pos+1]; } public: ::std::istream& read(::std::istream& stream, ::std::streampos = -1); ::std::ostream& write( ::std::ostream& stream ); }; template psubvec::psubvec(const psubvec& v) { if (v.m_data) { T length = v.m_data[0]; T count = 0; while (length >>= 1) // find bit length (note: cannot assume int) count++; m_data = new T [2 << count]; if (m_data == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * size_t(2 << count) ); } length = v.m_data[0]; for (T i = 0; i < length + 1; i++) { m_data[i] = v.m_data[i]; } } else { m_data = NULL; } } template psubvec::~psubvec() { if (m_data) { delete [] m_data; m_data = NULL; } } template psubvec& psubvec::operator = (const psubvec& v) { if (this != &v) { if (v.m_data) { T length = v.m_data[0]; T count = 0; while (length >>= 1) // find bit length (note: cannot assume int) count++; m_data = new T [2 << count]; if (m_data == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * size_t(2 << count) ); } length = v.m_data[0]; for (T i = 0; i < length + 1; i++) { m_data[i] = v.m_data[i]; } } else { m_data = NULL; } } return *this; } template void psubvec::push_back(const T item) { if (!m_data) { m_data = new T [2]; m_data[0] = 1; m_data[1] = item; } else { T length = m_data[0] + 1; if ((length & (length - 1)) == 0) { // determine if next length would be power of 2 T *new_data = new T [length << 1]; if (new_data == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * size_t(length << 1) ); } for (T i = 0; i < length; i++) new_data[i] = m_data[i]; delete [] m_data; m_data = new_data; } m_data[0] = length; m_data[length] = item; } } template void psubvec::clear() { if (m_data) { delete [] m_data; m_data = NULL; } } template ::std::istream& psubvec::read( ::std::istream& stream, ::std::streampos ) { if (m_data) { delete [] m_data; m_data = NULL; } T length; stream.read( (char *) &length, sizeof(T) ); if (length) { T copy = length; T count = 0; while (length >>= 1) // find bit length (note: cannot assume int) count++; m_data = new T [2 << count]; if (m_data == NULL) { throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * size_t(2 << count) ); } stream.read((char *) &m_data, sizeof(T)*(copy+1) ); } return stream; } template ::std::ostream& psubvec::write( ::std::ostream& stream ) { if (m_data) { stream.write((char *) &m_data, sizeof(T)*(m_data[0]+1)); } return stream; } /////////////////////////////////////////////////////////////////////////////////////////////// // And now the quick mapping routine // Helper class keyvaluepair... template class keyvaluepair { public: T1 m_key; T2 m_value; public: keyvaluepair(const T1 key = T1(), const T2 value = T2()) { m_key = key; m_value = value; } T1& key() { return m_key; } const T1 key() const { return m_key; } T2& value() { return m_value; } const T2& value() const { return m_value; } ::std::istream& read( ::std::istream& stream ); ::std::ostream& write( ::std::ostream& stream ); }; template inline bool operator == (const keyvaluepair& a, const keyvaluepair& b) { return (a.m_key == b.m_key); } template inline bool operator < (const keyvaluepair& a, const keyvaluepair& b) { return (a.m_key < b.m_key); } template inline bool operator > (const keyvaluepair& a, const keyvaluepair& b) { return (a.m_key > b.m_key); } // Note: read and write only work for structures without pointers template ::std::istream& keyvaluepair::read( ::std::istream& stream ) { stream.read( (char *) &m_key, sizeof(T1) ); stream.read( (char *) &m_value, sizeof(T2) ); return stream; } template ::std::ostream& keyvaluepair::write( ::std::ostream& stream ) { stream.write( (char *) &m_key, sizeof(T1) ); stream.write( (char *) &m_value, sizeof(T2) ); return stream; } template class keyvaluepairref { // Quick mod - TV #if defined(_MSC_VER) protected: #else public: #endif T1 m_key; T2 *m_value; public: keyvaluepairref(const T1 key = T1()) { m_key = key; m_value = NULL; } keyvaluepairref(const T1 key, const T2& value) { m_key = key; m_value = new T2(value); } keyvaluepairref(const keyvaluepairref& k) { m_key = k.m_key; m_value = new T2(*(k.m_value)); } keyvaluepairref& operator = (const keyvaluepairref& k) { if (this != &k) { m_key = k.m_key; m_value = new T2(*(k.m_value)); } return *this; } virtual ~keyvaluepairref() { if (m_value) {delete m_value; m_value = NULL;} } T1& key() { return m_key; } const T1 key() const { return m_key; } T2& value() { return *m_value; } const T2& value() const { return *m_value; } // Quick mod - TV #if defined(_MSC_VER) friend bool operator == (const keyvaluepairref& a, const keyvaluepairref& b); friend bool operator < (const keyvaluepairref& a, const keyvaluepairref& b); friend bool operator > (const keyvaluepairref& a, const keyvaluepairref& b); #endif // virtual ::std::istream& read( ::std::istream& stream ); virtual ::std::ostream& write( ::std::ostream& stream ); }; template inline bool operator == (const keyvaluepairref& a, const keyvaluepairref& b) { return (a.m_key == b.m_key); } template inline bool operator < (const keyvaluepairref& a, const keyvaluepairref& b) { return (a.m_key < b.m_key); } template inline bool operator > (const keyvaluepairref& a, const keyvaluepairref& b) { return (a.m_key > b.m_key); } // Note: read and write only work for structures without pointers template ::std::istream& keyvaluepairref::read( ::std::istream& stream ) { stream.read( (char *) &m_key, sizeof(T1) ); #ifndef _WIN32 m_value = new T2; #endif stream.read( (char *) m_value, sizeof(T2) ); return stream; } template ::std::ostream& keyvaluepairref::write( ::std::ostream& stream ) { stream.write( (char *) &m_key, sizeof(T1) ); stream.write( (char *) m_value, sizeof(T2) ); return stream; } // ...and yuk! it gets worse... now we have to define a whole new class: template class pmemmap { // It looks very similar to a pqvector... protected: pqvector m_vector; public: pmemmap() {;} pmemmap(const pmemmap& map ) { m_vector = map.m_vector; } ~pmemmap() {;} pmemmap& operator = (const pmemmap& map ) { if (this != &map) m_vector = map.m_vector; return *this; } // // at, [] and so on T2& at(size_t i) { return m_vector.at(i).value(); } const T2& at(size_t i) const { return m_vector.at(i).value(); } T2& operator [] (size_t i) { return m_vector.at(i).value(); } const T2& operator [] (size_t i) const { return m_vector.at(i).value(); } T2& head() { return m_vector.head().value(); } const T2& head() const { return m_vector.head().value(); } T2& tail() { return m_vector.tail().value(); } const T2& tail() const { return m_vector.tail().value(); } size_t size() const { return m_vector.size(); } void clear() { m_vector.clear(); } // // standard operations (unordered vector) T2& find(const T1& item) const { return m_vector.find(Pair(item)).value(); } size_t findindex(const T1& item) const { return m_vector.findindex(Pair(item)); } // // binary operations (ordered vector) T2& search(const T1& item) { return m_vector.search(Pair(item)).value(); } const T2& search(const T1& item) const { return m_vector.search(Pair(item)).value(); } size_t searchindex(const T1& item) const { return m_vector.searchindex(Pair(item)); } void remove_at(size_t i) { m_vector.remove_at(i); } void remove_at(const pvecint& list) { m_vector.remove_at(list); } void remove(const T1& item) { remove_at(m_vector.searchindex(item)); } size_t add(const T1& k, const T2& v, int type = paftl::ADD_UNIQUE) // note: does not replace! { return m_vector.add( Pair(k,v), type ); } // extras T1& key(size_t i) { return m_vector.at(i).key(); } const T1 key(size_t i) const { return m_vector.at(i).key(); } T2& value(size_t i) { return m_vector.at(i).value(); } const T2& value(size_t i) const { return m_vector.at(i).value(); } T2& current() { return m_vector.current().value(); } const T2& current() const { return m_vector.current().value(); } // read and write (structures without pointers *only*) ::std::istream& read( ::std::istream& stream ); ::std::ostream& write( ::std::ostream& stream ); }; // Note: read and write only work for structures without pointers template ::std::istream& pmemmap::read( ::std::istream& stream ) { for (size_t i = m_vector.size() - 1; i != paftl::npos; i--) { m_vector.remove_at(i); } // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length; stream.read( (char *) &length, sizeof(unsigned int) ); for (size_t j = 0; j < size_t(length); j++) { // these should be in order, so just push them: Pair p; p.read(stream); m_vector.push_back(p); } return stream; } template ::std::ostream& pmemmap::write( ::std::ostream& stream ) { // check for max unsigned int exceeded if (m_vector.size() > size_t((unsigned int)-1)) { throw pexception( pexception::MAX_ARRAY_EXCEEDED, m_vector.size() ); } // n.b., do not change this to size_t as it will cause 32bit to 64bit conversion problems unsigned int length = (unsigned int)(m_vector.size()); stream.write( (char *) &length, sizeof(unsigned int) ); for (size_t i = 0; i < m_vector.size(); i++) { m_vector[i].write(stream); } return stream; } // ...to stop the MS compiler complaining... #define kvp(T1,T2) keyvaluepair template class pmap : public pmemmap { }; // ...to stop the MS compiler complaining... #define kvpr(T1,T2) keyvaluepairref template class pqmap : public pmemmap { }; /////////////////////////////////////////////////////////////////////////////// // ptree: a simple tree class // Allows template of a template (recursive) definition for tree #define ptreeT ptree template class ptree { public: class exception : public pexception { public: enum exception_t { PTREE_UNDEFINED = 0x1000, UNASSIGNED_DATA = 0x1001 }; public: exception(int n_exception = PTREE_UNDEFINED) : pexception( n_exception ) {} }; protected: T *m_data; ptree *m_parent; pvector m_children; public: ptree() { m_data = NULL; m_parent = NULL; } ptree(const T& data) { m_data = new T(data); m_parent = NULL; } ptree(const ptree& tree ) { m_data = tree.m_data; for (int i = 0; i < tree.m_children.size(); i++) { ptree *child = new ptree( *(tree.m_children[i]) ); m_children.push_back( child ); m_children.tail()->m_parent = this; } } ptree& operator = (const ptree& tree) { if (this != &tree) { m_data = tree.m_data; for (int i = 0; i < tree.m_children.size(); i++) { ptree *child = new ptree( *(tree.m_children[i]) ); m_children.push_back( child ); m_children.tail()->m_parent = this; } } return *this; } ~ptree() { delete m_data; m_data = NULL; while (m_children.size()) { delete m_children.tail(); m_children.pop_back(); } } void addChild(const T& data) { m_children.push_back( new ptree(data) ); m_children.tail()->m_parent = this; } void removeChild(int ref) { ptree *child = m_children[ref]; m_children.remove(ref); delete child; } int getChildCount() const { return m_children.size(); } ptree& getChild(int ref) const { return *(m_children[ref]); } ptree& getLastChild() const { return *(m_children[m_children.size() - 1]); } int hasParent() const { return m_parent ? 1 : 0; } ptree& getParent() const { return *m_parent; } void setParent(ptree& parent) { if (m_parent) { for (int i = 0; i < m_parent->m_children.size(); i++) { if (m_parent->m_children[i] == this) { m_parent->m_children.remove(i); } } } m_parent = &parent; } void setValue(const T& data) { m_data = new T(data); } T& getValue() const { if (!m_data) throw exception( exception::UNASSIGNED_DATA ); return *m_data; } pvector getPath() { pvector path; getPath(path); return path; } void getPath(pvector& path) { path.push_back( getValue() ); if (m_parent) { m_parent->getPath(path); } } }; /////////////////////////////////////////////////////////////////////////////// template class pflipper { protected: T m_contents[2]; short parity; public: pflipper() { parity = 0; } pflipper( const T& a, const T& b ) { parity = 0; m_contents[0] = a; m_contents[1] = b; } pflipper( const pflipper& f ) { parity = f.parity; m_contents[0] = f.m_contents[0]; m_contents[1] = f.m_contents[1]; } virtual ~pflipper() { } pflipper& operator = (const pflipper& f ) { if (this != &f) { parity = f.parity; m_contents[0] = f.m_contents[0]; m_contents[1] = f.m_contents[1]; } return *this; } void flip() { parity = (parity == 0) ? 1 : 0; } T& a() { return m_contents[parity]; } T& b() { return m_contents[(parity == 0) ? 1 : 0]; } const T& a() const { return m_contents[parity]; } const T& b() const { return m_contents[(parity == 0) ? 1 : 0]; } }; /////////////////////////////////////////////////////////////////////////////// // Read and write runlength encoded vectors, with byte alignment through T // note: vector must have been allocated to accept stream template ::std::istream& read_rle( ::std::istream& stream, T *vector, size_t length ) { unsigned char *data = (unsigned char *) vector; for (size_t i = 0; i < sizeof(T); i++) { unsigned char runlength = 0, current, last; size_t count = 0; while (count < length) { stream.get((char&)current); if (count && current == last) { stream.get((char&)runlength); } else { last = current; runlength = 1; } for (size_t i = count; i < count + runlength; i++) { data[i + sizeof(T) * count] = current; } count += runlength; } } return stream; } template ::std::ostream& write_rle( ::std::ostream& stream, T *vector, size_t length ) { unsigned char *data = (unsigned char *) vector; for (size_t i = 0; i < sizeof(T); i++) { unsigned char runlength = 0, current; size_t count = 0; while (count < length) { do { current = data[i + sizeof(T) * count]; runlength++; count++; } while (count < length && current == data[i + sizeof(T) * count] && runlength < 255); if (runlength == 1) { stream.put(current); } else { stream.put(current); stream.put(current); runlength -= 1; // since we've written current twice anyway to mark the run stream.put(runlength); } runlength = 0; } } return stream; } /////////////////////////////////////////////////////////////////////////////// // Hashing for LZW compression const size_t HASHBITSIZE = 12; const size_t HASHTABLESIZE = 5021; // n.b., prime > 4096 //const size_t HASHTABLESIZE = 65983; // n.b., prime > 65536 const size_t HASHMAXVALUE = (1 << HASHBITSIZE) - 1; const size_t HASHMAXCODE = HASHMAXVALUE - 1; struct phash { unsigned int code; unsigned int prefix; unsigned char character; }; class phashtable { protected: mutable size_t m_current; unsigned int m_nextcode; phash m_table[HASHTABLESIZE]; public: phashtable(); void add_encode(unsigned int prefix, unsigned char character); void add_decode(unsigned int prefix, unsigned char character); size_t search(unsigned int prefix, unsigned char character) const; unsigned char *decode(unsigned char *buffer, unsigned int code); int getnextcode() { return m_nextcode; } }; inline phashtable::phashtable() { for (size_t i = 0; i < HASHTABLESIZE; i++) { m_table[i].code = -1; } m_nextcode = 256; // 0-255 for standard characters } inline void phashtable::add_encode(unsigned int prefix, unsigned char character) { if (m_nextcode <= HASHMAXCODE) { m_table[m_current].code = m_nextcode; m_table[m_current].prefix = prefix; m_table[m_current].character = character; m_nextcode++; } } inline void phashtable::add_decode(unsigned int prefix, unsigned char character) { if (m_nextcode <= HASHMAXCODE) { m_table[m_nextcode].prefix = prefix; m_table[m_nextcode].character = character; m_nextcode++; } } inline size_t phashtable::search(unsigned int prefix, unsigned char character) const { // the bracket overkill on the following line ensures paftl.h compiles on a GNU compiler m_current = (((unsigned int) character) << (HASHBITSIZE-8)) ^ prefix; size_t offset; if (m_current == 0) { offset = 1; } else { offset = HASHTABLESIZE - m_current; } while ( m_table[m_current].code != (unsigned int) -1 && (m_table[m_current].prefix != prefix || m_table[m_current].character != character)) { if (offset > m_current) m_current += HASHTABLESIZE; m_current -= offset; } return m_table[m_current].code; } inline unsigned char *phashtable::decode(unsigned char *buffer, unsigned int code) { while (code > 255) { *buffer++ = m_table[code].character; code = m_table[code].prefix; } *buffer = code; return buffer; } /////////////////////////////////////////////////////////////////////////////// // LZW as of June 2003 US patent has expired // as of June 2004 the European patent expires // Note to paftl users: ensure that you meet patent requirements for your usage // LZW uses a class so that the hash table may be retained over multiple // vector read / writes, as well as holding a read buffer // 12 bit, 4096 pattern holder // Note: you must *flush* after writing -- the idea is you can write several // vectors before a flush template class plzw { protected: // read / write buffering unsigned long m_bitbuffer; bool m_bitswaiting; protected: bool m_firstever; unsigned char m_character; unsigned int m_prefix; phashtable m_hashtable; unsigned char m_decodedstring[HASHTABLESIZE]; // <- impossible that the decode string is ever as long as the hash table size public: plzw(); ::std::istream& read( ::std::istream& stream, T *vector, int length ); ::std::ostream& write( ::std::ostream& stream, T *vector, int length ); protected: ::std::istream& get(::std::istream& stream, unsigned int& code); ::std::ostream& put(::std::ostream& stream, const unsigned int code); }; template plzw::plzw() { m_firstever = true; m_bitswaiting = false; } template ::std::istream& plzw::read(::std::istream& stream, T *vector, int length ) { unsigned char *data = (unsigned char *) vector; unsigned char *string; if (m_firstever) { get(stream, m_prefix); m_character = m_prefix; data[0] = m_character; } // T is sequenced, as we assume that patterns will recur through aligned bytes of T for (unsigned int i = (m_firstever ? 1 : 0); i < sizeof(T) * length;) { unsigned int nextcode; get(stream, nextcode); if (nextcode >= (unsigned int) m_hashtable.getnextcode()) { *m_decodedstring = m_character; string = m_hashtable.decode(m_decodedstring + 1, m_prefix); } else { string = m_hashtable.decode(m_decodedstring, nextcode); } m_character = *string; if (i != 0) { // this should be skipped on initial read m_hashtable.add_decode(m_prefix,m_character); } while (string >= m_decodedstring && i < sizeof(T) * length) { data[i] = *string--; i++; } m_prefix = nextcode; } // skip to next byte boundary for next read... (and retain context) m_bitswaiting = false; m_firstever = false; return stream; } template ::std::ostream& plzw::write(::std::ostream& stream, T *vector, int length ) { unsigned char *data = (unsigned char *) vector; m_prefix = data[0]; for (unsigned int i = 0; i < sizeof(T) * length; i++) { m_character = data[i]; int code = m_hashtable.search(m_prefix, m_character); if (code != -1) { m_prefix = code; } else { m_hashtable.add_encode(m_prefix, m_character); put(stream, m_prefix); m_prefix = m_character; } } // skip to next byte boundary put(stream, m_prefix); if (m_bitswaiting) { stream.put((unsigned char)(m_bitbuffer & 0xFF)); m_bitswaiting = false; } return stream; } // stored, 1 and 2 are the 12-bit codes, // a b & c are first 4 bits, second 4 bits and third four bits respectively // b1 a1 // c2 c1 // b2 a2 template ::std::istream& plzw::get(::std::istream& stream, unsigned int& code) { unsigned char bits; if (!m_bitswaiting) { stream.get((char&)bits); code = bits; stream.get((char&)bits); code |= (bits & 0x0F) << 8; m_bitbuffer = bits & 0xF0; m_bitswaiting = true; } else { stream.get((char&)bits); code = ((unsigned int)bits) | (m_bitbuffer << 4); m_bitswaiting = false; } return stream; } template ::std::ostream& plzw::put(::std::ostream& stream, const unsigned int code) { if (!m_bitswaiting) { stream.put((unsigned char)(code & 0xFF)); m_bitbuffer = code >> 8; m_bitswaiting = true; } else { unsigned char bits; bits = ((code >> 4) & 0xF0) | m_bitbuffer; stream.put(bits); stream.put((unsigned char)(code & 0xFF)); m_bitswaiting = false; } return stream; } /////////////////////////////////////////////////////////////////////////////// // } // namespace paftl } #endif ================================================ FILE: mgraph440/pixelbase.cpp ================================================ #include "mgraph440/pixelbase.h" namespace mgraph440 { PixelRefVector PixelBase::pixelateLine( Line l, int scalefactor ) const { PixelRefVector pixel_list; // this is *not* correct for lines that are off the edge... // should use non-constrained version (false), and find where line enters the region PixelRef a = pixelate( l.start(), true, scalefactor ); PixelRef b = pixelate( l.end(), true, scalefactor ); l.normalScale( m_region ); pixel_list.push_back( a ); int scaledcols = m_cols * scalefactor; int scaledrows = m_rows * scalefactor; int parity = 1; // Line goes upwards if (a.y > b.y) { parity = -1; // Line goes downwards a.y *= -1; b.y *= -1; // Set ay and by saves work on comparisons later on } // special case 1 if (a.x == b.x) { while (a.y < b.y ) { a.y += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } } else if (a.y == b.y) { while ( a.x < b.x ) { a.x += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); // Lines always go left to right } } else { double hw_ratio = l.height() / l.width(); // Working all of these out leaves less scope for floating point error double wh_ratio = l.width() / l.height(); double x0_const = l.ay() - double(parity) * hw_ratio * l.ax(); double y0_const = l.ax() - double(parity) * wh_ratio * l.ay(); while (a.x < b.x || a.y < b.y) { PixelRef e; e.y = parity * int( double(scaledrows) * (x0_const + parity * hw_ratio * (double(a.x + 1) / double(scaledcols))) ); // Note when decending 1.5 -> 1 and ascending 1.5 -> 2 if (parity < 0) { e.x = int( double(scaledcols) * (y0_const + wh_ratio * ( double(a.y) / double(scaledrows))) ); } else { e.x = int( double(scaledcols) * (y0_const + wh_ratio * (double(a.y + 1) / double(scaledrows))) ); } if (a.y < e.y) { while (a.y < e.y && a.y < b.y) { a.y += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } if (a.x < b.x) { a.x += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } } else if (a.x < e.x) { while (a.x < e.x && a.x < b.x) { a.x += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } if (a.y < b.y) { a.y += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } } else { // Special case: exactly diagonal step (should only require one step): // (Should actually never happen) (Doesn't: checked with RFH) a.x += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); a.y += 1; pixel_list.push_back( PixelRef(a.x,parity * a.y) ); } } } return pixel_list; } } ================================================ FILE: mgraph440/pixelbase.h ================================================ #pragma once #include "mgraph440/p2dpoly.h" #include "mgraph440/pixelref.h" namespace mgraph440 { class PixelBase { public: int m_rows; int m_cols; QtRegion m_region; PixelBase() {;} // constrain is constrain to bounding box (i.e., in row / col bounds) virtual PixelRef pixelate(const Point2f&, bool constrain = true, int scalefactor = 1 ) const = 0; PixelRefVector pixelateLine( Line l, int scalefactor = 1 ) const; bool includes(const PixelRef pix) const { return (pix.x >= 0 && pix.x < m_cols && pix.y >= 0 && pix.y < m_rows); } const QtRegion& getRegion() const { return m_region; } }; } ================================================ FILE: mgraph440/pixelref.h ================================================ #pragma once #include "mgraph440/p2dpoly.h" namespace mgraph440 { class PixelRef { public: short x = 0; short y = 0; PixelRef( short ax = -1, short ay = -1 ) { x = ax; y = ay; } PixelRef( int i ) { x = short(i >> 16); y = short(i & 0xffff); } bool empty() { return x == -1 && y == -1; } PixelRef up() const { return PixelRef(x, y + 1); } PixelRef left() const { return PixelRef(x - 1, y); } PixelRef right() const { return PixelRef(x + 1, y); } PixelRef down() const { return PixelRef(x, y - 1); } short& operator [] (int i) { return (i == XAXIS) ? x : y; } bool within( const PixelRef bl, const PixelRef tr ) const { return (x >= bl.x && x <= tr.x && y >= bl.y && y <= tr.y); } bool encloses( PixelRef testpoint ) const { return (testpoint.x >= 0 && testpoint.x < x && testpoint.y >= 0 && testpoint.y < y);} // directions for the ngraph: enum {NODIR = 0x00, HORIZONTAL = 0x01, VERTICAL = 0x02, POSDIAGONAL = 0x04, NEGDIAGONAL = 0x08, DIAGONAL = 0x0c, NEGHORIZONTAL = 0x10, NEGVERTICAL = 0x20}; short& row(char dir) { return (dir & VERTICAL) ? x : y; } short& col(char dir) { return (dir & VERTICAL) ? y : x; } const short& row(char dir) const { return (dir & VERTICAL) ? x : y; } const short& col(char dir) const { return (dir & VERTICAL) ? y : x; } PixelRef& move(char dir) { switch (dir) { case POSDIAGONAL: x++; y++; break; case NEGDIAGONAL: x++; y--; break; case HORIZONTAL: x++; break; case VERTICAL: y++; break; case NEGHORIZONTAL: x--; break; case NEGVERTICAL: y--; break; } return *this; } friend bool operator == (const PixelRef a, const PixelRef b); friend bool operator != (const PixelRef a, const PixelRef b); friend bool operator < (const PixelRef a, const PixelRef b); friend bool operator > (const PixelRef a, const PixelRef b); friend PixelRef operator + (const PixelRef a, const PixelRef b); friend PixelRef operator - (const PixelRef a, const PixelRef b); friend PixelRef operator / (const PixelRef a, const int factor); friend double dist(const PixelRef a, const PixelRef b); friend double angle(const PixelRef a, const PixelRef b, const PixelRef c); operator int() const { return ((int(x) << 16) + (int(y) & 0xffff)); } }; const PixelRef NoPixel( -1, -1 ); typedef std::vector PixelRefVector; inline bool operator == (const PixelRef a, const PixelRef b) { return (a.x == b.x) && (a.y == b.y); } inline bool operator != (const PixelRef a, const PixelRef b) { return (a.x != b.x) || (a.y != b.y); } inline bool operator < (const PixelRef a, const PixelRef b) { return (a.x < b.x) || (a.x == b.x && a.y < b.y); } inline bool operator > (const PixelRef a, const PixelRef b) { return (a.x > b.x) || (a.x == b.x && a.y > b.y); } inline PixelRef operator + (const PixelRef a, const PixelRef b) { return PixelRef(a.x + b.x, a.y + b.y); } inline PixelRef operator - (const PixelRef a, const PixelRef b) { return PixelRef(a.x - b.x, a.y - b.y); } inline PixelRef operator / (const PixelRef a, const int factor) { return PixelRef(a.x / factor, a.y / factor); } struct PixelRefPair { PixelRef a; PixelRef b; PixelRefPair(const PixelRef x = NoPixel, const PixelRef y = NoPixel) { a = x < y ? x : y; b = x < y ? y : x; } friend bool operator == (const PixelRefPair& x, const PixelRefPair& y); friend bool operator != (const PixelRefPair& x, const PixelRefPair& y); friend bool operator < (const PixelRefPair& x, const PixelRefPair& y); friend bool operator > (const PixelRefPair& x, const PixelRefPair& y); }; // note: these are made with a is always less than b inline bool operator == (const PixelRefPair& x, const PixelRefPair& y) { return (x.a == y.a && x.b == y.b); } inline bool operator != (const PixelRefPair& x, const PixelRefPair& y) { return (x.a != y.a || x.b != y.b); } inline bool operator < (const PixelRefPair& x, const PixelRefPair& y) { return ( (x.a == y.a) ? x.b < y.b : x.a < y.a ); } inline bool operator > (const PixelRefPair& x, const PixelRefPair& y) { return ( (x.a == y.a) ? x.b > y.b : x.a > y.a ); } } ================================================ FILE: mgraph440/point.cpp ================================================ #include "mgraph440/point.h" namespace mgraph440 { Point::~Point() { if (m_node) { delete m_node; m_node = NULL; delete m_attributes; m_attributes = NULL; } } std::ifstream& Point::read(std::ifstream& stream, int version, int attr_count) { if (m_node) { delete m_node; m_node = NULL; delete m_attributes; m_attributes = NULL; } stream.read( (char *) &m_state, sizeof(m_state) ); // block is the same size as m_noderef used to be for ease of replacement: // (note block NO LONGER used!) stream.read( (char *) &m_block, sizeof(m_block) ); if (version < VERSION_BLOCKEDQUAD) { m_block = 0; } stream.read( (char *) &m_misc, sizeof(m_misc) ); if (version >= VERSION_GRID_CONNECTIONS) { stream.read( (char *) &m_grid_connections, sizeof(m_grid_connections) ); } if (version >= VERSION_NGRAPH_INTROD) { stream.read( (char *) &m_merge, sizeof(m_merge) ); bool ngraph; stream.read( (char *) &ngraph, sizeof(ngraph) ); if (ngraph) { m_node = new Node; m_node->read(stream, version); if (version < VERSION_ATTRIBUTES_TABLE) { // don't deal with this here, just get the attributes into memory m_attributes = new AttrBody(-1,g_attr_header); m_attributes->read( stream, attr_count ); } } } if (version >= VERSION_POINT_LOCATIONS) { stream.read((char *) &m_location, sizeof(m_location)); } if (version < VERSION_SHAPE_MAPS) { // old layer information m_data_objects.read(stream); } if (version >= VERSION_BOUNDARYGRAPH && version < VERSION_NEWBOUNDARYGRAPH) { // dummy pvecint to hold old format boundary nodes pvecint old_boundary_nodes; old_boundary_nodes.read(stream); } return stream; } std::ostream& Point::write(std::ostream& stream, int version) { stream.write( (char *) &m_state, sizeof(m_state) ); // block is the same size as m_noderef used to be for ease of replacement: // note block is no longer used at all stream.write( (char *) &m_block, sizeof(m_block) ); stream.write( (char *) &m_misc, sizeof(m_misc) ); stream.write( (char *) &m_grid_connections, sizeof(m_grid_connections) ); stream.write( (char *) &m_merge, sizeof(m_merge) ); bool ngraph; if (m_node) { ngraph = true; stream.write( (char *) &ngraph, sizeof(ngraph) ); m_node->write(stream, version); } else { ngraph = false; stream.write( (char *) &ngraph, sizeof(ngraph) ); } stream.write((char *) &m_location, sizeof(m_location)); return stream; } } ================================================ FILE: mgraph440/point.h ================================================ #pragma once #include "mgraph440/attr.h" #include "mgraph440/ngraph.h" namespace mgraph440 { class OldPoint1 { friend class PointMap; protected: int m_noderef; int m_state; }; class OldPoint2 { friend class PointMap; protected: int m_noderef; int m_state; int m_misc; }; class Point { friend class Bin; friend class PointMap; friend class MetaGraph; // <- for file conversion routines friend class PafAgent; friend class PafWalker; public: enum { EMPTY = 0x0001, FILLED = 0x0002, BLOCKED = 0x0004, CONTEXTFILLED = 0x0008, // PARTBLOCKED = 0x0008 deprecated SELECTED = 0x0010, EDGE = 0x0020, MERGED = 0x0040, // PINNED = 0x0020 deprecated AGENTFILLED = 0x0080, AGENTFADE = 0x0100, AGENTA = 0x0200, AGENTB = 0x0400, AGENTC = 0x0800, UPDATELINEADDED = 0x1000, UPDATELINEREMOVED = 0x2000, HIGHLIGHT = 0x4000, AUGMENTED = 0x8000 // AV TV }; // note the order of these connections is important and used elsewhere: enum { CONNECT_E = 0x01, CONNECT_NE = 0x02, CONNECT_N = 0x04, CONNECT_NW = 0x08, CONNECT_W = 0x10, CONNECT_SW = 0x20, CONNECT_S = 0x40, CONNECT_SE = 0x80 }; int m_block; // not used, unlikely to be used, but kept for time being int m_state; int m_misc; // <- undocounter / point seen register / agent reference number, etc char m_grid_connections; // this is a standard set of grid connections, with bits set for E,NE,N,NW,W,SW,S,SE Node *m_node; // graph links Point2f m_location; // note: this is large, but it helps allow loading of non-standard grid points, // whilst allowing them to be displayed as a visibility graph, also speeds up time to // display float m_color; // although display color for the point now introduced PixelRef m_merge; // to merge with another point PixelRef m_extent; // used to speed up graph analysis (not sure whether or not it breaks it!) float m_dist; // used to speed up metric analysis float m_cumangle; // cummulative angle -- used in metric analysis and angular analysis // hmm... this is for my 3rd attempt at a quick line intersect algo: // every line that goes through the gridsquare -- memory intensive I know, but what can you do: // accuracy is imperative here! Calculated pre-fillpoints / pre-makegraph, and (importantly) it works. pqmap m_lines; // and when dynamic lines are being used, the process flag tells you which q octants to reprocess: // // Deprecated, kept for compatibility with previous versions: AttrBody *m_attributes; // deprecated: now PointMap has an attribute table to handle this pmap m_data_objects; // deprecated: (first int is data layer -- presumably the KEY not the index, second int is object ref) // int m_processflag; public: Point() { m_state = EMPTY; m_block = 0; m_misc = 0; m_grid_connections = 0; m_node = NULL; m_attributes = NULL; m_processflag = 0; m_merge = NoPixel; m_user_data = NULL; } Point& operator = (const Point&) { throw 1; } Point(const Point&) { throw 1; } ~Point(); bool filled() const { return (m_state & FILLED) == FILLED; } bool selected() const { return (m_state & SELECTED) == SELECTED; } int getDataObject( int layer ) { size_t var = m_data_objects.searchindex( layer ); if (var != paftl::npos) return m_data_objects.at(var); return -1; // note: not paftl::npos } AttrBody& getAttributes() { return *m_attributes; } void setAttributes(const AttrBody& attr) { if (m_attributes) delete m_attributes; m_attributes = new AttrBody(attr); } std::ifstream& read(std::ifstream& stream, int version, int attr_count); std::ostream &write(std::ostream &stream, int version); void *m_user_data; Node& getNode() { return *m_node; } }; } ================================================ FILE: mgraph440/pointmap.cpp ================================================ #include "mgraph440/pointmap.h" #include "mgraph440/containerutils.h" namespace mgraph440 { bool PointMap::read(std::ifstream& stream, int version ) { if (version >= VERSION_POINT_MAP_NAMES) { m_name = dXstring440::readString(stream); } else { m_name = "VGA Map"; } // NOTE: You MUST set m_spacepix manually! m_displayed_attribute = -1; if (m_points) { for (int i = 0; i < m_cols; i++) { delete [] m_points[i]; } delete [] m_points; m_points = NULL; } stream.read( (char *) &m_spacing, sizeof(m_spacing) ); if (version < VERSION_STATE_RECORDED) { if (version >= VERSION_SPARK_GRAPH_INTROD) { bool redundant; stream.read( (char *) &redundant, sizeof(redundant) ); } else { double redundant; stream.read( (char *) &redundant, sizeof(redundant) ); } } stream.read( (char *) &m_rows, sizeof(m_rows) ); stream.read( (char *) &m_cols, sizeof(m_cols) ); stream.read( (char *) &m_point_count, sizeof(m_point_count) ); stream.read( (char *) &m_bottom_left, sizeof(m_bottom_left) ); m_region = QtRegion( Point2f(m_bottom_left.x-m_spacing/2.0, m_bottom_left.y-m_spacing/2.0), Point2f(m_bottom_left.x+double(m_cols-1)*m_spacing + m_spacing/2.0, m_bottom_left.y+double(m_rows-1)*m_spacing + m_spacing/2.0) ); // for old data versions: int attr_count = -1, which_attributes = -1; int displayed_attribute; // n.b., temp variable necessary to force recalc below if (version >= VERSION_ATTRIBUTES_TABLE) { // our data read stream.read((char *)&displayed_attribute,sizeof(displayed_attribute)); m_attributes.read( stream, version ); } else if (version >= VERSION_NGRAPH_INTROD) { // ick, a very specific subset have this file format: stream.read( (char *) &which_attributes, sizeof(which_attributes) ); stream.read( (char *) &attr_count, sizeof(int) ); } m_points = new Point *[m_cols]; for (int j = 0; j < m_cols; j++) { m_points[j] = new Point [m_rows]; // ...and read... if (version >= VERSION_LAYERS_INTROD) { for (int k = 0; k < m_rows; k++) { m_points[j][k].read(stream,version,attr_count); // check if occdistance of any pixel's bin is set, meaning that // the isovist analysis was done if(!m_hasIsovistAnalysis) { for(int b = 0; b < 32; b++) { if(m_points[j][k].m_node && m_points[j][k].m_node->occdistance(b) > 0) { m_hasIsovistAnalysis = true; break; } } } } } else if (version >= VERSION_EXTRA_POINT_DATA_INTROD) { // Hmm... more untidiness from a previous incarnation OldPoint2 *oldpoints = new OldPoint2 [m_rows]; stream.read( (char *) oldpoints, sizeof(OldPoint2) * m_rows ); for (int k = 0; k < m_rows; k++) { m_points[j][k].m_block = oldpoints[k].m_noderef; // <- block is actually for something else! m_points[j][k].m_state = oldpoints[k].m_state; m_points[j][k].m_misc = oldpoints[k].m_misc; } } else { // Hmm... more untidiness from a previous incarnation OldPoint1 *oldpoints = new OldPoint1 [m_rows]; stream.read( (char *) oldpoints, sizeof(OldPoint1) * m_rows ); for (int k = 0; k < m_rows; k++) { m_points[j][k].m_block= oldpoints[k].m_noderef; // <- block is actually for something else! m_points[j][k].m_state = oldpoints[k].m_state; } } for (int k = 0; k < m_rows; k++) { // Old style point node reffing and also unselects selected nodes which would otherwise be difficult if (version >= VERSION_QUICK_GRAPH_INTROD) { // would soon be better simply to turn off the select flag.... m_points[j][k].m_state &= ( Point::EMPTY | Point::FILLED | Point::MERGED | Point::BLOCKED | Point::CONTEXTFILLED | Point::EDGE); } else if (m_points[j][k].m_state == -1) { m_points[j][k].m_state = Point::EMPTY; } else { m_points[j][k].m_state = Point::FILLED; } // Set the node pixel if it exists: if (m_points[j][k].m_node) { m_points[j][k].m_node->setPixel(PixelRef(j,k)); } // Set the point location if required: if (version < VERSION_POINT_LOCATIONS) { m_points[j][k].m_location = depixelate(PixelRef(j,k)); } // Add merge line if merged: if (!m_points[j][k].m_merge.empty()) { depthmapX440::addIfNotExists(m_merge_lines, PixelRefPair(PixelRef(j,k),m_points[j][k].m_merge)); } } } // this is my attempt to enter these into the new attribute table: if (version >= VERSION_NGRAPH_INTROD && version < VERSION_ATTRIBUTES_TABLE) { if (which_attributes != GraphVertexList::NONE) { displayed_attribute = 0; convertAttributes(which_attributes); } else { displayed_attribute = -1; } } // and if the attribute tables are ready, calculate the direct grid connections: if (version >= VERSION_NGRAPH_INTROD && version < VERSION_GRID_CONNECTIONS) { addGridConnections(); } m_selection = NO_SELECTION; m_pinned_selection = false; m_initialised = true; m_blockedlines = false; if (version >= VERSION_POINT_MAPS) { stream.read((char *) &m_processed, sizeof(m_processed)); stream.read((char *) &m_boundarygraph, sizeof(m_boundarygraph)); } // now, as soon as loaded, must recalculate our screen display: // note m_displayed_attribute should be -2 in order to force recalc... m_displayed_attribute = -2; setDisplayedAttribute(displayed_attribute); return true; } // A horrible piece of code: this is to convert a file from the old format // AttrHeader / AttrBody to the new format Attributes Table // This code converts attributes for all versions // between VERSION_NGRAPH_INTROD and VERSION_ATTRIBUTES_TABLE void PointMap::convertAttributes(int which_attributes) { if (which_attributes & GraphVertexList::BASIC) { int connectivity_col = m_attributes.insertLockedColumn("Connectivity"); for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { // insert row... int row = m_attributes.insertRow(PixelRef(i,j)); float val; val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::NEIGHBOURHOOD_SIZE); m_attributes.setValue(row, connectivity_col, val); } } } } if (which_attributes & GraphVertexList::LOCAL) { int cluster_col = m_attributes.insertColumn("Visual Clustering Coefficient"); int control_col = m_attributes.insertColumn("Visual Control"); int controllability_col = m_attributes.insertColumn("Visual Controllability"); for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { int row = m_attributes.getRowid(PixelRef(i,j)); float val; val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::CLUSTER); m_attributes.setValue(row, cluster_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::CONTROL_HILL); m_attributes.setValue(row, control_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::CONTROL_TURN); m_attributes.setValue(row, controllability_col, val); } } } } if (which_attributes & GraphVertexList::GLOBAL) { int entropy_col = m_attributes.insertColumn("Visual Entropy"); int integ_hh_col = m_attributes.insertColumn("Visual Integration [HH]"); int integ_tk_col = m_attributes.insertColumn("Visual Integration [Tekl]"); int depth_col = m_attributes.insertColumn("Visual Mean Depth"); int count_col = m_attributes.insertColumn("Visual Node Count"); int rel_entropy_col = m_attributes.insertColumn("Visual Relativised Entropy"); for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { int row = m_attributes.getRowid(PixelRef(i,j)); float val; val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::ENTROPY); m_attributes.setValue(row, entropy_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::REL_ENTROPY); m_attributes.setValue(row, rel_entropy_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::INTEGRATION_HILL); m_attributes.setValue(row, integ_hh_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::INTEGRATION_TEKL); m_attributes.setValue(row, integ_tk_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::MEAN_DEPTH); m_attributes.setValue(row, depth_col, val); val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::GRAPH_SIZE); m_attributes.setValue(row, count_col, val); } } } } if (which_attributes & GraphVertexList::POINTDEPTH) { int col = m_attributes.insertColumn("Visual Step Depth"); for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { int row = m_attributes.getRowid(PixelRef(i,j)); float val; val = (float) m_points[i][j].getAttributes().getAttr(AttrHeader::POINT_DEPTH); m_attributes.setValue(row, col, val); } } } } if (which_attributes & GraphVertexList::METRIC) { int mspa_col = m_attributes.insertColumn("Metric Mean Shortest-Path Angle"); int mspl_col = m_attributes.insertColumn("Metric Mean Shortest-Path Distance"); int dist_col = m_attributes.insertColumn("Metric Mean Straight-Line Distance"); int count_col = m_attributes.insertColumn("Metric Node Count"); for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { int row = m_attributes.getRowid(PixelRef(i,j)); double val, total = m_points[i][j].getAttributes().getAttr(AttrHeader::METRIC_GRAPH_SIZE); // val = m_points[i][j].getAttributes().getAttr(AttrHeader::TOTAL_METRIC_ANGLE) / total; m_attributes.setValue(row, mspa_col, float(val)); val = m_points[i][j].getAttributes().getAttr(AttrHeader::TOTAL_METRIC_DEPTH) / total; m_attributes.setValue(row, mspl_col, float(val)); val = m_points[i][j].getAttributes().getAttr(AttrHeader::TOTAL_EUCLID_DIST) / total; m_attributes.setValue(row, dist_col, float(val)); // m_attributes.setValue(row, count_col, float(total)); } } } } for (int i = 0; i < m_cols; i++) { for (int j = 0; j < m_rows; j++) { if (m_points[i][j].m_attributes) { delete m_points[i][j].m_attributes; m_points[i][j].m_attributes = NULL; } } } } ///////////////////////////////////////////////////////////////////////////////// // Update connections will load an old graph and add char information void PointMap::addGridConnections() { for (int i = 0; i < m_attributes.getRowCount(); i++) { PixelRef curs = m_attributes.getRowKey(i); PixelRef node = curs.right(); Point& point = getPoint(curs); point.m_grid_connections = 0; for (int i = 0; i < 32; i += 4) { Bin& bin = point.m_node->bin(i); bin.first(); while (!bin.is_tail()) { if (node == bin.cursor()) { point.m_grid_connections |= (1 << (i / 4)); break; } bin.next(); } char dir; if (i == 0) { dir = PixelRef::VERTICAL; } else if (i == 4 || i == 8) { dir = PixelRef::NEGHORIZONTAL; } else if (i == 12 || i == 16) { dir = PixelRef::NEGVERTICAL; } else if (i == 20 || i == 24) { dir = PixelRef::HORIZONTAL; } node.move(dir); } } } void PointMap::setDisplayedAttribute(int col) { if (m_displayed_attribute == col) { return; } else { m_displayed_attribute = col; } // make a local copy of the display params for access speed: m_display_params = m_attributes.getDisplayParams(); m_attributes.setDisplayColumn(m_displayed_attribute,true); } // constrain is used to constrain to existing rows / cols // (not quite the same as constraining to bounding box due to spacing offsets) PixelRef PointMap::pixelate( const Point2f& p, bool constrain, int scalefactor ) const { PixelRef ref; double spacing = m_spacing / double(scalefactor); ref.x = int(floor( (p.x - m_bottom_left.x + (m_spacing / 2.0)) / spacing )); ref.y = int(floor( (p.y - m_bottom_left.y + (m_spacing / 2.0)) / spacing )); if (constrain) { if (ref.x < 0) ref.x = 0; else if (ref.x >= m_cols * scalefactor) ref.x = (m_cols * scalefactor) - 1; if (ref.y < 0) ref.y = 0; else if (ref.y >= m_rows * scalefactor) ref.y = (m_rows * scalefactor) - 1; } return ref; } // dangerous: used only for making a false selection set bool PointMap::overrideSelPixel(PixelRef pix) { m_selection = OVERRIDE_SELECTION; if (!(m_points[pix.x][pix.y].m_state & Point::SELECTED)) { m_points[pix.x][pix.y].m_state |= Point::SELECTED; m_selection_set.insert(pix); } return true; } bool PointMap::clearSel() { if (m_selection == NO_SELECTION) { return false; } for (auto& sel: m_selection_set) { getPoint(sel).m_state &= ~Point::SELECTED; } m_selection_set.clear(); m_selection = NO_SELECTION; m_attributes.deselectAll(); return true; } bool PointMaps::write(std::ostream& stream, int version, bool displayedmaponly) { if (!displayedmaponly) { stream.write((char *) &m_displayed_map, sizeof(m_displayed_map)); int count = size(); stream.write((char *) &count, sizeof(count)); for (int i = 0; i < count; i++) { at(i).write( stream, version ); } } else { int dummy; // displayed map is 0: dummy = 0; stream.write((char *) &dummy, sizeof(dummy)); // count is 1 dummy = 1; stream.write((char *) &dummy, sizeof(dummy)); // at(m_displayed_map).write(stream, version); } return true; } bool PointMap::write( std::ostream& stream, int version ) { dXstring440::writeString(stream, m_name); stream.write( (char *) &m_spacing, sizeof(m_spacing) ); stream.write( (char *) &m_rows, sizeof(m_rows) ); stream.write( (char *) &m_cols, sizeof(m_cols) ); stream.write( (char *) &m_point_count, sizeof(m_point_count) ); stream.write( (char *) &m_bottom_left, sizeof(m_bottom_left) ); stream.write( (char *) &m_displayed_attribute, sizeof(m_displayed_attribute) ); m_attributes.write( stream, version ); for (int j = 0; j < m_cols; j++) { for (int k = 0; k < m_rows; k++) { m_points[j][k].write( stream, version ); } } stream.write((char *) &m_processed, sizeof(m_processed)); stream.write((char *) &m_boundarygraph, sizeof(m_boundarygraph)); return false; } } ================================================ FILE: mgraph440/pointmap.h ================================================ #pragma once #include "mgraph440/spacepix.h" #include "mgraph440/point.h" #include "mgraph440/pixelref.h" #include "mgraph440/attributes.h" namespace mgraph440 { class PointMap : public PixelBase { public: enum { NO_SELECTION = 0, SINGLE_SELECTION = 1, COMPOUND_SELECTION = 2, LAYER_SELECTION = 4, OVERRIDE_SELECTION = 8 }; bool m_processed; bool m_boundarygraph; std::string m_name; SuperSpacePixel *m_spacepix; Point2f m_bottom_left; double m_spacing; mutable int m_displayed_attribute; AttributeTable m_attributes; int m_point_count; bool m_hasIsovistAnalysis = false; int m_selection; bool m_pinned_selection; bool m_initialised; bool m_blockedlines; mutable DisplayParams m_display_params; std::set m_selection_set; // n.b., m_selection_set stored as int for compatibility with other map layers Point **m_points; // will contain the graph reference when created std::vector m_merge_lines; Point& getPoint(const PixelRef& p) const { return m_points[p.x][p.y]; } bool setSpacePixel(const SuperSpacePixel *spacepix) {m_spacepix = (SuperSpacePixel *) spacepix; return true;} bool read( std::ifstream& stream, int version ); Point2f depixelate( const PixelRef& p, double scalefactor = 1.0 ) const; // Inlined below void convertAttributes( int which_attributes ); void addGridConnections(); // adds grid connections where graph does not include them void setDisplayedAttribute( int col ); PixelRef pixelate(const Point2f &p, bool constrain, int scalefactor) const; AttributeTable& getAttributeTable() { return m_attributes; } bool overrideSelPixel(PixelRef pix); double getSpacing() const { return m_spacing; } bool clearSel(); // clear the current selection // Note: passed by ref, use with care in multi-threaded app const std::set& getSelSet() const { return m_selection_set; } bool write(std::ostream &stream, int version ); }; inline Point2f PointMap::depixelate( const PixelRef& p, double scalefactor ) const { return Point2f( m_bottom_left.x + m_spacing * scalefactor * double(p.x), m_bottom_left.y + m_spacing * scalefactor * double(p.y) ); } class PointMaps : public prefvec { public: int m_displayed_map; SuperSpacePixel *m_spacepix; pmap m_data_objects; // deprecated: (first int is data layer -- presumably the KEY not the index, second int is object ref) void setDisplayedPointMapRef(int i) { m_displayed_map = i; } PointMap& getDisplayedPointMap() { return at(m_displayed_map); } bool overrideSelPixel(PixelRef pix); // set a pixel to selected: careful! void setSpacePixel(SuperSpacePixel *spacepix) { m_spacepix = spacepix; for (size_t i = 0; i < size(); i++) at(i).setSpacePixel(spacepix); } int getDataObject( int layer ) { size_t var = m_data_objects.searchindex( layer ); if (var != paftl::npos) return m_data_objects.at(var); return -1; // note: not paftl::npos } bool read(std::ifstream& stream, int version) { stream.read((char *) &m_displayed_map, sizeof(m_displayed_map)); int count; stream.read((char *) &count, sizeof(count)); for (int i = 0; i < count; i++) { push_back(PointMap()); tail().setSpacePixel( (SuperSpacePixel *) this ); tail().read( stream, version ); } return true; } bool write(std::ostream &stream, int version, bool displayedmaponly = false ); }; } ================================================ FILE: mgraph440/salaprogram.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // salaprogram.cpp - a component of the depthmapX - spatial network analysis platform // SalaScripting language ///////////////////////////////////////////////////////////////////////// // SalaScripting language // A "Pythonesque" language, which is pre-interpretted, and thus generally // should run fairly fast // The class implementation is very much hardcoded for built-in classes, // so user defined classes will be difficult to implement // (but would you really want classes in an inbuilt scripting language?! -- I guess some people would) // User defined functions are not included yet, but should be fairly easy using a global function stack // alongside the global variable stack #include #include #include #include "mgraph440/pafmath.h" #include #include #include #include namespace mgraph440 { /////////////////////////////////////////////////////////////////////////////////////////////// // Assign and list access rather incongruently in math ops, but never mind: bool g_sala_loaded = false; prefvec g_sala_math_ops; prefvec g_sala_comp_ops; prefvec g_sala_logical_ops; prefvec g_sala_global_funcs; prefvec g_sala_member_funcs; void loadSalaProgram() { // math ops g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_ADD, "+", "add" ) ); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_SUBTRACT, "-", "subtract" ) ); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MINUS, "-", "negative" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_PLUS, "+", "positive" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MULTIPLY, "*", "multiply" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_DIVIDE, "/", "divide" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MODULO, "%", "modulo" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_POWER, "^", "power" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_ASSIGN, "=", "assignment" )); g_sala_math_ops.push_back(SalaFuncLabel( SalaObj::S_LIST_ACCESS, "[]", "list access" )); // list access included even though not parsed directly like this // comp ops g_sala_comp_ops.push_back( SalaFuncLabel( SalaObj::S_GT, ">", "greater than" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_LT, "<", "less than" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_GEQ, ">=", "greater than or equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_LEQ, "<=", "less than or equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_NEQ, "!=", "not equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_EQ, "==", "equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_IS, "is", "is the same object as" )); // logical ops g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_NOT, "not", "logical not" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_NOT, "!", "logical not" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_AND, "and", "logical and" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_AND, "&&", "logical and" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_OR, "or", "logical or" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_OR, "||", "logical or" )); // global functions g_sala_global_funcs.push_back( SalaFuncLabel( SalaObj::S_SQRT, "sqrt", "square root" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LOG, "log", "log base 10" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LN, "ln", "natural logarithm" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_RAND, "random", "random number (0.0 to 1.0)" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_SIN, "sin", "sine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_COS, "cos", "cosine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_TAN, "tan", "tangent" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ASIN, "asin", "inverse sine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ACOS, "acos", "inverse cosine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ATAN, "atan", "inverse tangent" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LEN, "len", "array or string length" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_RANGE, "range", "set of integers" )); // member functions g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FAPPEND, "append", "append item" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FEXTEND, "extend", "extend by list" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FPOP, "pop", "pop (last) item" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FCLEAR, "clear", "clear contents" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FVALUE, "value", "get attribute value" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FSETVALUE, "setvalue", "set attribute value" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FMARK, "mark", "get node mark" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FSETMARK, "setmark", "set node mark" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FCONNECTIONS, "connections", "get list of connections" )); g_sala_loaded = true; } /////////////////////////////////////////////////////////////////////////////////////////////// SalaProgram::SalaProgram(SalaObj context) { if (!g_sala_loaded) { loadSalaProgram(); } // col is used when run in update mode, it does not form part of the program: m_col = -1; m_thisobj = context; } SalaProgram::~SalaProgram() { } // use istrstream to make an istream from a string: // istrstream file(char *); bool SalaProgram::parse(std::istream& program) { m_var_stack.clear(); m_error_stack.clear(); // this ensures wipe of any pre-existing variables in the global context: m_root_command = SalaCommand(this,NULL,-1,SalaCommand::SC_ROOT); int line = 0; SalaCommand *parent = &m_root_command; while (!program.eof()) { // the problem with a language being "Pythonesque" is that the "end" of // any control is implicit through the amount of indentation // Thus, the parser eats the white space, only handing of control // to a function when it is ready to parse, and knows its parent int indent = 0; bool endloop = false; while (!endloop) { char ch = program.peek(); switch (ch) { case ' ': indent++; break; case 13: break; // ignore case '\n': line++; indent = 0; break; case '#': // hit comment, read to end of line: while (ch != EOF && ch != '\n') { program.get(); ch = program.peek(); } line++; break; case '\\': // hit line continuation, ignore everything after it: while (ch != EOF && ch != '\n') { program.get(); ch = program.peek(); } line++; break; case EOF: program.get(); // actually shift onto the eof character endloop = true; break; default: endloop = true; break; } if (!endloop) { program.get(); } } // okay, we now know indent level, and we are ready to parse: if (!program.eof()) { while (indent <= parent->m_indent) { parent = parent->m_parent; } parent->m_children.push_back(SalaCommand(this,parent,indent)); SalaCommand &thiscommand = parent->m_children.tail(); try { line = thiscommand.parse(program,line); } catch (SalaError e) { if (e.lineno == -1) e.lineno = line; m_error_stack.push_back(e); return false; } // sort out commands capable of having children: if (thiscommand.m_command == SalaCommand::SC_FOR || thiscommand.m_command == SalaCommand::SC_IF || thiscommand.m_command == SalaCommand::SC_WHILE) { parent = &thiscommand; } else if (thiscommand.m_command == SalaCommand::SC_ELSE) { if (parent->m_children.size() < 2) { m_error_stack.push_back(SalaError("'Else' must be preceded by an 'if','for' or 'while'", thiscommand.m_line)); return false; } int command = parent->m_children[parent->m_children.size()-2].m_command; if (command != SalaCommand::SC_IF && command != SalaCommand::SC_ELIF && command != SalaCommand::SC_FOR && command != SalaCommand::SC_WHILE) { m_error_stack.push_back(SalaError("'Else' must be preceded by an 'if','for' or 'while'", thiscommand.m_line)); return false; } parent = &thiscommand; } else if (thiscommand.m_command == SalaCommand::SC_ELIF) { if (parent->m_children.size() < 2) { m_error_stack.push_back(SalaError("'Elif' must be preceded by an 'if' condition", thiscommand.m_line)); return false; } int command = parent->m_children[parent->m_children.size()-2].m_command; if (command != SalaCommand::SC_IF && command != SalaCommand::SC_ELIF) { m_error_stack.push_back(SalaError("'Elif' must be preceded by an 'if' condition", thiscommand.m_line)); return false; } parent = &thiscommand; } } } // do a quick check that all 'for', 'if' and 'elif' have children: // TO DO! return true; } SalaObj SalaProgram::evaluate() { for (size_t i = 0; i < m_var_stack.size(); i++) { // uninitialise all variables: m_var_stack[i].uninit(); } m_marked = false; // run the program SalaObj obj; bool ret = false, ifhandled = false; m_root_command.evaluate(obj,ret,ifhandled); // clear marks if they've been used: if (m_marked) { AttributeTable *table = m_thisobj.getTable(); for (int i = 0; i < table->getRowCount(); i++) { // Quick mod - TV #if defined(_MSC_VER) table->setMark(i,SalaObj()); #else SalaObj objTmp = SalaObj(); table->setMark(i,objTmp); #endif } m_marked = false; } return obj; } // this function is called by depthmapX to run a script to update a column // the operation is on a single node / row of the database combination bool SalaProgram::runupdate(int col, const std::set &selset) { AttributeTable *table = m_thisobj.getTable(); bool pointmap = (m_thisobj.type & SalaObj::S_POINTMAP) ? true : false; // // note: reference, will change object directly, which is important for commands running the program int& row = m_thisobj.data.graph.node; m_col = col; if (selset.size()) { for (auto& sel: selset) { row = sel; // *** NB! selsets for vga store pixelrefs keys, *all* others use rowids directly *** try { SalaObj val = evaluate(); float v = (float) val.toDouble(); // note, toDouble will type check and throw if there's a problem if (!std::isfinite(v)) { v = -1.0f; } table->changeValue(pointmap ? table->getRowid(row) : row,m_col,v); } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } else { for (int i = 0; i < table->getRowCount(); i++) { row = pointmap ? table->getRowKey(i) : i; // *** NB! selsets for vga store pixelrefs keys, *all* others use rowids directly *** try { SalaObj val = evaluate(); float v = (float) val.toDouble(); // note, toDouble will type check and throw if there's a problem if (!std::isfinite(v)) { v = -1.0f; } table->changeValue(i,m_col,v); } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } return true; } // this function is called by depthmapX to run a script to select values // the operation is on a single node / row of the database combination bool SalaProgram::runselect(std::vector &selsetout, const std::set& selsetin) { AttributeTable *table = m_thisobj.getTable(); bool pointmap = (m_thisobj.type & SalaObj::S_POINTMAP) ? true : false; // int& row = m_thisobj.data.graph.node; if (selsetin.size()) { for (auto& sel: selsetin) { row = sel; // *** NB! selsets for vga store pixelrefs keys, *all* others use rowids directly *** try { SalaObj val = evaluate(); bool v = val.toBool(); // note, toBool will type check and throw if there's a problem if (v) { selsetout.push_back(sel); } } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } else { for (int i = 0; i < table->getRowCount(); i++) { row = pointmap ? table->getRowKey(i) : i; // *** NB! selsets for vga store pixelrefs keys, *all* others use rowids directly *** try { SalaObj val = evaluate(); bool v = val.toBool(); // note, toBool will type check and throw if there's a problem if (v) { selsetout.push_back(row); } } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } return true; } std::string SalaProgram::getLastErrorMessage() const { const SalaError& error = m_error_stack.tail(); if (error.lineno == -1) { return error.message; } else { return error.message + " on line " + dXstring440::formatString(error.lineno+1,"%d"); } } //////////////////////////////////////////////////////////////////////////// SalaCommand::SalaCommand(SalaProgram *program, SalaCommand *parent, int indent, Command command) { m_program = program; m_parent = parent; m_indent = indent; m_command = command; m_line = 0; } int SalaCommand::parse(std::istream& program, int line) { m_func_stack.clear(); m_eval_stack.clear(); m_var_names.clear(); m_command = SC_NONE; // useful to know which line the command starts on for debugging purposes m_line = line; int last = SP_FUNCTION; bool endloop = false; bool overridecache = false; bool firstword = true; SalaBuffer buffer; char cache = ' '; // while (!endloop && !program.eof()) { char alpha = program.get(); switch (alpha) { // string constant case '\"': case '\'': // variants: either delimit with single or double quotes if (!buffer.empty()) { decode(buffer); buffer.clear(); } { char delim = alpha; char beta = program.peek(); while (beta != EOF && beta != '\n' && (beta != delim || alpha == '\\')) { alpha = program.get(); beta = program.peek(); buffer.add(alpha); } if (beta == EOF || beta == '\n') { throw SalaError("No closing quote",m_line); } else { program.get(); // take off closing quote and discard } // add even if the string constant is empty: m_eval_stack.push_back( std::string(buffer) ); buffer.clear(); last = SP_DATA; } break; // operator stack case '+': case '-': if (!buffer.empty()) { last = decode(buffer); if (last & SP_NUMBER && cache == 'e') { // check for 9.999e+99... // decode will handle later: buffer.add(alpha); break; } // otherwise handled, clear the buffer: buffer.clear(); } if (last == SP_FUNCTION || last == SP_COMMAND) { pushFunc( alpha == '+' ? SalaObj(SalaObj::S_PLUS) : SalaObj(SalaObj::S_MINUS) ); } else { pushFunc( alpha == '+' ? SalaObj(SalaObj::S_ADD) : SalaObj(SalaObj::S_SUBTRACT) ); } last = SP_FUNCTION; break; case '=': if (!buffer.empty()) { // n.b., this will catch '>=', '<=', '==' and '!=' if (strchr("><=!",cache) != NULL) { buffer.add(alpha); last = decode(buffer); buffer.clear(); overridecache = true; // handled next step (see default clause below) break; } else { last = decode(buffer); buffer.clear(); } } buffer.add(alpha); // <- '=' decoded later break; case '!': case '<': case '>': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // note: this looks a little odd, simply adding to the buffer, but these // are handled by the default function next step if still hanging on the buffer buffer.add(alpha); break; case '/': case '*': case '%': case '^': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } last = decode(std::string(1,alpha)); break; case '(': // note: the opening bracket forms a function if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } if (last == SP_DATA) { // whatever that just went onto the eval stack, the user thought it was a function... // alert them: throw SalaError(m_last_string + " is not a known function name", m_line); // (in the future, we may well want to transfer an object hashed function name to the func stack instead) } else if (last == SP_NUMBER) { throw SalaError("Cannot treat a number as if it were a function", m_line); } // check for pair of open / close brackets: () or ( ) -- this is a null value { char beta = program.peek(); while (beta != EOF && beta == ' ') { alpha = program.get(); beta = program.peek(); } if (beta == ')') { alpha = program.get(); m_eval_stack.push_back(SalaObj()); last = SP_DATA; } else { pushFunc( SalaObj::S_OPEN_BRACKET ); last = SP_FUNCTION; } } break; case ')': // note: the closing bracket forms a data packet: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_CLOSE_BRACKET ); last = SP_DATA; break; case '[': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // check for pair of open / close brackets: [] or [ ] -- this is a null value or empty list depending on context { char beta = program.peek(); while (beta != EOF && beta == ' ') { alpha = program.get(); beta = program.peek(); } if (beta == ']') { alpha = program.get(); if (last == SP_DATA) { throw SalaError("Accessor operator ('[]') requires a parameter", m_line); } else { // put an empty list on the stack m_eval_stack.push_back( SalaObj(SalaObj::S_CONST_LIST, 0) ); } last = SP_DATA; } else { if (last == SP_DATA) { // list accessor function pushFunc( SalaObj::S_LIST_ACCESS ); pushFunc( SalaObj::S_OPEN_SQR_BRACKET_ACCESS ); } else { // making an list... pushFunc( SalaObj::S_OPEN_SQR_BRACKET_LIST ); } last = SP_FUNCTION; } } break; case ']': // note: the closing bracket forms a data packet: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_CLOSE_SQR_BRACKET ); last = SP_DATA; break; case ',': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_COMMA ); last = SP_FUNCTION; break; case ':': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // end of command (def, if, else, elif and for) if (m_command == SC_FOR || m_command == SC_WHILE || m_command == SC_IF || m_command == SC_ELIF || m_command == SC_ELSE) { bool commentfound = false; alpha = program.get(); while (!program.eof() && alpha != '\n') { // continue to end of line, only comments allowed though! if (!commentfound) { if (alpha == '#') { commentfound = true; } else if (alpha != ' ' && alpha != 13) { // 13 ignored, as it appears \n is 10 in this stream... (so 13,10 can be found) throw SalaError("'For', 'if', 'else', etc cannot have execution part on same line; insert a new line after ':'", m_line); } } alpha = program.get(); } line++; endloop = true; } else { throw SalaError("Unexpected colon ':' in expression",m_line); } break; // end of line: case '\\': // hit line continuation, read to end of line: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } while (!program.eof() && program.get() != '\n'); // note, end loop is not set, this is a continuation character line++; // line is incremented, although it this command will still start on the original line break; case '#': // loop through until hit \n or end if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } while (!program.eof() && program.get() != '\n'); line++; // should have hit a line end (or if it's end of file, it doesn't matter) endloop = true; break; case '\n': // force end of command parse: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } line++; // hit a line end endloop = true; break; case ' ': // white space: read word if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } break; case '.': // currently handled inelegantly through decode for either number (1.002) or member access (blah.x()) buffer.add('.'); break; case '\t': throw SalaError("Tab character found: please use only spaces to indent lines",m_line); break; default: if (strchr("<>=!",cache)) { // >, <, = and ! are held as next step operators last = decode(buffer); buffer.clear(); } if (alpha != EOF && alpha != 13) { // 13 ignored, as it appears \n is 10 in this stream... if (!isalphanum_(alpha) && alpha != '&' && alpha != '|') { // include & and | for and and or throw SalaError("Unrecognised symbol ('" + std::string(1,alpha) + "')",m_line); } buffer.add(alpha); } break; } if (overridecache) { cache = ' '; overridecache = false; } else { cache = alpha; } if (last == SP_COMMAND) { if (m_command == SC_FOR) { // check the name of the for variable: alpha = program.get(); while (alpha == ' ') { alpha = program.get(); } if (!isalpha_(alpha)) { throw SalaError("'For' command expecting variable name",m_line); } while (isalphanum_(alpha)) { buffer.add(alpha); alpha = program.get(); } if (alpha != ' ') { throw SalaError("Command expecting syntax 'for xyz in'...",m_line); } // add the for iterator variable: m_program->m_var_stack.push_back(SalaObj()); int x = m_program->m_var_stack.size() - 1; m_var_names.add(buffer,x); m_for_iter = SalaObj( SalaObj::S_VAR, x); // now check for 'in' while (alpha == ' ') { alpha = program.get(); } if (alpha != 'i' || program.get() != 'n') { throw SalaError("Command expecting syntax 'for xyz in'...",m_line); } } last = SP_FUNCTION; } } if (!buffer.empty()) { decode(buffer); buffer.clear(); last = SP_DATA; } // push remaining functions onto eval stack: while (m_func_stack.size()) { if (m_func_stack.tail().type & SalaObj::S_BRACKET) { throw SalaError("Unmatched brackets",m_line); } m_eval_stack.push_back(m_func_stack.tail()); m_func_stack.pop_back(); } if (m_eval_stack.size() == 0 && m_command != SC_ELSE) { // note, else is by definition empty throw SalaError("Partial or missing command",m_line); } return line; } int SalaCommand::decode(std::string string) // string copied as makelower applied { // ideally, some form of hashing the string should be performed so that // functions can be found quicker than a long list of "else ifs" int retvar = SP_NONE; dXstring440::toLower(string); if (m_command == SC_NONE) { if (string == "return") { m_command = SC_RETURN; retvar = SP_COMMAND; } else if (string == "for") { m_command = SC_FOR; // n.b. will still need a variable name and "in": for x in ... retvar = SP_COMMAND; } else if (string == "while") { m_command = SC_WHILE; retvar = SP_COMMAND; } else if (string == "if") { m_command = SC_IF; retvar = SP_COMMAND; } else if (string == "elif") { m_command = SC_ELIF; retvar = SP_COMMAND; } else if (string == "else") { m_command = SC_ELSE; retvar = SP_COMMAND; } } if (retvar == SP_COMMAND) { // m_last_string = string; // make a copy for debugging purposes return retvar; } // numeric constant if (isdigit(string[0]) || (string.length() > 1 && string[0] == '.' && isdigit(string[1]))) { if (string[string.length()-1] == 'e') { // handle later... at the moment we have hit + or - in 9.999e+99 or 9.999e-99 m_last_string = string; // make a copy for debugging purposes return SP_NUMBER; } if (string.find_first_of('.') != std::string::npos || string.find_first_of('e') != std::string::npos) { m_eval_stack.push_back( atof(string.c_str()) ); } else { m_eval_stack.push_back( atoi(string.c_str()) ); } retvar = SP_NUMBER; } // this is a different 'e' to the 'e' above -> natural logarithm else if (string == "e") { m_eval_stack.push_back( 2.7182818284590452353602874713527 ); retvar = SP_NUMBER; } else if (string == "pi") { m_eval_stack.push_back( 3.1415926535897932384626433832795 ); retvar = SP_NUMBER; } // boolean constants else if (string == "true") { m_eval_stack.push_back( bool(true) ); retvar = SP_NUMBER; } else if (string == "false") { m_eval_stack.push_back( bool(false) ); retvar = SP_NUMBER; } // this else if (string == "this") { m_eval_stack.push_back( SalaObj(SalaObj::S_THIS) ); retvar = SP_DATA; } else if (string == "none") { m_eval_stack.push_back(SalaObj()); retvar = SP_DATA; } else { // everything else should be in one of the operator / func lists: size_t i; if (retvar == SP_NONE) { // note, math ops include assignment for (i = 0 ; i < g_sala_math_ops.size(); i++) { if (string == g_sala_math_ops[i].name) { pushFunc( g_sala_math_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_comp_ops.size(); i++) { if (string == g_sala_comp_ops[i].name) { pushFunc( g_sala_comp_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_logical_ops.size(); i++) { if (string == g_sala_logical_ops[i].name) { pushFunc( g_sala_logical_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_global_funcs.size(); i++) { if (string == g_sala_global_funcs[i].name) { pushFunc( g_sala_global_funcs[i].func ); retvar = SP_FUNCTION; } } } } if (retvar == SP_NONE) { size_t n = string.find_first_of("."); if (n != std::string::npos) { if (n > 0) { decode(string.substr(0,n)); } if (decode_member(string.substr(n+1),false) == SP_NONE) { throw SalaError("There is no known member function called " + string.substr(n+1),m_line); } retvar = SP_FUNCTION; } else { // see if it's a member function of 'this': retvar = decode_member(string,true); if (retvar == SP_NONE) { // see if it exists in the variable stack (walk up scope) SalaCommand *parent = m_parent; size_t n = paftl::npos; int x = -1; while (parent != NULL && n == -1) { n = parent->m_var_names.searchindex(string); if (n != paftl::npos) { x = parent->m_var_names.value(n); } parent = parent->m_parent; } if (x != -1) { m_eval_stack.push_back( SalaObj( SalaObj::S_VAR, x) ); retvar = SP_DATA; } else { m_program->m_var_stack.push_back(SalaObj()); x = m_program->m_var_stack.size() - 1; // note: attach simply to your m_parent, not parent variable, which has walked up the stack m_parent->m_var_names.add(string,x); m_eval_stack.push_back( SalaObj( SalaObj::S_VAR, x) ); retvar = SP_DATA; } } } } if (retvar == SP_NONE) { // should never reach this point throw SalaError("There is no known function or variable called " + string,m_line); } if (m_command == SC_NONE) { m_command = SC_EXPR; } m_last_string = string; // make a copy for debugging purposes return retvar; } // note, thisobj not usually known (type S_NALL), // but, depending where SalaScript is called from, it may be: // a graph node / table row (for "select by query" and "edit connections") // a map (not yet implemented, but intended for scripting agents) int SalaCommand::decode_member(const std::string& string, bool apply_to_this) { int retvar = SP_NONE; // note, all hardcoded for built in classes: // string classes: for (size_t i = 0; i < g_sala_member_funcs.size(); i++) { // note '&' in the type -- essentially allows for inheritance between objects (tuple is type of list, etc) if (!apply_to_this || (m_program->m_thisobj.type & g_sala_member_funcs[i].type) != 0) { if (string == g_sala_member_funcs[i].name) { pushFunc( g_sala_member_funcs[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_FUNCTION && apply_to_this) { m_eval_stack.push_back(SalaObj(SalaObj::S_THIS)); } return retvar; } void SalaCommand::pushFunc(const SalaObj& func) { // note comma is part of the "Bracket" class of things: if (func.type & SalaObj::S_BRACKET) { if (func.type == SalaObj::S_CLOSE_BRACKET) { while (m_func_stack.size() && m_func_stack.tail().type != SalaObj::S_OPEN_BRACKET) { m_eval_stack.push_back(m_func_stack.tail()); m_func_stack.pop_back(); } if (m_func_stack.size()) { // don't necessarily pop it... if it's a group marker, we want to hang onto it: if (m_func_stack.tail().data.count > 1) { m_func_stack.tail().type = SalaObj::S_CONST_TUPLE; m_eval_stack.push_back(m_func_stack.tail()); } m_func_stack.pop_back(); // remove opening bracket } } else if (func.type == SalaObj::S_CLOSE_SQR_BRACKET) { while (m_func_stack.size() && (m_func_stack.tail().type & SalaObj::S_OPEN_SQR_BRACKET) == 0) { m_eval_stack.push_back(m_func_stack.tail()); m_func_stack.pop_back(); } if (m_func_stack.size()) { // don't pop it, always make a list from a make list command, even if it's only one item long: if (m_func_stack.tail().type == SalaObj::S_OPEN_SQR_BRACKET_LIST || m_func_stack.tail().data.count > 1) { m_func_stack.tail().type = SalaObj::S_CONST_LIST; m_eval_stack.push_back(m_func_stack.tail()); } m_func_stack.pop_back(); } } else if (func.type == SalaObj::S_COMMA) { // go and increment your associated group / list while (m_func_stack.size() && m_func_stack.tail().type != SalaObj::S_OPEN_BRACKET && (m_func_stack.tail().type & SalaObj::S_OPEN_SQR_BRACKET) == 0) { m_eval_stack.push_back(m_func_stack.tail()); m_func_stack.pop_back(); } if (m_func_stack.size()) { m_func_stack.tail().data.count++; } } else { m_func_stack.push_back( func ); } } else if (!m_func_stack.size() || func.precedence() > m_func_stack.tail().precedence()) { // original: > m_func_stack.push_back(func); } else { while (m_func_stack.size() && func.precedence() <= m_func_stack.tail().precedence()) { // original <= m_eval_stack.push_back(m_func_stack.tail()); m_func_stack.pop_back(); } m_func_stack.push_back(func); } } void SalaCommand::evaluate(SalaObj& obj, bool& ret, bool& ifhandled) { int begin = m_eval_stack.size()-1; SalaObj *p_obj = NULL; switch (m_command) { case SC_EXPR: obj = evaluate(begin,p_obj); break; case SC_RETURN: ret = true; obj = evaluate(begin,p_obj); break; case SC_ROOT: { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } } break; case SC_IF: { SalaObj test = evaluate(begin,p_obj); if (test.toBool() == true) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } ifhandled = true; } else { ifhandled = false; } } break; case SC_ELIF: if (!ifhandled) { SalaObj test = evaluate(begin,p_obj); if (test.toBool() == true) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } ifhandled = true; } } break; case SC_ELSE: if (!ifhandled) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } } break; case SC_FOR: { // eventually I'd like to do this with generators / iterators rather than constructing a list each time SalaObj list = evaluate(begin,p_obj); if (list.type == SalaObj::S_LIST) { int len = list.data.list.list->size(); if (len != 0) { for (int i = 0; i < len; i++) { // reset all my stack (actually, all parent functions should do this!) for (size_t j = 0; j < m_var_names.size(); j++) { m_program->m_var_stack[m_var_names.value(j)].uninit(); } m_program->m_var_stack[m_for_iter.data.var] = list.data.list.list->at(i); for (size_t k = 0; k < m_children.size(); k++) { m_children[k].evaluate(obj,ret,ifhandled); if (ret) break; } if (ret) break; } ifhandled = true; } else { ifhandled = false; } } else { ifhandled = false; } } break; case SC_WHILE: { int counter = 0; while (evaluate(begin,p_obj).toBool()) { for (size_t k = 0; k < m_children.size(); k++) { m_children[k].evaluate(obj,ret,ifhandled); if (ret) break; } if (ret) break; if (++counter == 0x04000000) { // <- an arbitrary big number throw SalaError("Infinite loop",m_line); } begin = m_eval_stack.size()-1; } if (counter) { ifhandled = true; } else { ifhandled = false; } } break; default: throw SalaError("Unknown command",m_line); break; } } SalaObj SalaCommand::evaluate(int& pointer, SalaObj* &p_obj) { if (pointer < 0) { throw SalaError("Missing argument",m_line); } SalaObj data = m_eval_stack[pointer]; pointer--; if (data.type == SalaObj::S_FUNCTION) { SalaObj::Func func = data.data.func; int group = (func & SalaObj::S_GROUP); if (group == SalaObj::S_MATH_OPS) { try { switch (func) { case SalaObj::S_ADD: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) + evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 + tmp2; } #endif break; case SalaObj::S_SUBTRACT: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) - evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 - tmp2; } #endif break; case SalaObj::S_PLUS: data = evaluate(pointer,p_obj); // just ignore it break; case SalaObj::S_MINUS: // Quick mod - TV #if defined(_MSC_VER) data = -evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = -tmp1; } #endif break; case SalaObj::S_MULTIPLY: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) * evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 * tmp2; } #endif break; case SalaObj::S_DIVIDE: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) / evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp2 / tmp1; } #endif break; case SalaObj::S_MODULO: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) % data; // reverse order #else { SalaObj tmp1 = evaluate(pointer, p_obj); data = tmp1 % data; } #endif break; case SalaObj::S_POWER: data = evaluate(pointer,p_obj); // reverse order data = pow(evaluate(pointer,p_obj).toDouble(),data.toDouble()); break; case SalaObj::S_ASSIGN: data = evaluate(pointer,p_obj); // reverse order evaluate(pointer,p_obj); if (p_obj != nullptr) { *p_obj = data; } else { throw SalaError("Cannot assign to constant, function or none",m_line); } data = SalaObj(); // assign returns nil value break; case SalaObj::S_LIST_ACCESS: { int x = evaluate(pointer,p_obj).toInt(); data = evaluate(pointer,p_obj); if (data.type == SalaObj::S_LIST) { // setting p_obj allows things above this in the stack to modify it p_obj = &(data.list_at(x)); return *p_obj; } else if (data.type == SalaObj::S_STRING) { // but n.b., strings cannot be modified, keep p_obj as null p_obj = NULL; return data.char_at(x); } else throw SalaError("Cannot be applied to " + data.getTypeIndefArt() + data.getTypeStr(),m_line); } break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_math_ops.size(); i++) { if (g_sala_math_ops[i].func == func) { e.message = "In '" + g_sala_math_ops[i].name + "' operator: " + e.message; break; } } e.lineno = m_line; throw e; } } else if (group == SalaObj::S_LOGICAL_OPS) { try { switch (func) { case SalaObj::S_OR: // note: you cannot simply say evaluate(x) || evaluate(y) because if evaluate(x) is true, // the in-built || operator will not evaluate(y) // but... it's on the eval stack... it would be nice simply to pop the eval stack at // this point if the first half evaluates to true, thus emulating C... but it's in reverse order too! data = evaluate(pointer,p_obj); data = evaluate(pointer,p_obj).toBool() || data.toBool(); break; case SalaObj::S_AND: data = evaluate(pointer,p_obj).toBool() && evaluate(pointer,p_obj).toBool(); break; case SalaObj::S_NOT: data = !evaluate(pointer,p_obj).toBool(); break; case SalaObj::S_EQ: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) == evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer, p_obj); SalaObj tmp2 = evaluate(pointer, p_obj); data = (tmp1 == tmp2); } #endif break; case SalaObj::S_IS: // Quick mod - TV #if defined(_MSC_VER) data = op_is(evaluate(pointer,p_obj),evaluate(pointer,p_obj)); #else { SalaObj tmp1 = evaluate(pointer, p_obj); SalaObj tmp2 = evaluate(pointer, p_obj); data = op_is(tmp1, tmp2); } #endif break; case SalaObj::S_NEQ: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) != evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = (tmp1 != tmp2); } #endif break; case SalaObj::S_GT: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) > data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 > data); } #endif break; case SalaObj::S_LT: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) < data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 < data); } #endif break; case SalaObj::S_GEQ: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) >= data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 >= data); } #endif break; case SalaObj::S_LEQ: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) <= data; // revese order #else { SalaObj tmp1 = evaluate(pointer, p_obj); data = (tmp1 <= data); } #endif break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_logical_ops.size(); i++) { if (g_sala_logical_ops[i].func == func) { e.message = "In '" + g_sala_logical_ops[i].name + "' operator: " + e.message; break; } } for (size_t j = 0; j < g_sala_comp_ops.size(); j++) { if (g_sala_comp_ops[j].func == func) { e.message = "In '" + g_sala_comp_ops[j].name + "' operator: " + e.message; break; } } e.lineno = m_line; throw e; } } else if (group == SalaObj::S_GLOBAL_FUNCS) { try { switch (func) { case SalaObj::S_LEN: data = evaluate(pointer,p_obj); data = SalaObj( data.length() ); break; case SalaObj::S_RANGE: data = evaluate(pointer,p_obj); { int len = data.length(); if (len != 2 && len != 3) { throw SalaError("Range takes either 2 or 3 parameters",m_line); } int start = data.data.list.list->at(0).toInt(); int end = data.data.list.list->at(1).toInt(); int step = (len == 3) ? data.data.list.list->at(2).toInt() : 1; if (step == 0) { throw SalaError("Range cannot have a step of 0",m_line); } int listlen = (int) ceil(float(end - start) / float(step)); if (listlen <= 0) { data = SalaObj( SalaObj::S_LIST ); } else { data = SalaObj( SalaObj::S_LIST, listlen ); for (int i = start, j = 0; i < end; i += step, j++) { data.data.list.list->at(j) = i; } } } break; case SalaObj::S_SQRT: data = sqrt(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_LOG: data = log10(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_LN: data = ln(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_RAND: data = evaluate(pointer,p_obj); data.ensureNone(); data = SalaObj(prandom()); break; case SalaObj::S_SIN: data = sin(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_COS: data = cos(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_TAN: data = tan(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ASIN: data = asin(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ACOS: data = acos(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ATAN: data = atan(evaluate(pointer,p_obj).toDouble()); break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_global_funcs.size(); i++) { if (g_sala_global_funcs[i].func == func) { e.message = "In '" + g_sala_global_funcs[i].name + "' function: " + e.message; break; } } e.lineno = m_line; throw e; } } else if (group == SalaObj::S_MEMBER_FUNCS) { try { SalaObj param = evaluate(pointer,p_obj); SalaObj obj = evaluate(pointer,p_obj); switch (obj.type) { case SalaObj::S_LIST: case SalaObj::S_TUPLE: switch (func) { case SalaObj::S_FAPPEND: obj.data.list.list->push_back(param); data = SalaObj(); // returns none break; case SalaObj::S_FEXTEND: if (param.type & SalaObj::S_LIST) { int count = param.data.list.list->size(); for (int i = 0; i < count; i++) { obj.data.list.list->push_back(param.data.list.list->at(i)); } } else { throw SalaError("Parameter must be a list not " + param.getTypeIndefArt() + param.getTypeStr(),m_line); } data = SalaObj(); // returns none break; case SalaObj::S_FPOP: if (obj.data.list.list->size() == 0) { throw SalaError("List is empty", m_line); } if (param.type == SalaObj::S_NONE) { data = obj.data.list.list->tail(); obj.data.list.list->pop_back(); } else { pvector& list = *(obj.data.list.list); int i = param.toInt(); if (i < 0) i += list.size(); if (i < 0 || i >= (int)list.size()) throw SalaError("Index out of range"); data = list.at(i); list.remove_at(i); } break; case SalaObj::S_FCLEAR: param.ensureNone(); obj.data.list.list->clear(); obj = SalaObj(); break; default: throw SalaError("Not a member function of " + obj.getTypeStr(),m_line); } break; case SalaObj::S_SHAPEMAPOBJ: case SalaObj::S_POINTMAPOBJ: switch (func) { case SalaObj::S_FVALUE: { const std::string& str = param.toStringRef(); AttributeTable *table = obj.getTable(); int col = -1; if (str != "Ref Number") { col = table->getColumnIndex(str); if (col == -1) { throw SalaError(str + " is an unknown column",m_line); } } // *** NB! vga is keyed off pixelrefs *all* others use rowids directly *** // (this may seem an odd way to do it, but it speeds up connection hunting to use whichever method the map uses -- note idepthmap uses the method to access attributes) data = SalaObj(table->getValue((obj.type == SalaObj::S_POINTMAPOBJ) ? table->getRowid(obj.data.graph.node) : obj.data.graph.node,col)); } break; case SalaObj::S_FSETVALUE: { if (param.length() != 2) { throw SalaError("Function takes 2 parameters"); } const std::string& str = param.list_at(0).toStringRef(); float val = (float) param.list_at(1).toDouble(); AttributeTable *table = obj.getTable(); int col = -1; if (str != "Ref Number") { col = table->getColumnIndex(str); if (col == -1) { throw SalaError(str + " is an unknown column",m_line); } } // *** NB! vga is keyed off pixelrefs *all* others use rowids directly *** // (this may seem an odd way to do it, but it speeds up connection hunting to use whichever method the map uses -- note idepthmap uses the method to access attributes) table->setValue((obj.type == SalaObj::S_POINTMAPOBJ) ? table->getRowid(obj.data.graph.node) : obj.data.graph.node, col, val); data = SalaObj(); // returns none } break; case SalaObj::S_FCONNECTIONS: { data = connections(obj, param); } break; case SalaObj::S_FMARK: { param.ensureNone(); AttributeTable *table = obj.getTable(); data = table->getMark((obj.type == SalaObj::S_POINTMAPOBJ) ? table->getRowid(obj.data.graph.node) : obj.data.graph.node); } break; case SalaObj::S_FSETMARK: { AttributeTable *table = obj.getTable(); table->setMark((obj.type == SalaObj::S_POINTMAPOBJ) ? table->getRowid(obj.data.graph.node) : obj.data.graph.node, param); m_program->m_marked = true; // <- this tells the program to tidy up marks between executions data = SalaObj(); // returns none } break; default: throw SalaError("Not a member function of " + obj.getTypeStr(),m_line); } break; default: throw SalaError("Not a member function of " + obj.getTypeStr(), m_line); } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_member_funcs.size(); i++) { if (g_sala_member_funcs[i].func == func) { SalaObj type = SalaObj(g_sala_member_funcs[i].type); e.message = "In " + type.getTypeStr() + " '" + g_sala_member_funcs[i].name + "' function: " + e.message; break; } } e.lineno = m_line; throw e; } } } else if (data.type == SalaObj::S_THIS) { p_obj = &(m_program->m_thisobj); return *p_obj; } else if (data.type & SalaObj::S_VAR) { // retrieve value from variable stack (keeping in a variable stack means it can be reassigned dynamically) p_obj = &(m_program->m_var_stack[data.data.var]); return *p_obj; } else if (data.type & SalaObj::S_CONST_LIST) { // build an list from either a const tuple or const list: int x = data.data.count; data = SalaObj((data.type == SalaObj::S_CONST_LIST) ? SalaObj::S_LIST : SalaObj::S_TUPLE, x); for (--x; x >= 0; x--) { data.data.list.list->at(x) = evaluate(pointer,p_obj); // n.b., direct access to the list } } p_obj = NULL; return data; } ///////////////////////////////////////////////////////////////////////////////// SalaObj SalaCommand::connections(SalaObj graphobj, SalaObj param) { // now, depending on type of object, it may or may not be allowed parameters: // for point maps it can be none (all connections) or a bin number (0-32) // for segment maps it can be 'all' or 'forward' or 'back' (a string -- no parameters is excluded due to potential for errors) // for axial maps it must be none SalaObj list; if ((graphobj.type & SalaObj::S_MAP) == SalaObj::S_POINTMAP) { // point map version Node& node = graphobj.data.graph.map.point->getPoint(graphobj.data.graph.node).getNode(); if (param.type == SalaObj::S_NONE) { int count = node.count(); list = SalaObj( SalaObj::S_LIST, count); node.first(); for (int i = 0; i < count; i++) { graphobj.data.graph.node = node.cursor(); list.data.list.list->at(i) = graphobj; node.next(); } } else { int b = param.toInt(); // note, will throw if it's not the right type if (b < 0 || b > 31) { throw SalaError("Bin must be in range 0 to 31"); } Bin& bin = node.bin(b); int count = bin.count(); list = SalaObj( SalaObj::S_LIST, count); bin.first(); for (int i = 0; i < count; i++) { graphobj.data.graph.node = bin.cursor(); list.data.list.list->at(i) = graphobj; bin.next(); } } } else { const Connector& connector = graphobj.data.graph.map.shape->getConnections().at(graphobj.data.graph.node); int mode = Connector::CONN_ALL; if (graphobj.data.graph.map.shape->isSegmentMap()) { const std::string& str = param.toStringRef(); if (str == "forward") { mode = Connector::SEG_CONN_FW; } else if (str == "back") { mode = Connector::SEG_CONN_BK; } else if (str == "all") { mode = Connector::SEG_CONN_ALL; } } else { param.ensureNone(); } int count = connector.count(mode); list = SalaObj( SalaObj::S_LIST, count); connector.first(); for (int i = 0; i < count; i++) { graphobj.data.graph.node = connector.cursor(mode); list.data.list.list->at(i) = graphobj; connector.next(); } } return list; } ///////////////////////////////////////////////////////////////////////////////// AttributeTable *SalaObj::getTable() { if ((type & SalaObj::S_MAP) == SalaObj::S_POINTMAP) { return &(data.graph.map.point->getAttributeTable()); } else { return &(data.graph.map.shape->getAttributeTable()); } } int SalaObj::precedence() const { int prec = 0; if ((type & S_BRACKET) == 0) { // preserve bracket on func stack until after close bracket, remember to strip any at end switch (func()) { case S_ASSIGN: prec = 1; // do absolutely last! break; case S_AND: prec = 2; break; case S_OR: prec = 3; break; case S_NOT: prec = 4; break; case S_EQ: case S_IS: case S_LT: case S_GT: case S_LEQ: case S_GEQ: case S_NEQ: prec = 5; break; case S_ADD: case S_SUBTRACT: prec = 6; break; case S_MULTIPLY: case S_DIVIDE: case S_MODULO: prec = 7; break; case S_POWER: prec = 8; break; default: // function -- place straight on eval stack when you meet next operator prec = 9; break; } } return prec; } } ================================================ FILE: mgraph440/salaprogram.h ================================================ // salaprogram.h - a component of the depthmapX - spatial network analysis platform // SalaScripting language // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __SALAPROGRAM_H__ #define __SALAPROGRAM_H__ #include "mgraph440/stringutils.h" #include "mgraph440/paftl.h" #include #include #include namespace mgraph440 { class AttributeTable; class PointMap; class ShapeMap; inline bool isalphanum_(char c) { if (isalnum(c) || c == '_') return true; else return false; } inline bool isalpha_(char c) { if (isalpha(c) || c == '_') return true; else return false; } struct SalaError { int lineno; std::string message; SalaError(const std::string& m = std::string(), int li = -1) { message = m; lineno = li; } }; ///////////////////////////////////////////////////////////////////////////////////////// // A series of 8-byte types to go in the SalaObj data union // note, they cannot cannot instantiate a copy constructor as it is used as // a member of the union in SalaObj class SalaObj; struct SalaStr { public: int *refcount; std::string *string; public: friend bool operator == (const SalaStr& a, const SalaStr& b); friend bool operator != (const SalaStr& a, const SalaStr& b); friend bool operator < (const SalaStr& a, const SalaStr& b); friend bool operator > (const SalaStr& a, const SalaStr& b); // operator const std::string&() { return *string; } char char_at(size_t i) const { return string->operator[](i); } size_t length() const { return string->length(); } }; inline bool operator == (const SalaStr& a, const SalaStr& b) { return *(a.string) == *(b.string); } inline bool operator != (const SalaStr& a, const SalaStr& b) { return *(a.string) != *(b.string); } inline bool operator < (const SalaStr& a, const SalaStr& b) { return *(a.string) < *(b.string); } inline bool operator > (const SalaStr& a, const SalaStr& b) { return *(a.string) > *(b.string); } struct SalaList { int *refcount; pvector *list; public: friend bool operator == (const SalaList& a, const SalaList& b); friend bool operator != (const SalaList& a, const SalaList& b); // inlines below }; struct SalaGrf { int node; union Map { PointMap *point; // vga ShapeMap *shape; // everything else }; Map map; }; // SalaObj is 16 bytes, which is larger than I intended, but it appears // when you put both a double (8 bytes) and an int (4 bytes) into a class, it pads // to 16 bytes rather than the 12 you would expect // union members aren't allow copy constructors, so the list functionality // is built directly into the SalaObj, making it no more inefficient than if it // were to reference directly to another object to find, e.g., length or refcount // note lists are stored by reference. I'm not sure if this is a good idea! class SalaObj { friend class SalaProgram; friend class SalaCommand; friend class SalaArray; public: // Object types enum Type { S_BRACKET = 0x0000003f, S_OPEN_SQR_BRACKET = 0x0000000c, S_OPEN_BRACKET = 0x00000001, S_CLOSE_BRACKET = 0x00000002, S_OPEN_SQR_BRACKET_LIST = 0x00000004, S_OPEN_SQR_BRACKET_ACCESS = 0x00000008, S_CLOSE_SQR_BRACKET = 0x00000010, S_COMMA = 0x00000020, // bracket includes comma for checking purposes S_NONE = 0x00000100, S_UNINIT = 0x00000200, S_FUNCTION = 0x00000400, S_BOOL = 0x00001000, S_CHAR = 0x00002000, S_INT = 0x00004000, S_DOUBLE = 0x00008000, S_NUMBER = 0x0000c000, S_STRING = 0x00010000, S_VAR = 0x00020000, S_CONST_LIST = 0x00100000, S_CONST_TUPLE = 0x00300000, // tuple is a type of list S_LIST = 0x00400000, S_TUPLE = 0x00500000, // tuple is a type of list // maps are bitwise 'or'ed to node to make appropriate node type for each map S_GRAPHOBJ = 0x01000000, S_MAP = 0x06000000, S_POINTMAP = 0x02000000, S_SHAPEMAP = 0x04000000, // however, as the variable is uses the typename of the enum, each must be filled in explicitly: S_POINTMAPOBJ = 0x03000000, S_SHAPEMAPOBJ = 0x05000000, S_THIS = 0x10000000 }; // Built-in Functions, note, some of the groupings contain other operations (eg., math ops includes assign, and logical ops includes both comparators and logical ops) enum Func { S_FNULL = 0x00000000, S_GROUP = 0xf0000000, S_MATH_OPS = 0x10000000, S_LOGICAL_OPS = 0x20000000, S_GLOBAL_FUNCS = 0x30000000, S_MEMBER_FUNCS = 0x40000000, S_ADD = 0x10000001, S_SUBTRACT = 0x10000002, S_MINUS = 0x10000003, S_PLUS = 0x10000004, S_MULTIPLY = 0x10000005, S_DIVIDE = 0x10000006, S_MODULO = 0x10000007, S_POWER = 0x10000008, S_ASSIGN = 0x10000009, S_LIST_ACCESS = 0x1000000a, S_LT = 0x20000001, S_GT = 0x20000002, S_LEQ = 0x20000003, S_GEQ = 0x20000004, S_EQ = 0x20000005, S_NEQ = 0x20000006, S_AND = 0x20000007, S_OR = 0x20000008, S_NOT = 0x20000009, S_IS = 0x2000000a, S_LEN = 0x30000001, S_RANGE = 0x30000002, S_SQRT = 0x30000003, S_LOG = 0x30000004, S_LN = 0x30000005, S_RAND = 0x30000006, S_SIN = 0x30000007, S_COS = 0x30000008, S_TAN = 0x30000009, S_ASIN = 0x3000000a, S_ACOS = 0x3000000b, S_ATAN = 0x3000000c, S_FPOP = 0x40000001, S_FAPPEND = 0x40000002, S_FEXTEND = 0x40000003, S_FCLEAR = 0x40000004, S_FVALUE = 0x40000011, S_FSETVALUE = 0x40000012, S_FCONNECTIONS = 0x40000013, S_FMARK = 0x40000014, S_FSETMARK = 0x40000015 }; protected: union Data { bool b; char ch; int i; double f; SalaList list; SalaStr str; SalaGrf graph; Func func; int var; int count; // used by brackets to count how many objects they have }; Data data; Type type; public: SalaObj() { type = S_NONE; } // Two usages: (a) used for brackets (=groups of things, hence the count) and commas // (b) used for lists SalaObj(Type t) { type = t; if (t & S_LIST) { data.list.refcount = new int(1); data.list.list = new pvector; } else { data.count = 1; } } // Two usages: (a) used to address variable or user function tables // (b) used for lists SalaObj(Type t, int v) { type = t; if (t & S_LIST) { data.list.refcount = new int(1); data.list.list = new pvector; data.list.list->set(v); // set blanks } else { data.var = v; } } // other constructors SalaObj(bool a) { type = S_BOOL; data.b = a; } SalaObj(int a) { type = S_INT; data.i = a; } SalaObj(double a) { type = S_DOUBLE; data.f = a; } SalaObj(Func f) { type = S_FUNCTION; data.func = f; } SalaObj(const std::string& a) { type = S_STRING; data.str.refcount = new int(1); data.str.string = new std::string(a); } // note, type required here as sometimes this will be an axial map, sometimes segment map, sometimes point map, // also not fully filled in until runtime, but still required by parse SalaObj(Type t, SalaGrf graph) { type = t; data.graph = graph; } // SalaObj(const SalaObj& obj); SalaObj& operator = (const SalaObj& obj); ~SalaObj(); void reset(); void uninit() { reset(); type = S_UNINIT; } // <- used to uninitialise variables before running program, thus they give nice error messages if used before initialisation int func() const { return data.func; } int precedence() const; bool toBool() const; int toInt() const; double toDouble() const; std::string toString() const; const std::string& toStringRef() const; friend SalaObj op_is(SalaObj& a, SalaObj& b); friend SalaObj operator - (SalaObj& a); friend SalaObj operator + (SalaObj& a, SalaObj& b); friend SalaObj operator - (SalaObj& a, SalaObj& b); friend SalaObj operator / (SalaObj& a, SalaObj& b); friend SalaObj operator * (SalaObj& a, SalaObj& b); friend SalaObj operator % (SalaObj& a, SalaObj& b); friend bool operator || (SalaObj& a, SalaObj& b); friend bool operator && (SalaObj& a, SalaObj& b); friend bool operator ! (SalaObj& a); friend bool operator == (SalaObj& a, SalaObj& b); friend bool operator != (SalaObj& a, SalaObj& b); friend bool operator > (SalaObj& a, SalaObj& b); friend bool operator < (SalaObj& a, SalaObj& b); friend bool operator >= (SalaObj& a, SalaObj& b); friend bool operator <= (SalaObj& a, SalaObj& b); // operations for lists: SalaObj& list_at(int i); SalaObj char_at(int i); // actually returns a string of the char -- note constant int length(); // check for no parameters void ensureNone() { if (type != SalaObj::S_NONE) throw SalaError("Does not take any parameters"); } // // operations for graphs / graph nodes: AttributeTable *getTable(); // const std::string getTypeStr() const; const std::string getTypeIndefArt() const; }; // Quick mod - TV class SalaProgram; class SalaCommand { friend class SalaProgram; // enum Command { SC_NONE, SC_ROOT, SC_EXPR, SC_RETURN, SC_FOR, SC_WHILE, SC_IF, SC_ELIF, SC_ELSE }; enum { SP_NONE, SP_DATA, SP_NUMBER, SP_FUNCTION, SP_COMMAND }; // used while calculating what is on eval stack protected: // SalaProgram *m_program; // information about the running program (in particular, the global variable and error stack) SalaCommand *m_parent; prefvec m_children; // pqmap m_var_names; // Command m_command; int m_indent; // vital for program flow due to Pythonesque syntax pvector m_eval_stack; pvector m_func_stack; // SalaObj m_for_iter; // object used in a for loop // int m_line; // useful for debugging to know which line this command starts on std::string m_last_string; // occassionally useful in debugging if the user does something unsyntactical // public: SalaCommand() { m_program = NULL; m_parent = NULL; m_indent = 0; m_command = SC_NONE; } SalaCommand(SalaProgram *program, SalaCommand *parent, int indent, Command command = SC_NONE); protected: int parse(::std::istream& program, int line); int decode(std::string string); int decode_member(const std::string& string, bool apply_to_this); void pushFunc(const SalaObj& func); // void evaluate(SalaObj& obj, bool& ret, bool& ifhandled); SalaObj evaluate(int& pointer, SalaObj* &p_obj); SalaObj connections(SalaObj graphnode, SalaObj param); }; class SalaProgram { friend class SalaCommand; // SalaCommand m_root_command; pvector m_var_stack; prefvec m_error_stack; // // column is stored away from the context, as it's not actually passed to the program itself, just used to update a column int m_col; // m_thisobj stores contextual information (which attribute table, node etc) // NB ! -- this can be messed with by SalaCommand! SalaObj m_thisobj; // bool m_marked; // this is used to tell the program that a node has been "marked" -- all marks are cleared at the end of the execution // public: SalaProgram(SalaObj context); ~SalaProgram(); bool parse(::std::istream& program); SalaObj evaluate(); bool runupdate(int col, const std::set &selset = std::set()); bool runselect(std::vector& selsetout, const std::set &selsetin = std::set()); std::string getLastErrorMessage() const; }; inline SalaObj::SalaObj(const SalaObj& obj) { type = obj.type; switch(obj.type) { case S_FUNCTION: data.func = obj.data.func; break; case S_BOOL: data.b = obj.data.b; break; case S_INT: data.i = obj.data.i; break; case S_DOUBLE: data.f = obj.data.f; break; case S_VAR: data.var = obj.data.var; break; case S_STRING: data.str.string = obj.data.str.string; data.str.refcount = obj.data.str.refcount; *(data.str.refcount) += 1; break; case S_LIST: case S_TUPLE: data.list.list = obj.data.list.list; data.list.refcount = obj.data.list.refcount; *(data.list.refcount) += 1; break; case S_NONE: case S_UNINIT: case S_THIS: break; case S_SHAPEMAPOBJ: case S_SHAPEMAP: data.graph.map.shape = obj.data.graph.map.shape; data.graph.node = obj.data.graph.node; break; case S_POINTMAPOBJ: case S_POINTMAP: data.graph.map.point = obj.data.graph.map.point; data.graph.node = obj.data.graph.node; break; case S_OPEN_BRACKET: case S_CLOSE_BRACKET: case S_OPEN_SQR_BRACKET_LIST: case S_OPEN_SQR_BRACKET_ACCESS: case S_CLOSE_SQR_BRACKET: case S_COMMA: case S_CONST_LIST: case S_CONST_TUPLE: data.count = obj.data.count; break; default: throw SalaError("Cannot instantiate unknown type"); } } inline SalaObj& SalaObj::operator = (const SalaObj& obj) { if (this != &obj) { reset(); type = obj.type; switch(obj.type) { case S_FUNCTION: data.func = obj.data.func; break; case S_BOOL: data.b = obj.data.b; break; case S_INT: data.i = obj.data.i; break; case S_DOUBLE: data.f = obj.data.f; break; case S_VAR: data.var = obj.data.var; break; case S_STRING: data.str.string = obj.data.str.string; data.str.refcount = obj.data.str.refcount; *(data.str.refcount) += 1; break; case S_LIST: case S_TUPLE: data.list.list = obj.data.list.list; data.list.refcount = obj.data.list.refcount; *(data.list.refcount) += 1; break; case S_NONE: case S_UNINIT: case S_THIS: break; case S_SHAPEMAPOBJ: case S_SHAPEMAP: data.graph.map.shape = obj.data.graph.map.shape; data.graph.node = obj.data.graph.node; break; case S_POINTMAPOBJ: case S_POINTMAP: data.graph.map.point = obj.data.graph.map.point; data.graph.node = obj.data.graph.node; break; case S_OPEN_BRACKET: case S_CLOSE_BRACKET: case S_OPEN_SQR_BRACKET_LIST: case S_OPEN_SQR_BRACKET_ACCESS: case S_CLOSE_SQR_BRACKET: case S_COMMA: case S_CONST_LIST: case S_CONST_TUPLE: data.count = obj.data.count; break; default: throw SalaError("Cannot instantiate unknown type"); } } return *this; } inline SalaObj::~SalaObj() { reset(); } inline void SalaObj::reset() { if (type & S_STRING) { *(data.str.refcount) -= 1; if (*(data.str.refcount) == 0) { delete data.str.refcount; delete data.str.string; } data.str.refcount = NULL; data.str.string = NULL; } else if (type & S_LIST) { *(data.list.refcount) -= 1; if (*(data.list.refcount) == 0) { delete data.str.refcount; delete data.list.list; } data.str.refcount = NULL; data.list.list = NULL; } type = S_NONE; } inline bool SalaObj::toBool() const { switch(type) { case S_BOOL: return data.b; case S_INT: return data.i != 0; case S_DOUBLE: return data.f != 0.0; default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a boolean value")); } return false; } inline int SalaObj::toInt() const { switch(type) { case S_BOOL: return data.b ? 1 : 0; case S_INT: return data.i; case S_DOUBLE: return int(floor(data.f)); // ensure properly implemented default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to an integer value")); } return 0; } inline double SalaObj::toDouble() const { switch(type) { case S_BOOL: return data.b ? 1.0 : 0.0; case S_INT: return double(data.i); case S_DOUBLE: return data.f; default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a floating point number")); } return 0.0; } inline std::string SalaObj::toString() const { switch(type) { case S_INT: return dXstring440::formatString(data.i); case S_DOUBLE: return dXstring440::formatString(data.f); case S_STRING: return *(data.str.string); default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a string")); } return std::string(); } inline const std::string& SalaObj::toStringRef() const { if (type != S_STRING) { throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a string reference")); } return *(data.str.string); } inline SalaObj operator + (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: throw SalaError("Cannot add booleans"); case SalaObj::S_INT: return SalaObj(a.data.i + b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f + b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) + b.data.f) : (a.data.f + double(b.data.i)); case SalaObj::S_STRING: return SalaObj(*(a.data.str.string) + *(b.data.str.string)); default: throw SalaError(std::string("Cannot add ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" to ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator - (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: throw SalaError("Cannot subtract booleans"); case SalaObj::S_INT: return SalaObj(a.data.i - b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f - b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) - b.data.f) : (a.data.f - double(b.data.i)); default: throw SalaError(std::string("Cannot subtract ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" from ") + a.getTypeIndefArt() + a.getTypeStr()); } return SalaObj(); } inline SalaObj operator - (SalaObj& a) { switch (a.type) { case SalaObj::S_BOOL: throw SalaError("Cannot minus booleans"); case SalaObj::S_INT: return SalaObj(-a.data.i); case SalaObj::S_DOUBLE: return SalaObj(-a.data.f); default: throw SalaError(std::string("Cannot minus ") + a.getTypeIndefArt() + a.getTypeStr()); } return SalaObj(); } inline SalaObj operator * (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: return SalaObj(a.data.i * b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f * b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) * b.data.f) : (a.data.f * double(b.data.i)); default: throw SalaError(std::string("Cannot multiply ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator % (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: return SalaObj(a.data.i % b.data.i); case SalaObj::S_DOUBLE: return SalaObj(::std::fmod(a.data.f,b.data.f)); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? fmod(double(a.data.i),b.data.f) : fmod(a.data.f,double(b.data.i)); default: throw SalaError(std::string("Cannot multiply ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator / (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: if (b.data.i != 0) return SalaObj(a.data.i / b.data.i); else throw SalaError("Integer divide by zero error"); case SalaObj::S_DOUBLE: return SalaObj(a.data.f / b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) / b.data.f) : (a.data.f / double(b.data.i)); default: throw SalaError(std::string("Cannot divide ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + a.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } // assume already bools (use convert to bool first) inline bool operator && (SalaObj& a, SalaObj& b) { return a.data.b && b.data.b; } // assume already bools (use convert to bool first) inline bool operator || (SalaObj& a, SalaObj& b) { return a.data.b || b.data.b; } // assume already bools (use convert to bool first) inline bool operator ! (SalaObj& a) { return !a.data.b; } inline bool operator == (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_NONE: return true; // none == none case SalaObj::S_BOOL: return a.data.b == b.data.b; case SalaObj::S_INT: return a.data.i == b.data.i; case SalaObj::S_DOUBLE: return a.data.f == b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) == b.data.f) : (a.data.f == double(b.data.i)); case SalaObj::S_STRING: return a.data.str == b.data.str; case SalaObj::S_LIST: return a.data.list == b.data.list; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '=='")); } return false; } inline SalaObj op_is(SalaObj& a, SalaObj& b) { // note, op_is is forgiving: does not complain if cannot compare, just returns false switch (a.type & b.type) { case SalaObj::S_NONE: return true; // none is none case SalaObj::S_BOOL: return a.data.b == b.data.b; case SalaObj::S_INT: return a.data.i == b.data.i; case SalaObj::S_DOUBLE: return a.data.f == b.data.f; // n.b., no number! int is not double and v.v. case SalaObj::S_STRING: return a.data.str.string == b.data.str.string; // n.b.: pointer compare! case SalaObj::S_LIST: return a.data.list.list == b.data.list.list; // n.b.: pointer compare! } return false; } inline bool operator != (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b != b.data.b; case SalaObj::S_INT: return a.data.i != b.data.i; case SalaObj::S_DOUBLE: return a.data.f != b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) != b.data.f) : (a.data.f != double(b.data.i)); case SalaObj::S_STRING: return a.data.str != b.data.str; case SalaObj::S_LIST: return a.data.list != b.data.list; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '!='")); } return false; } inline bool operator < (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b < b.data.b; case SalaObj::S_INT: return a.data.i < b.data.i; case SalaObj::S_DOUBLE: return a.data.f < b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) < b.data.f) : (a.data.f < double(b.data.i)); case SalaObj::S_STRING: return a.data.str < b.data.str; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '<'")); } return false; } inline bool operator > (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b > b.data.b; case SalaObj::S_INT: return a.data.i > b.data.i; case SalaObj::S_DOUBLE: return a.data.f > b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) > b.data.f) : (a.data.f > double(b.data.i)); case SalaObj::S_STRING: return a.data.str > b.data.str; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '>'")); } return false; } inline bool operator <= (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b <= b.data.b; case SalaObj::S_INT: return a.data.i <= b.data.i; case SalaObj::S_DOUBLE: return a.data.f <= b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) <= b.data.f) : (a.data.f <= double(b.data.i)); default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '<='")); } return false; } inline bool operator >= (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b >= b.data.b; case SalaObj::S_INT: return a.data.i >= b.data.i; case SalaObj::S_DOUBLE: return a.data.f >= b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) >= b.data.f) : (a.data.f >= double(b.data.i)); default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '>='")); } return false; } // list operations: note -> precheck in program and sort into list and string inline SalaObj& SalaObj::list_at(int i) { if (i < 0) i += (int)data.list.list->size(); if (i < 0 || size_t(i) >= data.list.list->size()) throw SalaError("Index out of range"); return data.list.list->at(i); } inline SalaObj SalaObj::char_at(int i) // actually returns a string of the char { if (i < 0) i += data.str.length(); if (i < 0 || i >= static_cast(data.str.length())) throw SalaError("String index out of range"); return SalaObj(std::string(1,data.str.char_at(i))); } inline int SalaObj::length() { if (type & S_LIST) return (int)data.list.list->size(); else if (type == S_STRING) return (int)data.str.length(); throw SalaError("Cannot get the length of " + getTypeIndefArt() + getTypeStr()); } ///////////////////////////////////////////////////////////////////////////////////// inline const std::string SalaObj::getTypeStr() const { switch(type) { case S_NONE: return "none"; case S_UNINIT: return "uninitialised variable"; case S_FUNCTION: return "function"; case S_BOOL: return "boolean"; case S_INT: return "integer"; case S_DOUBLE: return "float"; case S_STRING: return "string"; case S_LIST: return "list"; case S_TUPLE: return "tuple"; case S_THIS: return "this"; default: break; } if (type & S_GRAPHOBJ) { return "graph object"; } else if (type & S_MAP) { return "graph"; } return "unknown type"; } inline const std::string SalaObj::getTypeIndefArt() const { switch(type & ~S_GRAPHOBJ) { case S_FUNCTION: case S_BOOL: case S_DOUBLE: case S_STRING: case S_TUPLE: case S_LIST: case S_SHAPEMAP: case S_POINTMAP: return "a "; case S_INT: case S_UNINIT: return "an "; case S_NONE: case S_THIS: return ""; default: return "an "; // unknown type } return std::string(); } ///////////////////////////////////////////////////////////////////////////////////// // comparisons for lists (must be after the associated SalaObj comparisons have been declared) inline bool operator == (const SalaList& a, const SalaList& b) { if (a.list->size() != a.list->size()) return false; for (size_t i = 0; i < a.list->size(); i++) { if (a.list->at(i) != b.list->at(i)) return false; } return true; } inline bool operator != (const SalaList& a, const SalaList& b) { if (a.list->size() != a.list->size()) return true; for (size_t i = 0; i < a.list->size(); i++) { if (a.list->at(i) != b.list->at(i)) return true; } return false; } ///////////////////////////////////////////// // helpers for parser: struct SalaBuffer { int bufpos; char buffer[128]; SalaBuffer() { bufpos = -1; buffer[0] = '\0'; } void add(char c) { bufpos++; if (bufpos > 127) throw SalaError("Overlong string of characters"); buffer[bufpos] = c; } void clear() { bufpos = -1; buffer[0] = '\0'; } operator std::string() { buffer[bufpos + 1] = '\0'; return std::string(buffer); } bool empty() { return bufpos == -1; } }; /////////////////////////////////////////////////// ///////////////////////////////////////////// // Operator and function names struct SalaFuncLabel { SalaObj::Func func; std::string name; std::string desc; SalaFuncLabel(SalaObj::Func f = SalaObj::S_FNULL, const std::string& str = std::string(), const std::string& des = std::string()) { func = f; name = str; desc = des; } }; struct SalaMemberFuncLabel : public SalaFuncLabel { SalaObj::Type type; SalaMemberFuncLabel(SalaObj::Type t = SalaObj::S_NONE, SalaObj::Func f = SalaObj::S_FNULL, const std::string& str = std::string(), const std::string& des = std::string()) { type = t; func = f; name = str; desc = des; } }; ///////////////////////////////////////////////////////////////////////////////////// } #endif ================================================ FILE: mgraph440/shapemap.cpp ================================================ #include "mgraph440/shapemap.h" #include "mgraph440/pointmap.h" #include "mgraph440/spacepix.h" #include "mgraph440/exceptions.h" namespace mgraph440 { static const double TOLERANCE_A = 1e-9; // import TOLERANCE_B from axial map... static const double TOLERANCE_B = 1e-12; // copied from SpacePixel PixelRef ShapeMap::pixelate( const Point2f& p, bool constrain, int ) const { PixelRef r; Point2f p1 = p; p1.normalScale(m_region); if (constrain) { if (p1.x <= 0.0) { r.x = 0; } else if (p1.x >= 1.0) { r.x = m_cols - 1; } else { r.x = short(floor(p1.x * m_cols)); } } else { r.x = short(floor(p1.x * m_cols)); } if (constrain) { if (p1.y <= 0.0) { r.y = 0; } else if (p1.y >= 1.0) { r.y = m_rows - 1; } else { r.y = short(floor(p1.y * m_rows)); } } else { r.y = short(floor(p1.y * m_rows)); } return r; } bool ShapeMap::read( std::ifstream& stream, int version, bool drawinglayer ) { // turn off selection / editable etc m_selection = false; m_editable = false; m_show = true; // <- by default show m_map_type = ShapeMap::EMPTYMAP; // clear old BSP tree (if exists) m_bsp_tree = false; m_bsp_root = NULL; // clear old: if (m_pixel_shapes) { for (int i = 0; i < m_cols; i++) { delete [] m_pixel_shapes[i]; } delete [] m_pixel_shapes; m_pixel_shapes = NULL; } if (m_display_shapes) { delete [] m_display_shapes; m_display_shapes = NULL; } m_objects.clear(); m_shapes.clear(); m_attributes.clear(); m_connectors.clear(); m_links.clear(); m_unlinks.clear(); m_undobuffer.clear(); // read in an old file: if (drawinglayer && version < VERSION_DRAWING_SHAPES) { // the data in the file is for a SpacePixel // the easiest solution, although not the most memory effective, is to read in the space pixel, // and convert to a shape map: SpacePixel layer; layer.read(stream,version); m_name = layer.m_name; m_show = layer.m_show; m_editable = false; // <- don't take from spacepixel in case conflicts in some way m_region = layer.m_region; m_rows = layer.m_rows; m_cols = layer.m_cols; m_tolerance = std::max(m_region.width(), m_region.height()) * TOLERANCE_A; m_shape_ref = -1; for (size_t i = 0; i < layer.m_lines.size(); i++) { m_shape_ref++; int index = m_shapes.add(m_shape_ref, SalaShape(layer.m_lines[i].line)); // insert a dummy attribute row: m_attributes.insertRow(m_shape_ref); // note: as this is always a drawing layer, no need to set shape attributes } // prepare pixel map (using same number of cols and rows as the original spacepixel for convenience) m_pixel_shapes = new pqvector *[m_cols]; for (int j = 0; j < m_cols; j++) { m_pixel_shapes[j] = new pqvector[m_rows]; } // Now add the pixel shapes pixel map: // pixelate all polys in the pixel structure: for (size_t k = 0; k < m_shapes.size(); k++) { makePolyPixels(m_shapes.key(k)); } // set to read in display attribute: // note that even though it's only a drawing layer, this still needs to be done invalidateDisplayedAttribute(); setDisplayedAttribute(-1); // all done return true; } // name m_name = dXstring440::readString(stream); if (version >= VERSION_MAP_TYPES) { stream.read( (char *) &m_map_type, sizeof(m_map_type)); } else { // old versions data maps or drawing maps, // the axial reader will override this with its own map type designation if necessary if (drawinglayer) { m_map_type = DRAWINGMAP; } else { m_map_type = DATAMAP; } } if (version >= VERSION_DRAWING_SHAPES_B) { stream.read( (char *) &m_show, sizeof(m_show) ); stream.read( (char *) &m_editable, sizeof(m_editable) ); } // PixelBase read // read extents: stream.read( (char *) &m_region, sizeof(m_region) ); // read rows / cols stream.read( (char *) &m_rows, sizeof(m_rows) ); stream.read( (char *) &m_cols, sizeof(m_cols) ); // calculate geom data: m_tolerance = std::max(m_region.width(), m_region.height()) * TOLERANCE_A; // read next object ref to be used: stream.read((char *) &m_obj_ref, sizeof(m_obj_ref)); stream.read((char *) &m_shape_ref, sizeof(m_shape_ref)); // read shape data int count = 0; stream.read((char *) &count, sizeof(count)); for (int j = 0; j < count; j++) { int key; stream.read((char *) &key, sizeof(key)); int index = m_shapes.add(key, SalaShape()); m_shapes.value(index).read(stream,version); } if (version < VERSION_SHAPE_CENTROIDS) { // manually set centroid according to type: for (size_t i = 0; i < m_shapes.size(); i++) { switch (m_shapes[i].m_type & SalaShape::SHAPE_TYPE) { case SalaShape::SHAPE_POINT: m_shapes[i].m_centroid = m_shapes[i].m_region.bottom_left; break; case SalaShape::SHAPE_LINE: m_shapes[i].m_centroid = m_shapes[i].m_region.getCentre(); break; case SalaShape::SHAPE_POLY: m_shapes[i].setCentroidAreaPerim(); break; default: break; } } } // read object data (currently unused) stream.read((char *) &count, sizeof(count)); for (int k = 0; k < count; k++) { int key; stream.read((char *) &key, sizeof(key)); int index = m_objects.add(key, SalaObject()); m_objects.value(index).read(stream,version); } // read attribute data m_attributes.read(stream,version); stream.read((char *)&m_displayed_attribute,sizeof(m_displayed_attribute)); // prepare pixel map: m_pixel_shapes = new pqvector *[m_cols]; int i; for (i = 0; i < m_cols; i++) { m_pixel_shapes[i] = new pqvector[m_rows]; } // Now add the pixel shapes pixel map: // pixelate all polys in the pixel structure: for (size_t j = 0; j < m_shapes.size(); j++) { makePolyPixels(m_shapes.key(j)); } // later versions can have shape connections: if (version >= VERSION_AXIAL_SHAPES) { int count; stream.read((char *)&count,sizeof(count)); for (int i = 0; i < count; i++) { m_connectors.push_back(Connector()); m_connectors[i].read(stream,version); if (version < VERSION_NO_SELF_CONNECTION) { size_t self = m_connectors[i].m_connections.searchindex(i); if (self != paftl::npos) { m_connectors[i].m_connections.remove_at(self); } } } m_links.read(stream); m_unlinks.read(stream); } // some miscellaneous extra data for mapinfo files if (m_mapinfodata) { delete m_mapinfodata; m_mapinfodata = NULL; } if (version >= VERSION_MAPINFO_SHAPES) { char x = stream.get(); if (x == 'm') { m_mapinfodata = new MapInfoData; m_mapinfodata->read(stream,version); } } invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); return true; } void ShapeMap::makePolyPixels(int polyref) { // first add into pixels, and ensure you have a bl, tr for the set (useful for testing later) SalaShape& poly = m_shapes.search(polyref); if (poly.isClosed()) { pmap relations; for (size_t k = 0; k < poly.size(); k++) { int nextk = (k + 1) % poly.size(); Line li(poly[k],poly[nextk]); if (k == 0) { poly.m_region = li; } else { poly.m_region = runion(poly.m_region,li); } PixelRefVector pixels = pixelateLine(li); // debug // int duplicate_shaperefs = 0; // end debug for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; size_t x = m_pixel_shapes[pix.x][pix.y].searchindex(ShapeRef(polyref)); if (x == paftl::npos) { x = m_pixel_shapes[pix.x][pix.y].add(ShapeRef(polyref),paftl::ADD_HERE); } m_pixel_shapes[pix.x][pix.y][x].m_polyrefs.push_back(k); relations.add(pixels[i],ShapeRef::SHAPE_EDGE); } } // erase joined sides, and look for min: PixelRef minpix = NoPixel; for (size_t j = 0; j < relations.size(); j++) { PixelRef pix = relations.key(j); PixelRef nextpix; nextpix = pix.right(); if (includes(nextpix) && m_pixel_shapes[nextpix.x][nextpix.y].searchindex(ShapeRef(polyref)) != paftl::npos) { relations.value(j) &= ~ShapeRef::SHAPE_R; } nextpix = pix.up(); if (includes(nextpix) && m_pixel_shapes[nextpix.x][nextpix.y].searchindex(ShapeRef(polyref)) != paftl::npos) { relations.value(j) &= ~ShapeRef::SHAPE_T; } nextpix = pix.down(); if (includes(nextpix) && m_pixel_shapes[nextpix.x][nextpix.y].searchindex(ShapeRef(polyref)) != paftl::npos) { relations.value(j) &= ~ShapeRef::SHAPE_B; } nextpix = pix.left(); if (includes(nextpix) && m_pixel_shapes[nextpix.x][nextpix.y].searchindex(ShapeRef(polyref)) != paftl::npos) { relations.value(j) &= ~ShapeRef::SHAPE_L; } if ((relations.value(j) & (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) == (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) { if ((minpix == NoPixel) || (relations.key(j) < (int)minpix)) { minpix = relations.key(j); } } } shapePixelBorder(relations,polyref,ShapeRef::SHAPE_L,minpix,minpix,true); // go through any that aren't on the outer border: this will be internal edges, and will cause problems // for point in polygon algorithms! size_t i; for (i = 0; i < relations.size(); i++) { PixelRef pix = relations.key(i); unsigned char& tags = m_pixel_shapes[pix.x][pix.y].search(polyref).m_tags; if (tags == 0x00) { tags |= ShapeRef::SHAPE_INTERNAL_EDGE; } } // now, any remaining tags are internal sides, and need to be cleared through fill // we could go either direction, but we just go left to right: for (i = 0; i < relations.size(); i++) { PixelRef pix = relations.key(i); if (relations.value(i) & ShapeRef::SHAPE_R) { int pos = 0; do { PixelRef nextpix = pix.right(); if (!includes(nextpix)) { // this shouldn't happen break; } // returns -1 if cannot add due to already existing: pos = m_pixel_shapes[nextpix.x][nextpix.y].add(ShapeRef(polyref,ShapeRef::SHAPE_CENTRE)); pix = nextpix; } while (pos != -1); } } // Done...! This polygon is registered in the pixel polygon structure } else { // Open shapes much easier! switch (poly.m_type & SalaShape::SHAPE_TYPE) { case SalaShape::SHAPE_POINT: { PixelRef pix = pixelate(poly.m_centroid); size_t x = m_pixel_shapes[pix.x][pix.y].searchindex(ShapeRef(polyref)); if (x == paftl::npos) { x = m_pixel_shapes[pix.x][pix.y].add(ShapeRef(polyref,ShapeRef::SHAPE_OPEN),paftl::ADD_HERE); } } break; case SalaShape::SHAPE_LINE: { PixelRefVector pixels = pixelateLine(poly.m_region); for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; size_t x = m_pixel_shapes[pix.x][pix.y].searchindex(ShapeRef(polyref)); if (x == paftl::npos) { x = m_pixel_shapes[pix.x][pix.y].add(ShapeRef(polyref,ShapeRef::SHAPE_OPEN),paftl::ADD_HERE); } } } break; case SalaShape::SHAPE_POLY: for (size_t k = 0; k < poly.size() - 1; k++) { int nextk = (k + 1); Line li(poly[k],poly[nextk]); if (k == 0) { poly.m_region = li; } else { poly.m_region = runion(poly.m_region,li); } PixelRefVector pixels = pixelateLine(li); for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; size_t x = m_pixel_shapes[pix.x][pix.y].searchindex(ShapeRef(polyref)); if (x == paftl::npos) { x = m_pixel_shapes[pix.x][pix.y].add(ShapeRef(polyref,ShapeRef::SHAPE_OPEN),paftl::ADD_HERE); } m_pixel_shapes[pix.x][pix.y][x].m_polyrefs.push_back(k); } } break; } } } void SalaShape::setCentroidAreaPerim() { m_area = 0.0; m_perimeter = 0.0; m_centroid = Point2f(0,0); for (size_t i = 0; i < size(); i++) { Point2f& p1 = at(i); Point2f& p2 = at((i+1)%size()); double a_i = (p1.x * p2.y - p2.x * p1.y) / 2.0; m_area += a_i; a_i /= 6.0; m_centroid.x += (p1.x+p2.x) * a_i; m_centroid.y += (p1.y+p2.y) * a_i; Point2f side = p2 - p1; m_perimeter += side.length(); } m_type &= ~SHAPE_CCW; if (sgn(m_area) == 1) { m_type |= SHAPE_CCW; } m_centroid.scale(2.0/m_area); // note, *not* fabs(m_area) as it is then confused by clockwise ordered shapes m_area = fabs(m_area); if (isOpen()) { // take off the automatically collected final side Point2f side = tail() - head(); m_perimeter -= side.length(); } } void ShapeMap::setDisplayedAttribute(int col) const { if (!m_invalidate && m_displayed_attribute == col) { return; } m_displayed_attribute = col; m_invalidate = true; // always override at this stage: m_attributes.setDisplayColumn(m_displayed_attribute,true); m_invalidate = false; } void ShapeMap::shapePixelBorder(pmap& relations, int polyref, int side, PixelRef currpix, PixelRef minpix, bool first) { if (!first && currpix == minpix && side == ShapeRef::SHAPE_L) { // looped: return; } size_t rel = relations.searchindex(currpix); if (relations[rel] & side) { m_pixel_shapes[currpix.x][currpix.y].search(polyref).m_tags |= side; relations[rel] &= ~side; // <- clear to check all have been done later side <<= 1; if (side > ShapeRef::SHAPE_T) { side = ShapeRef::SHAPE_L; } shapePixelBorder(relations,polyref,side,currpix,minpix,false); } else { currpix.move( moveDir(side) ); side >>= 1; if (side < ShapeRef::SHAPE_L) { side = ShapeRef::SHAPE_T; } shapePixelBorder(relations,polyref,side,currpix,minpix,false); } } bool SalaShape::read(std::ifstream& stream, int version) { // defaults m_draworder = -1; m_selected = false; stream.read((char *)&m_type,sizeof(m_type)); int sss = sizeof(m_region); stream.read((char *)&m_region,sizeof(m_region)); if (version >= VERSION_SHAPE_CENTROIDS) { stream.read((char *)&m_centroid,sizeof(m_centroid)); if (version >= VERSION_SHAPE_AREA_PERIMETER) { stream.read((char *)&m_area,sizeof(m_area)); stream.read((char *)&m_perimeter,sizeof(m_perimeter)); } } else { // old types were simply 1,2,3... these are now labelled using bits: if (m_type == 3) { m_type = SHAPE_POLY; } else if (m_type == 4) { m_type = SHAPE_POLY | SHAPE_CLOSED; } } pqvector::read(stream); if (version < VERSION_SHAPE_AREA_PERIMETER) { if (m_type & SHAPE_POLY) { setCentroidAreaPerim(); } else if (m_type & SHAPE_LINE) { m_perimeter = m_region.length(); } } return true; } int ShapeMap::moveDir(int side) { int dir; switch (side) { case ShapeRef::SHAPE_L: dir = PixelRef::NEGHORIZONTAL; break; case ShapeRef::SHAPE_B: dir = PixelRef::NEGVERTICAL; break; case ShapeRef::SHAPE_R: dir = PixelRef::HORIZONTAL; break; case ShapeRef::SHAPE_T: dir = PixelRef::VERTICAL; break; } return dir; } // n.b., only works from current selection (and uses point selected attribute) int ShapeMap::makeShapeFromPointSet(const PointMap& pointmap) { bool bounds_good = true; PixelRefVector selset; Point2f offset = Point2f(pointmap.getSpacing()/2,pointmap.getSpacing()/2); for (auto &sel: pointmap.getSelSet()) { selset.push_back(sel); if (!m_region.contains_touch(pointmap.depixelate(sel)-offset) || !m_region.contains_touch(pointmap.depixelate(sel)+offset)) { bounds_good = false; } } if (!bounds_good) { QtRegion r(pointmap.getRegion().bottom_left - offset,pointmap.getRegion().top_right + offset); init(m_shapes.size(),r); } pmap relations; for (size_t j = 0; j < selset.size(); j++) { PixelRef pix = selset[j]; int x = relations.add(pix,ShapeRef::SHAPE_EDGE); if (pointmap.includes(pix.right()) && pointmap.getPoint(pix.right()).selected()) { relations.value(x) &= ~ShapeRef::SHAPE_R; } if (pointmap.includes(pix.up()) && pointmap.getPoint(pix.up()).selected()) { relations.value(x) &= ~ShapeRef::SHAPE_T; } if (pointmap.includes(pix.down()) && pointmap.getPoint(pix.down()).selected()) { relations.value(x) &= ~ShapeRef::SHAPE_B; } if (pointmap.includes(pix.left()) && pointmap.getPoint(pix.left()).selected()) { relations.value(x) &= ~ShapeRef::SHAPE_L; } } // now find pixel with SHAPE_B | SHAPE_L PixelRef minpix = NoPixel; size_t k; for (k = 0; k < relations.size(); k++) { if ((relations.value(k) & (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) == (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) { if ((minpix == NoPixel) || (relations.key(k) < (int)minpix)) { minpix = relations.key(k); } } } // now follow round anticlockwise... SalaShape poly(SalaShape::SHAPE_POLY | SalaShape::SHAPE_CLOSED); pointPixelBorder(pointmap,relations,poly,ShapeRef::SHAPE_L,minpix,minpix,true); bool retvar = true; for (k = 0; k < relations.size(); k++) { if (relations[k] != 0) { // more than one shape! return -1; } } poly.setCentroidAreaPerim(); m_shape_ref++; int rowid = m_shapes.add(m_shape_ref,poly); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(m_shape_ref); } else { // pixelate all polys in the pixel new structure: for (size_t i = 0; i < m_shapes.size(); i++) { makePolyPixels(m_shapes.key(i)); } } m_attributes.insertRow(m_shape_ref); m_newshape = true; return m_shape_ref; } // the replacement for datalayers ShapeMap::ShapeMap(const std::string& name, int type) : m_attributes(name) { m_name = name; m_map_type = type; m_hasgraph = false; // shape and object counters m_obj_ref = -1; m_shape_ref = -1; // pixel map m_pixel_shapes = NULL; // // -1 is the shape ref column (which will be shown by default) m_displayed_attribute = -1; m_display_shapes = NULL; m_invalidate = false; // for polygons: m_show_lines = true; m_show_fill = true; m_show_centroids = false; // data (MUST be set before use) m_tolerance = 0.0; m_selection = false; // note show is m_show = true; m_editable = false; m_bsp_tree = false; m_bsp_root = NULL; // m_mapinfodata = NULL; } ShapeMap::~ShapeMap() { if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } if (m_pixel_shapes) { for (int i = 0; i < m_cols; i++) { delete [] m_pixel_shapes[i]; } delete [] m_pixel_shapes; m_pixel_shapes = NULL; } if (m_display_shapes) { delete [] m_display_shapes; m_display_shapes = NULL; } if (m_mapinfodata) { delete m_mapinfodata; m_mapinfodata = NULL; } } Point2f ShapeMap::pointOffset(const PointMap& pointmap, int currpix, int side) { Point2f p; switch (side) { case ShapeRef::SHAPE_L: p = Point2f(-pointmap.getSpacing()/2,0.0); break; case ShapeRef::SHAPE_B: p = Point2f(0.0,-pointmap.getSpacing()/2); break; case ShapeRef::SHAPE_R: p = Point2f(pointmap.getSpacing()/2,0.0); break; case ShapeRef::SHAPE_T: p = Point2f(0.0,pointmap.getSpacing()/2); break; } return p; } // note that this is almost exactly the same as shapePixelBorder void ShapeMap::pointPixelBorder(const PointMap& pointmap, pmap& relations, SalaShape& poly, int side, PixelRef currpix, PixelRef minpix, bool first) { if (!first && currpix == minpix && side == ShapeRef::SHAPE_L) { // looped: return; } size_t rel = relations.searchindex(currpix); if (relations[rel] & side) { poly.push_back(pointmap.depixelate(currpix)+pointOffset(pointmap,currpix,side)); relations[rel] &= ~side; // <- clear to check all have been done later side <<= 1; if (side > ShapeRef::SHAPE_T) { side = ShapeRef::SHAPE_L; } pointPixelBorder(pointmap,relations,poly,side,currpix,minpix,false); } else { currpix.move( moveDir(side) ); side >>= 1; if (side < ShapeRef::SHAPE_L) { side = ShapeRef::SHAPE_T; } pointPixelBorder(pointmap,relations,poly,side,currpix,minpix,false); } } bool ShapeMap::clearSel() { // note, only clear if need be, as m_attributes.deselectAll is slow if (m_selection_set.size()) { m_attributes.deselectAll(); m_selection = false; for (auto& sel: m_selection_set) { m_shapes.value(sel).m_selected = false; } m_selection_set.clear(); } return true; } // this can be reinit as well void ShapeMap::init(int size, const QtRegion &r) { if (m_pixel_shapes) { for (int i = 0; i < m_cols; i++) { delete [] m_pixel_shapes[i]; } delete [] m_pixel_shapes; m_pixel_shapes = NULL; } if (m_display_shapes) { delete [] m_display_shapes; m_display_shapes = NULL; } m_rows = std::min(std::max(20,(int)sqrt((double)size)),32768); m_cols = std::min(std::max(20,(int)sqrt((double)size)),32768); if (m_region.atZero()) { m_region = r; } else { m_region = runion(m_region,r); } // calculate geom data: m_tolerance = std::max(m_region.width(), m_region.height()) * TOLERANCE_A; // m_pixel_shapes = new pqvector *[m_cols]; for (int i = 0; i < m_cols; i++) { m_pixel_shapes[i] = new pqvector[m_rows]; } } int ShapeMap::makeLineShape(const Line& line, bool through_ui, bool tempshape) { // note, map must have editable flag on if we are to make a shape through the user interface: if (through_ui && !m_editable) { return -1; } bool bounds_good = true; if (!(m_region.contains_touch(line.start()) && m_region.contains_touch(line.end()))) { bounds_good = false; init(m_shapes.size(),line); } m_shape_ref++; // note, shape constructor sets centroid, length etc int rowid = m_shapes.add(m_shape_ref,SalaShape(line)); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(m_shape_ref); } else { // pixelate all polys in the pixel new structure: for (size_t i = 0; i < m_shapes.size(); i++) { makePolyPixels(m_shapes.key(i)); } } if (!tempshape) { m_attributes.insertRow(m_shape_ref); m_newshape = true; } if (through_ui) { // // manually add connections: if (m_hasgraph) { if (isAxialMap()) { connectIntersected(rowid,true); // "true" means line-line intersections only will be applied } else { connectIntersected(rowid,false); } } // if through ui, set undo counter: m_undobuffer.push_back(SalaEvent(SalaEvent::SALA_CREATED,m_shape_ref)); // update displayed attribute if through ui: invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); } return m_shape_ref; } // code to add intersections when shapes are added to the graph one by one: int ShapeMap::connectIntersected(int rowid, bool linegraph) { int shaperef = m_shapes.key(rowid); int conn_col = m_attributes.getOrInsertColumnIndex("Connectivity"); m_attributes.setColumnLock(conn_col); int leng_col = -1; if (linegraph) { // historically line length has always been added at this point leng_col = m_attributes.getOrInsertLockedColumnIndex("Line Length"); } // all indices should match... this grows connectors if necessary to same length as shapes while (m_connectors.size() < m_shapes.size()) { m_connectors.push_back( Connector() ); } int connectivity = linegraph ? getLineConnections( shaperef, m_connectors[rowid].m_connections, TOLERANCE_B*std::max(m_region.height(),m_region.width())) : getShapeConnections( shaperef, m_connectors[rowid].m_connections, TOLERANCE_B*std::max(m_region.height(),m_region.width())); m_attributes.setValue(rowid, conn_col, (float) connectivity ); if (linegraph) { m_attributes.setValue(rowid, leng_col, (float) m_shapes[rowid].getLength() ); } // now go through our connections, and add ourself: for (size_t k = 0; k < m_connectors[rowid].m_connections.size(); k++) { int myplace = m_connectors[rowid].m_connections[k]; if (myplace != rowid) { // <- exclude self! m_connectors[myplace].m_connections.add(rowid); m_attributes.incrValue(myplace,conn_col); } } return connectivity; } // this assumes this is a line map (to speed up axial map creation) // use the other version, getShapeConnections for arbitrary shape-shape connections // note, connections are listed by rowid in list, *not* reference number // (so they may vary: must be checked carefully when shapes are removed / added) int ShapeMap::getLineConnections(int lineref, pvecint& connections, double tolerance) { SalaShape& poly = m_shapes.search(lineref); if (!poly.isLine()) { return 0; } const Line& l = poly.getLine(); pvecint testedshapes; // As of version 10, self-connections are *not* added // In the past: // it's useful to have yourself in your connections list // (apparently! -- this needs checking, as most of the time it is then checked to exclude self again!) // connections.add(m_shapes.searchindex(lineref)); testedshapes.add(lineref); int num_intersections = 0; PixelRefVector list = pixelateLine( l ); for (size_t i = 0; i < list.size(); i++) { pqvector& shapes = m_pixel_shapes[ list[i].x ][ list[i].y ]; for (size_t j = 0; j < shapes.size(); j++) { ShapeRef& shape = shapes[j]; if (testedshapes.searchindex(shape.m_shape_ref) != paftl::npos) { continue; } testedshapes.add(shape.m_shape_ref,paftl::ADD_HERE); if ((shape.m_tags & ShapeRef::SHAPE_OPEN) == ShapeRef::SHAPE_OPEN) { try { const Line& line = m_shapes.search(shape.m_shape_ref).getLine(); if ( intersect_region(line, l, line.length() * tolerance) ) { // n.b. originally this followed the logic that we must normalise intersect_line properly: tolerance * line length one * line length two // in fact, works better if it's just line.length() * tolerance... if ( intersect_line(line, l, line.length() * tolerance) ) { connections.add(m_shapes.searchindex(shape.m_shape_ref)); num_intersections++; } } } catch (pexception) { // the lineref may have been deleted -- this is supposed to be tidied up // just ignore... } } } } return num_intersections; } // this is only problematic as there is lots of legacy code with shape-in-shape testing, int ShapeMap::getShapeConnections(int shaperef, pvecint& connections, double tolerance) { // In versions prior to 10, note that unlike getLineConnections, self-connection is excluded by all of the following functions // As of version 10, both getShapeConnections and getLineConnections exclude self-connection size_t index = m_shapes.searchindex(shaperef); if (index != paftl::npos) { SalaShape& shape = m_shapes[index]; if (shape.isPoint()) { // a point is simple, it never intersects itself: pointInPolyList(shape.getPoint(),connections); } else if (shape.isPolygon()) { // a closed poly is actually quite simple too as we already have code using a polyref: polyInPolyList(shaperef,connections,tolerance); } else if (shape.isLine()) { // line is a bit slow because there's no tested shape as in getLineConnections, but similar: lineInPolyList(shape.getLine(),connections,shaperef,tolerance); } else if (shape.isPolyLine()) { // this is the worst for efficiency: potential for many possible retries of the same shape: for (size_t i = 1; i < shape.size() - 1; i++) { Line li(shape[i-1], shape[i]); lineInPolyList(li,connections,shaperef,tolerance); } } } return connections.size(); } // similar to above, but builds a list void ShapeMap::pointInPolyList(const Point2f& p, pvecint& shapeindexlist) const { if (!m_region.contains(p)) { return ; } pvecint testedshapes; PixelRef pix = pixelate(p); pqvector &shapes = m_pixel_shapes[pix.x][pix.y]; for (size_t i = 0; i < shapes.size(); i++) { const ShapeRef& shape = shapes[i]; if (testedshapes.searchindex(shape.m_shape_ref) != paftl::npos) { continue; } testedshapes.add(shape.m_shape_ref,paftl::ADD_HERE); int shapeindex = testPointInPoly(p,shape); // if there's a shapeindex, then add (note it is an add -- you may be passed a list again to expand) if (shapeindex != -1) { shapeindexlist.add(shapeindex); } } } // note, lineref is only used as an "exclude self" test when called from getShapeConnections void ShapeMap::lineInPolyList(const Line& li_orig, pvecint& shapeindexlist, int lineref, double tolerance) const { if (!intersect_region(m_region,li_orig)) { return; } Line li = li_orig; if (!m_region.contains(li.start()) || !m_region.contains(li.end())) { li.crop(m_region); } pointInPolyList(li.start(),shapeindexlist); pointInPolyList(li.end(),shapeindexlist); // only now pixelate and test for any other shapes: PixelRefVector list = pixelateLine(li); for (size_t i = 0; i < list.size(); i++) { PixelRef pix = list[i]; if (includes(pix)) { pqvector& shapes = m_pixel_shapes[pix.x][pix.y]; for (size_t j = 0; j < shapes.size(); j++) { const ShapeRef& shape = shapes[j]; // slow to do this as it can repeat -- really need to use a linetest like structure to avoid retest of // polygon lines if (shape.m_shape_ref != lineref && shape.m_tags & (ShapeRef::SHAPE_EDGE | ShapeRef::SHAPE_INTERNAL_EDGE | ShapeRef::SHAPE_OPEN)) { const SalaShape& poly = m_shapes.search(shape.m_shape_ref); switch (poly.m_type & (SalaShape::SHAPE_LINE | SalaShape::SHAPE_POLY)) { case SalaShape::SHAPE_LINE: if (intersect_region(li,poly.m_region)) { // note: in this case m_region is stored as a line: if (intersect_line(li,poly.m_region,tolerance)) { shapeindexlist.add(m_shapes.searchindex(shape.m_shape_ref)); } } break; case SalaShape::SHAPE_POLY: { for (int k = 0; k < shape.m_polyrefs.size(); k++) { Line lineb = Line(poly[shape.m_polyrefs[k]],poly[((shape.m_polyrefs[k]+1)%poly.size())]); if (intersect_region(li,lineb)) { if (intersect_line(li,lineb,tolerance)) { shapeindexlist.add(m_shapes.searchindex(shape.m_shape_ref)); } } } } break; default: break; } } } } } } void ShapeMap::polyInPolyList(int polyref, pvecint& shapeindexlist, double tolerance) const { size_t index = m_shapes.searchindex(polyref); if (index == paftl::npos) { return; } const SalaShape& poly = m_shapes[index]; if (poly.isClosed()) { // <- it ought to be, you shouldn't be using this function if not! pvecint testedlist; // easiest just to use scan lines to find internal pixels rather than trace a complex border: PixelRef minpix = pixelate(poly.m_region.bottom_left); PixelRef maxpix = pixelate(poly.m_region.top_right); // pass one: shape centre of either object coincident automatically adds int x; for (x = minpix.x; x <= maxpix.x; x++) { for (int y = minpix.y; y <= maxpix.y; y++) { size_t pos = m_pixel_shapes[x][y].searchindex(polyref); if (pos != paftl::npos) { pqvector& shaperefs = m_pixel_shapes[x][y]; // this has us in it, now looked through everything else: for (size_t i = 0; i < shaperefs.size(); i++) { ShapeRef& shaperef = shaperefs[i]; if (i != pos && ((shaperefs[pos].m_tags & ShapeRef::SHAPE_CENTRE) || (shaperef.m_tags & ShapeRef::SHAPE_CENTRE))) { if (testedlist.add(shaperef.m_shape_ref) != -1) { shapeindexlist.add(m_shapes.searchindex(shaperef.m_shape_ref)); } } } } } } // that was the easy bit... now, pass 2, for non centre things: for (x = minpix.x; x <= maxpix.x; x++) { for (int y = minpix.y; y <= maxpix.y; y++) { size_t pos = m_pixel_shapes[x][y].searchindex(polyref); if (pos != paftl::npos) { pqvector& shaperefs = m_pixel_shapes[x][y]; ShapeRef& shaperef = shaperefs[pos]; if ((shaperef.m_tags & ShapeRef::SHAPE_CENTRE) == 0) { // this has us in it, now looked through everything else: for (size_t i = 0; i < shaperefs.size(); i++) { ShapeRef& shaperefb = shaperefs[i]; if (i != pos && testedlist.searchindex(shaperefb.m_shape_ref) == paftl::npos) { size_t indexb = m_shapes.searchindex(shaperefb.m_shape_ref); const SalaShape& polyb = m_shapes[indexb]; if (polyb.isPoint()) { if (testPointInPoly(polyb.getPoint(),shaperef) != -1) { shapeindexlist.add((int)indexb); } } else if (polyb.isLine()) { if (testPointInPoly(polyb.getLine().start(),shaperef) != -1 || testPointInPoly(polyb.getLine().end(),shaperef) != -1) { testedlist.add(shaperefb.m_shape_ref,paftl::ADD_HERE); shapeindexlist.add((int)indexb); } else { for (int k = 0; k < shaperef.m_polyrefs.size(); k++) { Line line = Line(poly[shaperef.m_polyrefs[k]],poly[((shaperef.m_polyrefs[k]+1)%poly.size())]); if (intersect_region(line,polyb.getLine())) { if (intersect_line(line,polyb.getLine(),tolerance)) { testedlist.add(shaperefb.m_shape_ref,paftl::ADD_HERE); shapeindexlist.add((int)indexb); break; } } } } } else if (polyb.isPolyLine()) { if (testPointInPoly(polyb[shaperefb.m_polyrefs[0]],shaperef) != -1) { testedlist.add(shaperefb.m_shape_ref,paftl::ADD_HERE); shapeindexlist.add(indexb); } else { for (int k = 0; k < shaperef.m_polyrefs.size(); k++) { for (int kk = 0; kk < shaperefb.m_polyrefs.size(); kk++) { Line line = Line(poly[shaperef.m_polyrefs[k]],poly[((shaperef.m_polyrefs[k]+1)%poly.size())]); Line lineb = Line(polyb[shaperefb.m_polyrefs[kk]],polyb[((shaperefb.m_polyrefs[kk]+1)%polyb.size())]); if (intersect_region(line,lineb)) { if (intersect_line(line,lineb,tolerance)) { if (testedlist.add(shaperefb.m_shape_ref) != -1) { shapeindexlist.add(indexb); break; } } } } } } } else { // poly to poly, ick! // first test one entirely inside the other // any point at all will suffice to check this: however, we need to check that the polyref point *itself* is within the // pixel, not just part of the line associated with it... if ((pixelate(polyb[shaperefb.m_polyrefs[0]]) == PixelRef(x,y) && testPointInPoly(polyb[shaperefb.m_polyrefs[0]],shaperef) != -1) || (pixelate(poly[shaperef.m_polyrefs[0]]) == PixelRef(x,y) && testPointInPoly(poly[shaperef.m_polyrefs[0]],shaperefb) != -1)) { testedlist.add(shaperefb.m_shape_ref,paftl::ADD_HERE); shapeindexlist.add(indexb); } else { // now check crossing bool breakit = false; for (int k = 0; k < shaperef.m_polyrefs.size() && !breakit; k++) { for (int kk = 0; kk < shaperefb.m_polyrefs.size(); kk++) { Line line = Line(poly[shaperef.m_polyrefs[k]],poly[((shaperef.m_polyrefs[k]+1)%poly.size())]); Line lineb = Line(polyb[shaperefb.m_polyrefs[kk]],polyb[((shaperefb.m_polyrefs[kk]+1)%polyb.size())]); if (intersect_region(line,lineb)) { if (intersect_line(line,lineb,tolerance)) { testedlist.add(shaperefb.m_shape_ref,paftl::ADD_HERE); shapeindexlist.add(indexb); breakit = true; break; } } } } } } } } } } } } } else { throw depthmapX440::RuntimeException("this function is to be used for polygons only"); } } // helper for point in poly -- // currently needs slight rewrite to avoid problem if point is in line with a vertex // (counter incremented twice on touching implies not in poly when is) int ShapeMap::testPointInPoly(const Point2f& p, const ShapeRef& shape) const { size_t shapeindex = paftl::npos; // simplist: in shape centre if (shape.m_tags & ShapeRef::SHAPE_CENTRE) { shapeindex = m_shapes.searchindex(shape.m_shape_ref); } // check not an open shape (cannot be inside) else if ((shape.m_tags & ShapeRef::SHAPE_OPEN) == 0) { const SalaShape& poly = m_shapes.search(shape.m_shape_ref); if (poly.m_region.contains_touch(p)) { // next simplest, on the outside border: int alpha = 0; int counter = 0; int parity = 0; if (shape.m_tags & ShapeRef::SHAPE_EDGE) { // run a test line to the edge: if (shape.m_tags & (ShapeRef::SHAPE_L | ShapeRef::SHAPE_R)) { if (shape.m_tags & ShapeRef::SHAPE_L) { parity = -1; } else if (shape.m_tags & ShapeRef::SHAPE_R) { parity = +1; } for (int j = 0; j < shape.m_polyrefs.size(); j++) { Line lineb = Line(poly[shape.m_polyrefs[j]],poly[((shape.m_polyrefs[j]+1)%poly.size())]); if (lineb.bottom_left.y <= p.y && lineb.top_right.y >= p.y) { // crosses or touches... but we need to check // touching exception: if (lineb.t_start().y == p.y) { if (parity * lineb.t_start().x >= parity * p.x) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.t_end().y == p.y) { if (parity * lineb.t_end().x >= parity * p.x) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't horizontal, so we can find the intersection point: else if (parity * (lineb.grad(XAXIS)*(p.y-lineb.ay()) + lineb.ax()) >= parity * p.x) { counter++; } } } } else { if (shape.m_tags & ShapeRef::SHAPE_B) { parity = -1; } else if (shape.m_tags & ShapeRef::SHAPE_T) { parity = +1; } for (int j = 0; j < shape.m_polyrefs.size(); j++) { Line lineb = Line(poly[shape.m_polyrefs[j]],poly[((shape.m_polyrefs[j]+1)%poly.size())]); if (lineb.bottom_left.x <= p.x && lineb.top_right.x >= p.x) { // crosses or touches... but we need to check // touching exception: if (lineb.top_right.x == p.x) { if (parity * lineb.by() >= parity * p.y) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.bottom_left.x == p.x) { if (parity * lineb.ay() >= parity * p.y) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't vertical, so we can find the intersection point: else if (parity * (lineb.grad(YAXIS)*(p.x-lineb.ax()) + lineb.ay()) >= parity * p.y) { counter++; } } } } if (counter % 2 != 0 && alpha == 0) { shapeindex = m_shapes.searchindex(shape.m_shape_ref); } } // and now the pig -- it's somewhere in the middle of the poly: else if (shape.m_tags & ShapeRef::SHAPE_INTERNAL_EDGE) { pvecint testnodes; size_t j; for (j = 0; j < size_t(shape.m_polyrefs.size()); j++) { // <- note, polyrefs is a subvec and has maximum number according to sizeof(T) testnodes.add(shape.m_polyrefs[j]); } PixelRef pix2 = pixelate(p); // bit of code duplication like this, but easier on params to this function: pix2.move(PixelRef::NEGVERTICAL); // move pix2 down, search for this shape... size_t nextindex = m_pixel_shapes[pix2.x][pix2.y].searchindex(shape.m_shape_ref); while (nextindex != paftl::npos) { const ShapeRef& shape2 = m_pixel_shapes[pix2.x][pix2.y][nextindex]; for (int k = 0; k < shape2.m_polyrefs.size(); k++) { testnodes.add(shape2.m_polyrefs[k]); } pix2.move(PixelRef::NEGVERTICAL); // move pix2 down, search for this shape... if (includes(pix2)) { nextindex = m_pixel_shapes[pix2.x][pix2.y].searchindex(shape.m_shape_ref); } else { nextindex = paftl::npos; } } int alpha = 0; int counter = 0; int parity = -1; for (j = 0; j < testnodes.size(); j++) { Line lineb = Line(poly[testnodes[j]],poly[((testnodes[j]+1)%poly.size())]); if (lineb.bottom_left.x <= p.x && lineb.top_right.x >= p.x) { // crosses or touches... but we need to check // touching exception: if (lineb.top_right.x == p.x) { if (parity * lineb.by() >= parity * p.y) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.bottom_left.x == p.x) { if (parity * lineb.ay() >= parity * p.y) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't vertical, so we can find the intersection point: else if (parity * (lineb.grad(YAXIS)*(p.x-lineb.ax()) + lineb.ay()) >= parity * p.y) { counter++; } } } if (counter % 2 != 0 && alpha == 0) { shapeindex = m_shapes.searchindex(shape.m_shape_ref); } } } } return (shapeindex == paftl::npos) ? -1 : int(shapeindex); // note convert to -1 } bool ShapeMap::write(std::ostream &stream, int version ) { // name dXstring440::writeString(stream, m_name); stream.write( (char *) &m_map_type, sizeof(m_map_type)); stream.write( (char *) &m_show, sizeof(m_show) ); stream.write( (char *) &m_editable, sizeof(m_editable) ); // PixelBase write // write extents: stream.write( (char *) &m_region, sizeof(m_region) ); // write rows / cols stream.write( (char *) &m_rows, sizeof(m_rows) ); stream.write( (char *) &m_cols, sizeof(m_cols) ); // write next object ref to be used: stream.write((char *) &m_obj_ref, sizeof(m_obj_ref)); stream.write((char *) &m_shape_ref, sizeof(m_shape_ref)); // write shape data int count = m_shapes.size(); stream.write((char *) &count, sizeof(count)); for (int j = 0; j < count; j++) { int key = m_shapes.key(j); stream.write((char *) &key, sizeof(key)); m_shapes.value(j).write(stream); } // write object data (currently unused) count = m_objects.size(); stream.write((char *) &count, sizeof(count)); for (int k = 0; k < count; k++) { int key = m_objects.key(k); stream.write((char *) &key, sizeof(key)); m_objects.value(k).write(stream); } // write attribute data m_attributes.write(stream,version); stream.write((char *)&m_displayed_attribute,sizeof(m_displayed_attribute)); // write connections data count = m_connectors.size(); stream.write((char *)&count,sizeof(count)); for (int i = 0; i < count; i++) { m_connectors[i].write(stream); } m_links.write(stream); m_unlinks.write(stream); // some miscellaneous extra data for mapinfo files if (m_mapinfodata) { stream.put('m'); m_mapinfodata->write(stream); } else { stream.put('x'); } return true; } bool SalaShape::write(std::ostream &stream) { stream.write((char *)&m_type,sizeof(m_type)); stream.write((char *)&m_region,sizeof(m_region)); stream.write((char *)&m_centroid,sizeof(m_centroid)); stream.write((char *)&m_area,sizeof(m_area)); stream.write((char *)&m_perimeter,sizeof(m_perimeter)); pqvector::write(stream); return true; } } ================================================ FILE: mgraph440/shapemap.h ================================================ #pragma once #include "mgraph440/pixelbase.h" #include "mgraph440/mapinfodata.h" #include "mgraph440/attributes.h" #include "mgraph440/connector.h" #include "mgraph440/paftl.h" #include "mgraph440/mgraph_consts.h" #include "mgraph440/stringutils.h" #include "mgraph440/bspnode.h" namespace mgraph440 { class SalaShape : public pqvector { public: enum {SHAPE_POINT = 0x01, SHAPE_LINE = 0x02, SHAPE_POLY = 0x04, SHAPE_CIRCLE = 0x08, SHAPE_TYPE = 0x0f, SHAPE_CLOSED = 0x40, SHAPE_CCW = 0x80 }; friend class ShapeMap; unsigned char m_type; Point2f m_centroid; // centre of mass, but also used as for point if object is a point Line m_region; // bounding box, but also used as a line if object is a line, hence type double m_area; double m_perimeter; // these are all temporary data which are recalculated on reload mutable bool m_selected; mutable float m_color; mutable int m_draworder; SalaShape(unsigned char type = 0) { m_type = type; m_draworder = -1; m_selected = false; m_area = 0.0; m_perimeter = 0.0; } SalaShape(const Point2f& point) { m_type = SHAPE_POINT; m_draworder = -1; m_selected = false; m_region = Line(point,point); m_centroid = point; m_area = 0.0; m_perimeter = 0.0; } SalaShape(const Line& line) { m_type = SHAPE_LINE; m_draworder = -1; m_selected = false; m_region = line; m_centroid = m_region.getCentre(); m_area = 0.0; m_perimeter = m_region.length(); } // bool isOpen() const { return (m_type & SHAPE_CLOSED) == 0; } bool isClosed() const { return (m_type & SHAPE_CLOSED) == SHAPE_CLOSED; } bool isPoint() const { return (m_type == SHAPE_POINT); } bool isLine() const { return (m_type == SHAPE_LINE); } bool isPolyLine() const { return (m_type & (SHAPE_POLY | SHAPE_CLOSED)) == SHAPE_POLY; } bool isPolygon() const { return (m_type & (SHAPE_POLY | SHAPE_CLOSED)) == (SHAPE_POLY | SHAPE_CLOSED); } // bool isCCW() const // { return (m_type & SHAPE_CCW) == SHAPE_CCW; } // // const Point2f& getPoint() const { return m_centroid; } const Line& getLine() const { return m_region; } // const QtRegion& getBoundingBox() const // { return m_region; } // // // double getArea() const // { return m_area; } // double getPerimeter() const // { return m_perimeter; } // // duplicate function, but easier to understand naming convention double getLength() const { return m_perimeter; } // // void setCentroidAreaPerim(); // void setCentroid(const Point2f& p); // // duplicate function, but easier to understand naming convention // const Point2f& getCentroid() const // { return m_centroid; } // // // double getAngDev() const; // // // pqvector getClippingSet(QtRegion& clipframe) const; // // bool read(std::ifstream& stream, int version); bool write(std::ostream& stream); }; ///////////////////////////////////////////////////////////////////////////////////////////////// class SalaObject : public pvecint { friend class ShapeMap; protected: Point2f m_centroid; public: SalaObject() {;} // bool read(std::ifstream& stream, int version); bool write(std::ostream& stream); }; inline bool SalaObject::read(std::ifstream& stream, int) { stream.read((char *)&m_centroid,sizeof(m_centroid)); pvecint::read(stream); return true; } inline bool SalaObject::write(std::ostream& stream) { stream.write((char *)&m_centroid,sizeof(m_centroid)); pvecint::write(stream); return true; } struct SalaEvent { enum { SALA_NULL_EVENT, SALA_CREATED, SALA_DELETED, SALA_MOVED }; int m_action; int m_shape_ref; SalaShape m_geometry; SalaEvent(int action = SALA_NULL_EVENT, int shape_ref = -1) { m_action = action; m_shape_ref = shape_ref; } }; struct ShapeRef { enum {SHAPE_REF_NULL = 0xFFFFFFFF}; enum {SHAPE_L = 0x01, SHAPE_B = 0x02, SHAPE_R = 0x04, SHAPE_T = 0x08 }; enum {SHAPE_EDGE = 0x0f, SHAPE_INTERNAL_EDGE = 0x10, SHAPE_CENTRE = 0x20, SHAPE_OPEN = 0x40 }; unsigned char m_tags; unsigned int m_shape_ref; psubvec m_polyrefs; ShapeRef( unsigned int sref = SHAPE_REF_NULL, unsigned char tags = 0x00 ) { m_shape_ref = sref; m_tags = tags; } friend bool operator == (const ShapeRef& a, const ShapeRef& b); friend bool operator != (const ShapeRef& a, const ShapeRef& b); friend bool operator < (const ShapeRef& a, const ShapeRef& b); friend bool operator > (const ShapeRef& a, const ShapeRef& b); }; inline bool operator == (const ShapeRef& a, const ShapeRef& b) { return a.m_shape_ref == b.m_shape_ref; } inline bool operator != (const ShapeRef& a, const ShapeRef& b) { return a.m_shape_ref != b.m_shape_ref; } inline bool operator < (const ShapeRef& a, const ShapeRef& b) { return a.m_shape_ref < b.m_shape_ref; } inline bool operator > (const ShapeRef& a, const ShapeRef& b) { return a.m_shape_ref > b.m_shape_ref; } class ShapeMap : public PixelBase { public: ShapeMap(const std::string& name = std::string(),int type = EMPTYMAP); virtual ~ShapeMap(); enum {EMPTYMAP = 0x0000, SEGMENTMAP = 0x0040, AXIALMAP = 0x0020, ALLLINEMAP = 0x0010, DRAWINGMAP = 0x0001, DATAMAP = 0x0002}; int m_map_type; std::string m_name; bool m_show; // used when shape map is a drawing layer bool m_editable; bool m_selection; mutable BSPNode *m_bsp_root; mutable bool m_bsp_tree; // quick grab for shapes pqvector **m_pixel_shapes; // i rows of j columns // for screen drawing mutable int *m_display_shapes; pqmap m_shapes; pqmap m_objects; // THIS IS UNUSED! Meant for each object to have many shapes prefvec m_undobuffer; AttributeTable m_attributes; // for graph functionality // Note: this list is stored PACKED for optimal performance on graph analysis // ALWAYS check it is in the same order as the shape list and attribute table prefvec m_connectors; int m_shape_ref; pqvector m_links; pqvector m_unlinks; double m_tolerance; int m_obj_ref; mutable bool m_invalidate; mutable int m_displayed_attribute; MapInfoData *m_mapinfodata; std::set m_selection_set; // note: uses rowids not keys mutable bool m_show_lines; mutable bool m_show_fill; mutable bool m_show_centroids; bool m_hasgraph; mutable bool m_newshape; // if a new shape has been added void makePolyPixels(int shaperef); // required for PixelBase, have to implement your own version of pixelate PixelRef pixelate( const Point2f& p, bool constrain = true, int = 1) const; const std::string& getName() const { return m_name; } bool read( std::ifstream& stream, int version, bool drawinglayer = false ); bool write( std::ostream& stream, int version ); void invalidateDisplayedAttribute() { m_invalidate = true; } void setDisplayedAttribute( int col ) const; void shapePixelBorder(pmap& relations, int shaperef, int side, PixelRef currpix, PixelRef minpix, bool first); int moveDir(int side); // convert a selected pixels to a layer object (note, uses selection attribute on pixel, you must select to make this work): int makeShapeFromPointSet(const PointMap& pointmap); AttributeTable& getAttributeTable() { return m_attributes; } // use set displayed attribute instead unless you are deliberately changing the column order: void overrideDisplayedAttribute(int attribute) { m_displayed_attribute = attribute; } const prefvec& getConnections() const { return m_connectors; } bool isSegmentMap() const { return m_map_type == SEGMENTMAP; } void pointPixelBorder(const PointMap& pointmap, pmap& relations, SalaShape& shape, int side, PixelRef currpix, PixelRef minpix, bool first); bool clearSel(); void init(int size, const QtRegion& r); Point2f pointOffset(const PointMap& pointmap, int currpix, int side); int makeLineShape(const Line& line, bool through_ui = false, bool tempshape = false); bool isAxialMap() const { return m_map_type == ALLLINEMAP || m_map_type == AXIALMAP; } // Connect a particular shape into the graph int connectIntersected(int rowid, bool linegraph); // Get the connections for a particular line int getLineConnections(int lineref, pvecint& connections, double tolerance); // Get arbitrary shape connections for a particular shape int getShapeConnections(int polyref, pvecint& connections, double tolerance); // retrieve lists of polys point intersects: void pointInPolyList(const Point2f& p, pvecint& shapeindexlist) const; void lineInPolyList(const Line& li, pvecint& shapeindexlist, int lineref = -1, double tolerance = 0.0) const; void polyInPolyList(int polyref, pvecint& shapeindexlist, double tolerance = 0.0) const; // helper to make actual test of point in shape: int testPointInPoly(const Point2f& p, const ShapeRef& shape) const; }; // Quick mod - TV template class ShapeMaps : public /*protected*/ prefvec { public: size_t m_displayed_map; ShapeMaps() { m_displayed_map = paftl::npos;} virtual ~ShapeMaps() {;} // size_t addMap(const std::string& name, int type); void setDisplayedMapRef(size_t map); // Quick mod - TV T& getMap(size_t index) { return prefvec::at(index); } size_t getMapRef(const std::string& name) const; bool read( std::ifstream& stream, int version ); bool write(::std::ostream &stream, int version, bool displayedmaponly = false ); }; template void ShapeMaps::setDisplayedMapRef(size_t map) { if (m_displayed_map != paftl::npos && m_displayed_map != map) prefvec::at(m_displayed_map).clearSel(); m_displayed_map = map; } template size_t ShapeMaps::addMap(const std::string& name, int type) { ShapeMaps::push_back(T(name,type)); setDisplayedMapRef(pmemvec::size()-1); return (pmemvec::size()-1); } template bool ShapeMaps::read( std::ifstream& stream, int version ) { prefvec::clear(); // empty existing data // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map; stream.read((char *)&displayed_map,sizeof(displayed_map)); m_displayed_map = size_t(displayed_map); // read maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = 0; stream.read((char *) &count, sizeof(count)); if (version < VERSION_NO_SHAPEMAP_NAME_LOOKUP) { for (size_t i = 0; i < size_t(count); i++) { // dummy name lookup (now simply creates on fly, as the name lookup may be corrupted in earlier versions) std::string name = dXstring440::readString(stream); int number; stream.read((char *)&number,sizeof(number)); } } for (size_t j = 0; j < size_t(count); j++) { ShapeMaps::push_back(T()); prefvec::tail().read(stream,version); } return true; } template bool ShapeMaps::write( ::std::ostream& stream, int version, bool displayedmaponly ) { if (!displayedmaponly) { // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map = (unsigned int)(m_displayed_map); stream.write((char *)&displayed_map,sizeof(displayed_map)); // write maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = (unsigned int) pmemvec::size(); stream.write((char *) &count, sizeof(count)); for (size_t j = 0; j < count; j++) { prefvec::at(j).write(stream,version); } } else { unsigned int dummy; // displayed map is 0 dummy = 0; stream.write((char *)&dummy,sizeof(dummy)); // count is 1 dummy = 1; stream.write((char *)&dummy,sizeof(dummy)); // write map: prefvec::at(m_displayed_map).write(stream,version); } return true; } template size_t ShapeMaps::getMapRef(const std::string& name) const { // note, only finds first map with this name for (size_t i = 0; i < pmemvec::size(); i++) { if (prefvec::at(i).getName() == name) return i; } return -1; } } ================================================ FILE: mgraph440/spacepix.cpp ================================================ #include "mgraph440/spacepix.h" namespace mgraph440 { PixelRef SpacePixel::pixelate( const Point2f& p, bool constrain, int ) const { PixelRef r; Point2f p1 = p; p1.normalScale(m_region); r.x = short(p1.x * double(m_cols-1e-9)); if (constrain) { if (r.x >= m_cols) r.x = m_cols - 1; else if (r.x < 0) r.x = 0; } r.y = short(p1.y * double(m_rows-1e-9)); if (constrain) { if (r.y >= m_rows) r.y = m_rows - 1; else if (r.y < 0) r.y = 0; } return r; } bool SpacePixel::read( std::ifstream& stream, int version ) { // clear anything that was there: if (m_pixel_lines) { for (int i = 0; i < m_cols; i++) { delete [] m_pixel_lines[i]; } delete [] m_pixel_lines; m_pixel_lines = NULL; } if (m_display_lines) { delete [] m_display_lines; m_display_lines = NULL; } m_lines.clear(); // read name: if (version >= VERSION_SPACEPIXELGROUPS) { m_name = dXstring440::readString(stream ); stream.read( (char *) &m_show, sizeof(m_show) ); } else { m_name = ""; } if (m_name.empty()) { m_name = ""; } m_edit = false; // <- just default to not editable on read if (version >= VERSION_LAYERCOLORS) { stream.read( (char *) &m_color, sizeof(m_color) ); } // read extents: stream.read( (char *) &m_region, sizeof(m_region) ); // read rows / cols stream.read( (char *) &m_rows, sizeof(m_rows) ); stream.read( (char *) &m_cols, sizeof(m_cols) ); // could work these two out on the fly, but it's easier to have them stored: //m_pixel_height = m_region.height() / double(m_rows); //m_pixel_width = m_region.width() / double(m_cols); // prepare loader: m_pixel_lines = new pvecint *[m_cols]; for (int i = 0; i < m_cols; i++) { m_pixel_lines[i] = new pvecint[m_rows]; } if (version < VERSION_DYNAMICLINES) { // read lines as refvec... prefvec lines; lines.read( stream ); // ... and transfer to new system: m_ref = -1; for (size_t i = 0; i < lines.size(); i++) { m_lines.add(++m_ref, LineTest(lines[i],0)); } } else { stream.read((char *) &m_ref, sizeof(m_ref)); m_lines.read( stream ); } if (version < VERSION_SPACEPIXELGROUPS) { // Scale up lines (should just work) for (size_t i = 0; i < m_lines.size(); i++) { m_lines[i].line.denormalScale(m_region); } } // now load into structure: for (size_t n = 0; n < m_lines.size(); n++) { PixelRefVector list = pixelateLine( m_lines[n].line ); for (size_t m = 0; m < list.size(); m++) { // note: m_pixel_lines is an *ordered* list! --- used by other ops. m_pixel_lines[list[m].x][list[m].y].push_back( n ); } } return true; } } ================================================ FILE: mgraph440/spacepix.h ================================================ #pragma once #include "mgraph440/shapemap.h" #include "mgraph440/pafcolor.h" #include "mgraph440/paftl.h" #include "mgraph440/p2dpoly.h" namespace mgraph440 { struct LineTest { Line line; unsigned int test; LineTest(const Line& l = Line(), int t = -1) { line = l; test = t; } }; class SpacePixel : public PixelBase { friend class PointMap; friend class AxialMaps; friend class AxialPolygons; friend class ShapeMap; // for transfer to everything being ShapeMaps public: //protected: PafColor m_color; std::string m_name; bool m_show; bool m_edit; pvecint **m_pixel_lines; int m_ref; pmap m_lines; // // for screen drawing mutable int *m_display_lines; PixelRef pixelate( const Point2f& p, bool constrain = true, int = 1 ) const; const pmap& getAllLines() const // Danger! Use solely to look at the raw line data { return m_lines; } std::string getName() { return m_name; } virtual bool read( std::ifstream& stream, int version ); }; // simply check they are the same name... useful for findindex from the group inline bool operator == (const SpacePixel& a, const SpacePixel& b) { return a.m_name == b.m_name; } template class SpacePixelGroup : public pqvector { protected: std::string m_name; // <- file name mutable int m_current_layer; public: QtRegion m_region; // easier public for now // SpacePixelGroup(const std::string& name = std::string()) { m_name = name; m_current_layer = -1; } void setName(const std::string& name) { m_name = name; } const std::string& getName() const { return m_name; } // QtRegion& getRegion() const { return (QtRegion&) m_region; } // // Screen functionality: void makeViewportShapes( const QtRegion& viewport = QtRegion() ) const; bool findNextShape(bool& nextlayer) const; // Quick mod - TV #if 0 #if !defined(_MSC_VER) size_t size() const { return pmemvec::size(); } T& at(size_t pos) { return prefvec::at(pos); } T& tail() { return prefvec::tail(); } #endif #endif public: bool read(std::ifstream& stream, int version, bool = true); bool write(std::ostream &stream, int version ); }; template bool SpacePixelGroup::read( std::ifstream& stream, int version, bool ) { if (version >= VERSION_SPACEPIXELGROUPS) { m_name = dXstring440::readString(stream); stream.read( (char *) &m_region, sizeof(m_region) ); int count; stream.read( (char *) &count, sizeof(count) ); for (int i = 0; i < count; i++) { SpacePixelGroup::push_back(T()); prefvec::tail().read(stream,version,true); } } else { m_name = ""; SpacePixelGroup::push_back(T()); prefvec::tail().read(stream,version,true); m_region = prefvec::tail().getRegion(); } if (m_name.empty()) { m_name = ""; } return true; } template bool SpacePixelGroup::write( std::ostream& stream, int version ) { dXstring440::writeString(stream, m_name); stream.write( (char *) &m_region, sizeof(m_region) ); // Quick mod - TV int count = prefvec::size(); stream.write( (char *) &count, sizeof(count) ); for (int i = 0; i < count; i++) { prefvec::at(i).write(stream,version); } return true; } typedef SpacePixelGroup < ShapeMap> SpacePixelFile; typedef SpacePixelGroup SuperSpacePixel; } ================================================ FILE: mgraph440/stringutils.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mgraph440/stringutils.h" #include #include #include #include #include namespace dXstring440 { std::vector split(const std::string &s, char delim, bool skipEmptyTokens) { std::vector elems; std::stringstream ss; ss.str(s); std::string item; while (std::getline(ss, item, delim)) { if (skipEmptyTokens && item.empty()) { continue; } elems.push_back(item); } return elems; } std::string readString(std::istream & stream) { unsigned int length; stream.read(reinterpret_cast(&length), sizeof(length)); if ( length == 0) { return std::string(); } std::string result( length, '\0'); char *ptr = &result[0]; stream.read(ptr, length); return result; } void writeString(std::ostream &stream, const std::string &s) { unsigned int length = s.length(); stream.write(reinterpret_cast(&length), sizeof(unsigned int)); if (length > 0) { stream.write(s.data(), length); } } std::string formatString(double value, const std::string &format) { std::vector buffer(24 + format.length(), '\0'); sprintf( &buffer[0], format.c_str(), value ); return std::string(&buffer[0]); } std::string formatString(int value, const std::string &format) { std::vector buffer(24 + format.length(), '\0'); sprintf( &buffer[0], format.c_str(), value ); return std::string(&buffer[0]); } std::string& toLower(std::string &str) { std::transform(str.begin(), str.end(), str.begin(), tolower); return str; } // trim from start (in place) void ltrim(std::string &s, char c) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [&c](int ch) { return ch != c; })); } // trim from end (in place) void rtrim(std::string &s, char c) { s.erase(std::find_if(s.rbegin(), s.rend(), [&c](int ch) { return ch != c; }).base(), s.end()); } void makeInitCaps(std::string &s) { bool literal = false; bool reset = true; for( auto& c : s) { if (!isalpha(c)) { if ( c == '"') { literal = !literal; } reset = true; } else { if (!literal) { if (reset) { c = toupper(c); } else { c = tolower(c); } } reset = false; } } } bool isDouble(const std::string &s) { // nasty const cast to satisfy the function signature - we will not change the value of endPtr char *endPtr = const_cast(&s[0]); strtod(s.c_str(), &endPtr); return endPtr != &s[0]; } } ================================================ FILE: mgraph440/stringutils.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Collection of utility functions that are required to add pstring functionality // to std::strings (i.e. splitting and compatible serialisation/deserialisation) #include #include #include #include #pragma once namespace dXstring440 { std::vector split(const std::string &s, char delim, bool skipEmptyTokens = false); std::string readString(std::istream & stream); void writeString(std::ostream &stream, const std::string &s); std::string formatString(double value, const std::string &format = "%+.16le"); std::string formatString(int value, const std::string &format = "% 16d"); /// Inplace conversion to lower case std::string &toLower(std::string &str); void ltrim(std::string &s, char c = ' '); void rtrim(std::string &s, char c = ' '); void makeInitCaps(std::string &s); bool isDouble(const std::string &s); template bool beginsWith(const T &input, const T match) { return input.size() >= match.size() && equal(match.begin(), match.end(), input.begin()); } } ================================================ FILE: mgraph440Test/CMakeLists.txt ================================================ set(mgraph440Test mgraph440Test) set(mgraph440Test_SRCS main.cpp testcontainers.cpp testconverters.cpp) set(LINK_LIBS salalib mgraph440 genlib) include_directories("../ThirdParty/Catch") add_executable(${mgraph440Test} ${mgraph440Test_SRCS}) target_link_libraries(${mgraph440Test} ${LINK_LIBS}) ================================================ FILE: mgraph440Test/main.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: mgraph440Test/testcontainers.cpp ================================================ // Copyright (C) 2018 Christian Sailer // Copyright (C) 2019 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../cliTest/selfcleaningfile.h" #include "../genlib/containerutils.h" #include "../genlib/readwritehelpers.h" #include "../mgraph440/paftl.h" using namespace mgraph440; template void comparePvecAndStdVec(const pvector &pvec, const std::vector &stdVec) { REQUIRE(pvec.size() == stdVec.size()); for (size_t i = 0; i < stdVec.size(); ++i) { REQUIRE(pvec[i] == stdVec[i]); } } TEST_CASE("Comaptibility between vector pvector streaming") { std::vector intVec{1, 5, 34, -2, 5}; SelfCleaningFile intFile("integers.bin"); { std::ofstream outfile(intFile.Filename()); dXreadwrite::writeVector(outfile, intVec); } pvector pveci; { std::ifstream infile(intFile.Filename()); pveci.read(infile); } comparePvecAndStdVec(pveci, intVec); pvector intPvec; intPvec.push_back(324); intPvec.push_back(-23); intPvec.push_back(87764); intPvec.push_back(-9); { std::ofstream outfile(intFile.Filename()); intPvec.write(outfile); } std::vector copyVec; { std::ifstream infile(intFile.Filename()); dXreadwrite::readIntoVector(infile, copyVec); } comparePvecAndStdVec(intPvec, copyVec); } template void comparePmapAndStdMap(const pmap &pMap, const std::map &stdMap) { const double EPSILON = 0.001; REQUIRE(pMap.size() == stdMap.size()); for (size_t i = 0; i < stdMap.size(); ++i) { REQUIRE(pMap.key(i) == depthmapX::getMapAtIndex(stdMap, i)->first); REQUIRE(pMap.value(i) == Approx(double(depthmapX::getMapAtIndex(stdMap, i)->second)).epsilon(EPSILON)); } } TEST_CASE("Comaptibility between map pmap streaming") { std::map intFloatMap; intFloatMap.insert(std::make_pair(1, 0.1f)); intFloatMap.insert(std::make_pair(5, 5000.0f)); intFloatMap.insert(std::make_pair(34, -3.4f)); intFloatMap.insert(std::make_pair(-2, 0.2f)); intFloatMap.insert(std::make_pair(6, 0.6f)); SelfCleaningFile intFloatFile("intFloatMap.bin"); { std::ofstream outfile(intFloatFile.Filename()); dXreadwrite::writeMap(outfile, intFloatMap); } pmap pmapi; { std::ifstream infile(intFloatFile.Filename()); pmapi.read(infile); } comparePmapAndStdMap(pmapi, intFloatMap); pmap intFloatPmap; intFloatPmap.add(324, 0.2f); intFloatPmap.add(-23, 14000); intFloatPmap.add(87764, -0.102f); intFloatPmap.add(-9, 0.00001f); { std::ofstream outfile(intFloatFile.Filename()); intFloatPmap.write(outfile); } std::map copyMap; { std::ifstream infile(intFloatFile.Filename()); dXreadwrite::readIntoMap(infile, copyMap); } comparePmapAndStdMap(intFloatPmap, copyMap); } ================================================ FILE: mgraph440Test/testconverters.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "../mgraph440/legacyconverters.h" #include "catch.hpp" TEST_CASE("vector conversion") { std::vector vec{1, 4, 5}; mgraph440::pvector result = genshim440::toPVector(vec); REQUIRE(result.size() == 3); REQUIRE(result[0] == 1); REQUIRE(result[1] == 4); REQUIRE(result[2] == 5); } ================================================ FILE: moduleTest/CMakeLists.txt ================================================ set(moduleTest moduleTest) set(moduleTest_SRCS main.cpp) include_directories("../ThirdParty/Catch" "../ThirdParty/FakeIt") set(modules_coreTest "" CACHE INTERNAL "modules_coreTest" FORCE) set(MODULES_GUI FALSE) set(MODULES_CLI FALSE) set(MODULES_CLI_TEST FALSE) set(MODULES_CORE FALSE) set(MODULES_CORE_TEST TRUE) add_subdirectory(../modules modules) add_executable(${moduleTest} ${moduleTest_SRCS}) target_link_libraries(${moduleTest} salalib genlib mgraph440 ${modules_coreTest} ${modules_core}) ================================================ FILE: moduleTest/main.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: modules/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . file(GLOB children "*") foreach(child ${children}) if(IS_DIRECTORY ${child} AND EXISTS ${child}/CMakeLists.txt) add_subdirectory(${child}) endif() endforeach() ================================================ FILE: modules/segmentshortestpaths/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . if(MODULES_CORE) add_subdirectory(core) endif() if(MODULES_GUI) add_subdirectory(gui) endif() if(MODULES_CLI) add_subdirectory(cli) endif() if(MODULES_CORE_TEST) add_subdirectory(coreTest) endif() if(MODULES_CLI_TEST) add_subdirectory(cliTest) endif() ================================================ FILE: modules/segmentshortestpaths/RegressionTest/regressionconfig.json ================================================ { "rundir": "rundir", "basebinlocation": "../../BaselineBinaries", "testbinlocation": "../../../build", "testcases": { "shortest_segment_metric_path": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENTSHORTESTPATH", "extraArgs": { "-sspo":"531074,185526", "-sspd":"534231,183853", "-sspt":"metric" } }], "shortest_segment_tulip_path": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENTSHORTESTPATH", "extraArgs": { "-sspo":"531074,185526", "-sspd":"534231,183853", "-sspt":"tulip" } }], "shortest_segment_topological_path": [{ "infile": "../../../testdata/barnsbury_extended1_segment.graph", "outfile": "out.graph", "mode": "SEGMENTSHORTESTPATH", "extraArgs": { "-sspo":"531074,185526", "-sspd":"534231,183853", "-sspt":"topological" } }] } } ================================================ FILE: modules/segmentshortestpaths/cli/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(segmentpathscli segmentpathscli) set(segmentpathscli_SRCS segmentshortestpathparser.cpp) set(modules_cli "${modules_cli}" "segmentpathscli" CACHE INTERNAL "modules_cli" FORCE) add_compile_definitions(SEGMENTPATHS_CLI_LIBRARY) add_library(${segmentpathscli} OBJECT ${segmentpathscli_SRCS}) ================================================ FILE: modules/segmentshortestpaths/cli/segmentshortestpathparser.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmentshortestpathparser.h" #include "depthmapXcli/exceptions.h" #include "depthmapXcli/parsingutils.h" #include "depthmapXcli/runmethods.h" #include "depthmapXcli/simpletimer.h" #include "modules/segmentshortestpaths/core/segmmetricshortestpath.h" #include "modules/segmentshortestpaths/core/segmtopologicalshortestpath.h" #include "modules/segmentshortestpaths/core/segmtulipshortestpath.h" #include "salalib/entityparsing.h" #include #include using namespace depthmapX; void SegmentShortestPathParser::parse(int argc, char **argv) { std::string originPoint; std::string destinationPoint; for (int i = 1; i < argc; ++i) { if (std::strcmp("-sspo", argv[i]) == 0) { if (!originPoint.empty()) { throw CommandLineException("-sspo can only be provided once"); } ENFORCE_ARGUMENT("-sspo", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid origin point provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } originPoint = argv[i]; } if (std::strcmp("-sspd", argv[i]) == 0) { if (!destinationPoint.empty()) { throw CommandLineException("-sspd can only be provided once"); } ENFORCE_ARGUMENT("-sspd", i) if (!has_only_digits_dots_commas(argv[i])) { std::stringstream message; message << "Invalid destination point provided (" << argv[i] << "). Should only contain digits dots and commas" << std::flush; throw CommandLineException(message.str().c_str()); } destinationPoint = argv[i]; } else if (std::strcmp("-sspt", argv[i]) == 0) { ENFORCE_ARGUMENT("-sspt", i) if (std::strcmp(argv[i], "tulip") == 0) { m_stepType = StepType::TULIP; } else if (std::strcmp(argv[i], "metric") == 0) { m_stepType = StepType::METRIC; } else if (std::strcmp(argv[i], "topological") == 0) { m_stepType = StepType::TOPOLOGICAL; } else { throw CommandLineException(std::string("Invalid step type: ") + argv[i]); } } } if (originPoint.empty() || destinationPoint.empty()) { throw CommandLineException("Both -sspo and -sspd must be provided"); } std::stringstream pointsStream; pointsStream << "x,y"; pointsStream << "\n" << originPoint; pointsStream << "\n" << destinationPoint; std::vector parsed = EntityParsing::parsePoints(pointsStream, ','); m_originPoint = parsed[0]; m_destinationPoint = parsed[1]; if (m_stepType == StepType::NONE) { throw CommandLineException("Step depth type (-sspt) must be provided"); } } void SegmentShortestPathParser::run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const { auto mGraph = dm_runmethods::loadGraph(clp.getFileName().c_str(), perfWriter); std::cout << "ok\nSelecting cells... " << std::flush; auto graphRegion = mGraph->getRegion(); if (!graphRegion.contains(m_originPoint)) { throw depthmapX::RuntimeException("Origin point outside of target region"); } if (!graphRegion.contains(m_destinationPoint)) { throw depthmapX::RuntimeException("Destination point outside of target region"); } QtRegion r(m_originPoint, m_originPoint); mGraph->setCurSel(r, false); r = QtRegion(m_destinationPoint, m_destinationPoint); mGraph->setCurSel(r, true); std::cout << "ok\nCalculating shortest path... " << std::flush; std::unique_ptr comm(new ICommunicator()); switch (m_stepType) { case SegmentShortestPathParser::StepType::TULIP: { DO_TIMED("Calculating tulip shortest path", SegmentTulipShortestPath(mGraph->getDisplayedShapeGraph()).run(comm.get())) break; } case SegmentShortestPathParser::StepType::METRIC: { DO_TIMED("Calculating metric shortest path", SegmentMetricShortestPath(mGraph->getDisplayedShapeGraph()).run(comm.get())) break; } case SegmentShortestPathParser::StepType::TOPOLOGICAL: { DO_TIMED("Calculating topological shortest path", SegmentTopologicalShortestPath(mGraph->getDisplayedShapeGraph()).run(comm.get())) break; } default: { throw depthmapX::SetupCheckException("Error, unsupported step type"); } } std::cout << " ok\nWriting out result..." << std::flush; DO_TIMED("Writing graph", mGraph->write(clp.getOuputFile().c_str(), METAGRAPH_VERSION, false)) std::cout << " ok" << std::endl; } ================================================ FILE: modules/segmentshortestpaths/cli/segmentshortestpathparser.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapXcli/imodeparser.h" #include "genlib/p2dpoly.h" #include class SegmentShortestPathParser : public IModeParser { public: SegmentShortestPathParser() : m_stepType(StepType::NONE) {} virtual std::string getModeName() const { return "SEGMENTSHORTESTPATH"; } virtual std::string getHelp() const { return "Mode options for pointmap SEGMENTSHORTESTPATH are:\n" " -sspo point where to calculate shortest path between.\n" " -sspd point where to calculate shortest path between.\n" " -sspt step type. One of metric, tulip or topological.\n"; } enum class StepType { NONE, TULIP, METRIC, TOPOLOGICAL }; virtual void parse(int argc, char **argv); virtual void run(const CommandLineParser &clp, IPerformanceSink &perfWriter) const; Point2f getShortestPathOrigin() const { return m_originPoint; } Point2f getShortestPathDestination() const { return m_destinationPoint; } StepType getStepType() const { return m_stepType; } private: Point2f m_originPoint; Point2f m_destinationPoint; StepType m_stepType; }; ================================================ FILE: modules/segmentshortestpaths/cliTest/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(segmentpathsclitest segmentpathsclitest) set(segmentpathsclitest_SRCS segmentshortestpathparsertest.cpp) set(modules_cliTest "${modules_cliTest}" "segmentpathsclitest" CACHE INTERNAL "modules_cliTest" FORCE) add_compile_definitions(SEGMENTPATHS_CLI_TEST_LIBRARY) add_library(${segmentpathsclitest} OBJECT ${segmentpathsclitest_SRCS}) ================================================ FILE: modules/segmentshortestpaths/cliTest/segmentshortestpathparsertest.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "cliTest/argumentholder.h" #include "cliTest/selfcleaningfile.h" #include "modules/segmentshortestpaths/cli/segmentshortestpathparser.h" #include TEST_CASE("SegmentShortestPathParser", "Error cases") { SECTION("Missing argument to -sspo") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspd", "0,0", "-sspo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sspo requires an argument")); } SECTION("Missing argument to -sspd") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspo", "0,0", "-sspd"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sspd requires an argument")); } SECTION("Missing argument to -sspt") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspo", "0,0", "-sspd", "0,0", "-sspt"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("-sspt requires an argument")); } SECTION("rubbish input to -sspo") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspd", "0,0", "-sspo", "foo"}; REQUIRE_THROWS_WITH( parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid origin point provided (foo). Should only contain digits dots and commas")); } SECTION("rubbish input to -sspd") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspo", "0,0", "-sspd", "foo"}; REQUIRE_THROWS_WITH( parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid destination point provided (foo). Should only contain digits dots and commas")); } SECTION("rubbish input to -sspt") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog", "-sspo", "0,0", "-sspd", "0,0", "-sspt", "foo"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Invalid step type: foo")); } SECTION("Neiter points nor point file provided") { SegmentShortestPathParser parser; ArgumentHolder ah{"prog"}; REQUIRE_THROWS_WITH(parser.parse(ah.argc(), ah.argv()), Catch::Contains("Both -sspo and -sspd must be provided")); } } TEST_CASE("Successful SegmentShortestPathParser", "Read successfully") { SegmentShortestPathParser parser; double originX = 1.0; double originY = 2.0; double destinationX = 1.1; double destinationY = 1.2; SECTION("Read from commandline") { std::stringstream originStream; originStream << originX << "," << originY << std::flush; std::stringstream destinationStream; destinationStream << destinationX << "," << destinationY << std::flush; ArgumentHolder ah{"prog", "-sspo", originStream.str(), "-sspd", destinationStream.str(), "-sspt", "topological"}; parser.parse(ah.argc(), ah.argv()); } auto originPoint = parser.getShortestPathOrigin(); auto destinationPoint = parser.getShortestPathDestination(); REQUIRE(originPoint.x == Approx(originX)); REQUIRE(originPoint.y == Approx(originY)); REQUIRE(destinationPoint.x == Approx(destinationX)); REQUIRE(destinationPoint.y == Approx(destinationY)); } ================================================ FILE: modules/segmentshortestpaths/core/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(segmentpathscore segmentpathscore) set(segmentpathscore_SRCS segmmetricshortestpath.cpp segmtopologicalshortestpath.cpp segmtulipshortestpath.cpp) set(modules_core "${modules_core}" "segmentpathscore" CACHE INTERNAL "modules_core" FORCE) add_compile_definitions(SEGMENTPATHS_CORE_LIBRARY) add_library(${segmentpathscore} OBJECT ${segmentpathscore_SRCS}) ================================================ FILE: modules/segmentshortestpaths/core/segmmetricshortestpath.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmmetricshortestpath.h" #include "genlib/stringutils.h" bool SegmentMetricShortestPath::run(Communicator *) { AttributeTable &attributes = m_map.getAttributeTable(); int shapeCount = m_map.getShapeCount(); bool retvar = true; int dist_col = attributes.insertOrResetColumn("Metric Shortest Path Distance"); int path_col = attributes.insertOrResetColumn("Metric Shortest Path Order"); // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < shapeCount; cursor++) { AttributeRow &row = m_map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue("Axial Line Ref")); seglengths.push_back(row.getValue("Segment Length")); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } int maxbin = 512; std::vector seen(shapeCount, 0xffffffff); std::vector audittrail(shapeCount); std::vector list[512]; // 512 bins! int open = 0; auto &selected = m_map.getSelSet(); if (selected.size() != 2) { return false; } int refFrom = *selected.begin(); int refTo = *selected.rbegin(); seen[refFrom] = 0; open++; double length = seglengths[refFrom]; audittrail[refFrom] = TopoMetSegmentRef(refFrom, Connector::SEG_CONN_ALL, length * 0.5, -1); // better to divide by 511 but have 512 bins... list[(int(floor(0.5 + 511 * length / maxseglength))) % 512].push_back(refFrom); m_map.getAttributeRowFromShapeIndex(refFrom).setValue(dist_col, 0); unsigned int segdepth = 0; int bin = 0; std::map parents; bool refFound = false; while (open != 0 && !refFound) { while (list[bin].empty()) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // this is necessary using unsigned ints for "seen", as it is possible to add a node twice if (here.done) { continue; } else { here.done = true; } Connector &axline = m_map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; if (seen[connected_cursor] > segdepth) { float length = seglengths[connected_cursor]; seen[connected_cursor] = segdepth; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); parents[connected_cursor] = here.ref; // puts in a suitable bin ahead of us... open++; // // better to divide by 511 but have 512 bins... list[(bin + int(floor(0.5 + 511 * length / maxseglength))) % 512].push_back(connected_cursor); AttributeRow &row = m_map.getAttributeRowFromShapeIndex(connected_cursor); row.setValue(dist_col, here.dist + length * 0.5); } if (connected_cursor == refTo) { refFound = true; break; } iter++; } } auto refToParent = parents.find(refTo); int counter = 0; while (refToParent != parents.end()) { AttributeRow &row = m_map.getAttributeRowFromShapeIndex(refToParent->first); row.setValue(path_col, counter); counter++; refToParent = parents.find(refToParent->second); } m_map.getAttributeRowFromShapeIndex(refFrom).setValue(path_col, counter); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { AttributeRow &row = iter->getRow(); if (row.getValue(path_col) < 0) { row.setValue(dist_col, -1); } else { row.setValue(path_col, counter - row.getValue(path_col)); } } m_map.overrideDisplayedAttribute(-2); m_map.setDisplayedAttribute(path_col); return retvar; } ================================================ FILE: modules/segmentshortestpaths/core/segmmetricshortestpath.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/ianalysis.h" class SegmentMetricShortestPath : public IAnalysis { private: ShapeGraph &m_map; public: SegmentMetricShortestPath(ShapeGraph &map) : m_map(map) {} std::string getAnalysisName() const override { return "Metric Shortest Path"; } bool run(Communicator *) override; }; ================================================ FILE: modules/segmentshortestpaths/core/segmtopologicalshortestpath.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmtopologicalshortestpath.h" #include "genlib/stringutils.h" bool SegmentTopologicalShortestPath::run(Communicator *comm) { AttributeTable &attributes = m_map.getAttributeTable(); int shapeCount = m_map.getShapeCount(); bool retvar = true; int depth_col = attributes.insertOrResetColumn("Topological Shortest Path Depth"); int path_col = attributes.insertOrResetColumn("Topological Shortest Path Order"); // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < shapeCount; cursor++) { AttributeRow &row = m_map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue("Axial Line Ref")); seglengths.push_back(row.getValue("Segment Length")); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } int maxbin = 2; std::vector seen(shapeCount, 0xffffffff); std::vector audittrail(shapeCount); std::vector list[512]; // 512 bins! int open = 0; auto &selected = m_map.getSelSet(); if (selected.size() != 2) { return false; } int refFrom = *selected.begin(); int refTo = *selected.rbegin(); seen[refFrom] = 0; open++; double length = seglengths[refFrom]; audittrail[refFrom] = TopoMetSegmentRef(refFrom, Connector::SEG_CONN_ALL, length * 0.5, -1); list[0].push_back(refFrom); m_map.getAttributeRowFromShapeIndex(refFrom).setValue(depth_col, 0); unsigned int segdepth = 0; int bin = 0; std::map parents; bool refFound = false; while (open != 0) { while (list[bin].empty()) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // this is necessary using unsigned ints for "seen", as it is possible to add a node twice if (here.done) { continue; } else { here.done = true; } Connector &axline = m_map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; AttributeRow &row = m_map.getAttributeRowFromShapeIndex(connected_cursor); if (seen[connected_cursor] > segdepth) { float length = seglengths[connected_cursor]; int axialref = axialrefs[connected_cursor]; seen[connected_cursor] = segdepth; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); // puts in a suitable bin ahead of us... open++; // if (axialrefs[here.ref] == axialref) { list[bin].push_back(connected_cursor); row.setValue(depth_col, segdepth); } else { list[(bin + 1) % 2].push_back(connected_cursor); seen[connected_cursor] = segdepth + 1; // this is so if another node is connected directly to this one but is found later it is // still handled -- note it can result in the connected cursor being added twice row.setValue(depth_col, segdepth + 1); } if(parents.find(connected_cursor) == parents.end()) { parents[connected_cursor] = here.ref; } } if (connected_cursor == refTo) { refFound = true; break; } iter++; } if (refFound) break; } auto refToParent = parents.find(refTo); int counter = 0; while (refToParent != parents.end()) { AttributeRow &row = m_map.getAttributeRowFromShapeIndex(refToParent->first); row.setValue(path_col, counter); counter++; refToParent = parents.find(refToParent->second); } m_map.getAttributeRowFromShapeIndex(refFrom).setValue(path_col, counter); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { AttributeRow &row = iter->getRow(); if (row.getValue(path_col) < 0) { row.setValue(depth_col, -1); } else { row.setValue(path_col, counter - row.getValue(path_col)); } } m_map.overrideDisplayedAttribute(-2); // <- override if it's already showing m_map.setDisplayedAttribute(depth_col); return retvar; } ================================================ FILE: modules/segmentshortestpaths/core/segmtopologicalshortestpath.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/ianalysis.h" class SegmentTopologicalShortestPath : public IAnalysis { private: ShapeGraph &m_map; public: SegmentTopologicalShortestPath(ShapeGraph &map) : m_map(map) {} std::string getAnalysisName() const override { return "Topological Shortest Path"; } bool run(Communicator *comm) override; }; ================================================ FILE: modules/segmentshortestpaths/core/segmtulipshortestpath.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmtulipshortestpath.h" #include "genlib/stringutils.h" // revised to use tulip bins for faster analysis of large spaces bool SegmentTulipShortestPath::run(Communicator *) { AttributeTable &attributes = m_map.getAttributeTable(); int angle_col = attributes.insertOrResetColumn("Angular Shortest Path Angle"); int path_col = attributes.insertOrResetColumn("Angular Shortest Path Order"); // The original code set tulip_bins to 1024, divided by two and added one // in order to duplicate previous code (using a semicircle of tulip bins) size_t tulip_bins = 513; std::vector covered(m_map.getConnections().size()); for (size_t i = 0; i < m_map.getConnections().size(); i++) { covered[i] = false; } std::vector> bins(tulip_bins); auto &selected = m_map.getSelSet(); if (selected.size() != 2) { return false; } int refFrom = *selected.begin(); int refTo = *selected.rbegin(); int opencount = 0; int row = std::distance(m_map.getAllShapes().begin(), m_map.getAllShapes().find(refFrom)); if (row != -1) { bins[0].push_back(SegmentData(0, row, SegmentRef(), 0, 0.0, 0)); opencount++; } std::map parents; bool refFound = false; int depthlevel = 0; auto binIter = bins.begin(); int currentbin = 0; while (opencount && !refFound) { while (binIter->empty()) { depthlevel++; binIter++; currentbin++; if (binIter == bins.end()) { binIter = bins.begin(); } } SegmentData lineindex; if (binIter->size() > 1) { // it is slightly slower to delete from an arbitrary place in the bin, // but it is necessary to use random paths to even out the number of times through equal paths int curr = pafrand() % binIter->size(); auto currIter = binIter->begin() + curr; lineindex = *currIter; binIter->erase(currIter); // note: do not clear choice values here! } else { lineindex = binIter->front(); binIter->pop_back(); } opencount--; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; Connector &line = m_map.getConnections()[lineindex.ref]; // convert depth from tulip_bins normalised to standard angle // (note the -1) double depth_to_line = depthlevel / ((tulip_bins - 1) * 0.5); m_map.getAttributeRowFromShapeIndex(lineindex.ref).setValue(angle_col, depth_to_line); int extradepth; if (lineindex.dir != -1) { for (auto &segconn : line.m_forward_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int)floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first, lineindex.ref, lineindex.segdepth + 1, 0.0, 0)); if(parents.find(segconn.first.ref) == parents.end()) { parents[segconn.first.ref] = lineindex.ref; } opencount++; } } } if (lineindex.dir != 1) { for (auto &segconn : line.m_back_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int)floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first, lineindex.ref, lineindex.segdepth + 1, 0.0, 0)); if(parents.find(segconn.first.ref) == parents.end()) { parents[segconn.first.ref] = lineindex.ref; } opencount++; } } } if (lineindex.ref == refTo) { refFound = true; break; } } } auto refToParent = parents.find(refTo); int counter = 0; while (refToParent != parents.end()) { AttributeRow &row = m_map.getAttributeRowFromShapeIndex(refToParent->first); row.setValue(path_col, counter); counter++; refToParent = parents.find(refToParent->second); } m_map.getAttributeRowFromShapeIndex(refFrom).setValue(path_col, counter); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { AttributeRow &row = iter->getRow(); if (row.getValue(path_col) < 0) { row.setValue(angle_col, -1); } else { row.setValue(path_col, counter - row.getValue(path_col)); } } m_map.overrideDisplayedAttribute(-2); // <- override if it's already showing m_map.setDisplayedAttribute(angle_col); return true; } ================================================ FILE: modules/segmentshortestpaths/core/segmtulipshortestpath.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ianalysis.h" class SegmentTulipShortestPath : public IAnalysis { private: ShapeGraph &m_map; public: SegmentTulipShortestPath(ShapeGraph &map) : m_map(map) {} std::string getAnalysisName() const override { return "Tulip Shortest Path"; } bool run(Communicator *) override; }; ================================================ FILE: modules/segmentshortestpaths/coreTest/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(segmentpathscoretest segmentpathscoretest) set(segmentpathscoretest_SRCS segmentpathscoretest.cpp) set(modules_coreTest "${modules_coreTest}" "segmentpathscoretest" CACHE INTERNAL "modules_coreTest" FORCE) add_compile_definitions(SEGMENTPATHS_CORE_TEST_LIBRARY) add_library(${segmentpathscoretest} OBJECT ${segmentpathscoretest_SRCS}) ================================================ FILE: modules/segmentshortestpaths/coreTest/segmentpathscoretest.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "modules/segmentshortestpaths/core/segmmetricshortestpath.h" #include "modules/segmentshortestpaths/core/segmtopologicalshortestpath.h" #include "modules/segmentshortestpaths/core/segmtulipshortestpath.h" #include "salalib/axialmap.h" #include "salalib/mapconverter.h" TEST_CASE("Shortest paths working examples", "") { const float EPSILON = 0.001; // construct an axial map which will result in three different paths for the three types ShapeGraph axialMap("Dummy drawing map", ShapeMap::AXIALMAP); axialMap.initialiseAttributesAxial(); std::vector lines; lines.push_back(Line(Point2f(1.05000000, 1.00000000), Point2f(3.60000000, 1.00000000))); lines.push_back(Line(Point2f(3.43455142, 2.92439257), Point2f(4.15448579, 3.75607430))); lines.push_back(Line(Point2f(2.40000000, 3.00000000), Point2f(3.60000000, 3.00000000))); lines.push_back(Line(Point2f(1.15022677, 0.90136061), Point2f(1.34977323, 2.09863939))); lines.push_back(Line(Point2f(3.50000000, 3.10000000), Point2f(3.50000000, 0.90000000))); lines.push_back(Line(Point2f(1.24560093, 1.95201016), Point2f(2.11199711, 2.42593102))); lines.push_back(Line(Point2f(1.96351621, 2.29850806), Point2f(2.56074850, 3.07943312))); lines.push_back(Line(Point2f(1.28848772, 1.91061952), Point2f(1.75546653, 2.84134127))); lines.push_back(Line(Point2f(1.61521977, 2.72198377), Point2f(2.59540115, 3.02997701))); lines.push_back(Line(Point2f(1.23737734, 1.07071068), Point2f(0.45955989, 0.29289322))); for (Line line : lines) { axialMap.makeLineShape(line); } axialMap.makeConnections(); REQUIRE(axialMap.getShapeCount() == 10); std::unique_ptr segmentMap = MapConverter::convertAxialToSegment(nullptr, axialMap, "Dummy segment map", true, true, 0.4); REQUIRE(segmentMap->getShapeCount() == 10); // select the two edges QtRegion selRegion(lines[1].midpoint(), lines[1].midpoint()); segmentMap->setCurSel(selRegion, false); selRegion.bottom_left = lines[9].midpoint(); selRegion.top_right = lines[9].midpoint(); segmentMap->setCurSel(selRegion, true); REQUIRE(segmentMap->getSelCount() == 2); { REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Angular Shortest Path Angle")); REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Angular Shortest Path Order")); SegmentTulipShortestPath(*segmentMap.get()).run(nullptr); REQUIRE(segmentMap->getAttributeTable().hasColumn("Angular Shortest Path Angle")); REQUIRE(segmentMap->getAttributeTable().hasColumn("Angular Shortest Path Order")); int angleColIdx = segmentMap->getAttributeTable().getColumnIndex("Angular Shortest Path Angle"); int orderColIdx = segmentMap->getAttributeTable().getColumnIndex("Angular Shortest Path Order"); std::vector expectedAngles = {-1, 0, 0.54297, 1.42969, -1, -1, -1, 1.24219, 0.734375, 1.82422}; std::vector expectedOrder = {-1, 0, 1, 4, -1, -1, -1, 3, 2, 5}; for (int i = 0; i < lines.size(); i++) { QtRegion selRegion(lines[i].midpoint(), lines[i].midpoint()); AttributeRow &shapeRow = segmentMap->getAttributeRowFromShapeIndex(segmentMap->getShapesInRegion(selRegion).begin()->first); REQUIRE(shapeRow.getValue(angleColIdx) == Approx(expectedAngles[i]).epsilon(EPSILON)); REQUIRE(shapeRow.getValue(orderColIdx) == expectedOrder[i]); } } { REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Metric Shortest Path Distance")); REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Metric Shortest Path Order")); SegmentMetricShortestPath(*segmentMap.get()).run(nullptr); REQUIRE(segmentMap->getAttributeTable().hasColumn("Metric Shortest Path Distance")); REQUIRE(segmentMap->getAttributeTable().hasColumn("Metric Shortest Path Order")); int distanceColIdx = segmentMap->getAttributeTable().getColumnIndex("Metric Shortest Path Distance"); int orderColIdx = segmentMap->getAttributeTable().getColumnIndex("Metric Shortest Path Order"); std::vector expectedDistances = {-1, 0, 1, 3.57756, -1, 2.67689, 1.89156, -1, -1, 4.58446}; std::vector expectedOrder = {-1, 0, 1, 4, -1, 3, 2, -1, -1, 5}; for (int i = 0; i < lines.size(); i++) { QtRegion selRegion(lines[i].midpoint(), lines[i].midpoint()); AttributeRow &shapeRow = segmentMap->getAttributeRowFromShapeIndex(segmentMap->getShapesInRegion(selRegion).begin()->first); REQUIRE(shapeRow.getValue(distanceColIdx) == Approx(expectedDistances[i]).epsilon(EPSILON)); REQUIRE(shapeRow.getValue(orderColIdx) == expectedOrder[i]); } } { REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Topological Shortest Path Depth")); REQUIRE_FALSE(segmentMap->getAttributeTable().hasColumn("Topological Shortest Path Order")); SegmentTopologicalShortestPath(*segmentMap.get()).run(nullptr); REQUIRE(segmentMap->getAttributeTable().hasColumn("Topological Shortest Path Depth")); REQUIRE(segmentMap->getAttributeTable().hasColumn("Topological Shortest Path Order")); int depthColIdx = segmentMap->getAttributeTable().getColumnIndex("Topological Shortest Path Depth"); int orderColIdx = segmentMap->getAttributeTable().getColumnIndex("Topological Shortest Path Order"); std::vector expectedDepths = {2, 0, -1, -1, 1, -1, -1, -1, -1, 3}; std::vector expectedOrder = {2, 0, -1, -1, 1, -1, -1, -1, -1, 3}; for (int i = 0; i < lines.size(); i++) { QtRegion selRegion(lines[i].midpoint(), lines[i].midpoint()); AttributeRow &shapeRow = segmentMap->getAttributeRowFromShapeIndex(segmentMap->getShapesInRegion(selRegion).begin()->first); REQUIRE(shapeRow.getValue(depthColIdx) == Approx(expectedDepths[i]).epsilon(EPSILON)); REQUIRE(shapeRow.getValue(orderColIdx) == expectedOrder[i]); } } } ================================================ FILE: modules/segmentshortestpaths/gui/CMakeLists.txt ================================================ # Copyright (C) 2020 Petros Koutsolampros # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . set(segmentpathsgui segmentpathsgui) set(segmentpathsgui_SRCS uictrigger.cpp segmentpathsmainwindow.cpp) set(modules_gui "${modules_gui}" "segmentpathsgui" CACHE INTERNAL "modules_gui" FORCE) find_package(Qt5 COMPONENTS Core Widgets Gui OpenGL REQUIRED) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${Qt5Core_INCLUDE_DIRS}) include_directories(${Qt5Widgets_INCLUDE_DIRS}) include_directories(${Qt5Gui_INCLUDE_DIRS}) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC_SEARCH_PATHS "../../../depthmapX/UI") add_definitions(${Qt5Core_DEFINITIONS}) add_definitions(${Qt5Widgets_DEFINITIONS}) add_definitions(${Qt5Gui_DEFINITIONS}) add_compile_definitions(SEGMENTPATHS_GUI_LIBRARY) add_library(${segmentpathsgui} OBJECT ${segmentpathsgui_SRCS} ../../../depthmapX/imainwindowmodule.h) ================================================ FILE: modules/segmentshortestpaths/gui/segmentpathsmainwindow.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "segmentpathsmainwindow.h" #include "modules/segmentshortestpaths/core/segmmetricshortestpath.h" #include "modules/segmentshortestpaths/core/segmtopologicalshortestpath.h" #include "modules/segmentshortestpaths/core/segmtulipshortestpath.h" #include "depthmapX/mainwindowhelpers.h" #include #include bool SegmentPathsMainWindow::createMenus(MainWindow *mainWindow) { QMenu *toolsMenu = MainWindowHelpers::getOrAddRootMenu(mainWindow, tr("&Tools")); QMenu *segmentMenu = MainWindowHelpers::getOrAddMenu(toolsMenu, tr("&Segment")); QMenu *shortestPathsMenu = MainWindowHelpers::getOrAddMenu(segmentMenu, tr("Shortest Paths")); QAction *angularPathAct = new QAction(tr("Angular shortest path"), mainWindow); angularPathAct->setStatusTip(tr("Create an angular shortest path")); connect(angularPathAct, &QAction::triggered, this, [this, mainWindow] { OnShortestPath(mainWindow, PathType::ANGULAR); }); shortestPathsMenu->addAction(angularPathAct); QAction *metricPathAct = new QAction(tr("Metric shortest path"), mainWindow); metricPathAct->setStatusTip(tr("Create a metric shortest path")); connect(metricPathAct, &QAction::triggered, this, [this, mainWindow] { OnShortestPath(mainWindow, PathType::METRIC); }); shortestPathsMenu->addAction(metricPathAct); QAction *topoPathAct = new QAction(tr("Topological shortest path"), mainWindow); topoPathAct->setStatusTip(tr("Create a topological shortest path")); connect(topoPathAct, &QAction::triggered, this, [this, mainWindow] { OnShortestPath(mainWindow, PathType::TOPOLOGICAL); }); shortestPathsMenu->addAction(topoPathAct); return true; } void SegmentPathsMainWindow::OnShortestPath(MainWindow *mainWindow, PathType pathType) { QGraphDoc *graphDoc = mainWindow->activeMapDoc(); if (graphDoc == nullptr) return; if (graphDoc->m_communicator) { QMessageBox::warning(mainWindow, tr("Warning"), tr("Please wait, another process is running"), QMessageBox::Ok, QMessageBox::Ok); return; } if (graphDoc->m_meta_graph->getDisplayedMapType() != ShapeMap::SEGMENTMAP) { QMessageBox::warning(mainWindow, tr("Warning"), tr("Please make sure the displayed map is a segment map"), QMessageBox::Ok, QMessageBox::Ok); return; } if (graphDoc->m_meta_graph->getDisplayedShapeGraph().getSelSet().size() != 2) { QMessageBox::warning(mainWindow, tr("Warning"), tr("Please select two segments to create a path between"), QMessageBox::Ok, QMessageBox::Ok); return; } graphDoc->m_communicator = new CMSCommunicator(); switch (pathType) { case PathType::ANGULAR: graphDoc->m_communicator->setAnalysis(std::unique_ptr( new SegmentTulipShortestPath(graphDoc->m_meta_graph->getDisplayedShapeGraph()))); break; case PathType::METRIC: graphDoc->m_communicator->setAnalysis(std::unique_ptr( new SegmentMetricShortestPath(graphDoc->m_meta_graph->getDisplayedShapeGraph()))); break; case PathType::TOPOLOGICAL: graphDoc->m_communicator->setAnalysis(std::unique_ptr( new SegmentTopologicalShortestPath(graphDoc->m_meta_graph->getDisplayedShapeGraph()))); break; } graphDoc->m_communicator->SetFunction(CMSCommunicator::FROMCONNECTOR); graphDoc->m_communicator->setSuccessUpdateFlags(QGraphDoc::NEW_DATA); graphDoc->m_communicator->setSuccessRedrawFlags(QGraphDoc::VIEW_ALL, QGraphDoc::REDRAW_POINTS, QGraphDoc::NEW_DATA); graphDoc->CreateWaitDialog(tr("Calculating shortest path...")); graphDoc->m_thread.render(graphDoc); } ================================================ FILE: modules/segmentshortestpaths/gui/segmentpathsmainwindow.h ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "depthmapX/imainwindowmodule.h" class SegmentPathsMainWindow : public IMainWindowModule { private: enum PathType { ANGULAR, METRIC, TOPOLOGICAL }; private slots: void OnShortestPath(MainWindow *mainWindow, PathType pathType); public: SegmentPathsMainWindow() : IMainWindowModule() {} bool createMenus(MainWindow *mainWindow); }; ================================================ FILE: modules/segmentshortestpaths/gui/uictrigger.cpp ================================================ // This file is required to trigger cmake's AUTOUIC in the depthmapX directory // if it is not included then the ui_*.h files in that directory are not generated // and then not found by the module which is built first because it is a dependency // of depthmapX. #include "depthmapX/ui_ColourScaleDlg.h" ================================================ FILE: releases/README.txt ================================================ depthmapX To install, just unpack the content of this zip file to your local hard drive and start depthmapX - this should contain everything you need. depthmapX documentation can be found at https://github.com/blackseamonster/depthmapX/tree/master/docs The wiki for this project is at: https://github.com/blackseamonster/depthmapX/wiki Changelog - Fixed some internal memory/runtime issues - Import links from file - Fixed crash on zoom-out issue - command line app (depthmapXcli) - restructured the code base to have more libraries that can be tested and reused - added catch as unit test framework - made simple mode option persistent - fixed persistence of user options on Windows - fixed mouse wheel zoom (center on mouse pointer, not center of the map) If you have any issues or questions, you can raise a ticket at https://github.com/blackseamonster/depthmapX/issues or send an email to depthmapX@blackseamonster.com ================================================ FILE: releases/gplv3.txt ================================================ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ================================================ FILE: releases/lgplv3.txt ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ================================================ FILE: releases/licenses.txt ================================================ depthmapX C 2000-2010 University College London, Alasdair Turner, Eva Friedrich C 2011-2014 Tasos Varoudis, UCL C 2017 Christian Sailer, Petros Koutsolampros Released under Gnu Public License (GPL v3) Please see gplv3.txt for license details This program uses QT5 under the LGPL v3 Please see lgplv3.txt for license details ================================================ FILE: salaTest/CMakeLists.txt ================================================ set(salaTest salaTest) set(salaTest_SRCS main.cpp testentityparsing.cpp testpointmap.cpp testlinkutils.cpp testgridproperties.cpp testisovistdef.cpp testmgraph.cpp testshapegraphs.cpp teststructsizes.cpp testsparksieve.cpp testattributetable.cpp testattributetableindex.cpp testlayermanager.cpp testattributetablehelpers.cpp testattributetableview.cpp testshapemaps.cpp testgeometrygenerators.cpp testmapinfodata.cpp testsalaprogram.cpp testdxfp.cpp testshaperemove.cpp testmapconversion.cpp testpointinpoly.cpp testpushvalues.cpp testisovist.cpp ) # salaTest_SRCS include_directories("../ThirdParty/Catch" "../ThirdParty/FakeIt") set(LINK_LIBS salalib genlib mgraph440) add_executable(${salaTest} ${salaTest_SRCS}) target_link_libraries(${salaTest} ${LINK_LIBS}) ================================================ FILE: salaTest/main.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #define CATCH_CONFIG_MAIN #include "catch.hpp" ================================================ FILE: salaTest/testattributetable.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "Catch/fakeit.hpp" #include #include #include #include #include TEST_CASE("test attribute column") { AttributeColumnImpl col("colName"); REQUIRE(col.getName() == "colName"); REQUIRE(col.getFormula() == ""); REQUIRE_FALSE(col.isHidden()); REQUIRE_FALSE(col.isLocked()); col.setLock(true); REQUIRE_FALSE(col.isHidden()); REQUIRE(col.isLocked()); col.setHidden(true); REQUIRE(col.isHidden()); REQUIRE(col.isLocked()); REQUIRE(col.m_stats.max == -1.0); REQUIRE(col.m_stats.min == -1.0); REQUIRE(col.m_stats.total == -1.0); REQUIRE(col.m_stats.visibleMax == -1.0); REQUIRE(col.m_stats.visibleMin == -1.0); REQUIRE(col.m_stats.visibleTotal == -1.0); col.updateStats(1.2f); REQUIRE(col.m_stats.max == Approx(1.2)); REQUIRE(col.m_stats.min == Approx(1.2)); REQUIRE(col.m_stats.total == Approx(1.2)); REQUIRE(col.m_stats.visibleMax == -1.0); REQUIRE(col.m_stats.visibleMin == -1.0); REQUIRE(col.m_stats.visibleTotal == -1.0); col.updateStats(2.0f); REQUIRE(col.m_stats.max == Approx(2.0)); REQUIRE(col.m_stats.min == Approx(1.2)); REQUIRE(col.m_stats.total == Approx(3.2)); REQUIRE(col.m_stats.visibleMax == -1.0); REQUIRE(col.m_stats.visibleMin == -1.0); REQUIRE(col.m_stats.visibleTotal == -1.0); col.updateStats(3.0f,1.2f); REQUIRE(col.m_stats.max == Approx(3.0)); REQUIRE(col.m_stats.min == Approx(1.2)); REQUIRE(col.m_stats.total == Approx(5)); REQUIRE(col.m_stats.visibleMax == -1.0); REQUIRE(col.m_stats.visibleMin == -1.0); REQUIRE(col.m_stats.visibleTotal == -1.0); // test read/write SelfCleaningFile scf("column.bin"); { std::ofstream outfile(scf.Filename()); col.write(outfile, 0); } AttributeColumnImpl copy(""); { std::ifstream infile(scf.Filename()); copy.read(infile); } REQUIRE(copy.getName() == "colName"); REQUIRE(copy.getFormula() == ""); REQUIRE(copy.isHidden()); REQUIRE(copy.isLocked()); REQUIRE(copy.m_stats.max == Approx(3.0)); REQUIRE(copy.m_stats.min == Approx(1.2)); REQUIRE(copy.m_stats.total == Approx(5)); REQUIRE(copy.m_stats.visibleMax == -1.0); REQUIRE(copy.m_stats.visibleMin == -1.0); REQUIRE(copy.m_stats.visibleTotal == -1.0); } TEST_CASE("test attribute row") { using namespace fakeit; Mock colMan; When(Method(colMan,getColumnIndex).Using(std::string("col1"))).AlwaysReturn(0); When(Method(colMan,getColumnIndex).Using(std::string("col2"))).AlwaysReturn(1); When(Method(colMan,getColumnIndex).Using(std::string("colx"))).AlwaysThrow(std::out_of_range("mock out of range")); When(Method(colMan,getNumColumns)).Return(2); Mock col1; Mock col2; When(Method(colMan, getColumn).Using(0)).AlwaysReturn(col1.get()); When(Method(colMan, getColumn).Using(1)).AlwaysReturn(col2.get()); When(Method(col1,updateStats)).AlwaysReturn(); When(Method(col2,updateStats)).AlwaysReturn(); AttributeRowImpl row(colMan.get()); row.setValue("col1", 1.2f); REQUIRE(row.getValue("col1") == Approx(1.2f)); REQUIRE(row.getValue(0) == Approx(1.2f)); row.setValue(1, 2.2f); REQUIRE(row.getValue("col2") == Approx(2.2f)); REQUIRE(row.getValue(1) == Approx(2.2f)); row.setValue(1, 3.2f); REQUIRE(row.getValue("col2") == Approx(3.2f)); REQUIRE(row.getValue(1) == Approx(3.2f)); Verify(Method(col1,updateStats).Using(1.2f,0.0f)).Once(); Verify(Method(col2,updateStats).Using(2.2f,0.0f)).Once(); Verify(Method(col2,updateStats).Using(3.2f,2.2f)).Once(); REQUIRE_THROWS_AS(row.setValue("colx", 1.1f), std::out_of_range); REQUIRE_THROWS_AS(row.setValue(2, 1.2f), std::out_of_range); REQUIRE_THROWS_AS(row.getValue("colx"), std::out_of_range); REQUIRE_THROWS_AS(row.getValue(2), std::out_of_range); // test attribute row impl only methods // note that these do not affect the column manager - that will have to // be handled by the caller - that's why these are impl only! row.addColumn(); REQUIRE(row.getValue(2) == -1.0f); row.removeColumn(1); REQUIRE(row.getValue(1) == -1.0f); REQUIRE(row.getValue(0) == Approx(1.2f)); REQUIRE_THROWS_AS(row.getValue(2), std::out_of_range); //test reading/writing SelfCleaningFile scf("rowfile.bin"); { std::ofstream outfile(scf.Filename()); row.write(outfile); } Mock copiedColMan; When(Method(copiedColMan,getNumColumns)).Return(2); AttributeRowImpl copiedRow(copiedColMan.get()); { std::ifstream infile(scf.Filename()); copiedRow.read(infile); } REQUIRE(copiedRow.getValue(0) == Approx(1.2f)); row.incrValue(0, 1.0f); REQUIRE(row.getValue(0) == Approx(2.2f)); Verify(Method(col1,updateStats).Using(2.2f,1.2f)).Once(); AttributeRow& ifRef = row; ifRef.incrValue(0); REQUIRE(row.getValue(0) == Approx(3.2f)); Verify(Method(col1,updateStats).Using(3.2f,2.2f)).Once(); } TEST_CASE("test attribute table") { AttributeTable table; table.insertOrResetColumn("col1"); table.getOrInsertColumn("col2"); table.insertOrResetLockedColumn("lcol1"); table.getOrInsertLockedColumn("lcol2", "formula"); REQUIRE(table.getNumColumns() == 4); REQUIRE(table.getColumnIndex("col2") == 1); REQUIRE(table.getColumnName(1) == "col2"); REQUIRE(table.getColumn(1).getName() == "col2"); REQUIRE(table.getColumn(1).isLocked() == false); REQUIRE(table.getColumn(3).getName() == "lcol2"); REQUIRE(table.getColumn(3).isLocked()); table.addRow(AttributeKey(0)); REQUIRE(table.getRow(AttributeKey(0)).getValue("col1") == -1 ); table.getRow(AttributeKey(0)).setValue("col1", 1.2f ); REQUIRE(table.getRow(AttributeKey(0)).getValue("col1") == Approx(1.2f) ); REQUIRE(table.getRow(AttributeKey(0)).getValue(0) == Approx(1.2f) ); REQUIRE(table.getRow(AttributeKey(0)).getValue("lcol2") == -1 ); table.getRow(AttributeKey(0)).setValue(3, 1.4f ); REQUIRE(table.getRow(AttributeKey(0)).getValue("lcol2") == Approx(1.4f) ); REQUIRE(table.getRow(AttributeKey(0)).getValue(3) == Approx(1.4f) ); REQUIRE_THROWS_AS(table.getRow(AttributeKey(0)).getValue(4), std::out_of_range); table.removeColumn(0); table.removeColumn(1); REQUIRE(table.getNumColumns() == 2); REQUIRE(table.getColumn(0).getName() == "col2"); REQUIRE(table.getColumn(1).getName() == "lcol2"); REQUIRE(table.getColumnIndex("lcol2") == 1); REQUIRE(table.getRow(AttributeKey(0)).getValue("col2") == -1.0 ); REQUIRE(table.getRow(AttributeKey(0)).getValue(0) == -1.0 ); REQUIRE(table.getRow(AttributeKey(0)).getValue("lcol2") == Approx(1.4f) ); REQUIRE(table.getRow(AttributeKey(0)).getValue(1) == Approx(1.4f) ); REQUIRE_THROWS_AS(table.getRow(AttributeKey(0)).getValue(2), std::out_of_range); table.addRow(AttributeKey(1)); REQUIRE_THROWS_AS(table.getRow(AttributeKey(1)).getValue(2), std::out_of_range); REQUIRE(table.getRow(AttributeKey(1)).getValue("col2") == -1.0 ); REQUIRE(table.getRow(AttributeKey(1)).getValue(0) == -1.0 ); REQUIRE(table.getRow(AttributeKey(1)).getValue("lcol2") == -1.0 ); REQUIRE(table.getRow(AttributeKey(1)).getValue(1) == -1.0 ); table.getRow(AttributeKey(1)).setValue(0, 2.4f); table.getRow(AttributeKey(1)).setValue("lcol2", 2.6f); REQUIRE(table.getRow(AttributeKey(1)).getValue("col2") == Approx(2.4) ); REQUIRE(table.getRow(AttributeKey(1)).getValue(1) == Approx(2.6) ); size_t idx = table.getOrInsertColumn("col2"); REQUIRE(idx == 0); REQUIRE(table.getRow(AttributeKey(1)).getValue("col2") == Approx(2.4) ); REQUIRE(table.getColumn(0).getStats().max == Approx(2.4)); idx = table.insertOrResetColumn("col2"); REQUIRE(idx == 0); REQUIRE(table.getRow(AttributeKey(1)).getValue("col2") == -1.0 ); REQUIRE(table.getColumn(0).getStats().max == -1.0); size_t newColIndex = table.getOrInsertColumn("newCol"); REQUIRE(newColIndex == 2); REQUIRE(table.getColumnName(2) == "newCol"); REQUIRE(table.getColumnIndex("newCol") == 2); REQUIRE(table.getColumn(2).getName() == "newCol"); REQUIRE(table.getRow(AttributeKey(0)).getValue(2) == -1.0); table.renameColumn("col2", "col_foo"); REQUIRE(table.getColumnName(0) == "col_foo"); REQUIRE(table.getColumnIndex("col_foo") == 0); REQUIRE(table.getColumn(0).getName() == "col_foo"); REQUIRE_THROWS_AS(table.getColumnIndex("col2"), std::out_of_range); table.getRow(AttributeKey(0)).setSelection(true); REQUIRE(table.getRow(AttributeKey(0)).isSelected()); auto iter = table.begin(); REQUIRE(iter->getRow().isSelected()); ++iter; REQUIRE_FALSE(iter->getRow().isSelected()); table.deselectAllRows(); for (auto& item : table) { REQUIRE_FALSE(item.getRow().isSelected()); } // check read/write LayerManagerImpl layerManager; SelfCleaningFile scf("tablefile.bin"); { std::ofstream outfile(scf.Filename()); table.write(outfile, layerManager); } } TEST_CASE("Existing and non-existing rows") { AttributeTable table; table.getOrInsertColumn("col1"); table.getOrInsertColumn("col2"); table.addRow(AttributeKey(0)).setValue(0, 1.0f); table.addRow(AttributeKey(1)).setValue(0, 0.5f); table.addRow(AttributeKey(2)).setValue(0, 2.0f); const AttributeTable& constRef = table; table.getRow(AttributeKey(0)); constRef.getRow(AttributeKey(0)); REQUIRE_THROWS_AS(table.getRow(AttributeKey(5)), std::out_of_range); REQUIRE_THROWS_AS(constRef.getRow(AttributeKey(5)), std::out_of_range); REQUIRE( table.getRowPtr(AttributeKey(1)) != 0); REQUIRE( constRef.getRowPtr(AttributeKey(1)) != 0); REQUIRE( table.getRowPtr(AttributeKey(5)) == 0); REQUIRE( constRef.getRowPtr(AttributeKey(5)) == 0); } TEST_CASE("normalised values"){ AttributeTable table; table.getOrInsertColumn("col1"); table.getOrInsertColumn("col2"); table.addRow(AttributeKey(0)).setValue(0, 1.0f); table.addRow(AttributeKey(1)).setValue(0, 0.5f); table.addRow(AttributeKey(2)).setValue(0, 2.0f); REQUIRE(table.getRow(AttributeKey(0)).getNormalisedValue(1) == Approx(0.5f)); REQUIRE(table.getRow(AttributeKey(0)).getNormalisedValue(0) == Approx(0.33333f)); REQUIRE(table.getRow(AttributeKey(1)).getNormalisedValue(0) == Approx(0.0f)); REQUIRE(table.getRow(AttributeKey(2)).getNormalisedValue(0) == Approx(1.0f)); table.addRow(AttributeKey(3)).setValue(1,1.0f); REQUIRE(table.getRow(AttributeKey(1)).getNormalisedValue(1) == Approx(0.5f)); REQUIRE(table.getRow(AttributeKey(3)).getNormalisedValue(1) == Approx(0.5f)); table.getRow(AttributeKey(0)).setValue(1,1.1f); REQUIRE(table.getRow(AttributeKey(3)).getNormalisedValue(1) == Approx(0.0f)); REQUIRE(table.getRow(AttributeKey(1)).getNormalisedValue(1) == Approx(-1.0f)); } TEST_CASE("attibute table iterations") { AttributeTable table; table.insertOrResetColumn("col1"); table.getOrInsertColumn("col2"); auto& row = table.addRow(AttributeKey(0)); row.setValue(0, 0.5f); auto& row2 = table.addRow(AttributeKey(1)); row2.setValue(0, 1.0f); AttributeTable::iterator iter = table.begin(); REQUIRE((*iter).getKey().value == 0); REQUIRE(iter->getRow().getValue(0) == Approx(0.5)); iter++; REQUIRE((*iter).getKey().value == 1); REQUIRE(iter->getRow().getValue(0) == Approx(1.0)); iter++; REQUIRE(iter == table.end()); for( auto& item : table) { item.getRow().setValue(1, 2.0f); } REQUIRE(table.getRow(AttributeKey(0)).getValue(1) == Approx(2.0)); REQUIRE(table.getRow(AttributeKey(1)).getValue(1) == Approx(2.0)); const AttributeTable& const_table = table; auto citer = const_table.begin(); REQUIRE((*citer).getKey().value == 0); REQUIRE(citer->getRow().getValue(0) == Approx(0.5)); citer++; REQUIRE((*citer).getKey().value == 1); REQUIRE(citer->getRow().getValue(0) == Approx(1.0)); citer++; auto cend = const_table.end(); REQUIRE(citer == cend); REQUIRE(citer == table.end()); AttributeTable::iterator foo(iter); AttributeTable::const_iterator cfoo(iter); AttributeTable::const_iterator ccfoo(citer); REQUIRE(iter == foo); REQUIRE(cfoo == iter); REQUIRE(ccfoo == iter); cfoo = table.end(); foo = table.begin(); cfoo = foo; foo->getRow().setValue(1,2.2f); ++foo; foo->getRow().setValue(1, 3.2f); REQUIRE(table.getRow(AttributeKey(0)).getValue(1) == Approx(2.2)); REQUIRE(table.getRow(AttributeKey(1)).getValue(1) == Approx(3.2)); } #include TEST_CASE("Attribute Table - serialisation") { LayerManagerImpl layerManager; layerManager.addLayer("extra layer"); REQUIRE(layerManager.getLayerIndex("extra layer") == 1); AttributeTable newTable; size_t colIndex1 = newTable.getOrInsertColumn("foo", "foo formula"); size_t colIndex2 = newTable.getOrInsertColumn("bar"); DisplayParams overAllDp; overAllDp.blue = 1.2f; overAllDp.red = 1.3f; DisplayParams fooDp; fooDp.blue = 2.2f; fooDp.red = 2.3f; DisplayParams barDp; newTable.getColumn(colIndex1).setDisplayParams(fooDp); newTable.getColumn(colIndex2).setDisplayParams(barDp); newTable.setDisplayParams(overAllDp); auto& row = newTable.addRow(AttributeKey(0)); auto& row2 = newTable.addRow(AttributeKey(10)); row.setValue(0,1.0f); row.setValue(1,2.0f); row2.setValue(0, 11.0f); row2.setValue(1, 12.0f); row2.setSelection(true); dXreimpl::pushSelectionToLayer(newTable, layerManager, "sel layer"); REQUIRE(isObjectVisible(layerManager, row2)); REQUIRE_FALSE(isObjectVisible(layerManager, row)); SelfCleaningFile newTableFile("newtable.bin"); { std::ofstream outfile(newTableFile.Filename()); newTable.write(outfile, layerManager); } AttributeTable copyTable; LayerManagerImpl copyLayerManager; { std::ifstream infile(newTableFile.Filename()); copyTable.read(infile, copyLayerManager); } auto& copyRow = copyTable.getRow(AttributeKey(0)); REQUIRE(copyRow.getValue(0) == Approx(1.0f)); REQUIRE(copyRow.getValue(1) == Approx(2.0f)); auto& copyRow2 = copyTable.getRow(AttributeKey(10)); REQUIRE(copyRow2.getValue(0) == Approx(11.0f)); REQUIRE(copyRow2.getValue(1) == Approx(12.0f)); REQUIRE(isObjectVisible(copyLayerManager, copyRow2)); REQUIRE_FALSE(isObjectVisible(copyLayerManager, copyRow)); REQUIRE(copyTable.getColumnIndex("foo") == colIndex1); REQUIRE(copyTable.getColumnIndex("bar") == colIndex2); REQUIRE(copyTable.getColumn(colIndex1).getDisplayParams().blue == Approx(fooDp.blue)); REQUIRE(copyTable.getDisplayParams().blue == Approx(overAllDp.blue)); } ================================================ FILE: salaTest/testattributetablehelpers.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include TEST_CASE("push to layer") { using namespace dXreimpl; using namespace fakeit; Mock layMan; AttributeTable table; When(Method(layMan,addLayer)).Do([](const std::string &name)->size_t{REQUIRE(name == "testlayer"); return 1;}); When(Method(layMan,getKey).Using(1)).AlwaysReturn(2); When(Method(layMan,isVisible).Using(1)).AlwaysReturn(true); When(Method(layMan,setLayerVisible)).AlwaysReturn(); table.insertOrResetColumn("col1"); table.getOrInsertColumn("col2"); auto& row = table.addRow(AttributeKey(0)); row.setValue(0, 0.5f); row.setSelection(true); auto& row2 = table.addRow(AttributeKey(1)); row2.setValue(0, 1.0f); pushSelectionToLayer(table, layMan.get(), "testlayer"); Verify(Method(layMan,addLayer)).Once(); Verify(Method(layMan,getKey).Using(1)).Once(); Verify(Method(layMan,setLayerVisible).Using(1, true)).Once(); REQUIRE(row.getLayerKey()== 3); REQUIRE(row2.getLayerKey() == 1); } ================================================ FILE: salaTest/testattributetableindex.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include TEST_CASE("Check index creation") { AttributeTable table; table.getOrInsertColumn("col1"); table.getOrInsertColumn("col2"); auto& row0 = table.addRow(AttributeKey(0)); auto& row1 = table.addRow(AttributeKey(1)); auto& row2 = table.addRow(AttributeKey(2)); auto& row3 = table.addRow(AttributeKey(3)); row0.setValue(0, 10.0); row1.setValue(0, 8.5); row2.setValue(0, 11.0); row3.setValue(0, 4.5); auto index = makeAttributeIndex(table, 0); REQUIRE(index.size() == 4); REQUIRE(index[0].key.value == 3); REQUIRE(index[1].key.value == 1); REQUIRE(index[2].key.value == 0); REQUIRE(index[3].key.value == 2); index[3].mutable_row->setValue(1, 1.5); REQUIRE(table.getRow(AttributeKey(2)).getValue(1) == Approx(1.5)); } ================================================ FILE: salaTest/testattributetableview.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include TEST_CASE("Test Attribute view"){ AttributeTable table; table.insertOrResetColumn("foo"); table.insertOrResetColumn("bar"); table.addRow(AttributeKey(0)).setValue(0,1.0f).setValue(1, 1.1f); table.addRow(AttributeKey(7)).setValue(0,0.7f).setValue(1,1.7f); AttributeTableView view(table); view.setDisplayColIndex(0); REQUIRE(view.getConstTableIndex().front().key.value == 7); REQUIRE(view.getNormalisedValue(view.getConstTableIndex().front().key, *view.getConstTableIndex().front().row) == Approx(0.0f)); REQUIRE(&view.getDisplayParams() != &table.getDisplayParams()); REQUIRE(&view.getDisplayParams() == &table.getColumn(0).getDisplayParams()); table.addRow(AttributeKey(3)); view.setDisplayColIndex(-1); REQUIRE(view.getNormalisedValue(AttributeKey(3), table.getRow(AttributeKey(3))) == Approx(3.0/7)); REQUIRE(view.getConstTableIndex().size() == 3); REQUIRE(&table.getDisplayParams() == &view.getDisplayParams()); view.setDisplayColIndex(-2); REQUIRE(view.getNormalisedValue(AttributeKey(3), table.getRow(AttributeKey(3))) == Approx(3.0/7)); REQUIRE(view.getConstTableIndex().empty()); REQUIRE(&table.getDisplayParams() == &view.getDisplayParams()); } TEST_CASE("Test attribute table handle") { AttributeTable table; table.insertOrResetColumn("foo"); table.insertOrResetColumn("bar"); table.addRow(AttributeKey(0)).setValue(0,1.0f).setValue(1, 1.1f); table.addRow(AttributeKey(7)).setValue(0,0.7f).setValue(1,1.7f); AttributeTableHandle handle(table); handle.setDisplayColIndex(0); REQUIRE(handle.getTableIndex().front().key.value == 7); REQUIRE(handle.getConstTableIndex().front().key.value == 7); handle.getTableIndex().front().mutable_row->setValue(0, 0.8f); REQUIRE(table.getRow(AttributeKey(7)).getValue(0) == Approx(0.8)); handle.setDisplayColIndex(-1); REQUIRE(handle.getTableIndex().size() == 2); REQUIRE(&table.getDisplayParams() == &handle.getDisplayParams()); handle.setDisplayColIndex(-2); REQUIRE(handle.getTableIndex().empty()); REQUIRE(&table.getDisplayParams() == &handle.getDisplayParams()); } ================================================ FILE: salaTest/testdxfp.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/parsers/dxfp.h" #include "genlib/comm.h" #include "genlib/p2dpoly.h" TEST_CASE("DXF Parsing (lines)") { const float EPSILON = 0.001f; Point2f lineStart(-1,-2); Point2f lineEnd(3,4); std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nLINE\n" << "8\n"<< layer << "\n" << "10\n" << lineStart.x << "\n" << "20\n" << lineStart.y << "\n" << "30\n0\n" << "11\n" << lineEnd.x << "\n" << "21\n" << lineEnd.y << "\n" << "31\n0\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numLines() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().x == Approx(lineStart.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().y == Approx(lineStart.y).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().x == Approx(lineEnd.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().y == Approx(lineEnd.y).epsilon(EPSILON)); } TEST_CASE("DXF Parsing (arcs)") { const float EPSILON = 0.001f; Point2f centre(1,-2); float radius = 3; float startAngle = 45; float endAngle = 67; std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nARC\n" << "8\n"<< layer << "\n" << "10\n" << centre.x << "\n" << "20\n" << centre.y << "\n" << "30\n0\n" << "40\n" << radius << "\n" << "50\n" << startAngle << "\n" << "51\n" << endAngle << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numArcs() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getArc(0).getCentre().x == Approx(centre.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getArc(0).getCentre().y == Approx(centre.y).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getArc(0).getRadius() == Approx(radius).epsilon(EPSILON)); // arc start angle not publicly accessible // arc end angle not publicly accessible } TEST_CASE("DXF Parsing (circles)") { const float EPSILON = 0.001f; Point2f centre(1,-2); float radius = 3; std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nCIRCLE\n" << "8\n"<< layer << "\n" << "10\n" << centre.x << "\n" << "20\n" << centre.y << "\n" << "30\n0\n" << "40\n" << radius << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numCircles() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getCircle(0).getCentre().x == Approx(centre.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getCircle(0).getCentre().y == Approx(centre.y).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getCircle(0).getRadius() == Approx(radius).epsilon(EPSILON)); } TEST_CASE("DXF Parsing (points)") { const float EPSILON = 0.001f; Point2f point(1,-2); std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nPOINT\n" << "8\n"<< layer << "\n" << "10\n" << point.x << "\n" << "20\n" << point.y << "\n" << "30\n0\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numPoints() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getPoint(0).x == Approx(point.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getPoint(0).y == Approx(point.y).epsilon(EPSILON)); } TEST_CASE("DXF Parsing (lwpolyline)") { const float EPSILON = 0.001f; Point2f point1(-1,-2); Point2f point2(3,4); Point2f point3(-5,6); Point2f point4(7,-8); std::string layer("0"); int closed = 0; SECTION ("open polyline") { closed = 0; } SECTION ("closed polyline") { closed = 1; } std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nLWPOLYLINE\n" << "8\n"<< layer << "\n" << "10\n" << point1.x << "\n" << "20\n" << point1.y << "\n" << "30\n0\n" << "10\n" << point2.x << "\n" << "20\n" << point2.y << "\n" << "30\n0\n" << "10\n" << point3.x << "\n" << "20\n" << point3.y << "\n" << "30\n0\n" << "10\n" << point4.x << "\n" << "20\n" << point4.y << "\n" << "30\n0\n" << "70\n" << closed << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numPolyLines() == 1); DxfPolyLine polyline = dxfParser.getLayer(layer.c_str())->getPolyLine(0); REQUIRE(polyline.numVertices() == 4); REQUIRE(polyline.getVertex(0).x == Approx(point1.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(0).y == Approx(point1.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).x == Approx(point2.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).y == Approx(point2.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(2).x == Approx(point3.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(2).y == Approx(point3.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(3).x == Approx(point4.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(3).y == Approx(point4.y).epsilon(EPSILON)); REQUIRE((polyline.getAttributes() & polyline.CLOSED) == closed); } TEST_CASE("DXF Parsing (polyline)") { const float EPSILON = 0.001f; Point2f point1(-1,-2); Point2f point2(3,4); Point2f point3(-5,6); Point2f point4(7,-8); std::string layer("0"); int closed = 0; SECTION ("open polyline") { closed = 0; } SECTION ("closed polyline") { closed = 1; } std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nPOLYLINE\n" << "8\n"<< layer << "\n" << "70\n" << closed << "\n" << "0\nVERTEX\n" << "10\n" << point1.x << "\n" << "20\n" << point1.y << "\n" << "30\n0\n" << "0\nVERTEX\n" << "10\n" << point2.x << "\n" << "20\n" << point2.y << "\n" << "30\n0\n" << "0\nVERTEX\n" << "10\n" << point3.x << "\n" << "20\n" << point3.y << "\n" << "30\n0\n" << "0\nVERTEX\n" << "10\n" << point4.x << "\n" << "20\n" << point4.y << "\n" << "30\n0\n" << "0\nSEQEND\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numPolyLines() == 1); DxfPolyLine polyline = dxfParser.getLayer(layer.c_str())->getPolyLine(0); REQUIRE(polyline.numVertices() == 4); REQUIRE(polyline.getVertex(0).x == Approx(point1.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(0).y == Approx(point1.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).x == Approx(point2.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).y == Approx(point2.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(2).x == Approx(point3.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(2).y == Approx(point3.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(3).x == Approx(point4.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(3).y == Approx(point4.y).epsilon(EPSILON)); REQUIRE((polyline.getAttributes() & polyline.CLOSED) == closed); } TEST_CASE("DXF Parsing (spline)") { const float EPSILON = 0.001f; std::vector weights = { 0.0, 0.0, 0.0, 0.0, 2.72, 5.15, 6.93, 6.93, 6.93, 6.93}; std::vector controlPoints = { Point2f(32.80, 27.09), Point2f(31.58, 26.71), Point2f(29.28, 25.98), Point2f(30.69, 30.55), Point2f(31.35, 28.67), Point2f(31.64, 27.87) }; std::vector fitPoints = { Point2f(32.80, 27.09), Point2f(30.08, 27.09), Point2f(30.75, 29.42), Point2f(31.64, 27.87), }; std::string layer("0"); int closed = 0; SECTION ("open spline") { closed = 0; } SECTION ("closed spline") { closed = 1; } std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nSPLINE\n" << "8\n"<< layer << "\n" << "70\n"<< closed << "\n" << "72\n"<< (controlPoints.size() + fitPoints.size()) << "\n" << "73\n"<< controlPoints.size() << "\n"; std::vector::iterator weightsIter = weights.begin(), weightsEnd = weights.end(); for ( ; weightsIter != weightsEnd; ++weightsIter ) { stream << "40\n" << *weightsIter << "\n"; } std::vector::iterator cPointsIter = controlPoints.begin(), cPointsEnd = controlPoints.end(); for ( ; cPointsIter != cPointsEnd; ++cPointsIter ) { Point2f point = *cPointsIter; stream << "10\n" << point.x << "\n" << "20\n" << point.y << "\n" << "30\n0\n"; } std::vector::iterator fPointsIter = fitPoints.begin(), fPointsEnd = fitPoints.end(); for ( ; fPointsIter != fPointsEnd; ++fPointsIter ) { Point2f point = *fPointsIter; stream << "11\n" << point.x << "\n" << "21\n" << point.y << "\n" << "31\n0\n"; } stream << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numSplines() == 1); DxfSpline spline = dxfParser.getLayer(layer.c_str())->getSpline(0); REQUIRE(spline.numVertices() == controlPoints.size()); for (size_t i = 0; i < controlPoints.size(); i++) { REQUIRE(spline.getVertex(i).x == Approx(controlPoints[i].x).epsilon(EPSILON)); REQUIRE(spline.getVertex(i).y == Approx(controlPoints[i].y).epsilon(EPSILON)); } REQUIRE((spline.getAttributes() & spline.CLOSED) == closed); } TEST_CASE("DXF Parsing (zero-length line)") { // parser skips zero-length lines const float EPSILON = 0.001f; Point2f lineStart(1,2); Point2f lineEnd(1,2); std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nLINE\n" << "8\n"<< layer << "\n" << "10\n" << lineStart.x << "\n" << "20\n" << lineStart.y << "\n" << "30\n0\n" << "11\n" << lineEnd.x << "\n" << "21\n" << lineEnd.y << "\n" << "31\n0\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numLines() == 0); } TEST_CASE("DXF Parsing (zero-length lwpolyline)") { // parser does not skip zero-length polylines const float EPSILON = 0.001f; Point2f point1(1,2); Point2f point2(1,2); std::string layer("0"); int closed = 0; std::stringstream stream; stream << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nLWPOLYLINE\n" << "8\n"<< layer << "\n" << "10\n" << point1.x << "\n" << "20\n" << point1.y << "\n" << "30\n0\n" << "10\n" << point2.x << "\n" << "20\n" << point2.y << "\n" << "30\n0\n" << "70\n" << closed << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numPolyLines() == 1); DxfPolyLine polyline = dxfParser.getLayer(layer.c_str())->getPolyLine(0); REQUIRE(polyline.numVertices() == 2); REQUIRE(polyline.getVertex(0).x == Approx(point1.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(0).y == Approx(point1.y).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).x == Approx(point2.x).epsilon(EPSILON)); REQUIRE(polyline.getVertex(1).y == Approx(point2.y).epsilon(EPSILON)); REQUIRE((polyline.getAttributes() & polyline.CLOSED) == closed); } TEST_CASE("DXF Parsing (block)") { const float EPSILON = 0.001f; Point2f lineStart(-1,-2); Point2f lineEnd(3,4); std::string block("bl"); Point2f blockTranslation(5, -6); Point2f blockScale(1, 1); double blockRotation = 0; std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nBLOCKS\n" << "0\nBLOCK\n" << "2\n" << block << "\n" << "8\n" << layer << "\n" << "0\nLINE\n" << "8\n" << layer << "\n" << "10\n" << lineStart.x << "\n" << "20\n" << lineStart.y << "\n" << "30\n0\n" << "11\n" << lineEnd.x << "\n" << "21\n" << lineEnd.y << "\n" << "31\n0\n" << "0\nENDBLK\n" << "0\nENDSEC\n" << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nINSERT\n" << "8\n" << layer << "\n" << "2\n" << block << "\n" << "10\n" << blockTranslation.x << "\n" << "20\n" << blockTranslation.y << "\n" << "30\n" << 0 << "\n" << "41\n" << blockScale.x << "\n" << "42\n" << blockScale.y << "\n" << "43\n" << 0 << "\n" << "50\n" << blockRotation << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numLines() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().x == Approx(lineStart.x + blockTranslation.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().y == Approx(lineStart.y + blockTranslation.y).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().x == Approx(lineEnd.x + blockTranslation.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().y == Approx(lineEnd.y + blockTranslation.y).epsilon(EPSILON)); } TEST_CASE("DXF Parsing (deeper blocks)") { const float EPSILON = 0.001f; Point2f lineStart(-1,-2); Point2f lineEnd(3,4); std::string block("bl"); std::string blockInternal("bli"); Point2f blockTranslation(5, -6); Point2f blockScale(1, 1); double blockRotation = 0; std::string layer("0"); std::stringstream stream; stream << "0\nSECTION\n" << "2\nBLOCKS\n" << "0\nBLOCK\n" << "2\n" << block << "\n" << "8\n" << layer << "\n" << "0\nINSERT\n" << "8\n" << layer << "\n" << "2\n" << blockInternal << "\n" << "10\n" << blockTranslation.x << "\n" << "20\n" << blockTranslation.y << "\n" << "30\n" << 0 << "\n" << "41\n" << blockScale.x << "\n" << "42\n" << blockScale.y << "\n" << "43\n" << 0 << "\n" << "50\n" << blockRotation << "\n" << "0\nENDBLK\n" << "0\nBLOCK\n" << "2\n" << blockInternal << "\n" << "8\n" << layer << "\n" << "0\nLINE\n" << "8\n" << layer << "\n" << "10\n" << lineStart.x << "\n" << "20\n" << lineStart.y << "\n" << "30\n0\n" << "11\n" << lineEnd.x << "\n" << "21\n" << lineEnd.y << "\n" << "31\n0\n" << "0\nENDBLK\n" << "0\nENDSEC\n" << "0\nSECTION\n" << "2\nENTITIES\n" << "0\nINSERT\n" << "8\n" << layer << "\n" << "2\n" << block << "\n" << "10\n" << blockTranslation.x << "\n" << "20\n" << blockTranslation.y << "\n" << "30\n" << 0 << "\n" << "41\n" << blockScale.x << "\n" << "42\n" << blockScale.y << "\n" << "43\n" << 0 << "\n" << "50\n" << blockRotation << "\n" << "0\nENDSEC\n" << "0\nEOF\n"; DxfParser dxfParser; dxfParser.open(stream); REQUIRE(dxfParser.numLayers() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->numLines() == 1); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().x == Approx(lineStart.x + 2*blockTranslation.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getStart().y == Approx(lineStart.y + 2*blockTranslation.y).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().x == Approx(lineEnd.x + 2*blockTranslation.x).epsilon(EPSILON)); REQUIRE(dxfParser.getLayer(layer.c_str())->getLine(0).getEnd().y == Approx(lineEnd.y + 2*blockTranslation.y).epsilon(EPSILON)); } ================================================ FILE: salaTest/testentityparsing.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros, Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/entityparsing.h" #include "genlib/p2dpoly.h" #include #include TEST_CASE("Failing line parser", "") { const float EPSILON = 0.001; { // header only has 3 elements std::stringstream stream; stream << "x1,y1,x2" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parseLines(stream,','), Catch::Contains("Badly formatted header (should contain x1, y1, x2 and y2)")); } { // header has y1 twice instead of y2 std::stringstream stream; stream << "x1,y1,x2,y1" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parseLines(stream,','), Catch::Contains("Badly formatted header (should contain x1, y1, x2 and y2)")); } { // error parsing line std::stringstream stream; stream << "x1,y1,x2,y2" << std::endl; stream << "1.2,3.4,5.6" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parseLines(stream,','), Catch::Contains("Error parsing line")); } } TEST_CASE("Successful line parser", "") { const float EPSILON = 0.001; { std::stringstream stream; stream << "x1,y1,x2,y2" << std::endl; stream << "1.2,3.4,5.6,7.8" << std::endl; std::vector lines = EntityParsing::parseLines(stream,','); REQUIRE(lines.size() == 1); REQUIRE(lines[0].start().x == Approx(1.2).epsilon(EPSILON)); REQUIRE(lines[0].start().y == Approx(3.4).epsilon(EPSILON)); REQUIRE(lines[0].end().x == Approx(5.6).epsilon(EPSILON)); REQUIRE(lines[0].end().y == Approx(7.8).epsilon(EPSILON)); } { std::stringstream stream; stream << "x1\ty1\tx2\ty2" << std::endl; stream << "1.2\t3.4\t5.6\t7.8" << std::endl; std::vector lines = EntityParsing::parseLines(stream,'\t'); REQUIRE(lines.size() == 1); REQUIRE(lines[0].start().x == Approx(1.2).epsilon(EPSILON)); REQUIRE(lines[0].start().y == Approx(3.4).epsilon(EPSILON)); REQUIRE(lines[0].end().x == Approx(5.6).epsilon(EPSILON)); REQUIRE(lines[0].end().y == Approx(7.8).epsilon(EPSILON)); } { std::stringstream stream; stream << "x1\ty1\tx2\ty2" << std::endl; stream << "1.2\t3.4\t5.6\t7.8" << std::endl; stream << "0.1\t0.2\t0.3\t0.4" << std::endl; std::vector lines = EntityParsing::parseLines(stream,'\t'); REQUIRE(lines.size() == 2); REQUIRE(lines[0].start().x == Approx(1.2).epsilon(EPSILON)); REQUIRE(lines[0].start().y == Approx(3.4).epsilon(EPSILON)); REQUIRE(lines[0].end().x == Approx(5.6).epsilon(EPSILON)); REQUIRE(lines[0].end().y == Approx(7.8).epsilon(EPSILON)); REQUIRE(lines[1].start().x == Approx(0.1).epsilon(EPSILON)); REQUIRE(lines[1].start().y == Approx(0.2).epsilon(EPSILON)); REQUIRE(lines[1].end().x == Approx(0.3).epsilon(EPSILON)); REQUIRE(lines[1].end().y == Approx(0.4).epsilon(EPSILON)); } } TEST_CASE("Failing point parser", "") { const float EPSILON = 0.001; { // header only has 3 elements std::stringstream stream; stream << "x" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parsePoints(stream,','), Catch::Contains("Badly formatted header (should contain x and y)")); } { // header has y1 twice instead of y2 std::stringstream stream; stream << "x,x" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parsePoints(stream,','), Catch::Contains("Badly formatted header (should contain x and y)")); } { // error parsing line std::stringstream stream; stream << "x,y" << std::endl; stream << "1.2" << std::endl; REQUIRE_THROWS_WITH(EntityParsing::parsePoints(stream,','), Catch::Contains("Error parsing line")); } } TEST_CASE("Successful point parser", "") { const float EPSILON = 0.001; { std::stringstream stream; stream << "x,y" << std::endl; stream << "1.2,3.4" << std::endl; std::vector points = EntityParsing::parsePoints(stream,','); REQUIRE(points.size() == 1); REQUIRE(points[0].x == Approx(1.2).epsilon(EPSILON)); REQUIRE(points[0].y == Approx(3.4).epsilon(EPSILON)); } { std::stringstream stream; stream << "x\ty" << std::endl; stream << "1.2\t3.4" << std::endl; std::vector points = EntityParsing::parsePoints(stream,'\t'); REQUIRE(points.size() == 1); REQUIRE(points[0].x == Approx(1.2).epsilon(EPSILON)); REQUIRE(points[0].y == Approx(3.4).epsilon(EPSILON)); } { std::stringstream stream; stream << "x\ty" << std::endl; stream << "1.2\t3.4" << std::endl; stream << "0.1\t0.2" << std::endl; std::vector points = EntityParsing::parsePoints(stream,'\t'); REQUIRE(points.size() == 2); REQUIRE(points[0].x == Approx(1.2).epsilon(EPSILON)); REQUIRE(points[0].y == Approx(3.4).epsilon(EPSILON)); REQUIRE(points[1].x == Approx(0.1).epsilon(EPSILON)); REQUIRE(points[1].y == Approx(0.2).epsilon(EPSILON)); } } TEST_CASE("Test point parsing") { REQUIRE_THROWS_WITH(EntityParsing::parsePoint("foo", '|'), Catch::Contains("Badly formatted point data, should be |, was foo" )); auto point = EntityParsing::parsePoint("1.235|27.25", '|'); REQUIRE(point.x == Approx(1.235)); REQUIRE(point.y == Approx(27.25)); point = EntityParsing::parsePoint("1.235|bar", '|'); REQUIRE(point.x == Approx(1.235)); REQUIRE(point.y == 0.0); } TEST_CASE("Successful Isovist parser") { const float EPSILON = 0.0001; { std::stringstream stream; stream << "x,y\n1.0,2.34\n0.5,9.2\n" << std::flush; auto result = EntityParsing::parseIsovists(stream, ','); REQUIRE(result.size() == 2); REQUIRE(result[0].getLocation().x == Approx(1.0).epsilon(EPSILON)); REQUIRE(result[0].getLocation().y == Approx(2.34).epsilon(EPSILON)); REQUIRE(result[0].getAngle() == Approx(0.0).epsilon(EPSILON)); REQUIRE(result[0].getViewAngle() == 0.0); REQUIRE(result[1].getLocation().x == Approx(0.5).epsilon(EPSILON)); REQUIRE(result[1].getLocation().y == Approx(9.2).epsilon(EPSILON)); REQUIRE(result[1].getAngle() == Approx(0.0).epsilon(EPSILON)); REQUIRE(result[1].getViewAngle() == 0.0); } { std::stringstream stream; stream << "x,y,angle,viewAngle\n1.0,2.34,90,90\n0.5,9.2,180,270\n" << std::flush; auto result = EntityParsing::parseIsovists(stream, ','); REQUIRE(result.size() == 2); REQUIRE(result[0].getLocation().x == Approx(1.0).epsilon(EPSILON)); REQUIRE(result[0].getLocation().y == Approx(2.34).epsilon(EPSILON)); REQUIRE(result[0].getAngle() == Approx(M_PI/2.0).epsilon(EPSILON)); REQUIRE(result[0].getViewAngle() == Approx(M_PI/2.0).epsilon(EPSILON)); REQUIRE(result[1].getLocation().x == Approx(0.5).epsilon(EPSILON)); REQUIRE(result[1].getLocation().y == Approx(9.2).epsilon(EPSILON)); REQUIRE(result[1].getAngle() == Approx(M_PI).epsilon(EPSILON)); REQUIRE(result[1].getViewAngle() == Approx(M_PI*1.5).epsilon(EPSILON)); } } TEST_CASE("Failing Isovist parser") { { std::stringstream stream; stream << "x,angle,viewAngle\n" << std::flush; REQUIRE_THROWS_WITH(EntityParsing::parseIsovists(stream, ','), Catch::Contains("Badly formatted header (should contain x and y, might also have angle and viewangle for partial isovists)")); } { std::stringstream stream; stream << "x,y,angle,viewAngle\n1.0,1.0,270" << std::flush; REQUIRE_THROWS_WITH(EntityParsing::parseIsovists(stream, ','), Catch::Contains("Error parsing line: 1.0,1.0,270")); } } TEST_CASE("Parsing single isovist") { SECTION("Success full") { auto result = EntityParsing::parseIsovist("1,1"); REQUIRE(result.getLocation().x == Approx(1.0)); REQUIRE(result.getLocation().y == Approx(1.0)); REQUIRE(result.getAngle() == 0.0); REQUIRE(result.getViewAngle() == 0.0); } SECTION("Success partial isovist") { auto result = EntityParsing::parseIsovist("1,1,27,90"); REQUIRE(result.getLocation().x == Approx(1.0)); REQUIRE(result.getLocation().y == Approx(1.0)); REQUIRE(result.getAngle() == Approx(0.4712388)); REQUIRE(result.getViewAngle() == Approx(M_PI/2.0)); } SECTION("Failed bad string") { REQUIRE_THROWS_WITH(EntityParsing::parseIsovist("1,1,27"), Catch::Contains("Failed to parse '1,1,27' to an isovist definition")); } } ================================================ FILE: salaTest/testgeometrygenerators.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros, Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/geometrygenerators.h" #include "genlib/p2dpoly.h" TEST_CASE("Test disk triangles generation", "") { const float EPSILON = 0.001; int sides = 8; float radius = 2; std::vector expected { Point2f(0,0), Point2f(1.41421,1.41421), Point2f(0,2), Point2f(0,0), Point2f(2,0), Point2f(1.41421,1.41421), Point2f(0,0), Point2f(1.41421,-1.41421), Point2f(2,0), Point2f(0,0), Point2f(0,-2), Point2f(1.41421,-1.41421), Point2f(0,0), Point2f(-1.41421,-1.41421), Point2f(0,-2), Point2f(0,0), Point2f(-2,0), Point2f(-1.41421,-1.41421), Point2f(0,0), Point2f(-1.41421,1.41421), Point2f(-2,0), Point2f(0,0), Point2f(0,2), Point2f(-1.41421,1.41421) }; std::vector diskTriangles = GeometryGenerators::generateDiskTriangles(sides, radius); REQUIRE(diskTriangles.size() == expected.size()); for(size_t i = 0; i < diskTriangles.size(); i++) { REQUIRE(diskTriangles[i].x == Approx(expected[i].x).epsilon(EPSILON)); REQUIRE(diskTriangles[i].y == Approx(expected[i].y).epsilon(EPSILON)); } std::vector offsets { Point2f(1,2), Point2f(3, -4), Point2f(-5, -6), Point2f(-7, 8) }; std::vector multiDiskTriangles = GeometryGenerators::generateMultipleDiskTriangles(sides, radius, offsets); REQUIRE(multiDiskTriangles.size() == expected.size()*offsets.size()); for(size_t i = 0; i < multiDiskTriangles.size(); i++) { REQUIRE(multiDiskTriangles[i].x == Approx(expected[i%(sides*3)].x + offsets[i/(sides*3)].x).epsilon(EPSILON)); REQUIRE(multiDiskTriangles[i].y == Approx(expected[i%(sides*3)].y + offsets[i/(sides*3)].y).epsilon(EPSILON)); } } TEST_CASE("Test circle perimeter line generation", "") { const float EPSILON = 0.001; int sides = 8; float radius = 2; std::vector expected { SimpleLine(Point2f(1.41421,1.41421), Point2f(0,2)), SimpleLine(Point2f(2,0), Point2f(1.41421,1.41421)), SimpleLine(Point2f(1.41421,-1.41421), Point2f(2,0)), SimpleLine(Point2f(0,-2), Point2f(1.41421,-1.41421)), SimpleLine(Point2f(-1.41421,-1.41421), Point2f(0,-2)), SimpleLine(Point2f(-2,0), Point2f(-1.41421,-1.41421)), SimpleLine(Point2f(-1.41421,1.41421), Point2f(-2,0)), SimpleLine(Point2f(0,2), Point2f(-1.41421,1.41421)) }; std::vector circleLines = GeometryGenerators::generateCircleLines(sides, radius); REQUIRE(circleLines.size() == expected.size()); for(size_t i = 0; i < circleLines.size(); i++) { REQUIRE(circleLines[i].start().x == Approx(expected[i].start().x).epsilon(EPSILON)); REQUIRE(circleLines[i].start().y == Approx(expected[i].start().y).epsilon(EPSILON)); REQUIRE(circleLines[i].end().x == Approx(expected[i].end().x).epsilon(EPSILON)); REQUIRE(circleLines[i].end().y == Approx(expected[i].end().y).epsilon(EPSILON)); } std::vector offsets { Point2f(1,2), Point2f(3, -4), Point2f(-5, -6), Point2f(-7, 8) }; std::vector multiCircleLines = GeometryGenerators::generateMultipleCircleLines(sides, radius, offsets); REQUIRE(multiCircleLines.size() == expected.size()*offsets.size()); for(size_t i = 0; i < multiCircleLines.size(); i++) { REQUIRE(multiCircleLines[i].start().x == Approx(expected[i%sides].start().x + offsets[i/sides].x).epsilon(EPSILON)); REQUIRE(multiCircleLines[i].start().y == Approx(expected[i%sides].start().y + offsets[i/sides].y).epsilon(EPSILON)); REQUIRE(multiCircleLines[i].end().x == Approx(expected[i%sides].end().x + offsets[i/sides].x).epsilon(EPSILON)); REQUIRE(multiCircleLines[i].end().y == Approx(expected[i%sides].end().y + offsets[i/sides].y).epsilon(EPSILON)); } } ================================================ FILE: salaTest/testgridproperties.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/gridproperties.h" TEST_CASE("TestGridProperties", "Test the calculations of grid properties") { double maxDimension = 4.583; GridProperties gp(maxDimension); REQUIRE(gp.getDefault() == Approx(0.04)); REQUIRE(gp.getMax() == Approx(0.8)); REQUIRE(gp.getMin() == Approx(0.004)); } ================================================ FILE: salaTest/testisovist.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" TEST_CASE("Simple Isovist") { const float EPSILON = 0.001; // simple plan for isovist. dot as the origin // _ _ _ _ // | . | // | _ _| // | | // |_ _| std::vector planLines = { Line(Point2f(1, 1), Point2f(1, 3)), // Line(Point2f(1, 3), Point2f(3, 3)), // Line(Point2f(3, 3), Point2f(3, 2)), // Line(Point2f(3, 2), Point2f(2, 2)), // Line(Point2f(2, 2), Point2f(2, 1)), // Line(Point2f(2, 1), Point2f(1, 1)) // }; Point2f isovistOrigin(2.5, 2.5); std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->m_drawingFiles.emplace_back("Test SpacePixelGroup"); metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); for (Line &line : planLines) { metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(line); } SECTION("With a communicator") { std::unique_ptr comm(new ICommunicator); metaGraph->makeIsovist(comm.get(), isovistOrigin, 0, 0, false); } SECTION("Without a communicator") { metaGraph->makeIsovist(nullptr, isovistOrigin, 0, 0, false); } SalaShape &isovist = metaGraph->getDataMaps().front().getAllShapes().begin()->second; REQUIRE(isovist.isClosed()); REQUIRE(isovist.isPolygon()); // TODO: The current implementation generates a polygon of 12 points, potentially // because it takes them directly from the isovist gaps. This isovist only really // needs 5 points so it might make sense to run some sort of optimisation right // after generating the isovists REQUIRE(isovist.m_points.size() == 12); REQUIRE(isovist.m_points[0].x == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[0].y == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[1].x == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[1].y == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[2].x == Approx(1.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[2].y == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[3].x == Approx(1.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[3].y == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[4].x == Approx(1.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[4].y == Approx(1.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[5].x == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[5].y == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[6].x == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[6].y == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[7].x == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[7].y == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[8].x == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[8].y == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[9].x == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[9].y == Approx(2.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[10].x == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[10].y == Approx(2.5).epsilon(EPSILON)); REQUIRE(isovist.m_points[11].x == Approx(3.0).epsilon(EPSILON)); REQUIRE(isovist.m_points[11].y == Approx(2.5).epsilon(EPSILON)); } ================================================ FILE: salaTest/testisovistdef.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "../salalib/isovistdef.h" TEST_CASE("Full Isovist") { IsovistDefinition isovist(1.0, 1.0); REQUIRE(isovist.getLocation().x == Approx(1.0)); REQUIRE(isovist.getLocation().y == Approx(1.0)); REQUIRE(isovist.getAngle() == 0.0); REQUIRE(isovist.getViewAngle() == 0.0); } TEST_CASE("Partial Isovist") { SECTION("No overrun") { IsovistDefinition isovist(1.0, 1.0, 2.0, 1.0); REQUIRE(isovist.getLocation().x == Approx(1.0)); REQUIRE(isovist.getLocation().y == Approx(1.0)); REQUIRE(isovist.getAngle() == Approx(2.0)); REQUIRE(isovist.getViewAngle() == Approx(1.0)); REQUIRE(isovist.getLeftAngle() == Approx(1.5) ); REQUIRE(isovist.getRightAngle() == Approx(2.5) ); } SECTION("Overrun left") { IsovistDefinition isovist(1.0, 1.0, 0.1, 1.0); REQUIRE(isovist.getLocation().x == Approx(1.0)); REQUIRE(isovist.getLocation().y == Approx(1.0)); REQUIRE(isovist.getAngle() == Approx(0.1)); REQUIRE(isovist.getViewAngle() == Approx(1.0)); REQUIRE(isovist.getLeftAngle() == Approx(5.8831853072) ); REQUIRE(isovist.getRightAngle() == Approx(0.6) ); } SECTION("Overrun right") { IsovistDefinition isovist(1.0, 1.0, 6.1, 1.0); REQUIRE(isovist.getLocation().x == Approx(1.0)); REQUIRE(isovist.getLocation().y == Approx(1.0)); REQUIRE(isovist.getAngle() == Approx(6.1)); REQUIRE(isovist.getViewAngle() == Approx(1.0)); REQUIRE(isovist.getLeftAngle() == Approx(5.6) ); REQUIRE(isovist.getRightAngle() == Approx(0.31681469) ); } SECTION("Actually a full isovist in a partial list") { IsovistDefinition isovist(1.0, 1.0, 6.1, 2 * M_PI); REQUIRE(isovist.getLocation().x == Approx(1.0)); REQUIRE(isovist.getLocation().y == Approx(1.0)); REQUIRE(isovist.getAngle() == 0.0); REQUIRE(isovist.getViewAngle() == 0.0); REQUIRE(isovist.getLeftAngle() == 0.0); REQUIRE(isovist.getRightAngle() == 0.0 ); } } ================================================ FILE: salaTest/testlayermanager.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include TEST_CASE("Test layer manager") { LayerManagerImpl manager; REQUIRE(manager.isVisible(1)); REQUIRE(manager.getLayerName(0) == "Everything"); REQUIRE(manager.isLayerVisible(0)); REQUIRE(manager.getLayerIndex("Everything") == 0); REQUIRE(manager.getKey(0) == 1); size_t index1 = manager.addLayer("some layer"); REQUIRE(index1 == 1); REQUIRE_FALSE(manager.isVisible(2)); REQUIRE_FALSE(manager.isLayerVisible(1)); REQUIRE(manager.getLayerName(1) == "some layer"); REQUIRE(manager.getLayerIndex("some layer") == 1); REQUIRE(manager.getKey(1) == 2); REQUIRE(manager.getKey(5) == 32); manager.setLayerVisible(1, true); REQUIRE_FALSE(manager.isVisible(1)); REQUIRE(manager.isVisible(2)); size_t index2 = manager.addLayer("another layer"); REQUIRE(index2 == 2); REQUIRE(manager.getLayerName(2) == "another layer"); REQUIRE(manager.getLayerIndex("another layer") == 2); REQUIRE_FALSE(manager.isLayerVisible(2)); manager.setLayerVisible(2, true); REQUIRE_FALSE(manager.isVisible(1)); REQUIRE(manager.isVisible(2)); REQUIRE(manager.isVisible(4)); manager.setLayerVisible(2, false); REQUIRE_FALSE(manager.isVisible(1)); REQUIRE(manager.isVisible(2)); REQUIRE_FALSE(manager.isVisible(4)); manager.setLayerVisible(0, false); REQUIRE_FALSE(manager.isVisible(1)); REQUIRE_FALSE(manager.isVisible(2)); REQUIRE_FALSE(manager.isVisible(4)); manager.setLayerVisible(2, true); REQUIRE_FALSE(manager.isVisible(1)); REQUIRE_FALSE(manager.isVisible(2)); REQUIRE(manager.isVisible(4)); manager.setLayerVisible(0, true); REQUIRE(manager.isVisible(1)); REQUIRE_FALSE(manager.isVisible(2)); REQUIRE_FALSE(manager.isVisible(4)); REQUIRE_THROWS_AS(manager.addLayer("another layer"), LayerManager::DuplicateKeyException); // test read and write SelfCleaningFile serialisedManager("manager.bin"); { std::ofstream file(serialisedManager.Filename()); manager.write(file); } LayerManagerImpl copy; { std::ifstream file(serialisedManager.Filename()); copy.read(file); } REQUIRE(copy.getLayerName(1) == "some layer"); REQUIRE(copy.getLayerIndex("some layer") == 1); REQUIRE(copy.isVisible(1)); REQUIRE_FALSE(copy.isVisible(2)); REQUIRE_FALSE(copy.isVisible(4)); } ================================================ FILE: salaTest/testlinkutils.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" #include "salalib/linkutils.h" TEST_CASE("Test linking - fully filled grid (no geometry)", "") { double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 Point2f bottomLeft(0,0); Point2f topRight(2,4); int fill_type = 0; // = QDepthmapView::FULLFILL std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->setRegion(bottomLeft, topRight); PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); pointMap.setGrid(spacing, offset); Point2f gridBottomLeft = pointMap.getRegion().bottom_left; Point2f midPoint(gridBottomLeft.x + spacing * (floor(pointMap.getCols() * 0.5) + 0.5), gridBottomLeft.y + spacing * (floor(pointMap.getRows() * 0.5) + 0.5)); pointMap.makePoints(midPoint, fill_type); std::vector mergeLines; SECTION ("Successful: bottom-left to top-right") { mergeLines.push_back(Line(bottomLeft,topRight)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE(links.size() == 1); REQUIRE(links[0].a.x == 0); REQUIRE(links[0].a.y == 0); REQUIRE(links[0].b.x == 4); REQUIRE(links[0].b.y == 8); // make sure pixels are not already merged REQUIRE(!pointMap.isPixelMerged(links[0].a)); REQUIRE(!pointMap.isPixelMerged(links[0].b)); // merge depthmapX::mergePixelPairs(links, pointMap); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(links[0].a)); REQUIRE(pointMap.isPixelMerged(links[0].b)); const std::vector> &mergedPixelPairs = pointMap.getMergedPixelPairs(); REQUIRE(mergedPixelPairs.size() == 1); REQUIRE(mergedPixelPairs[0].first.x == 0); REQUIRE(mergedPixelPairs[0].first.y == 0); REQUIRE(mergedPixelPairs[0].second.x == 4); REQUIRE(mergedPixelPairs[0].second.y == 8); const std::vector &mergeLines = depthmapX::getMergedPixelsAsLines(pointMap); Point2f p1position = pointMap.depixelate(links[0].a); Point2f p2position = pointMap.depixelate(links[0].b); REQUIRE(mergeLines.size() == 1); REQUIRE(mergeLines[0].start().x == p1position.x); REQUIRE(mergeLines[0].start().y == p1position.y); REQUIRE(mergeLines[0].end().x == p2position.x); REQUIRE(mergeLines[0].end().y == p2position.y); } SECTION ("Successfull: bottom-left to top-right and bottom-right to top-left") { mergeLines.push_back(Line(bottomLeft,topRight)); Point2f start(topRight.x, bottomLeft.y); Point2f end(bottomLeft.x, topRight.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE(links.size() == 2); REQUIRE(links[0].a.x == 0); REQUIRE(links[0].a.y == 0); REQUIRE(links[0].b.x == 4); REQUIRE(links[0].b.y == 8); REQUIRE(links[1].a.x == 0); REQUIRE(links[1].a.y == 8); REQUIRE(links[1].b.x == 4); REQUIRE(links[1].b.y == 0); // make sure pixels are not already merged REQUIRE(!pointMap.isPixelMerged(links[0].a)); REQUIRE(!pointMap.isPixelMerged(links[0].b)); REQUIRE(!pointMap.isPixelMerged(links[1].a)); REQUIRE(!pointMap.isPixelMerged(links[1].b)); // merge depthmapX::mergePixelPairs(links, pointMap); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(links[0].a)); REQUIRE(pointMap.isPixelMerged(links[0].b)); REQUIRE(pointMap.isPixelMerged(links[1].a)); REQUIRE(pointMap.isPixelMerged(links[1].b)); } SECTION ("Failing: merge line start out of grid") { Point2f start(bottomLeft.x - spacing, bottomLeft.y - spacing); mergeLines.push_back(Line(start,topRight)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Line ends not both on painted analysis space")); } SECTION ("Failing: merge line end out of grid") { Point2f end(topRight.x + spacing, topRight.y + spacing); mergeLines.push_back(Line(bottomLeft,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Line ends not both on painted analysis space")); } SECTION ("Failing: second link start overlapping") { mergeLines.push_back(Line(bottomLeft,topRight)); Point2f start(bottomLeft.x, bottomLeft.y); Point2f end(topRight.x - 1, topRight.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Overlapping link found")); } SECTION("Failing: second link end overlapping") { mergeLines.push_back(Line(bottomLeft,topRight)); Point2f start(bottomLeft.x + 1, bottomLeft.y); Point2f end(topRight.x, topRight.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Overlapping link found")); } SECTION("Failing: fully overlapping link (bottom-left to top-right)") { mergeLines.push_back(Line(bottomLeft,topRight)); mergeLines.push_back(Line(bottomLeft,topRight)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Overlapping link found")); } SECTION("Failing: link overlapping to previously merged") { mergeLines.push_back(Line(bottomLeft,topRight)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE(links.size() == 1); REQUIRE(links[0].a.x == 0); REQUIRE(links[0].a.y == 0); REQUIRE(links[0].b.x == 4); REQUIRE(links[0].b.y == 8); // make sure pixels are not already merged REQUIRE(!pointMap.isPixelMerged(links[0].a)); REQUIRE(!pointMap.isPixelMerged(links[0].b)); // merge depthmapX::mergePixelPairs(links, pointMap); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(links[0].a)); REQUIRE(pointMap.isPixelMerged(links[0].b)); // now try to merge the same link again REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Link pixel found that is already linked on the map")); } } TEST_CASE("Test linking - half filled grid", "") { double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 int fill_type = 0; // = QDepthmapView::FULLFILL Point2f lineStart(0,0); Point2f lineEnd(2,4); Point2f bottomLeft(std::min(lineStart.x,lineEnd.x),std::min(lineStart.y,lineEnd.y)); Point2f topRight(std::max(lineStart.x,lineEnd.x),std::max(lineStart.y,lineEnd.y)); std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->m_drawingFiles.emplace_back("Test SpacePixelGroup"); metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(lineStart, lineEnd)); metaGraph->m_drawingFiles.back().m_region = metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion(); metaGraph->setRegion(metaGraph->m_drawingFiles.back().m_region.bottom_left, metaGraph->m_drawingFiles.back().m_region.top_right); PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); pointMap.setGrid(spacing, offset); Point2f gridBottomLeft = pointMap.getRegion().bottom_left; Point2f gridTopRight = pointMap.getRegion().top_right; Point2f topLeftFillPoint(gridBottomLeft.x+spacing, gridTopRight.y-spacing); pointMap.makePoints(topLeftFillPoint, fill_type); std::vector mergeLines; SECTION("Successful: top-left pixel to one to its right") { Point2f start(bottomLeft.x, topRight.y); Point2f end(bottomLeft.x + spacing, topRight.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE(links.size() == 1); REQUIRE(links[0].a.x == 0); REQUIRE(links[0].a.y == 8); REQUIRE(links[0].b.x == 1); REQUIRE(links[0].b.y == 8); // make sure pixels are not already merged REQUIRE(!pointMap.isPixelMerged(links[0].a)); REQUIRE(!pointMap.isPixelMerged(links[0].b)); // merge depthmapX::mergePixelPairs(links, pointMap); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(links[0].a)); REQUIRE(pointMap.isPixelMerged(links[0].b)); } SECTION("Failing: merge line (bottom-right to the one its left) completely out of grid") { Point2f start(topRight.x, bottomLeft.y); Point2f end(topRight.x - 1, bottomLeft.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Line ends not both on painted analysis space")); } SECTION("Failing: merge line (bottom-right to top-left) start out of grid") { Point2f start(topRight.x, bottomLeft.y); Point2f end(bottomLeft.x, topRight.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Line ends not both on painted analysis space")); } SECTION("Failing: merge line (top-left to bottom-right) end out of grid") { Point2f start(bottomLeft.x, topRight.y); Point2f end(topRight.x, bottomLeft.y); mergeLines.push_back(Line(start,end)); std::vector links = depthmapX::pixelateMergeLines(mergeLines,pointMap); REQUIRE_THROWS_WITH(depthmapX::mergePixelPairs(links, pointMap), Catch::Contains("Line ends not both on painted analysis space")); } } ================================================ FILE: salaTest/testmapconversion.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mapconverter.h" #include "salalib/mgraph.h" TEST_CASE("Failing empty drawing map conversion", "") { std::vector drawingFiles; REQUIRE_THROWS_WITH(MapConverter::convertDrawingToAxial(nullptr, "Axial map", drawingFiles), Catch::Contains("Failed to convert lines")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles), Catch::Contains("No lines found in drawing")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToConvex(nullptr, "Convex map", drawingFiles), Catch::Contains("No polygons found in drawing")); drawingFiles.push_back(SpacePixelFile("Drawing file")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToAxial(nullptr, "Axial map", drawingFiles), Catch::Contains("Failed to convert lines")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles), Catch::Contains("No lines found in drawing")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToConvex(nullptr, "Convex map", drawingFiles), Catch::Contains("No polygons found in drawing")); drawingFiles.back().m_spacePixels.push_back(ShapeMap("Drawing layer", ShapeMap::DRAWINGMAP)); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToAxial(nullptr, "Axial map", drawingFiles), Catch::Contains("Failed to convert lines")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles), Catch::Contains("No lines found in drawing")); REQUIRE_THROWS_WITH(MapConverter::convertDrawingToConvex(nullptr, "Convex map", drawingFiles), Catch::Contains("No polygons found in drawing")); } TEST_CASE("Failing empty axial to segment map conversion", "") { ShapeGraph segmentMap("Axial map", ShapeMap::AXIALMAP); // TODO: Does not throw an exception but maybe it should as the axial map is empty? // REQUIRE_THROWS_WITH(MapConverter::convertAxialToSegment(nullptr, segmentMap, "Segment map", false, false, 0), // Catch::Contains("No lines found in drawing")); } TEST_CASE("Failing empty data map conversion", "") { ShapeMap dataMap("Data map", ShapeMap::DATAMAP); REQUIRE_THROWS_WITH(MapConverter::convertDataToAxial(nullptr, "Axial map", dataMap), Catch::Contains("No lines found in data map")); REQUIRE_THROWS_WITH(MapConverter::convertDataToSegment(nullptr, "Segment map", dataMap), Catch::Contains("No lines found in data map")); REQUIRE_THROWS_WITH(MapConverter::convertDataToConvex(nullptr, "Convex map", dataMap), Catch::Contains("No polygons found in data map")); } TEST_CASE("Test drawing to segment conversion", "") { const float EPSILON = 0.001; Line line1(Point2f(0, 0), Point2f(0, 1)); Line line2(Point2f(0, 1), Point2f(1, 1)); Line line3(Point2f(1, 1), Point2f(1, 0)); std::vector drawingFiles; drawingFiles.push_back(SpacePixelFile("Drawing file")); drawingFiles.back().m_spacePixels.push_back(ShapeMap("Drawing layer", ShapeMap::DRAWINGMAP)); ShapeMap &drawingLayer = drawingFiles.back().m_spacePixels.back(); SECTION("Single line") { drawingLayer.makeLineShape(line1); // TODO: This fails with std::bad_alloc because there's only 1 line in the drawing REQUIRE_THROWS_WITH(MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles), Catch::Contains("std::bad_alloc")); } SECTION("Two lines") { drawingLayer.makeLineShape(line1); drawingLayer.makeLineShape(line2); // TODO: This fails with std::bad_alloc because there's only 2 lines in the drawing REQUIRE_THROWS_WITH(MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles), Catch::Contains("std::bad_alloc")); } SECTION("Three lines") { drawingLayer.makeLineShape(line1); drawingLayer.makeLineShape(line2); drawingLayer.makeLineShape(line3); std::unique_ptr segmentMap = MapConverter::convertDrawingToSegment(nullptr, "Segment map", drawingFiles); std::map &shapes = segmentMap->getAllShapes(); REQUIRE(shapes.size() == 3); auto shapeIter = shapes.begin(); REQUIRE(shapeIter->first == 0); const Line &segmentLine1 = shapeIter->second.getLine(); REQUIRE(segmentLine1.ax() == Approx(line1.ax()).epsilon(EPSILON)); REQUIRE(segmentLine1.ay() == Approx(line1.ay()).epsilon(EPSILON)); REQUIRE(segmentLine1.bx() == Approx(line1.bx()).epsilon(EPSILON)); REQUIRE(segmentLine1.by() == Approx(line1.by()).epsilon(EPSILON)); shapeIter++; REQUIRE(shapeIter->first == 1); const Line &segmentLine2 = shapeIter->second.getLine(); REQUIRE(segmentLine2.ax() == Approx(line2.ax()).epsilon(EPSILON)); REQUIRE(segmentLine2.ay() == Approx(line2.ay()).epsilon(EPSILON)); REQUIRE(segmentLine2.bx() == Approx(line2.bx()).epsilon(EPSILON)); REQUIRE(segmentLine2.by() == Approx(line2.by()).epsilon(EPSILON)); shapeIter++; REQUIRE(shapeIter->first == 2); const Line &segmentLine3 = shapeIter->second.getLine(); REQUIRE(segmentLine3.ax() == Approx(line3.ax()).epsilon(EPSILON)); REQUIRE(segmentLine3.ay() == Approx(line3.ay()).epsilon(EPSILON)); REQUIRE(segmentLine3.bx() == Approx(line3.bx()).epsilon(EPSILON)); REQUIRE(segmentLine3.by() == Approx(line3.by()).epsilon(EPSILON)); } } TEST_CASE("Test data to segment conversion", "") { const float EPSILON = 0.001; std::string newAttributeName = "testID"; ShapeMap dataMap("Data map", ShapeMap::DATAMAP); int newAttributeID = dataMap.addAttribute(newAttributeName); std::vector lines; std::vector> extraAttributes; lines.push_back(Line(Point2f(0, 0), Point2f(0, 1))); lines.push_back(Line(Point2f(0, 1), Point2f(1, 1))); lines.push_back(Line(Point2f(1, 1), Point2f(1, 0))); for (int i = 0; i < lines.size(); i++) { extraAttributes.push_back(std::map()); extraAttributes.back()[newAttributeID] = extraAttributes.size(); } SECTION("Single line with extra attributes") { dataMap.makeLineShape(lines[0], false, false, extraAttributes[0]); // TODO: This fails with std::bad_alloc because there's only 1 line in the data map REQUIRE_THROWS_WITH(MapConverter::convertDataToSegment(nullptr, "Segment map", dataMap, true), Catch::Contains("std::bad_alloc")); } SECTION("Two lines with extra attributes") { dataMap.makeLineShape(lines[0], false, false, extraAttributes[0]); dataMap.makeLineShape(lines[1], false, false, extraAttributes[1]); // TODO: This fails with std::bad_alloc because there's only 2 lines in the data map REQUIRE_THROWS_WITH(MapConverter::convertDataToSegment(nullptr, "Segment map", dataMap, true), Catch::Contains("std::bad_alloc")); } SECTION("Three lines") { dataMap.makeLineShape(lines[0], false, false, extraAttributes[0]); dataMap.makeLineShape(lines[1], false, false, extraAttributes[1]); dataMap.makeLineShape(lines[2], false, false, extraAttributes[2]); std::unique_ptr segmentMap = MapConverter::convertDataToSegment(nullptr, "Segment map", dataMap, true); int segmentNewAttributeID = segmentMap->getAttributeTable().getColumnIndex(newAttributeName); std::map &shapes = segmentMap->getAllShapes(); REQUIRE(shapes.size() == 3); auto shapeIter = shapes.begin(); for (int i = 0; i < lines.size(); i++) { REQUIRE(shapeIter->first == i); AttributeRow &row = segmentMap->getAttributeRowFromShapeIndex(shapeIter->first); REQUIRE(row.getValue(segmentNewAttributeID) == extraAttributes[i][newAttributeID]); const Line &segmentLine = shapeIter->second.getLine(); REQUIRE(segmentLine.ax() == Approx(lines[i].ax()).epsilon(EPSILON)); REQUIRE(segmentLine.ay() == Approx(lines[i].ay()).epsilon(EPSILON)); REQUIRE(segmentLine.bx() == Approx(lines[i].bx()).epsilon(EPSILON)); REQUIRE(segmentLine.by() == Approx(lines[i].by()).epsilon(EPSILON)); shapeIter++; } } SECTION("Four lines, second line twice") { dataMap.makeLineShape(lines[0], false, false, extraAttributes[0]); dataMap.makeLineShape(lines[1], false, false, extraAttributes[1]); dataMap.makeLineShape(lines[1], false, false, extraAttributes[1]); // this one should be removed by tidylines dataMap.makeLineShape(lines[2], false, false, extraAttributes[2]); std::unique_ptr segmentMap = MapConverter::convertDataToSegment(nullptr, "Segment map", dataMap, true); int segmentNewAttributeID = segmentMap->getAttributeTable().getColumnIndex(newAttributeName); std::map &shapes = segmentMap->getAllShapes(); REQUIRE(shapes.size() == 3); auto shapeIter = shapes.begin(); for (int i = 0; i < lines.size(); i++) { REQUIRE(shapeIter->first == i); AttributeRow &row = segmentMap->getAttributeRowFromShapeIndex(shapeIter->first); REQUIRE(row.getValue(segmentNewAttributeID) == extraAttributes[i][newAttributeID]); const Line &segmentLine = shapeIter->second.getLine(); REQUIRE(segmentLine.ax() == Approx(lines[i].ax()).epsilon(EPSILON)); REQUIRE(segmentLine.ay() == Approx(lines[i].ay()).epsilon(EPSILON)); REQUIRE(segmentLine.bx() == Approx(lines[i].bx()).epsilon(EPSILON)); REQUIRE(segmentLine.by() == Approx(lines[i].by()).epsilon(EPSILON)); shapeIter++; } } } ================================================ FILE: salaTest/testmapinfodata.cpp ================================================ // Copyright (C) 2017-2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" #include "salalib/parsers/mapinfodata.h" TEST_CASE("MapInfo failing header", "") { std::string mifdata = "Version 300\n"; SECTION("Missing quotes around delimiter") { mifdata += "Charset \"WindowsLatin1\"\n" \ "Delimiter ,\n" \ "Index 1,2\n" \ "CoordSys Earth Projection 8, 79, \"m\", -2, 49, 0.9996012717, 400000, -100000"; } SECTION("Missing CoordSys") { mifdata += "Charset \"WindowsLatin1\"\n" \ "Delimiter \",\"\n" \ "Index 1,2\n" \ "Bounds (-7845061.1011, -15524202.1641) (8645061.1011, 4470074.53373)\n"; } std::stringstream mifstream(mifdata); MapInfoData mapinfodata; REQUIRE_FALSE(mapinfodata.readheader(mifstream)); } TEST_CASE("MapInfo failing column attribute columns", "") { std::string mifdata = ""; SECTION("Missing Columns at beginning") { mifdata += "Tolumns 2\n" \ " ID Integer\n" \ " Length_m Float\n" \ "Data\n"; } SECTION("Missing Column number") { mifdata += "Columns\n" \ " ID Integer\n" \ " Length_m Float\n" \ "Data\n"; } SECTION("Missing Data at end") { mifdata += "Columns 2\n" \ " ID Integer\n" \ " Length_m Float\n" \ "Bata\n"; } std::string middata = "1,1017.81\n" \ "2,568.795\n" \ "3,216.026"; std::stringstream mifstream(mifdata); std::stringstream midstream(middata); std::vector columnheads; MapInfoData mapinfodata; REQUIRE_FALSE(mapinfodata.readcolumnheaders(mifstream, columnheads)); } TEST_CASE("MapInfo MID file with empty column", "") { const float EPSILON = 0.001; // A typical MIF std::string mifdata = "Version 300\n" \ "Charset \"WindowsLatin1\"\n" \ "Delimiter \",\"\n" \ "Index 1,2,3,4\n" \ "CoordSys Earth Projection 8, 79, \"m\", -2, 49, 0.9996012717, 400000, -100000\n"; mifdata += "Columns 4\n" \ " ID Integer\n" \ " Length_m Float\n" \ " Height_m Float\n" \ " Width_m Float\n" \ "Data\n" \ "\n" \ "Line 534014.29 182533.33 535008.52 182764.11\n" \ " Pen (1,2,0)\n" \ "Line 533798.68 183094.69 534365.48 183159.01\n" \ " Pen (1,2,0)\n" \ "Point 534014.29 182533.33\n" \ " Symbol (34,0,12)"; // A MID with empty columns std::string middata = "1,1017.81,,\n" \ "2,568.795,,\n" \ "3,216.026,,"; ShapeMap shapeMap("MapInfoTest"); MapInfoData mapinfodata; std::stringstream mifstream(mifdata); std::stringstream midstream(middata); REQUIRE(mapinfodata.import(mifstream, midstream, shapeMap) == MINFO_OK); AttributeTable& att = shapeMap.getAttributeTable(); REQUIRE(att.getNumColumns() == 4); REQUIRE(att.getColumn(0).getName() == "Id"); REQUIRE(att.getColumn(1).getName() == "Length_M"); REQUIRE(att.getColumn(2).getName() == "Height_M"); REQUIRE(att.getColumn(3).getName() == "Width_M"); std::map shapes = shapeMap.getAllShapes(); auto shapeRef0 = depthmapX::getMapAtIndex(shapes, 0); auto shapeRef1 = depthmapX::getMapAtIndex(shapes, 1); auto shapeRef2 = depthmapX::getMapAtIndex(shapes, 2); REQUIRE(att.getNumRows() == 3); auto &row0 = att.getRow(AttributeKey(shapeRef0->first)); auto &row1 = att.getRow(AttributeKey(shapeRef1->first)); auto &row2 = att.getRow(AttributeKey(shapeRef2->first)); REQUIRE(row0.getValue("Id") == 1); REQUIRE(row1.getValue("Id") == 2); REQUIRE(row2.getValue("Id") == 3); REQUIRE(row0.getValue("Length_M") == Approx(1017.81).epsilon(EPSILON)); REQUIRE(row1.getValue("Length_M") == Approx(568.795).epsilon(EPSILON)); REQUIRE(row2.getValue("Length_M") == Approx(216.026).epsilon(EPSILON)); REQUIRE(row0.getValue("Height_M") == -1); REQUIRE(row1.getValue("Height_M") == -1); REQUIRE(row2.getValue("Height_M") == -1); REQUIRE(row0.getValue("Width_M") == -1); REQUIRE(row1.getValue("Width_M") == -1); REQUIRE(row2.getValue("Width_M") == -1); } TEST_CASE("Complete proper MapInfo file", "") { const float EPSILON = 0.001; // A typical MIF std::string mifdata = "Version 300\n" \ "Charset \"WindowsLatin1\"\n" \ "Delimiter \",\"\n" \ "Index 1,2\n" \ "CoordSys Earth Projection 8, 79, \"m\", -2, 49, 0.9996012717, 400000, -100000"; SECTION("With Bounds") { mifdata += "Bounds (-7845061.1011, -15524202.1641) (8645061.1011, 4470074.53373)\n"; } SECTION("Without Bounds") { mifdata += "\n"; } mifdata += "Columns 2\n" \ " ID Integer\n" \ " Length_m Float\n" \ "Data\n" \ "\n" \ "Line 534014.29 182533.33 535008.52 182764.11\n" \ " Pen (1,2,0)\n" \ "Line 533798.68 183094.69 534365.48 183159.01\n" \ " Pen (1,2,0)\n" \ "Point 534014.29 182533.33\n" \ " Symbol (34,0,12)"; // A Typical MID std::string middata = "1,1017.81\n" \ "2,568.795\n" \ "3,216.026"; ShapeMap shapeMap("MapInfoTest"); MapInfoData mapinfodata; std::stringstream mifstream(mifdata); std::stringstream midstream(middata); REQUIRE(mapinfodata.import(mifstream, midstream, shapeMap) == MINFO_OK); std::map shapes = shapeMap.getAllShapes(); auto shapeRef0 = depthmapX::getMapAtIndex(shapes, 0); auto shapeRef1 = depthmapX::getMapAtIndex(shapes, 1); auto shapeRef2 = depthmapX::getMapAtIndex(shapes, 2); auto &shape0 = shapeRef0->second; auto &shape1 = shapeRef1->second; auto &shape2 = shapeRef2->second; REQUIRE(shapes.size() == 3); REQUIRE(shape0.isLine()); REQUIRE(shape0.getLine().ax() == Approx(534014.29).epsilon(EPSILON)); REQUIRE(shape0.getLine().ay() == Approx(182533.33).epsilon(EPSILON)); REQUIRE(shape0.getLine().bx() == Approx(535008.52).epsilon(EPSILON)); REQUIRE(shape0.getLine().by() == Approx(182764.11).epsilon(EPSILON)); REQUIRE(shape1.isLine()); REQUIRE(shape1.getLine().ax() == Approx(533798.68).epsilon(EPSILON)); REQUIRE(shape1.getLine().ay() == Approx(183094.69).epsilon(EPSILON)); REQUIRE(shape1.getLine().bx() == Approx(534365.48).epsilon(EPSILON)); REQUIRE(shape1.getLine().by() == Approx(183159.01).epsilon(EPSILON)); REQUIRE(shape2.isPoint()); REQUIRE(shape2.getPoint().x == Approx(534014.29).epsilon(EPSILON)); REQUIRE(shape2.getPoint().y == Approx(182533.33).epsilon(EPSILON)); AttributeTable& att = shapeMap.getAttributeTable(); REQUIRE(att.getNumColumns() == 2); REQUIRE(att.getColumnName(0) == "Id"); REQUIRE(att.getColumnName(1) == "Length_M"); REQUIRE(att.getNumRows() == 3); auto &row0 = att.getRow(AttributeKey(shapeRef0->first)); auto &row1 = att.getRow(AttributeKey(shapeRef1->first)); auto &row2 = att.getRow(AttributeKey(shapeRef2->first)); REQUIRE(row0.getValue("Id") == 1); REQUIRE(row1.getValue("Id") == 2); REQUIRE(row2.getValue("Id") == 3); REQUIRE(row0.getValue("Length_M") == Approx(1017.81).epsilon(EPSILON)); REQUIRE(row1.getValue("Length_M") == Approx(568.795).epsilon(EPSILON)); REQUIRE(row2.getValue("Length_M") == Approx(216.026).epsilon(EPSILON)); } ================================================ FILE: salaTest/testmgraph.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" TEST_CASE("Test getVisibleLines", "") { const float EPSILON = 0.001; // create a new MetaGraph std::unique_ptr mgraph(new MetaGraph()); Point2f visibleLineStart(0,0); Point2f visibleLineEnd(2,4); Point2f hiddenLineStart(1,1); Point2f hiddenLineEnd(3,5); // push a SpacePixelFile in the MetaGraph mgraph->m_drawingFiles.emplace_back("Test SpacePixelFile"); // push a ShapeMap in the SpacePixelFile mgraph->m_drawingFiles.back().m_spacePixels.emplace_back("Visible ShapeMap"); // add a line to the first ShapeMap mgraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(visibleLineStart, visibleLineEnd)); // push a ShapeMap in the SpacePixelFile mgraph->m_drawingFiles.back().m_spacePixels.emplace_back("Hidden ShapeMap"); // add a line to the second ShapeMap mgraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(hiddenLineStart, hiddenLineEnd)); SECTION( "Get visible lines when none is hidden" ) { // first check without hiding anything const std::vector& visibleLines = mgraph->getVisibleDrawingLines(); REQUIRE(visibleLines.size() == 2); REQUIRE(visibleLines[0].start().x == Approx(visibleLineStart.x).epsilon(EPSILON)); REQUIRE(visibleLines[0].start().y == Approx(visibleLineStart.y).epsilon(EPSILON)); REQUIRE(visibleLines[0].end().x == Approx(visibleLineEnd.x).epsilon(EPSILON)); REQUIRE(visibleLines[0].end().y == Approx(visibleLineEnd.y).epsilon(EPSILON)); REQUIRE(visibleLines[1].start().x == Approx(hiddenLineStart.x).epsilon(EPSILON)); REQUIRE(visibleLines[1].start().y == Approx(hiddenLineStart.y).epsilon(EPSILON)); REQUIRE(visibleLines[1].end().x == Approx(hiddenLineEnd.x).epsilon(EPSILON)); REQUIRE(visibleLines[1].end().y == Approx(hiddenLineEnd.y).epsilon(EPSILON)); } SECTION( "Get visible lines when some are hidden" ) { // now hide the second SpacePixelFile mgraph->m_drawingFiles.back().m_spacePixels.back().setShow(false); const std::vector& visibleLines = mgraph->getVisibleDrawingLines(); REQUIRE(visibleLines.size() == 1); REQUIRE(visibleLines[0].start().x == Approx(visibleLineStart.x).epsilon(EPSILON)); REQUIRE(visibleLines[0].start().y == Approx(visibleLineStart.y).epsilon(EPSILON)); REQUIRE(visibleLines[0].end().x == Approx(visibleLineEnd.x).epsilon(EPSILON)); REQUIRE(visibleLines[0].end().y == Approx(visibleLineEnd.y).epsilon(EPSILON)); } } TEST_CASE("Test pointMaps", "") { std::unique_ptr mgraph(new MetaGraph()); int pointMapIdx = mgraph->addNewPointMap("Kenny"); REQUIRE(mgraph->getPointMaps().size() == 1); REQUIRE(pointMapIdx == 0); REQUIRE(mgraph->getPointMaps()[0].getName() == "Kenny"); REQUIRE(mgraph->getDisplayedPointMapRef() == pointMapIdx); REQUIRE(mgraph->getDisplayedPointMap().getName() == "Kenny"); SECTION( "Add another and remove the first through the MetaGraph" ) { int pointMapIdx = mgraph->addNewPointMap("Stan"); REQUIRE(mgraph->getPointMaps().size() == 2); REQUIRE(pointMapIdx == 1); REQUIRE(mgraph->getPointMaps()[1].getName() == "Stan"); REQUIRE(mgraph->getDisplayedPointMapRef() == 1); REQUIRE(mgraph->getDisplayedPointMap().getName() == "Stan"); mgraph->setState(MetaGraph::POINTMAPS); mgraph->setViewClass(MetaGraph::SHOWVGATOP); mgraph->setDisplayedPointMapRef(0); REQUIRE(mgraph->getDisplayedPointMapRef() == 0); REQUIRE(mgraph->getDisplayedPointMap().getName() == "Kenny"); mgraph->removeDisplayedMap(); REQUIRE(mgraph->getPointMaps().size() == 1); REQUIRE(mgraph->getPointMaps()[0].getName() == "Stan"); REQUIRE(mgraph->getDisplayedPointMapRef() == 0); } } ================================================ FILE: salaTest/testpointinpoly.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mapconverter.h" #include "salalib/shapemap.h" TEST_CASE("Test point in polygon in shapemap", "") { // The problem this test was made to demostrate was that shapemaps with // extended bounds tended to make the point-in-polygon more inaccurate. std::unique_ptr shapeMap(new ShapeMap("Test ShapeMap")); // main testing shape shapeMap->makePolyShape( { Point2f(4.50, 5.75), // Point2f(5.75, 5.50), // Point2f(5.25, 4.75), // Point2f(4.75, 4.50) // }, false); // points inside the polygon std::vector pointsInsidePoly = { Point2f(5.1250, 5.1250), // Point2f(5.6345, 5.4522), // Point2f(4.5884, 5.6616), // Point2f(4.8049, 4.6123), // Point2f(5.1673, 4.8437), // Point2f(4.9441, 4.7368), // Point2f(4.7476, 5.1495), // Point2f(5.1005, 5.5024), // Point2f(5.3960, 5.1943) // }; // points outside (but very close to) the polygon std::vector pointsOutsidePoly = { Point2f(4.6951, 4.3877), // Point2f(4.4116, 5.8384), // Point2f(5.8655, 5.5478), // Point2f(5.3327, 4.6563), // Point2f(5.0559, 4.5132), // Point2f(4.5024, 5.1005), // Point2f(5.1495, 5.7476), // Point2f(5.6040, 5.0557) // }; for (Point2f point : pointsInsidePoly) { REQUIRE(shapeMap->pointInPolyList(point)[0] == 0); } for (Point2f point : pointsOutsidePoly) { REQUIRE(shapeMap->pointInPolyList(point).size() == 0); } // now extend the bounds // first little extra rectangle to extend the map region to 0.25, 0.25 shapeMap->makePolyShape( { Point2f(0.25, 0.25), // Point2f(0.50, 0.25), // Point2f(0.50, 0.50), // Point2f(0.25, 0.50) // }, false); // second little extra rectangle to extend the map region to 10.0, 10.0 shapeMap->makePolyShape( { Point2f(9.75, 9.75), // Point2f(10.0, 9.75), // Point2f(10.0, 10.0), // Point2f(9.75, 10.0) // }, false); for (Point2f point : pointsInsidePoly) { REQUIRE(shapeMap->pointInPolyList(point)[0] == 0); } for (Point2f point : pointsOutsidePoly) { REQUIRE(shapeMap->pointInPolyList(point).size() == 0); } } ================================================ FILE: salaTest/testpointmap.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" TEST_CASE("Test MetaGraph construction", "") { const float EPSILON = 0.001; double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 // create a new MetaGraph // The PointMap needs the m_region variable from this // object as a definition of the area the grid needs to cover std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); SECTION( "Construct a plain MetaGraph without underlying geometry" ) { Point2f bottomLeft(0,0); Point2f topRight(2,4); // set m_region to the bounds metaGraph->setRegion(bottomLeft, topRight); // check if the bounds are set correctly REQUIRE(metaGraph->getRegion().bottom_left.x == Approx(bottomLeft.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().bottom_left.y == Approx(bottomLeft.y).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.x == Approx(topRight.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.y == Approx(topRight.y).epsilon(EPSILON)); } SECTION( "Construct a MetaGraph using underlying geometry" ) { Point2f lineStart(0,0); Point2f lineEnd(2,4); Point2f bottomLeft(std::min(lineStart.x,lineEnd.x),std::min(lineStart.y,lineEnd.y)); Point2f topRight(std::max(lineStart.x,lineEnd.x),std::max(lineStart.y,lineEnd.y)); // push a SpacePixelFile in the MetaGraph metaGraph->m_drawingFiles.emplace_back("Test MetaGraph"); // push a ShapeMap in the SpacePixelFile metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); // add a line to the ShapeMap metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(lineStart, lineEnd)); // check if the ShapeMap bounds are set correctly REQUIRE(metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion().bottom_left.x == Approx(bottomLeft.x).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion().bottom_left.y == Approx(bottomLeft.y).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion().top_right.x == Approx(topRight.x).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion().top_right.y == Approx(topRight.y).epsilon(EPSILON)); // MetaGraph and SpacePixelFile do not automatically grow // their region when new shapemaps/files are added to them // therefore we have to do this externally metaGraph->m_drawingFiles.back().m_region = metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion(); // check if the SpacePixelFile bounds are set correctly REQUIRE(metaGraph->m_drawingFiles.back().m_region.bottom_left.x == Approx(bottomLeft.x).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_region.bottom_left.y == Approx(bottomLeft.y).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_region.top_right.x == Approx(topRight.x).epsilon(EPSILON)); REQUIRE(metaGraph->m_drawingFiles.back().m_region.top_right.y == Approx(topRight.y).epsilon(EPSILON)); metaGraph->setRegion(metaGraph->m_drawingFiles.back().m_region.bottom_left, metaGraph->m_drawingFiles.back().m_region.top_right); // check if the MetaGraph bounds are set correctly REQUIRE(metaGraph->getRegion().bottom_left.x == Approx(bottomLeft.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().bottom_left.y == Approx(bottomLeft.y).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.x == Approx(topRight.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.y == Approx(topRight.y).epsilon(EPSILON)); } // construct a sample pointMap PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); } TEST_CASE("Test grid filling", "") { const float EPSILON = 0.001; double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 // create a new MetaGraph // The PointMap needs the m_region variable from this // object as a definition of the area the grid needs to cover std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); // Construct a plain MetaGraph without underlying geometry { Point2f bottomLeft(0,0); Point2f topRight(2,4); // set m_region to the bounds metaGraph->setRegion(bottomLeft, topRight); // check if the bounds are set correctly REQUIRE(metaGraph->getRegion().bottom_left.x == Approx(bottomLeft.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().bottom_left.y == Approx(bottomLeft.y).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.x == Approx(topRight.x).epsilon(EPSILON)); REQUIRE(metaGraph->getRegion().top_right.y == Approx(topRight.y).epsilon(EPSILON)); } // construct a sample pointMap PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); // set the grid // create the grid with bounds as set above bool gridIsSet = pointMap.setGrid(spacing, offset); // check if the grid was set REQUIRE(gridIsSet); // check if the spacing is correct REQUIRE(spacing == pointMap.getSpacing()); // fill the grid // seems like fill_type is actually connected to the // QDepthmapView class which is a GUI class (depthmapview.h) // TODO Disentangle GUI enum from pointMap.makePoints int fill_type = 0; // = QDepthmapView::FULLFILL Point2f gridBottomLeft = pointMap.getRegion().bottom_left; SECTION( "Check if the points are made when fill selection in a cell" ) { // Check if the points are made (grid filled) when // the selected position is certainly in a cell // This calculation should make the point directly // at the centre of a central cell Point2f midPoint(gridBottomLeft.x + spacing * (floor(pointMap.getCols() * 0.5) + 0.5), gridBottomLeft.y + spacing * (floor(pointMap.getRows() * 0.5) + 0.5)); bool pointsMade = pointMap.makePoints(midPoint, fill_type); REQUIRE(pointsMade); } SECTION("Check if the points are made when fill selection between cells") { // Check if the points are made (grid filled) when // the selected position is certainly between cells // This calculation should make the point directly // at the edge of a central cell Point2f midPoint(gridBottomLeft.x + spacing * (floor(pointMap.getCols() * 0.5)), gridBottomLeft.y + spacing * (floor(pointMap.getRows() * 0.5))); bool pointsMade = pointMap.makePoints(midPoint, fill_type); REQUIRE(pointsMade); } } // PointMap::setGrid is quite convoluted with various parameters // affecting the result, such as the limits of the region to be // covered (bottomLeft, topRight), the spacing and the location // of the plan in space. For example every grid created will be // in relation to the origin (0,0), no matter where the region // is and the current pixel can always be calculated as if the // origin always falls in the centre of a cell. TEST_CASE("Quirks in grid creation - Origin always at 0", "") { double spacing = 0.5; const float EPSILON = 0.001; Point2f offset(0,0); // seems that this is always set to 0,0 Point2f bottomLeft(0,0); Point2f topRight(0,0); SECTION ("Region from origin to positive x, positive y quadrant") { spacing = 0.5; bottomLeft.x = 0; bottomLeft.y = 0; topRight.x = 1; topRight.y = 1; } SECTION ("Region away from origin to positive x, positive y quadrant") { spacing = 0.5; bottomLeft.x = 1; bottomLeft.y = 1; topRight.x = 2; topRight.y = 2; } SECTION ("Region from origin to negative x, negative y quadrant") { spacing = 0.5; bottomLeft.x = -1; bottomLeft.y = -1; topRight.x = 0; topRight.y = 0; } SECTION ("Region in all quadrants") { spacing = 0.5; bottomLeft.x = -1; bottomLeft.y = -1; topRight.x = 1; topRight.y = 1; } SECTION ("Region in positive x, positive y quadrant, non-rectangular") { spacing = 0.5; bottomLeft.x = 1; bottomLeft.y = 2; topRight.x = 3; topRight.y = 4; } SECTION ("Region in positive x, positive y quadrant, floating-point limits") { spacing = 0.5; bottomLeft.x = 1.1; bottomLeft.y = 2.2; topRight.x = 3.3; topRight.y = 4.4; } SECTION ("Region in positive x, positive y quadrant, floating-point limits") { spacing = 0.5; bottomLeft.x = 0.1; bottomLeft.y = 0.2; topRight.x = 0.3; topRight.y = 0.4; } SECTION ("Region in negative x, negative y quadrant, floating-point limits") { spacing = 0.5; bottomLeft.x = -0.4; bottomLeft.y = -0.3; topRight.x = -0.2; topRight.y = -0.1; } SECTION ("Region in all quadrants, floating-point limits") { spacing = 0.5; bottomLeft.x = -1.1; bottomLeft.y = -2.2; topRight.x = 3.3; topRight.y = 4.4; } SECTION ("Region in all quadrants, floating-point limits, smaller spacing") { spacing = 0.25; bottomLeft.x = 1.1; bottomLeft.y = 2.2; topRight.x = 3.3; topRight.y = 4.4; } std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->setRegion(bottomLeft, topRight); PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); bool gridIsSet = pointMap.setGrid(spacing, offset); int bottomLeftPixelIndexX = int(floor(bottomLeft.x / spacing - 0.5)) + 1; int bottomLeftPixelIndexY = int(floor(bottomLeft.y / spacing - 0.5)) + 1; int topRightPixelIndexX = int(floor(topRight.x / spacing - 0.5)) + 1; int topRightPixelIndexY = int(floor(topRight.y / spacing - 0.5)) + 1; int numCellsX = topRightPixelIndexX - bottomLeftPixelIndexX + 1; int numCellsY = topRightPixelIndexY - bottomLeftPixelIndexY + 1; // check if the size of the grid is as expected REQUIRE(pointMap.getCols() == numCellsX); REQUIRE(pointMap.getRows() == numCellsY); Point2f gridBottomLeft(bottomLeftPixelIndexX * spacing - 0.5 * spacing, bottomLeftPixelIndexY * spacing - 0.5 * spacing); // check if the bottom-left corner of the bottom-left pixel is as expected REQUIRE(pointMap.getRegion().bottom_left.x == Approx(gridBottomLeft.x).epsilon(EPSILON)); REQUIRE(pointMap.getRegion().bottom_left.y == Approx(gridBottomLeft.y).epsilon(EPSILON)); Point2f midPoint(gridBottomLeft.x + spacing * (floor(numCellsX * 0.5) + 0.5), gridBottomLeft.y + spacing * (floor(numCellsY * 0.5) + 0.5)); int fill_type = 0; // = QDepthmapView::FULLFILL bool pointsMade = pointMap.makePoints(midPoint, fill_type); // check if the grid is filled REQUIRE(pointsMade); } TEST_CASE("Test PointMap connections output", "") { const float EPSILON = 0.001; double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); double rectSize = 1.5; Point2f line0Start(0,0); Point2f line0End(0,rectSize); Point2f line1Start(0,rectSize); Point2f line1End(rectSize,rectSize); Point2f line2Start(rectSize,rectSize); Point2f line2End(rectSize,0); Point2f line3Start(rectSize,0); Point2f line3End(0,0); metaGraph->m_drawingFiles.emplace_back("Test SpacePixelGroup"); metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line0Start, line0End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line1Start, line1End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line2Start, line2End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line3Start, line3End)); metaGraph->m_drawingFiles.back().m_region = metaGraph->m_drawingFiles.back().m_spacePixels.back().getRegion(); metaGraph->setRegion(metaGraph->m_drawingFiles.back().m_region.bottom_left, metaGraph->m_drawingFiles.back().m_region.top_right); PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); Point2f gridBottomLeft = pointMap.getRegion().bottom_left; Point2f midPoint(gridBottomLeft.x + spacing * (floor(pointMap.getCols() * 0.5) + 0.5), gridBottomLeft.y + spacing * (floor(pointMap.getRows() * 0.5) + 0.5)); int fill_type = 0; // = QDepthmapView::FULLFILL bool gridIsSet = pointMap.setGrid(spacing, offset); bool pointsMade = pointMap.makePoints(midPoint, fill_type); bool boundaryGraph = false; double maxDist = -1; // a communicator is required in order to create the connections between the pixels std::unique_ptr comm(new ICommunicator()); bool graphMade = pointMap.sparkGraph2(comm.get(), boundaryGraph, maxDist); REQUIRE(graphMade); SECTION("PointMap::outputLinksAsCSV") { std::stringstream stream; pointMap.mergePixels(65537, 131074); pointMap.mergePixels(131073, 65538); pointMap.outputLinksAsCSV(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "RefFrom,RefTo", "65537,131074", "65538,131073"}; REQUIRE(lines == expected); } SECTION("PointMap::outputConnectionsAsCSV") { std::stringstream stream; pointMap.outputConnectionsAsCSV(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "RefFrom,RefTo", "65537,131073", "65537,131074", "65537,65538", "65538,131074", "65538,131073", "131073,131074"}; REQUIRE(lines == expected); } SECTION("PointMap::outputConnections") { std::stringstream stream; pointMap.outputConnections(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "#graph v1.0", "node {", " ref 65537", " origin 0.5 0.5 0", " connections [", " 131073,", " 131074,", " 65538,", " ]", "}", "node {", " ref 65538", " origin 0.5 1 0", " connections [", " 131074,", " 65537,", " 131073,", " ]", "}", "node {", " ref 131073", " origin 1 0.5 0", " connections [", " 131074,", " 65538,", " 65537,", " ]", "}", "node {", " ref 131074", " origin 1 1 0", " connections [", " 65538,", " 65537,", " 131073,", " ]", "}", "" }; REQUIRE(lines == expected); } } TEST_CASE("Direct pointmap linking - fully filled grid (no geometry)", "") { double spacing = 0.5; Point2f offset(0,0); // seems that this is always set to 0,0 Point2f bottomLeft(0,0); Point2f topRight(2,4); int fill_type = 0; // = QDepthmapView::FULLFILL std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->setRegion(bottomLeft, topRight); PointMap pointMap(metaGraph->getRegion(), metaGraph->m_drawingFiles, "Test PointMap"); pointMap.setGrid(spacing, offset); Point2f gridBottomLeft = pointMap.getRegion().bottom_left; Point2f midPoint(gridBottomLeft.x + spacing * (floor(pointMap.getCols() * 0.5) + 0.5), gridBottomLeft.y + spacing * (floor(pointMap.getRows() * 0.5) + 0.5)); pointMap.makePoints(midPoint, fill_type); std::vector mergeLines; PixelRef bottomLeftPixel = pointMap.pixelate(bottomLeft); PixelRef topRightPixel = pointMap.pixelate(topRight); // make sure pixels are not already merged REQUIRE(!pointMap.isPixelMerged(bottomLeftPixel)); REQUIRE(!pointMap.isPixelMerged(topRightPixel)); // merge pointMap.mergePixels(bottomLeftPixel, topRightPixel); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(bottomLeftPixel)); REQUIRE(pointMap.isPixelMerged(topRightPixel)); SECTION ("Make sure we get the correct number of merged pixel pairs") { const std::vector> &pixelPairs = pointMap.getMergedPixelPairs(); REQUIRE(pixelPairs.size() == 1); REQUIRE(pixelPairs[0].first == bottomLeftPixel); REQUIRE(pixelPairs[0].second == topRightPixel); } SECTION ("Overwrite the pixelpair by re-merging the first pixel of the pair") { PixelRef aboveBottomLeftPixel = pointMap.pixelate(Point2f(bottomLeft.x, bottomLeft.y + 1)); // merge pointMap.mergePixels(aboveBottomLeftPixel, topRightPixel); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(aboveBottomLeftPixel)); REQUIRE(pointMap.isPixelMerged(topRightPixel)); // and previous pixel is not merged any more REQUIRE(!pointMap.isPixelMerged(bottomLeftPixel)); // make sure we get the correct number of merged pixel pairs const std::vector> &pixelPairs = pointMap.getMergedPixelPairs(); REQUIRE(pixelPairs.size() == 1); REQUIRE(pixelPairs[0].first == aboveBottomLeftPixel); REQUIRE(pixelPairs[0].second == topRightPixel); } SECTION ("Overwrite the pixelpair by re-merging the second pixel of the pair") { PixelRef belowTopRightPixel = pointMap.pixelate(Point2f(topRight.x, topRight.y - 1)); // merge pointMap.mergePixels(bottomLeftPixel, belowTopRightPixel); // make sure pixels are merged REQUIRE(pointMap.isPixelMerged(bottomLeftPixel)); REQUIRE(pointMap.isPixelMerged(belowTopRightPixel)); // and previous pixel is not merged any more REQUIRE(!pointMap.isPixelMerged(topRightPixel)); // make sure we get the correct number of merged pixel pairs const std::vector> &pixelPairs2 = pointMap.getMergedPixelPairs(); REQUIRE(pixelPairs2.size() == 1); REQUIRE(pixelPairs2[0].first == bottomLeftPixel); REQUIRE(pixelPairs2[0].second == belowTopRightPixel); } SECTION ("Merge the same pixel twice to erase the pair") { pointMap.mergePixels(bottomLeftPixel, bottomLeftPixel); // make sure no pixel is merged REQUIRE(!pointMap.isPixelMerged(bottomLeftPixel)); REQUIRE(!pointMap.isPixelMerged(topRightPixel)); // make sure we get the correct number of merged pixel pairs const std::vector> &pixelPairs3 = pointMap.getMergedPixelPairs(); REQUIRE(pixelPairs3.size() == 0); } } ================================================ FILE: salaTest/testpushvalues.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mgraph.h" #include "salalib/pointdata.h" #include "salalib/shapemap.h" #include "salalib/spacepixfile.h" TEST_CASE("Push values from shapemaps to VGA", "") { float vgaMinX = 0.00; float vgaMinY = 0.00; float vgaMaxX = 6.00; float vgaMaxY = 6.00; float cellSize = 1.0; float minorOffset = cellSize * 0.05; // used to make sure that shapes don't fall exactly on the pointmap pixels // The testing pointmap looks like below, filled at the 'o' // // 1 2 3 4 5 // | | | | | | // - + - + - + - + - + - + - // 1 | o | o | o | o | o | // - + - + - + - + - + - + - // 2 | o | o | o | o | o | // - + - + - + - + - + - + - // 3 | o | o | o | o | o | // - + - + - + - + - + - + - // 4 | o | o | o | o | o | // - + - + - + - + - + - + - // 5 | o | o | o | o | o | // - + - + - + - + - + - + - // | | | | | | // in fact it should not be a requirement to make all these maps through // the metagraph, but instead through a "map pusher" of some sorts std::unique_ptr mgraph(new MetaGraph); mgraph->m_drawingFiles.emplace_back("Drawing file"); mgraph->m_drawingFiles.back().m_spacePixels.emplace_back("Drawing Map"); ShapeMap &drawingMap = mgraph->m_drawingFiles.back().m_spacePixels.back(); // rectangle containing the filled area of the pointmap offset by 0.5 to // make sure it falls exactly on the edge of the 1.0-sized cell drawingMap.makePolyShape( { Point2f(vgaMinX + cellSize * 0.5, vgaMinY + cellSize * 0.5), // Point2f(vgaMinX + cellSize * 0.5, vgaMaxY - cellSize * 0.5), // Point2f(vgaMaxX - cellSize * 0.5, vgaMaxY - cellSize * 0.5), // Point2f(vgaMaxX - cellSize * 0.5, vgaMinY + cellSize * 0.5) // }, false); Point2f bl = drawingMap.getRegion().bottom_left; Point2f tr = drawingMap.getRegion().top_right; mgraph->updateParentRegions(drawingMap); mgraph->addNewPointMap("VGA Map"); PointMap &vgaMap = mgraph->getPointMaps().back(); vgaMap.setGrid(1.0); vgaMap.makePoints(Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, (vgaMinY + vgaMaxY) * 0.5 + minorOffset), 0); vgaMap.sparkGraph2(nullptr, false, -1); AttributeTable &vgaTable = vgaMap.getAttributeTable(); int minI = std::numeric_limits::max(); int minJ = std::numeric_limits::max(); int maxI = -std::numeric_limits::max(); int maxJ = -std::numeric_limits::max(); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); if (key.x < minI) minI = key.x; if (key.y < minJ) minJ = key.y; if (key.x > maxI) maxI = key.x; if (key.y > maxJ) maxJ = key.y; } int midI = floor((minI + maxI) * 0.5); int midJ = floor((minJ + maxJ) * 0.5); std::string attributeName = "Shape Value"; int vgaAttrColIdx = vgaMap.addAttribute(attributeName); SECTION("Data map") { mgraph->addShapeMap("Test ShapeMap"); ShapeMap &sourceMap = mgraph->getDataMaps().back(); int sourceAttrColIdx = sourceMap.addAttribute(attributeName); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == -1); } SECTION("Single polygon input") { // main testing shape. drawn in a way so that it contains the pixels // that are not on the outer-edge of the pointmap sourceMap.makePolyShape( { Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMinY + cellSize * 1.5 - minorOffset) // }, false); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); // all values are 1 (like the polygon) except from those on the edges for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = 1; if (key.x == minI || key.x == maxI || key.y == minJ || key.y == maxJ) { expectedValue = -1; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Two overlapping polygons input", "") { // left polygon sourceMap.makePolyShape( { Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, vgaMinY + cellSize * 1.5 - minorOffset) // }, false); // right polygon sourceMap.makePolyShape( { Point2f((vgaMinX + vgaMaxX) * 0.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 - minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMinY + cellSize * 1.5 - minorOffset) // }, false); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); sourceMap.getAttributeTable().getRow(AttributeKey(1)).setValue(sourceAttrColIdx, 2); SECTION("Shared border max function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = 1; if (key.x == minI || key.x == maxI || key.y == minJ || key.y == maxJ) { // cells on the border expectedValue = -1; } else if (key.x > midI) { // cells on the right polygon expectedValue = 2; } else if (key.x == midI) { // cells on the shared border get the MAXIMUM value from the two polygons expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Shared border min function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MIN); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = 1; if (key.x == minI || key.x == maxI || key.y == minJ || key.y == maxJ) { // cells on the border expectedValue = -1; } else if (key.x > midI) { // cells on the right polygon expectedValue = 2; } else if (key.x == midI) { // cells on the shared border get the MINIMUM value from the two polygons expectedValue = 1; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Shared border average function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_AVG); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = 1; if (key.x == minI || key.x == maxI || key.y == minJ || key.y == maxJ) { // cells on the border expectedValue = -1; } else if (key.x > midI) { // cells on the right polygon expectedValue = 2; } else if (key.x == midI) { // cells on the shared border get the AVERAGE value of the two polygons expectedValue = 1.5; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Shared border total function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_TOT); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = 1; if (key.x == minI || key.x == maxI || key.y == minJ || key.y == maxJ) { // cells on the border expectedValue = -1; } else if (key.x > midI) { // cells on the right polygon expectedValue = 2; } else if (key.x == midI) { // cells on the shared border get the TOTAL value of the two polygons expectedValue = 3; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } } SECTION("Single line input", "") { // vertical line sourceMap.makeLineShape({ Point2f((vgaMinX + vgaMaxX) * 0.5 - minorOffset, vgaMinY + minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, vgaMaxY - minorOffset) // }); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI) { expectedValue = 1; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines input", "") { // vertical line sourceMap.makeLineShape({ Point2f((vgaMinX + vgaMaxX) * 0.5 - minorOffset, vgaMinY + minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, vgaMaxY - minorOffset) // }); // horizontal line sourceMap.makeLineShape({ Point2f(vgaMinX + minorOffset, (vgaMinY + vgaMaxY) * 0.5 - minorOffset), // Point2f(vgaMaxX - minorOffset, (vgaMinY + vgaMaxY) * 0.5 + minorOffset) // }); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); sourceMap.getAttributeTable().getRow(AttributeKey(1)).setValue(sourceAttrColIdx, 2); SECTION("Crossing lines max function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the MAXIMUM value of the two expectedValue = 2; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines min function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MIN); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the MINIMUM value of the two expectedValue = 1; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines average function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_AVG); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the AVERAGE value of the two expectedValue = 1.5; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines total function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_TOT); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the TOTAL value of the two expectedValue = 3; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } } SECTION("Single open polyline input", "") { // L shape sourceMap.makePolyShape( { Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset) // }, true); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == minI || key.y == maxJ) { expectedValue = 1; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing open polylines input", "") { // L shape sourceMap.makePolyShape( { Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset) // }, true); // L shape rotated 180 degrees sourceMap.makePolyShape( { Point2f(vgaMinX + cellSize * 1.5 - minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMinY + cellSize * 1.5 - minorOffset), // Point2f(vgaMaxX - cellSize * 1.5 + minorOffset, vgaMaxY - cellSize * 1.5 + minorOffset) // }, true); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); sourceMap.getAttributeTable().getRow(AttributeKey(1)).setValue(sourceAttrColIdx, 2); SECTION("Crossing open polylines max function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if ((key.x == minI && key.y == minJ) || (key.x == maxI && key.y == maxJ)) { // cells on line intersection get the MAXIMUM value of the two expectedValue = 2; } else if (key.x == minI || key.y == maxJ) { // L shape expectedValue = 1; } else if (key.x == maxI || key.y == minJ) { // L shape rotated 180 degrees expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing open polylines min function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MIN); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if ((key.x == minI && key.y == minJ) || (key.x == maxI && key.y == maxJ)) { // cells on line intersection get the MINUMUM value of the two expectedValue = 1; } else if (key.x == minI || key.y == maxJ) { // L shape expectedValue = 1; } else if (key.x == maxI || key.y == minJ) { // L shape rotated 180 degrees expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing open polylines average function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_AVG); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if ((key.x == minI && key.y == minJ) || (key.x == maxI && key.y == maxJ)) { // cells on line intersection get the AVERAGE value of the two expectedValue = 1.5; } else if (key.x == minI || key.y == maxJ) { // L shape expectedValue = 1; } else if (key.x == maxI || key.y == minJ) { // L shape rotated 180 degrees expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing open polylines total function") { mgraph->pushValuesToLayer(MetaGraph::VIEWDATA, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_TOT); // all values are -1 except from those under the line (1) for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if ((key.x == minI && key.y == minJ) || (key.x == maxI && key.y == maxJ)) { // cells on line intersection get the TOTAL value of the two expectedValue = 3; } else if (key.x == minI || key.y == maxJ) { // L shape expectedValue = 1; } else if (key.x == maxI || key.y == minJ) { // L shape rotated 180 degrees expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } } } SECTION("Axial map") { // the pushValues function takes the base shapemap so these sections are mainly to test // sending ShapeGraphs and setting the source map type to MetaGraph::VIEWAXIAL mgraph->addShapeGraph("Test Axial Map", ShapeMap::AXIALMAP); ShapeGraph &sourceMap = *mgraph->getShapeGraphs().back().get(); sourceMap.init(2, mgraph->getRegion()); sourceMap.initialiseAttributesAxial(); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == -1); } // vertical line sourceMap.makeLineShape({ Point2f((vgaMinX + vgaMaxX) * 0.5 - minorOffset, vgaMinY + minorOffset), // Point2f((vgaMinX + vgaMaxX) * 0.5 + minorOffset, vgaMaxY - minorOffset) // }); // horizontal line sourceMap.makeLineShape({ Point2f(vgaMinX + minorOffset, (vgaMinY + vgaMaxY) * 0.5 - minorOffset), // Point2f(vgaMaxX - minorOffset, (vgaMinY + vgaMaxY) * 0.5 + minorOffset) // }); int sourceAttrColIdx = sourceMap.addAttribute(attributeName); sourceMap.getAttributeTable().getRow(AttributeKey(0)).setValue(sourceAttrColIdx, 1); sourceMap.getAttributeTable().getRow(AttributeKey(1)).setValue(sourceAttrColIdx, 2); sourceMap.makeConnections(); REQUIRE(sourceMap.getAttributeTable().hasColumn("Connectivity")); SECTION("Crossing lines max function") { mgraph->pushValuesToLayer(MetaGraph::VIEWAXIAL, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MAX); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the MAXIMUM value of the two expectedValue = 2; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines min function") { mgraph->pushValuesToLayer(MetaGraph::VIEWAXIAL, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_MIN); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the MINIMUM value of the two expectedValue = 1; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines average function") { mgraph->pushValuesToLayer(MetaGraph::VIEWAXIAL, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_AVG); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the AVERAGE value of the two expectedValue = 1.5; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } SECTION("Crossing lines total function") { mgraph->pushValuesToLayer(MetaGraph::VIEWAXIAL, 0, MetaGraph::VIEWVGA, 0, sourceAttrColIdx, vgaAttrColIdx, MetaGraph::PUSH_FUNC_TOT); for (auto vgaRowIter = vgaTable.begin(); vgaRowIter != vgaTable.end(); vgaRowIter++) { PixelRef key(vgaRowIter->getKey().value); float expectedValue = -1; if (key.x == midI && key.y == midJ) { // cells on line intersection get the TOTAL value of the two expectedValue = 3; } else if (key.x == midI) { // vertical line expectedValue = 1; } else if (key.y == midJ) { // horizontal line expectedValue = 2; } REQUIRE(vgaRowIter->getRow().getValue(vgaAttrColIdx) == expectedValue); } } } } ================================================ FILE: salaTest/testsalaprogram.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "../salalib/mapconverter.h" #include "catch.hpp" #include "salalib/salaprogram.h" #include "genlib/p2dpoly.h" #include "salalib/mgraph.h" #include "salalib/axialmap.h" #include // Most of these test cases are adapted from salalib/salascript-tests.txt // with some added for completeness TEST_CASE("Trivial scripts") { std::stringstream script; SalaObj expected; SECTION("comment") { script << "# comment\n"; } SECTION("single dimension lists") { script << "x = [1,2]\n" << "x[1] = 10\n" << "x[1]\n"; expected = SalaObj(10); } SECTION("multiple dimension lists") { script << "x = [[1,2],[3,4]]\n" << "x[0][1] = 10\n" << "x[0][1]\n"; expected = SalaObj(10); } SECTION("range direct access") { script << "range(5,10)[2]\n"; expected = SalaObj(7); } SECTION("list return length") { script << "x = [1,2,3]\n" << "len(x)\n"; expected = SalaObj(3); } SECTION("list return list") { script << "x = [1,2,3]\n" << "x\n"; expected = SalaObj(SalaObj::Type::S_LIST, 3); expected.list_at(0) = SalaObj(1); expected.list_at(1) = SalaObj(2); expected.list_at(2) = SalaObj(3); } SECTION("2D list return length") { script << "x = [[1,2],[3,4]]\n" << "len(x)\n"; expected = SalaObj(2); } SECTION("2D list return list") { script << "x = [[1,2],[3,4]]\n" << "x\n"; expected = SalaObj(SalaObj::Type::S_LIST, 2); expected.list_at(0) = SalaObj(SalaObj::Type::S_LIST, 2); expected.list_at(0).list_at(0) = SalaObj(1); expected.list_at(0).list_at(1) = SalaObj(2); expected.list_at(1) = SalaObj(SalaObj::Type::S_LIST, 2); expected.list_at(1).list_at(0) = SalaObj(3); expected.list_at(1).list_at(1) = SalaObj(4); } SECTION("Pythonesque curios: lists by reference") { script << "x = [1,2,3,4]\n" << "y = x\n" << "y[3] = 40\n" << "x[3]\n"; expected = SalaObj(40); } SalaGrf graph; SalaObj context = SalaObj(SalaObj::S_POINTMAPOBJ, graph); SalaProgram program(context); program.parse(script); SalaObj result = program.evaluate(); REQUIRE(result == expected); } TEST_CASE("Trivial errors") { std::stringstream script; SECTION("simple for with error: i should be uninitialised") { script << "x = 0\n" << "for i in range(5,10):\n" << " x = 1\n" << "x = x + i\n"; } SalaGrf graph; SalaObj context = SalaObj(SalaObj::S_POINTMAPOBJ, graph); SalaProgram program(context); program.parse(script); REQUIRE_THROWS_WITH(program.evaluate(), ""); } TEST_CASE("Variables from outer scope are accessible in inner scope") { std::stringstream script; SalaObj expected; SECTION("Access to global scope from within a for loop") { script << "x = 5\n" << "for i in range(0,1):\n" << " x = 100\n" << "x"; expected = SalaObj(100); } SalaGrf graph; SalaObj context = SalaObj(SalaObj::S_POINTMAPOBJ, graph); SalaProgram program(context); program.parse(script); SalaObj result = program.evaluate(); REQUIRE(result.toInt() == expected.toInt()); } TEST_CASE("Shapemap scripts") { const double EPSILON = 0.001; Point2f line1Start(0,0); Point2f line1End (3,0); Point2f line2Start(1,1); Point2f line2End (1,-1); Point2f line3Start(2,1); Point2f line3End (2,-2); Point2f line4Start(2,1); Point2f line4End (4,1); Point2f line5Start(5,3); Point2f line5End (3,1); std::unique_ptr metaGraph(new MetaGraph("Test SuperSpacePixel")); metaGraph->m_drawingFiles.push_back(SpacePixelFile("Test SpacePixelGroup")); metaGraph->m_drawingFiles.back().m_spacePixels.push_back(ShapeMap("Test ShapeMap")); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line1Start, line1End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line2Start, line2End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line3Start, line3End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line4Start, line4End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line5Start, line5End)); auto shapeGraph = MapConverter::convertDrawingToAxial(0, "Test axial", metaGraph->m_drawingFiles); std::stringstream script; std::vector expectedColVals; SECTION("pass ref to new column") { script << "value(\"Ref Number\")\n"; expectedColVals.push_back(0.0); expectedColVals.push_back(1.0); expectedColVals.push_back(2.0); expectedColVals.push_back(3.0); expectedColVals.push_back(4.0); } SECTION("if, function of a function on a range") { script << "x = len(range(1,value(\"Ref Number\")))\n" << "if x == 2:\n" << " return 5\n" << "elif x < 1:\n" << " return 10\n" << "x\n" << "# first two objects should be set to 10, next to 5, and then ref number after that;\n"; expectedColVals.push_back(10.0); expectedColVals.push_back(10.0); expectedColVals.push_back(1.0); expectedColVals.push_back(5.0); expectedColVals.push_back(3.0); } SECTION("simple if") { script << "if value(\"Ref Number\") < 2:\n" << " 0\n" << "elif value(\"Ref Number\") == 3:\n" << " 5\n" << "else\n" << " 10\n"; expectedColVals.push_back(0.0); expectedColVals.push_back(0.0); expectedColVals.push_back(10.0); expectedColVals.push_back(5.0); expectedColVals.push_back(10.0); } SECTION("various member functions tests") { script << "this.value(\"Ref Number\")\n" << " len(range(1,this.value(\"Ref Number\")))\n" << "elif value(\"Ref Number\") == 3:\n" << " range(1,this.value(\"Ref Number\")).length()\n"; expectedColVals.push_back(0.0); expectedColVals.push_back(0.0); expectedColVals.push_back(1.0); expectedColVals.push_back(2.0); expectedColVals.push_back(3.0); } int newCol = shapeGraph->addAttribute("NewCol"); SalaGrf graph; graph.map.shape = shapeGraph.get(); SalaObj context = SalaObj(SalaObj::S_SHAPEMAPOBJ, graph); SalaProgram program(context); program.parse(script); program.runupdate(newCol); REQUIRE(shapeGraph->getAttributeTable().getNumRows() == expectedColVals.size()); auto iter = expectedColVals.begin(); auto &attributes = shapeGraph->getAttributeTable(); for (auto rowIter = attributes.begin(); rowIter != attributes.end(); rowIter++) { REQUIRE(rowIter->getRow().getValue(newCol) == Approx(*iter).epsilon(EPSILON)); iter++; } } TEST_CASE("Shapemap scripts with unexpected results") { const double EPSILON = 0.001; Point2f line1Start(0,0); Point2f line1End (3,0); Point2f line2Start(1,1); Point2f line2End (1,-1); Point2f line3Start(2,1); Point2f line3End (2,-2); Point2f line4Start(2,1); Point2f line4End (4,1); Point2f line5Start(5,3); Point2f line5End (3,1); std::unique_ptr metaGraph(new MetaGraph("Test SuperSpacePixel")); metaGraph->m_drawingFiles.push_back(SpacePixelFile("Test SpacePixelGroup")); metaGraph->m_drawingFiles.back().m_spacePixels.push_back(ShapeMap("Test ShapeMap")); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line1Start, line1End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line2Start, line2End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line3Start, line3End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line4Start, line4End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line5Start, line5End)); auto shapeGraph = MapConverter::convertDrawingToAxial(0, "Test axial", metaGraph->m_drawingFiles); std::stringstream script; std::vector expectedColVals; SECTION("for with else and 0 length ranges") { script << "int x = 0\n" << "for i in range(2,value(\"Ref Number\")):\n" << " x = x + i\n" << " x\n" << "else:\n" << " 0\n"; expectedColVals.push_back(0.0); expectedColVals.push_back(0.0); expectedColVals.push_back(0.0); expectedColVals.push_back(2.0); expectedColVals.push_back(5.0); } SECTION("Total Depth Calculation") { script << "total_depth = 0\n" << "depth = 0\n" << "pop_list = [this]\n" << "push_list = []\n" << "setmark(true)\n" << "while len(pop_list):\n" << " total_depth = total_depth + depth\n" << " curs = pop_list.pop()\n" << " for i in curs.connections():\n" << " if i.mark() is none:\n" << " i.setmark(true)\n" << " push_list.append(i)\n" << " if len(pop_list) == 0:\n" << " depth = depth + 1\n" << " pop_list = push_list\n" << " push_list = []\n" << "total_depth\n"; expectedColVals.push_back(7.0); expectedColVals.push_back(10.0); expectedColVals.push_back(6.0); expectedColVals.push_back(7.0); expectedColVals.push_back(10.0); } SECTION("Shortest Cycle") { script << "push_list = []\n" << "pop_list = []\n" << "live_paths = []\n" << "setmark([-1,0])\n" << "depth = 1\n" << "path_index = 0\n" << "for i in connections():\n" << " pop_list.append([path_index,i])\n" << " live_paths.append(1)\n" << " i.setmark([path_index,depth])\n" << " path_index = path_index + 1\n" << "if path_index < 2:\n" << " return -1 # no cycle possible\n" << "live_path_count = path_index\n" << "while len(pop_list) and live_path_count > 1:\n" << " curs = pop_list.pop()\n" << " path_index = curs[0]\n" << " this_node = curs[1]\n" << " live_paths[path_index] = live_paths[path_index] - 1\n" << " for i in this_node.connections():\n" << " if i.mark() is none:\n" << " i.setmark([path_index,depth+1])\n" << " push_list.append([path_index,i])\n" << " live_paths[path_index] = live_paths[path_index] + 1\n" << " elif i.mark()[0] != path_index and i.mark()[0] != -1:\n" << " # found a cycle!\n" << " return i.mark()[1] + this_node.mark()[1] + 1\n" << " if live_paths[path_index] == 0:\n" << " live_path_count = live_path_count - 1\n" << " if len(pop_list) == 0:\n" << " depth = depth + 1\n" << " pop_list = push_list\n" << " push_list = []\n" << "-1 # no cycle found\n"; expectedColVals.push_back(-1.0); expectedColVals.push_back(-1.0); expectedColVals.push_back(-1.0); expectedColVals.push_back(-1.0); expectedColVals.push_back(-1.0); } int newCol = shapeGraph->addAttribute("NewCol"); SalaGrf graph; graph.map.shape = shapeGraph.get(); SalaObj context = SalaObj(SalaObj::S_SHAPEMAPOBJ, graph); SalaProgram program(context); program.parse(script); program.runupdate(newCol); REQUIRE(shapeGraph->getAttributeTable().getNumRows() == expectedColVals.size()); auto iter = expectedColVals.begin(); auto &attributes = shapeGraph->getAttributeTable(); for (auto rowIter = attributes.begin(); rowIter != attributes.end(); rowIter++) { REQUIRE(rowIter->getRow().getValue(newCol) == Approx(*iter).epsilon(EPSILON)); iter++; } } TEST_CASE("Performance tests") { //# For a graph with 100000 segments for cpu timing: //x=value("Angular Connectivity")*value("Angular Step Depth")+value("Axial Line Ref")+value("Connectivity")/value("Segment Length")^value("T1024 Choice R1000 metric") //y=value("T1024 Choice R3000 metric")*value("T1024 Choice R4000 metric")/value("T1024 Choice R5000 metric")^value("T1024 Total Depth [Segment Length Wgt] R4000 metric") //y/x } ================================================ FILE: salaTest/testshapegraphs.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "../salalib/mapconverter.h" #include "../genlib/p2dpoly.h" #include "../salalib/mgraph.h" #include "../salalib/shapemap.h" #include "../salalib/axialmap.h" #include "catch.hpp" #include #include TEST_CASE("Testing ShapeGraph::writeAxialConnections"){ Point2f line1Start(0,0); Point2f line1End (3,0); Point2f line2Start(1,1); Point2f line2End (1,-1); Point2f line3Start(2,1); Point2f line3End (2,-2); std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->m_drawingFiles.emplace_back("Test SpacePixelGroup"); metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line1Start, line1End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line2Start, line2End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line3Start, line3End)); auto shapegraph = MapConverter::convertDrawingToAxial(0, "Test axial", metaGraph->m_drawingFiles); SECTION("writeAxialConnectionsAsDotGraph") { std::stringstream stream; shapegraph->writeAxialConnectionsAsDotGraph(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "strict graph {", " 0 -- 1", " 0 -- 2", " 1 -- 0", " 2 -- 0", "}", "" }; REQUIRE(lines == expected); } SECTION("writeAxialConnectionsAsPairsCSV") { std::stringstream stream; shapegraph->writeAxialConnectionsAsPairsCSV(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "refA,refB", "0,1", "0,2", "1,0", "2,0" }; REQUIRE(lines == expected); } } TEST_CASE("Testing ShapeGraph::writeSegmentConnections") { // As we are converting the drawing directly to segments // the lines need to touch, not cross Point2f line1Start(1,1); Point2f line1End (1,0); Point2f line2Start(1,0); Point2f line2End (2,0); Point2f line3Start(2,0); Point2f line3End (2,2); std::unique_ptr metaGraph(new MetaGraph("Test MetaGraph")); metaGraph->m_drawingFiles.emplace_back("Test SpacePixelGroup"); metaGraph->m_drawingFiles.back().m_spacePixels.emplace_back("Test ShapeMap"); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line1Start, line1End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line2Start, line2End)); metaGraph->m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(line3Start, line3End)); auto shapegraph = MapConverter::convertDrawingToSegment(0, "Test segment", metaGraph->m_drawingFiles); SECTION("writeSegmentConnectionsAsPairsCSV") { std::stringstream stream; shapegraph->writeSegmentConnectionsAsPairsCSV(stream); REQUIRE(stream.good()); char line[1000]; std::vector lines; while( !stream.eof()) { stream.getline(line, 1000); lines.push_back(line); } std::vector expected{ "refA,refB,ss_weight,for_back,dir", "0,1,1,0,1", "1,2,1,0,1", "1,0,1,1,-1", "2,1,1,1,-1" }; REQUIRE(lines == expected); } } // While the linking functionality is placed in the ShapeMap, // (for example the variables m_links and m_unlinks) it can // only be used through ShapeGraph because it starts with // m_hasgraph = true. Ideally the linking functionality should // move to the ShapeGraph TEST_CASE("Testing ShapeMap::getAllLinkLines and ShapeMap::getAllUnlinkPoints()") { const float EPSILON = 0.001; const double TOLERANCE_A = 1e-9; Point2f line0Start (0.522, 0.424); Point2f line0End (0.709, 1.098); Point2f line1Start (0.897, 1.123); Point2f line1End (1.122, 0.421); Point2f line2Start (1.073, 0.386); Point2f line2End (1.269, 1.196); std::unique_ptr shapeGraph(new ShapeGraph("Test ShapeMap")); shapeGraph->makeLineShape(Line(line0Start, line0End)); shapeGraph->makeLineShape(Line(line1Start, line1End)); shapeGraph->makeLineShape(Line(line2Start, line2End)); shapeGraph->makeShapeConnections(); shapeGraph->linkShapes(0,1); shapeGraph->unlinkShapes(1,2); std::vector linkLines = shapeGraph->getAllLinkLines(); REQUIRE(linkLines.size() == 1); REQUIRE(linkLines[0].start().x == Approx((line0Start.x + line0End.x)*0.5).epsilon(EPSILON)); REQUIRE(linkLines[0].start().y == Approx((line0Start.y + line0End.y)*0.5).epsilon(EPSILON)); REQUIRE(linkLines[0].end().x == Approx((line1Start.x + line1End.x)*0.5).epsilon(EPSILON)); REQUIRE(linkLines[0].end().y == Approx((line1Start.y + line1End.y)*0.5).epsilon(EPSILON)); std::vector unlinkPoints = shapeGraph->getAllUnlinkPoints(); REQUIRE(unlinkPoints.size() == 1); Point2f intersection = intersection_point(Line(line1Start, line1End), Line(line2Start, line2End), TOLERANCE_A); REQUIRE(unlinkPoints[0].x == Approx(intersection.x).epsilon(EPSILON)); REQUIRE(unlinkPoints[0].y == Approx(intersection.y).epsilon(EPSILON)); } ================================================ FILE: salaTest/testshapemaps.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "../genlib/p2dpoly.h" #include "../salalib/mgraph.h" #include "../salalib/shapemap.h" #include "../salalib/axialmap.h" #include "catch.hpp" #include #include TEST_CASE("Testing ShapeMap::getAllShapes variants") { const float EPSILON = 0.001; Point2f line0Start(0,1); Point2f line0End (3,2); Point2f line1Start(1,1); Point2f line1End (1,-1); std::unique_ptr shapeMap(new ShapeMap("Test ShapeMap")); shapeMap->makeLineShape(Line(line0Start, line0End)); shapeMap->makeLineShape(Line(line1Start, line1End)); std::vector polyVertices; polyVertices.push_back(Point2f(-1,-1)); polyVertices.push_back(Point2f( 2,-1)); polyVertices.push_back(Point2f( 0, 0)); shapeMap->makePolyShape(polyVertices, false, false); SECTION("ShapeMap::getAllShapesAsLines") { std::vector lines = shapeMap->getAllShapesAsLines(); REQUIRE(lines.size() == 5); REQUIRE(lines[0].start().x == Approx(line0Start.x).epsilon(EPSILON)); REQUIRE(lines[0].start().y == Approx(line0Start.y).epsilon(EPSILON)); REQUIRE(lines[0].end().x == Approx(line0End.x).epsilon(EPSILON)); REQUIRE(lines[0].end().y == Approx(line0End.y).epsilon(EPSILON)); REQUIRE(lines[1].start().x == Approx(line1Start.x).epsilon(EPSILON)); REQUIRE(lines[1].start().y == Approx(line1Start.y).epsilon(EPSILON)); REQUIRE(lines[1].end().x == Approx(line1End.x).epsilon(EPSILON)); REQUIRE(lines[1].end().y == Approx(line1End.y).epsilon(EPSILON)); REQUIRE(lines[2].start().x == Approx(polyVertices[0].x).epsilon(EPSILON)); REQUIRE(lines[2].start().y == Approx(polyVertices[0].y).epsilon(EPSILON)); REQUIRE(lines[2].end().x == Approx(polyVertices[1].x).epsilon(EPSILON)); REQUIRE(lines[2].end().y == Approx(polyVertices[1].y).epsilon(EPSILON)); REQUIRE(lines[3].start().x == Approx(polyVertices[1].x).epsilon(EPSILON)); REQUIRE(lines[3].start().y == Approx(polyVertices[1].y).epsilon(EPSILON)); REQUIRE(lines[3].end().x == Approx(polyVertices[2].x).epsilon(EPSILON)); REQUIRE(lines[3].end().y == Approx(polyVertices[2].y).epsilon(EPSILON)); REQUIRE(lines[4].start().x == Approx(polyVertices[2].x).epsilon(EPSILON)); REQUIRE(lines[4].start().y == Approx(polyVertices[2].y).epsilon(EPSILON)); REQUIRE(lines[4].end().x == Approx(polyVertices[0].x).epsilon(EPSILON)); REQUIRE(lines[4].end().y == Approx(polyVertices[0].y).epsilon(EPSILON)); } SECTION("ShapeMap::getAllLinesWithColour") { shapeMap->overrideDisplayedAttribute(-2); shapeMap->setDisplayedAttribute(-1); // displayed attribute is shape_ref std::vector> colouredLines = shapeMap->getAllLinesWithColour(); REQUIRE(colouredLines.size() == 2); REQUIRE(colouredLines[0].first.start().x == Approx(std::min(line0Start.x, line0End.x)).epsilon(EPSILON)); REQUIRE(colouredLines[0].first.start().y == Approx(std::min(line0Start.y, line0End.y)).epsilon(EPSILON)); REQUIRE(colouredLines[0].first.end().x == Approx(std::max(line0Start.x, line0End.x)).epsilon(EPSILON)); REQUIRE(colouredLines[0].first.end().y == Approx(std::max(line0Start.y, line0End.y)).epsilon(EPSILON)); REQUIRE(colouredLines[0].second.redf() == Approx(0.2f).epsilon(EPSILON)); REQUIRE(colouredLines[0].second.greenf() == Approx(0.2f).epsilon(EPSILON)); REQUIRE(colouredLines[0].second.bluef() == Approx(0.86667f).epsilon(EPSILON)); REQUIRE(colouredLines[1].first.start().x == Approx(line1Start.x).epsilon(EPSILON)); REQUIRE(colouredLines[1].first.start().y == Approx(line1Start.y).epsilon(EPSILON)); REQUIRE(colouredLines[1].first.end().x == Approx(line1End.x).epsilon(EPSILON)); REQUIRE(colouredLines[1].first.end().y == Approx(line1End.y).epsilon(EPSILON)); REQUIRE(colouredLines[1].second.redf() == Approx(0.13333f).epsilon(EPSILON)); REQUIRE(colouredLines[1].second.greenf() == Approx(0.86667f).epsilon(EPSILON)); REQUIRE(colouredLines[1].second.bluef() == Approx(0.53333f).epsilon(EPSILON)); } SECTION("ShapeMap::getAllPolygonsWithColour") { shapeMap->overrideDisplayedAttribute(-2); shapeMap->setDisplayedAttribute(-1); // displayed attribute is shape_ref std::vector, PafColor>> colouredPolygons = shapeMap->getAllPolygonsWithColour(); REQUIRE(colouredPolygons.size() == 1); auto iter = colouredPolygons.begin(); const std::vector vertices = iter->first; const PafColor colour = iter->second; REQUIRE(vertices[0].x == Approx(polyVertices[0].x).epsilon(EPSILON)); REQUIRE(vertices[0].y == Approx(polyVertices[0].y).epsilon(EPSILON)); REQUIRE(vertices[1].x == Approx(polyVertices[1].x).epsilon(EPSILON)); REQUIRE(vertices[1].y == Approx(polyVertices[1].y).epsilon(EPSILON)); REQUIRE(vertices[2].x == Approx(polyVertices[2].x).epsilon(EPSILON)); REQUIRE(vertices[2].y == Approx(polyVertices[2].y).epsilon(EPSILON)); REQUIRE(colour.redf() == Approx(0.86667f).epsilon(EPSILON)); REQUIRE(colour.greenf() == Approx(0.2f).epsilon(EPSILON)); REQUIRE(colour.bluef() == Approx(0.2f).epsilon(EPSILON)); } } ================================================ FILE: salaTest/testshaperemove.cpp ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/mapconverter.h" #include "salalib/mgraph.h" #include #include TEST_CASE("Testing deleting shapes from shapemaps") { std::unique_ptr shapeMap(new ShapeMap("Test ShapeMap")); // This is a hash (#) shape for simplicity shapeMap->makeLineShape(Line(Point2f(0.0, 0.5), Point2f(1.5, 0.5))); shapeMap->makeLineShape(Line(Point2f(0.5, 0.0), Point2f(0.5, 1.5))); shapeMap->makeLineShape(Line(Point2f(0.0, 1.0), Point2f(1.5, 1.0))); shapeMap->makeLineShape(Line(Point2f(1.0, 0.0), Point2f(1.0, 1.5))); REQUIRE(shapeMap->getAllShapes().size() == 4); SECTION("Delete from simple shapemap from the beginning") { int shapeCount = shapeMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { shapeMap->removeShape(shapeMap->getAllShapes().begin()->first, false); REQUIRE(shapeMap->getAllShapes().size() == idx - 1); } } SECTION("Delete from simple shapemap from the end") { int shapeCount = shapeMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { shapeMap->removeShape(shapeMap->getAllShapes().rbegin()->first, false); REQUIRE(shapeMap->getAllShapes().size() == idx - 1); } } SECTION("Delete from simple shapemap from the middle") { int shapeCount = shapeMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = depthmapX::getMapAtIndex(shapeMap->getAllShapes(), int(shapeMap->getAllShapes().size() / 2))->first; shapeMap->removeShape(shapeRef, false); REQUIRE(shapeMap->getAllShapes().size() == idx - 1); } } } TEST_CASE("Testing deleting shapes from axial maps") { std::unique_ptr shapeMap(new ShapeMap("Test ShapeMap")); // This is a hash (#) shape for simplicity shapeMap->makeLineShape(Line(Point2f(0.0, 0.5), Point2f(1.5, 0.5))); shapeMap->makeLineShape(Line(Point2f(0.5, 0.0), Point2f(0.5, 1.5))); shapeMap->makeLineShape(Line(Point2f(0.0, 1.0), Point2f(1.5, 1.0))); shapeMap->makeLineShape(Line(Point2f(1.0, 0.0), Point2f(1.0, 1.5))); std::unique_ptr axialMap = MapConverter::convertDataToAxial(nullptr, "Axial map", *shapeMap.get(), false); REQUIRE(axialMap->getAllShapes().size() == 4); REQUIRE(axialMap->getConnections().size() == 4); // creates this axial map: // 1 3 // | | // 0 - + - + - // | | // 2 - + - + - // | | // map of shaperef -> vector of shaperef (not indices) std::map> axialConnections; axialConnections[0] = {1, 3}; axialConnections[1] = {0, 2}; axialConnections[2] = {1, 3}; axialConnections[3] = {0, 2}; int axialConnectivityColIdx = axialMap->getAttributeTable().getColumnIndex("Connectivity"); AttributeTable &axialTable = axialMap->getAttributeTable(); // check if shapes have connectivity attribute values that reflect the expected number of connections for (const auto &shape : axialMap->getAllShapes()) { REQUIRE(axialTable.getRow(AttributeKey(shape.first)).getValue(axialConnectivityColIdx) == axialConnections[shape.first].size()); } // check if the shape connectors have the expected internal sizes and are connected to the expected // other shapes for (int i = 0; i < axialMap->getConnections().size(); i++) { Connector connector = axialMap->getConnections()[i]; std::vector expectedConnections = axialConnections[axialMap->getShapeRefFromIndex(i)->first]; REQUIRE(connector.count(Connector::CONN_ALL) == expectedConnections.size()); for (int otherShapeRef : expectedConnections) { REQUIRE(std::find(connector.m_connections.begin(), connector.m_connections.end(), otherShapeRef) != connector.m_connections.end()); } } SECTION("Delete from an axial map from the beginning") { std::map connectivitiesAfterRemoval; for (auto iter = axialMap->getAllShapes().begin(); iter != axialMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = axialConnections[iter->first].size(); } int shapeCount = axialMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = axialMap->getAllShapes().begin()->first; axialMap->removeShape(shapeRef, false); REQUIRE(axialMap->getAllShapes().size() == idx - 1); REQUIRE(axialMap->getConnections().size() == idx - 1); for (auto it = axialMap->getAllShapes().begin(); it != axialMap->getAllShapes().end(); it++) { std::vector connConnections = axialConnections[it->first]; if (std::find(connConnections.begin(), connConnections.end(), shapeRef) != connConnections.end()) { // if the other shape contains this one, then remove from its connectivity connectivitiesAfterRemoval[it->first] = connectivitiesAfterRemoval[it->first] - 1; } REQUIRE(axialTable.getRow(AttributeKey(it->first)).getValue(axialConnectivityColIdx) == connectivitiesAfterRemoval[it->first]); } } } SECTION("Delete from an axial map from the end") { std::map connectivitiesAfterRemoval; for (auto iter = axialMap->getAllShapes().begin(); iter != axialMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = axialConnections[iter->first].size(); } int shapeCount = axialMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = axialMap->getAllShapes().rbegin()->first; axialMap->removeShape(shapeRef, false); REQUIRE(axialMap->getAllShapes().size() == idx - 1); REQUIRE(axialMap->getConnections().size() == idx - 1); for (auto it = axialMap->getAllShapes().begin(); it != axialMap->getAllShapes().end(); it++) { std::vector connConnections = axialConnections[it->first]; if (std::find(connConnections.begin(), connConnections.end(), shapeRef) != connConnections.end()) { // if the other shape contains this one, then remove from its connectivity connectivitiesAfterRemoval[it->first] = connectivitiesAfterRemoval[it->first] - 1; } REQUIRE(axialTable.getRow(AttributeKey(it->first)).getValue(axialConnectivityColIdx) == connectivitiesAfterRemoval[it->first]); } } } SECTION("Delete from an axial map from the middle") { std::map connectivitiesAfterRemoval; for (auto iter = axialMap->getAllShapes().begin(); iter != axialMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = axialConnections[iter->first].size(); } int shapeCount = axialMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = depthmapX::getMapAtIndex(axialMap->getAllShapes(), int(axialMap->getAllShapes().size() / 2))->first; axialMap->removeShape(shapeRef, false); REQUIRE(axialMap->getAllShapes().size() == idx - 1); REQUIRE(axialMap->getConnections().size() == idx - 1); for (auto it = axialMap->getAllShapes().begin(); it != axialMap->getAllShapes().end(); it++) { std::vector connConnections = axialConnections[it->first]; if (std::find(connConnections.begin(), connConnections.end(), shapeRef) != connConnections.end()) { // if the other shape contains this one, then remove from its connectivity connectivitiesAfterRemoval[it->first] = connectivitiesAfterRemoval[it->first] - 1; } REQUIRE(axialTable.getRow(AttributeKey(it->first)).getValue(axialConnectivityColIdx) == connectivitiesAfterRemoval[it->first]); } } } } TEST_CASE("Testing deleting shapes from segment maps") { std::unique_ptr shapeMap(new ShapeMap("Test ShapeMap")); // This is a hash (#) shape for simplicity shapeMap->makeLineShape(Line(Point2f(0.0, 0.5), Point2f(1.5, 0.5))); shapeMap->makeLineShape(Line(Point2f(0.5, 1.5), Point2f(0.5, 0.0))); shapeMap->makeLineShape(Line(Point2f(0.0, 1.0), Point2f(1.5, 1.0))); shapeMap->makeLineShape(Line(Point2f(1.0, 0.0), Point2f(1.0, 1.5))); std::unique_ptr axialMap = MapConverter::convertDataToAxial(nullptr, "Axial map", *shapeMap.get(), false); // creates this axial map: // 1 3 // | | // 0 - + - + - // | | // 2 - + - + - // | | std::unique_ptr segmentMap = MapConverter::convertAxialToSegment(nullptr, *axialMap.get(), "Segment map", true); // axial lines have been split in three segments // | | // 5 11 // | | // - 6 - + - 7 - + - 8 - // | | // 4 10 // | | // - 0 - + - 1 - + - 2 - // | | // 3 9 // | | REQUIRE(segmentMap->getAllShapes().size() == 12); REQUIRE(segmentMap->getConnections().size() == 12); std::map> segmentForConnections; std::map> segmentBackConnections; segmentForConnections[0] = {1, 3, 4}; segmentBackConnections[0] = {}; segmentForConnections[1] = {2, 9, 10}; segmentBackConnections[1] = {0, 3, 4}; segmentForConnections[2] = {}; segmentBackConnections[2] = {1, 9, 10}; segmentForConnections[3] = {0, 1, 4}; segmentBackConnections[3] = {}; segmentForConnections[4] = {5, 6, 7}; segmentBackConnections[4] = {0, 1, 3}; segmentForConnections[5] = {}; segmentBackConnections[5] = {4, 6, 7}; segmentForConnections[6] = {4, 5, 7}; segmentBackConnections[6] = {}; segmentForConnections[7] = {8, 10, 11}; segmentBackConnections[7] = {4, 5, 6}; segmentForConnections[8] = {}; segmentBackConnections[8] = {7, 10, 11}; segmentForConnections[9] = {1, 2, 10}; segmentBackConnections[9] = {}; segmentForConnections[10] = {7, 8, 11}; segmentBackConnections[10] = {1, 2, 9}; segmentForConnections[11] = {}; segmentBackConnections[11] = {7, 8, 10}; int segmentConnectivityColIdx = segmentMap->getAttributeTable().getColumnIndex("Connectivity"); AttributeTable &segmentTable = segmentMap->getAttributeTable(); // check if shapes have connectivity attribute values that reflect the expected number of connections for (auto iter = segmentMap->getAllShapes().begin(); iter != segmentMap->getAllShapes().end(); iter++) { REQUIRE(segmentTable.getRow(AttributeKey(iter->first)).getValue(segmentConnectivityColIdx) == segmentForConnections[iter->first].size() + segmentBackConnections[iter->first].size()); } // check if the shape connectors have the expected internal sizes and are connected to the expected // other shapes for (int i = 0; i < segmentMap->getConnections().size(); i++) { Connector connector = segmentMap->getConnections()[i]; std::vector expectedForConnections = segmentForConnections[segmentMap->getShapeRefFromIndex(i)->first]; std::vector expectedBackConnections = segmentBackConnections[segmentMap->getShapeRefFromIndex(i)->first]; REQUIRE(connector.count(Connector::SEG_CONN_ALL) == expectedForConnections.size() + expectedBackConnections.size()); REQUIRE(connector.count(Connector::SEG_CONN_FW) == expectedForConnections.size()); REQUIRE(connector.count(Connector::SEG_CONN_BK) == expectedBackConnections.size()); for (int otherShapeRef : expectedForConnections) { bool inForConnections = std::find_if(connector.m_forward_segconns.begin(), connector.m_forward_segconns.end(), [&otherShapeRef](const std::pair &segmentRef) { return segmentRef.first.ref == otherShapeRef; }) != connector.m_forward_segconns.end(); REQUIRE(inForConnections); } for (int otherShapeRef : expectedBackConnections) { bool inBackConnections = std::find_if(connector.m_back_segconns.begin(), connector.m_back_segconns.end(), [&otherShapeRef](const std::pair &segmentRef) { return segmentRef.first.ref == otherShapeRef; }) != connector.m_back_segconns.end(); REQUIRE(inBackConnections); } } SECTION("Delete from a segment map from the beginning") { std::map connectivitiesAfterRemoval; for (auto iter = segmentMap->getAllShapes().begin(); iter != segmentMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = segmentForConnections[iter->first].size() + segmentBackConnections[iter->first].size(); } int shapeCount = segmentMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = segmentMap->getAllShapes().begin()->first; segmentMap->removeShape(shapeRef, false); REQUIRE(segmentMap->getAllShapes().size() == idx - 1); REQUIRE(segmentMap->getConnections().size() == idx - 1); } } SECTION("Delete from a segment map from the end") { std::map connectivitiesAfterRemoval; for (auto iter = segmentMap->getAllShapes().begin(); iter != segmentMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = segmentForConnections[iter->first].size() + segmentBackConnections[iter->first].size(); } int shapeCount = segmentMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = segmentMap->getAllShapes().rbegin()->first; segmentMap->removeShape(shapeRef, false); REQUIRE(segmentMap->getAllShapes().size() == idx - 1); REQUIRE(segmentMap->getConnections().size() == idx - 1); } } SECTION("Delete from a segment map from the middle") { std::map connectivitiesAfterRemoval; for (auto iter = segmentMap->getAllShapes().begin(); iter != segmentMap->getAllShapes().end(); iter++) { connectivitiesAfterRemoval[iter->first] = segmentForConnections[iter->first].size() + segmentBackConnections[iter->first].size(); } int shapeCount = segmentMap->getAllShapes().size(); for (size_t idx = shapeCount; idx > 0; idx--) { int shapeRef = depthmapX::getMapAtIndex(segmentMap->getAllShapes(), int(segmentMap->getAllShapes().size() / 2)) ->first; segmentMap->removeShape(shapeRef, false); REQUIRE(segmentMap->getAllShapes().size() == idx - 1); REQUIRE(segmentMap->getConnections().size() == idx - 1); } } } ================================================ FILE: salaTest/testsparksieve.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/sparksieve2.h" #include TEST_CASE("One block garbage") { Point2f centre(1,1); sparkSieve2 sieve(centre); std::vector lines; // these lines get turned into "blocks" based by a tanify function based on q and the centre given // above. Given q=4 and centre 1,1 this line will be from 0.625 to something bigger than 1 lines.push_back(Line(Point2f(0.5, 0.2), Point2f(0.5, 0.7))); sieve.block(lines,4); sieve.collectgarbage(); REQUIRE(sieve.m_gaps.size() == 1); REQUIRE(sieve.m_gaps.begin()->start == 0); REQUIRE(sieve.m_gaps.begin()->end == Approx(0.625)); } TEST_CASE("Shift start and end") { Point2f centre(1,1); sparkSieve2 sieve(centre); std::vector lines; // .625 -> > 1 lines.push_back(Line(Point2f(0.5, 0.2), Point2f(0.5, 0.7))); // < 0 -> 0.55555557 lines.push_back(Line(Point2f(0.5,0.1),Point2f(1.1,0.9))); sieve.block(lines,4); sieve.collectgarbage(); REQUIRE(sieve.m_gaps.size() == 1); REQUIRE(sieve.m_gaps.begin()->start == Approx(0.55555555555)); REQUIRE(sieve.m_gaps.begin()->end == Approx(0.625)); } TEST_CASE("delete gap") { Point2f centre(1,1); sparkSieve2 sieve(centre); std::vector lines; // < 0 -> > 1 the block covers the whole gap lines.push_back(Line(Point2f(1.1, 0.2), Point2f(0.5, 0.7))); sieve.block(lines,4); sieve.collectgarbage(); REQUIRE(sieve.m_gaps.empty()); } TEST_CASE("add gap") { Point2f centre(1,1); sparkSieve2 sieve(centre); std::vector lines; // 0.55555 -> .625 the block splits the gap lines.push_back(Line(Point2f(0.5, 0.2), Point2f(0.5, 0.1))); // 0.71428571 -> > 1 lines.push_back(Line(Point2f(0.5,0.3), Point2f(0.5,0.7))); sieve.block(lines,4); sieve.collectgarbage(); REQUIRE(sieve.m_gaps.size() == 2); auto iter = sieve.m_gaps.begin(); REQUIRE(iter->start == 0); REQUIRE(iter->end == Approx(0.55555555555)); iter++; REQUIRE(iter->start == Approx(0.625)); REQUIRE(iter->end == Approx( 0.71428571)); } ================================================ FILE: salaTest/teststructsizes.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "catch.hpp" #include "salalib/axialmap.h" #include "salalib/axialpolygons.h" /** * This seems a bit silly, but this is a list of structs that are serialised by just dumping the memory content * into a stream, so the size/layout of these must be the same across all platforms to ensure * reading writing of graph files. */ TEST_CASE("Enforce struct sizes") { REQUIRE(sizeof(RadialKey) == 16); REQUIRE(sizeof(RadialLine) == 64); REQUIRE(sizeof(PolyConnector) == 56); REQUIRE(sizeof(QtRegion) == 32); REQUIRE(sizeof(Line) == 40); } ================================================ FILE: salalib/CMakeLists.txt ================================================ set(salalib salalib) set(salalib_SRCS axialmap.cpp connector.cpp isovist.cpp mgraph.cpp ngraph.cpp pointdata.cpp salaprogram.cpp shapemap.cpp spacepix.cpp sparksieve2.cpp entityparsing.cpp linkutils.cpp gridproperties.cpp attributetable.cpp layermanagerimpl.cpp attributetableview.cpp geometrygenerators.cpp point.cpp pafcolor.cpp spacepixfile.cpp alllinemap.cpp axialminimiser.cpp axialpolygons.cpp tidylines.cpp mapconverter.cpp importutils.cpp attributetableindex.cpp ianalysis.h) add_compile_definitions(_DEPTHMAP SALALIB_LIBRARY) add_library(${salalib} STATIC ${salalib_SRCS} ${vgamodules_SRCS} ${axialmodules_SRCS} ${segmmodules_SRCS} ${parsers_SRCS}) add_subdirectory(vgamodules) add_subdirectory(axialmodules) add_subdirectory(segmmodules) add_subdirectory(parsers) add_subdirectory(agents) ================================================ FILE: salalib/agents/CMakeLists.txt ================================================ target_sources(salalib PUBLIC agent.h agentprogram.h agentset.h agentengine.h agentga.h agenthelpers.h PRIVATE agent.cpp agentprogram.cpp agentset.cpp agentengine.cpp agentga.cpp) ================================================ FILE: salalib/agents/agent.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agent.h" #include "agenthelpers.h" Agent::Agent(AgentProgram *program, PointMap *pointmap, int output_mode) { m_program = program; m_pointmap = pointmap; m_output_mode = output_mode; m_trail_num = -1; } void Agent::onInit(PixelRef node, int trail_num) { m_node = node; m_loc = m_pointmap->depixelate(m_node); if (m_output_mode & OUTPUT_GATE_COUNTS) { // see note about gates in Through vision analysis m_gate = (m_pointmap->getPoint(node).filled()) ? (int)m_pointmap->getAttributeTable().getRow(AttributeKey(m_node)).getValue(g_col_gate) : -1; } else { m_gate = -1; } m_gate_encountered = false; m_step = 0; m_stuck = false; m_stopped = false; m_frame = 0; m_target_lock = false; m_vector = Point2f(1, 0); m_at_target = false; m_at_destination = false; m_trail_num = trail_num; m_vector = onLook(true); m_vector.normalise(); m_target_pix = NoPixel; } void Agent::onMove() { m_at_target = false; m_frame++; if (m_program->m_destination_directed && dist(m_loc, m_destination) < 10.0) { // reached final destination onDestination(); } else if ((m_program->m_sel_type & AgentProgram::SEL_TARGETTED) && dist(m_loc, m_target) < m_pointmap->getSpacing()) { // reached target (intermediate destination) m_step = 0; onTarget(); m_vector = onLook(false); } else if (prandomr() < (1.0 / m_program->m_steps) && !m_target_lock) { // note, on average, will change 1 in steps m_step = 0; m_vector = onLook(false); /* if (m_program->m_destination_directed) { Point2f vec2 = m_destination - m_loc; vec2.normalise(); if (dot(vec2,m_vector) < 0.0) { m_vector = onLook(false); } } */ } if (m_stuck) { // oops... return; } // now step... PixelRef lastnode = m_node; onStep(); if (m_node != lastnode && m_output_mode != OUTPUT_NOTHING) { if (m_pointmap->getPoint(m_node).filled()) { AttributeRow &row = m_pointmap->getAttributeTable().getRow(AttributeKey(m_node)); if (m_output_mode & OUTPUT_COUNTS) { row.incrValue(g_col_total_counts); } if (m_output_mode & OUTPUT_GATE_COUNTS) { int obj = (int)row.getValue(g_col_gate); if (m_gate != obj) { m_gate = obj; if (m_gate != -1) { row.incrValue(g_col_gate_counts); // actually crossed into a new gate: m_gate_encountered = true; } } } } } // done. happy hamster. } void Agent::onDestination() { m_at_destination = true; } void Agent::onTarget() { m_occ_memory.a().clear(); m_at_target = true; } //////////////////////////////////////////////////////////////////// void Agent::onStep() { m_stopped = false; m_step++; // Point2f nextloc = m_loc + (m_pointmap->getSpacing() * m_vector); // note: false returns unconstrained pixel: goodStep must check it is in bounds using m_pointmap->includes PixelRef nextnode = m_pointmap->pixelate(nextloc, false); if (nextnode != m_node) { // quick check location is okay... if (goodStep(nextnode)) { m_node = nextnode; m_loc = nextloc; } else { // try other nearby nodes... if (!diagonalStep()) { m_stopped = true; } } } else { m_loc = nextloc; } if (!m_stopped && m_trail_num != -1) { m_program->m_trails[m_trail_num].push_back(Event2f(m_loc, m_program->m_steps)); } } bool Agent::diagonalStep() { Point2f vector1 = m_vector; vector1.rotate(M_PI / 4.0); Point2f nextloc1 = m_loc + (m_pointmap->getSpacing() * vector1); // note: "false" does not constrain to bounds: must be checked using m_pointmap->includes before getPoint is used PixelRef nextnode1 = m_pointmap->pixelate(nextloc1, false); Point2f vector2 = m_vector; vector2.rotate(-M_PI / 4.0); Point2f nextloc2 = m_loc + (m_pointmap->getSpacing() * vector2); // note: "false" does not constrain to bounds: must be checked using m_pointmap->includes before getPoint is used int nextnode2 = m_pointmap->pixelate(nextloc2, false); bool good = false; if (pafrand() % 2 == 0) { if (goodStep(nextnode1)) { m_node = nextnode1; m_loc = nextloc1; good = true; } else if (goodStep(nextnode2)) { m_node = nextnode2; m_loc = nextloc2; good = true; } } else { if (goodStep(nextnode2)) { m_node = nextnode2; m_loc = nextloc2; good = true; } else if (goodStep(nextnode1)) { m_node = nextnode1; m_loc = nextloc1; good = true; } } return good; } bool Agent::goodStep(PixelRef node) { if (!m_pointmap->includes(node)) { return false; } // n.b., you have to know how the nodes are labelled for this connectValue trick PixelRef dir; dir.x = node.x - m_node.x; dir.y = node.y - m_node.y; // now translate dir to correct CONNECT value if (m_pointmap->getPoint(m_node).getGridConnections() & connectValue(dir)) { return true; } return false; } ////////////////////////////////////////////////////////////////////// // The various look algorithms Point2f Agent::onLook(bool wholeisovist) { Point2f dir; if (m_program->m_sel_type & AgentProgram::SEL_GIBSONIAN) { dir = onGibsonianLook(wholeisovist); } else if ((m_program->m_sel_type & AgentProgram::SEL_OCCLUSION) == AgentProgram::SEL_OCCLUSION) { dir = onOcclusionLook(wholeisovist, m_program->m_sel_type); } else { switch (m_program->m_sel_type) { case AgentProgram::SEL_STANDARD: dir = onStandardLook(wholeisovist); break; case AgentProgram::SEL_LOS: case AgentProgram::SEL_LOS_OCC: if (m_program->m_destination_directed) { dir = onDirectedLoSLook(wholeisovist, m_program->m_sel_type); } else { dir = onLoSLook(wholeisovist, m_program->m_sel_type); } break; case AgentProgram::SEL_OPTIC_FLOW2: dir = onGibsonianLook2(wholeisovist); break; } } if ((m_program->m_sel_type & AgentProgram::SEL_GIBSONIAN) && !m_stuck) { // remember what the view looked like here, facing our new direction: calcLoS(binfromvec(dir), false); } if ((m_program->m_sel_type & AgentProgram::SEL_GIBSONIAN2) && !m_stuck) { calcLoS2(binfromvec(dir), false); } return dir; } Point2f Agent::onStandardLook(bool wholeisovist) { int tarpixelate = -1; int vbin = m_program->m_vbin; if (wholeisovist || vbin == -1) { vbin = 16; } int directionbin = 32 + binfromvec(m_vector) - vbin; int choices = 0; // reset for getting list, check in range: vbin = vbin * 2 + 1; if (vbin > 32) { vbin = 32; } for (int i = 0; i < vbin; i++) { choices += m_pointmap->getPoint(m_node).getNode().bincount((directionbin + i) % 32); } if (choices == 0) { if (!wholeisovist) { return onStandardLook(true); } else { m_stuck = true; m_target = m_loc; m_target_pix = m_node; return Point2f(0, 0); } } else { int chosen = pafrand() % choices; Node &node = m_pointmap->getPoint(m_node).getNode(); for (; chosen >= node.bincount(directionbin % 32); directionbin++) { chosen -= node.bincount(directionbin % 32); } Bin &bin = node.bin(directionbin % 32); bin.first(); tarpixelate = bin.cursor(); for (; chosen > 0; chosen--) { bin.next(); tarpixelate = bin.cursor(); } } m_target_pix = tarpixelate; m_target = m_pointmap->depixelate(tarpixelate); return (m_target - m_loc).normalise(); } // TODO: Expose this functionality to the UIs Point2f Agent::onWeightedLook(bool wholeisovist) { if (wholeisovist) { // use standard targetted look instead: return onStandardLook(true); } int tarpixelate = -1; int vbin = m_program->m_vbin; if (vbin == -1) { vbin = 16; } int aheadbin = binfromvec(m_vector); int directionbin = 32 + binfromvec(m_vector) - vbin; std::vector weightmap; double weight = 0.0; // reset for getting list, check in range: vbin = vbin * 2 + 1; if (vbin > 32) { vbin = 32; } for (int i = 0; i < vbin; i++) { Bin &bin = m_pointmap->getPoint(m_node).getNode().bin((directionbin + i) % 32); bin.first(); // Quick mod - TV #if defined(_MSC_VER) int node = bin.is_tail() ? -1 : bin.cursor(); #else int node = bin.is_tail() ? -1 : bin.cursor().x; #endif while (node != -1) { weight += ((directionbin + i) % 32 == aheadbin) ? 5.0 : 1.0; weightmap.push_back(wpair(weight, node)); bin.next(); // Quick mod - TV #if defined(_MSC_VER) node = bin.is_tail() ? -1 : bin.cursor(); #else node = bin.is_tail() ? -1 : bin.cursor().x; #endif } } if (weightmap.size() == 0) { return onWeightedLook(true); } else { double chosen = prandomr() * weight; for (size_t i = 0; i < weightmap.size(); i++) { if (chosen < weightmap[i].weight) { tarpixelate = weightmap[i].node; break; } } } m_target_pix = tarpixelate; m_target = m_pointmap->depixelate(tarpixelate); return (m_target - m_loc).normalise(); } Point2f Agent::onOcclusionLook(bool wholeisovist, int looktype) { if (AgentProgram::SEL_OCC_MEMORY) { m_occ_memory.flip(); m_occ_memory.a().clear(); } if (wholeisovist) { // use standard targetted look instead: return onStandardLook(true); } PixelRef tarpixelate = NoPixel; int vbin = m_program->m_vbin; if (vbin == -1) { vbin = 16; } int directionbin = 32 + binfromvec(m_vector) - vbin; // reset for getting list, check in range: vbin = vbin * 2 + 1; if (vbin > 32) { vbin = 32; } if (looktype == AgentProgram::SEL_OCC_ALL) { int choices = 0; Node &node = m_pointmap->getPoint(m_node).getNode(); for (int i = 0; i < vbin; i++) { if (node.m_occlusion_bins[(directionbin + i) % 32].size()) { choices += node.m_occlusion_bins[(directionbin + i) % 32].size(); } } if (choices == 0) { if (!wholeisovist) { return onStandardLook(false); } else { m_stuck = true; m_target_pix = m_node; m_target = m_loc; return Point2f(0, 0); } } else { size_t chosen = pafrand() % choices; for (; chosen >= node.m_occlusion_bins[directionbin % 32].size(); directionbin++) { chosen -= node.m_occlusion_bins[directionbin % 32].size(); } tarpixelate = node.m_occlusion_bins[directionbin % 32].at(chosen); } } else { int subset = 1; if (looktype == AgentProgram::SEL_OCC_BIN45) { subset = 3; } else if (looktype == AgentProgram::SEL_OCC_BIN60) { subset = 5; } std::vector weightmap; double weight = 0.0; Node &node = m_pointmap->getPoint(m_node).getNode(); for (int i = 0; i < vbin; i += subset) { PixelRef nigpix; double fardist = -1.0; for (int k = 0; k < subset; k++) { for (size_t j = 0; j < node.m_occlusion_bins[(directionbin + i + k) % 32].size(); j++) { PixelRef pix = node.m_occlusion_bins[(directionbin + i + k) % 32].at(j); if (dist(pix, m_node) > fardist) { fardist = dist(pix, m_node); nigpix = pix; } } } if (fardist != -1.0) { bool cont = true; if (looktype == AgentProgram::SEL_OCC_MEMORY) { depthmapX::addIfNotExists(m_occ_memory.a(), nigpix); // the turn chance (pafrand() % 2) may have to be modified later... if (!m_at_target && std::find(m_occ_memory.b().begin(), m_occ_memory.b().end(), nigpix) != m_occ_memory.b().end()) { cont = false; } } if (cont) { switch (looktype) { case AgentProgram::SEL_OCC_WEIGHT_DIST: weight += fardist; break; case AgentProgram::SEL_OCC_WEIGHT_ANG: weight += (double(vbin - abs(i - vbin))); break; case AgentProgram::SEL_OCC_WEIGHT_DIST_ANG: weight += fardist * (double(vbin - abs(i - vbin))); break; default: weight += 1.0; break; } weightmap.push_back(wpair(weight, nigpix)); } } } if (weightmap.size() == 0) { if (!wholeisovist) { return onStandardLook(false); } else { m_stuck = true; m_target = m_loc; return Point2f(0, 0); } } else { double chosen = prandomr() * weight; for (size_t i = 0; i < weightmap.size(); i++) { if (chosen < weightmap[i].weight) { tarpixelate = weightmap[i].node; break; } } } } m_target_pix = tarpixelate; m_target = m_pointmap->depixelate(tarpixelate); return (m_target - m_loc).normalise(); } // note: LOS look uses similar weighted choice mechanism Point2f Agent::onLoSLook(bool wholeisovist, int look_type) { int bbin = -1; if (m_program->m_destination_directed) { Point2f vec2 = m_destination - m_loc; vec2.normalise(); bbin = binfromvec(vec2); } int targetbin = -1; int vbin = m_program->m_vbin; if (wholeisovist || vbin == -1) { vbin = 16; } int directionbin = 32 + binfromvec(m_vector) - vbin; std::vector weightmap; double weight = 0.0; // reset for getting list, check in range: vbin = vbin * 2 + 1; if (vbin > 32) { vbin = 32; } for (int i = 0; i < vbin; i++) { double los = (look_type == AgentProgram::SEL_LOS) ? m_pointmap->getPoint(m_node).getNode().bindistance((directionbin + i) % 32) : m_pointmap->getPoint(m_node).getNode().occdistance((directionbin + i) % 32); if (m_program->m_los_sqrd) { los *= los; } if (m_program->m_destination_directed) { los *= 1.0 - double(binsbetween(((directionbin + i) % 32), bbin)) / 16.0; } weight += los; weightmap.push_back(wpair(weight, (directionbin + i) % 32)); } if (weight == 0.0) { if (!wholeisovist) { return onLoSLook(true, look_type); } else { // oops! m_stuck = true; return Point2f(0, 0); } } else { double chosen = prandomr() * weight; for (size_t i = 0; i < weightmap.size(); i++) { if (chosen < weightmap[i].weight) { targetbin = weightmap[i].node; break; } } } float angle = (float)anglefrombin2(targetbin); return Point2f(cosf(angle), sinf(angle)); } Point2f Agent::onDirectedLoSLook(bool wholeisovist, int look_type) { Point2f vec2 = m_destination - m_loc; vec2.normalise(); int targetbin = -1; int vbin = m_program->m_vbin; if (wholeisovist || vbin == -1) { vbin = 16; } int directionbin = 32 + binfromvec(vec2) - vbin; std::vector weightmap; double weight = 0.0; // reset for getting list, check in range: vbin = vbin * 2 + 1; if (vbin > 32) { vbin = 32; } for (int i = 0; i < vbin; i++) { double los = (look_type == AgentProgram::SEL_LOS) ? m_pointmap->getPoint(m_node).getNode().bindistance((directionbin + i) % 32) : m_pointmap->getPoint(m_node).getNode().occdistance((directionbin + i) % 32); if (m_program->m_los_sqrd) { los *= los; } weight += los; weightmap.push_back(wpair(weight, (directionbin + i) % 32)); } if (weight == 0.0) { if (!wholeisovist) { return onLoSLook(true, look_type); } else { // oops! m_stuck = true; return Point2f(0, 0); } } else { double chosen = prandomr() * weight; for (size_t i = 0; i < weightmap.size(); i++) { if (chosen < weightmap[i].weight) { targetbin = weightmap[i].node; break; } } } float angle = (float)anglefrombin2(targetbin); return Point2f(cosf(angle), sinf(angle)); } // Gibsonian agents record their last known information, // and act according to their rules: Point2f Agent::onGibsonianLook(bool wholeisovist) { // at start, go in any direction: if (wholeisovist) { return onLoSLook(true, AgentProgram::SEL_LOS); } // calcLoS(binfromvec(m_vector), true); // now, choose action according to type of agent: int rule_choice = -1; int dir = 0; for (int k = 0; k < 4; k++) { dir = onGibsonianRule(m_program->m_rule_order[k]); if (dir != 0) { rule_choice = m_program->m_rule_order[k]; break; } } float angle = 0.0; if (rule_choice != -1) { angle = (float)anglefrombin2((binfromvec(m_vector) + (2 * rule_choice + 1) * dir + 32) % 32); } // if no rule selection made, carry on in current direction return (rule_choice == -1) ? m_vector : Point2f(cosf(angle), sinf(angle)); } int Agent::onGibsonianRule(int rule) { int option = 0; switch (m_program->m_sel_type) { case AgentProgram::SEL_LENGTH: // rule_threshold from 0 to 100m if (m_curr_los[rule + 1] > m_program->m_rule_threshold[rule]) { option = 0x01; } if (m_curr_los[rule + 5] > m_program->m_rule_threshold[rule]) { option |= 0x10; } break; case AgentProgram::SEL_OPTIC_FLOW: // rule_threshold reflects from 0x (0) to 5x (100.0) if ((m_curr_los[rule + 1] + 1) / (m_last_los[rule + 1] + 1) > m_program->m_rule_threshold[rule] / 20.0) { option = 0x01; } if ((m_curr_los[rule + 5] + 1) / (m_last_los[rule + 5] + 1) > m_program->m_rule_threshold[rule] / 20.0) { option |= 0x10; } break; case AgentProgram::SEL_COMPARATIVE_LENGTH: // rule_threshold reflects from 0x (0) to 10x (100.0) if ((m_curr_los[rule + 1] + 1) / (m_curr_los[0] + 1) > m_program->m_rule_threshold[rule] / 10.0) { option = 0x01; } if ((m_curr_los[rule + 5] + 1) / (m_curr_los[0] + 1) > m_program->m_rule_threshold[rule] / 10.0) { option |= 0x10; } break; case AgentProgram::SEL_COMPARATIVE_OPTIC_FLOW: // rule_threshold reflects from 0x (0) to 10x (100.0) if ((m_curr_los[rule + 1] * m_last_los[0] + 1) / (m_last_los[rule + 1] * m_curr_los[0] + 1) > m_program->m_rule_threshold[rule] / 10.0) { option = 0x01; } if ((m_curr_los[rule + 5] * m_last_los[0] + 1) / (m_last_los[rule + 5] * m_curr_los[0] + 1) > m_program->m_rule_threshold[rule] / 10.0) { option |= 0x10; } break; } int dir = 0; if (option == 0x01 && m_program->m_rule_probability[0] > prandomr()) { dir = -1; } else if (option == 0x10 && m_program->m_rule_probability[0] > prandomr()) { dir = +1; } else if (option == 0x11 && m_program->m_rule_probability[0] > prandomr() * prandomr()) { // note, use random * random event as there are two ways to do this dir = (rand() % 2) ? -1 : +1; } return dir; } Point2f Agent::onGibsonianLook2(bool wholeisovist) { // at start, go in any direction: if (wholeisovist) { return onLoSLook(true, AgentProgram::SEL_LOS); } // calcLoS2(binfromvec(m_vector), true); int maxbin = 0; /* // first action: adjust to longest line of sight if (m_curr_los[3] > m_curr_los[0]) { maxbin = -m_program->m_vahead; if (m_curr_los[4] > m_curr_los[0] && (pafrand() % 2)) { maxbin = m_program->m_vahead; } } else if (m_curr_los[4] > m_curr_los[0]) { maxbin = m_program->m_vahead; } */ // second action, apply feeler rule: char dir = 0x00; if ((m_curr_los[1] - m_last_los[1]) / m_curr_los[1] > m_program->m_feeler_threshold) { dir |= 0x01; } if ((m_curr_los[2] - m_last_los[2]) / m_curr_los[2] > m_program->m_feeler_threshold) { dir |= 0x10; } if (dir == 0x01 && m_program->m_feeler_probability > prandomr()) { maxbin = -m_program->m_vbin; } else if (dir == 0x10 && m_program->m_feeler_probability > prandomr()) { maxbin = m_program->m_vbin; } else if (dir == 0x11 && m_program->m_feeler_probability > prandomr() * prandomr()) { maxbin = (pafrand() % 2) ? m_program->m_vbin : -m_program->m_vbin; } // third action: detect heading for dead-end if (maxbin == 0 && (m_curr_los[0] / m_pointmap->getSpacing() < m_program->m_ahead_threshold)) { if (m_curr_los[1] >= m_curr_los[2]) { maxbin = -m_program->m_vbin; } else { maxbin = m_program->m_vbin; } } int bin = binfromvec(m_vector) + maxbin; float angle = (float)anglefrombin2(bin); return (maxbin == 0) ? m_vector : Point2f(cosf(angle), sinf(angle)); } void Agent::calcLoS(int directionbin, bool curr) { float *los; if (curr) { los = m_curr_los; } else { los = m_last_los; } Node &node = m_pointmap->getPoint(m_node).getNode(); // ahead los[0] = node.bindistance(directionbin % 32); // directions: int count = 1; for (int i = 1; i <= 7; i += 2) { los[count] = node.bindistance((directionbin - i + 32) % 32); count++; } for (int j = 1; j <= 7; j += 2) { los[count] = node.bindistance((directionbin + j) % 32); count++; } } void Agent::calcLoS2(int directionbin, bool curr) { float *los; if (curr) { los = m_curr_los; } else { los = m_last_los; } Node &node = m_pointmap->getPoint(m_node).getNode(); // ahead los[0] = node.bindistance(directionbin % 32); // directions: los[1] = node.bindistance((directionbin - m_program->m_vbin + 32) % 32); los[2] = node.bindistance((directionbin + m_program->m_vbin) % 32); // los[3] = node.bindistance((directionbin - m_program->m_vahead + 32) % 32); los[4] = node.bindistance((directionbin + m_program->m_vahead) % 32); } ================================================ FILE: salalib/agents/agent.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "agentprogram.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" #include "genlib/p2dpoly.h" #include "genlib/pflipper.h" class Agent { public: enum { OUTPUT_NOTHING = 0x00, OUTPUT_COUNTS = 0x01, OUTPUT_GATE_COUNTS = 0x02, OUTPUT_TRAILS = 0x04 }; protected: AgentProgram *m_program; PointMap *m_pointmap; // PixelRef m_node; int m_step; int m_frame; int m_gate; bool m_stuck; bool m_stopped; bool m_target_lock; bool m_gate_encountered; bool m_at_target; bool m_at_destination; int m_output_mode; Point2f m_loc; Point2f m_target; Point2f m_vector; PixelRef m_target_pix; // a long term goal: Point2f m_destination; // // for recording trails: int m_trail_num; // // for occlusion memory pflipper m_occ_memory; // // extra memory of last observed values for Gibsonian agents: float m_last_los[9]; float m_curr_los[9]; public: Agent() { m_program = NULL; m_pointmap = NULL; m_output_mode = OUTPUT_NOTHING; } Agent(AgentProgram *program, PointMap *pointmap, int output_mode = OUTPUT_NOTHING); void onInit(PixelRef node, int trail_num = -1); void onClose(); Point2f onLook(bool wholeisovist); Point2f onStandardLook(bool wholeisovist); Point2f onWeightedLook(bool wholeisovist); Point2f onOcclusionLook(bool wholeisovist, int looktype); Point2f onLoSLook(bool wholeisovist, int look_type); Point2f onDirectedLoSLook(bool wholeisovist, int look_type); Point2f onGibsonianLook(bool wholeisovist); Point2f onGibsonianLook2(bool wholeisovist); int onGibsonianRule(int rule); void calcLoS(int directionbin, bool curr); void calcLoS2(int directionbin, bool curr); void onMove(); void onTarget(); void onDestination(); void onStep(); bool diagonalStep(); bool goodStep(PixelRef node); bool gateEncountered() { return m_gate_encountered; } const Point2f &getLoc() const { return m_loc; } // bool atTarget() const { return m_at_target; } bool atDestination() const { return m_at_destination; } // const Point2f &getLocation() const { return m_loc; } const Point2f &getVector() const { return m_vector; } const PixelRef getNode() const { return m_node; } int getFrame() const { return m_frame; } const PointMap &getPointMap() const { return *m_pointmap; } }; // note the add 0.5 means angles from e.g., -1/32 to 1/32 are in bin 0 inline int binfromvec(const Point2f &p) { return int(32.0 * (0.5 * p.angle() / M_PI) + 0.5); } // a random angle based on a bin direction inline double anglefrombin2(int here) { return (2.0 * M_PI) * ((double(here) - 0.5) / 32.0 + prandom() / 32.0); } inline int binsbetween(int bin1, int bin2) { int b = abs(bin1 - bin2); if (b > 16) { b = 32 - b; } return b; } // weighting struct wpair { double weight; int node; wpair(double w = 0.0, int n = -1) { weight = w; node = n; } }; // convert an x / y difference to it's corresponding connection direction inline char connectValue(PixelRef dir) { if (dir.y > 0) { return (Point::CONNECT_NE << (1 - dir.x)); } else if (dir.y < 0) { return (Point::CONNECT_SW << (dir.x + 1)); } else if (dir.x == 1) { return (char)Point::CONNECT_E; } else { return (char)Point::CONNECT_W; } } ================================================ FILE: salalib/agents/agentengine.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agentengine.h" #include "agenthelpers.h" // run one agent engine only AgentEngine::AgentEngine() { m_timesteps = 5000; m_gatelayer = -1; m_record_trails = false; } void AgentEngine::run(Communicator *comm, PointMap *pointmap) { for (auto &agentSet : agentSets) { if (agentSet.m_sel_type == AgentProgram::SEL_LOS_OCC) { pointmap->requireIsovistAnalysis(); } } time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, m_timesteps); } AttributeTable &table = pointmap->getAttributeTable(); int displaycol = table.getOrInsertColumn(g_col_total_counts); int output_mode = Agent::OUTPUT_COUNTS; if (m_gatelayer != -1) { output_mode |= Agent::OUTPUT_GATE_COUNTS; } int trail_num = -1; if (m_record_trails) { if (m_trail_count < 1) { m_trail_count = 1; } for (auto& agentSet: agentSets) { agentSet.m_trails = std::vector>(m_trail_count); } trail_num = 0; } // remove any agents that are left from a previous run for (auto &agentSet : agentSets) { agentSet.agents.clear(); } for (int i = 0; i < m_timesteps; i++) { for (auto &agentSet : agentSets) { int q = invcumpoisson(prandomr(), agentSet.m_release_rate); int length = agentSet.agents.size(); int k; for (k = 0; k < q; k++) { agentSet.agents.push_back(Agent(&(agentSet), pointmap, output_mode)); } for (k = 0; k < q; k++) { agentSet.init(length + k, trail_num); if (trail_num != -1) { trail_num++; // after trail count, stop recording: if (trail_num == m_trail_count) { trail_num = -1; } } } } for (auto &agentSet : agentSets) { agentSet.move(); } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, i); } } } pointmap->overrideDisplayedAttribute(-2); pointmap->setDisplayedAttribute(displaycol); } void AgentEngine::insertTrailsInMap(ShapeMap& trailsMap) { for (auto &agentSet : agentSets) { // there is currently only one AgentSet. If at any point there are more then // this could be amended to put the AgentSet id as a property of the trail for (auto &trail : agentSet.m_trails) { std::vector trailGeometry(trail.begin(), trail.end()); trailsMap.makePolyShape(trailGeometry, true, false); } } } ================================================ FILE: salalib/agents/agentengine.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "agentset.h" class AgentEngine { public: // public for now for speed std::vector agentSets; int m_gatelayer; int m_timesteps; public: bool m_record_trails; int m_trail_count = 50; public: AgentEngine(); void run(Communicator *comm, PointMap *pointmap); void insertTrailsInMap(ShapeMap& trailsMap); }; ================================================ FILE: salalib/agents/agentga.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agentga.h" #include "genlib/pafmath.h" int thisrun = 0; /////////////////////////////////////////////////////////////////////////////////////////////// static int rankselect(int popsize) { int num = int(prandom() * popsize * (popsize + 1) * 0.5); for (int i = 0; i < popsize; i++) { if (num < (popsize - i)) { return i; } num -= (popsize - i); } return 0; // <- this shouldn't happen } // note: this is tested and right: higher fitness, lower rank (so population[0] is best) int progcompare(const void *a, const void *b) { double test = (((AgentProgram *)a)->m_fitness - ((AgentProgram *)b)->m_fitness); if (test < 0.0) { return 1; } else if (test > 0.0) { return -1; } return 0; } AgentProgram *ProgramPopulation::makeChild() { int a = rankselect(POPSIZE); int b = rankselect(POPSIZE); while (a == b) b = rankselect(POPSIZE); m_population[POPSIZE - 1] = crossover(m_population[a], m_population[b]); m_population[POPSIZE - 1].mutate(); return &(m_population[POPSIZE - 1]); } // note: this is correct -- do not use &m_population! void ProgramPopulation::sort() { qsort(m_population, POPSIZE, sizeof(AgentProgram), progcompare); } ================================================ FILE: salalib/agents/agentga.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "agentprogram.h" const int POPSIZE = 500; // redo ASSAYs -- assaysize * assays (3 * 200 = 600 evaluations total) // then take mean fitness: due to large variation in fitnesses with // short assays such as this const int ASSAYS = 3; const int ASSAYSIZE = 25000; const int GENERATIONS = 10000; const int TIMESTEPS = 1600; struct ProgramPopulation { public: AgentProgram m_population[POPSIZE]; public: ProgramPopulation() {} AgentProgram *makeChild(); void sort(); }; ================================================ FILE: salalib/agents/agenthelpers.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once const static std::string g_col_total_counts = "Gate Counts"; const static std::string g_col_gate_counts = "__Internal_Gate_Counts"; const static std::string g_col_gate = "__Internal_Gate"; ================================================ FILE: salalib/agents/agentprogram.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agentprogram.h" #include "genlib/pafmath.h" #include "genlib/stringutils.h" #include AgentProgram::AgentProgram() { m_sel_type = SEL_LOS; m_steps = 3; m_vbin = 7; m_destination_directed = false; m_los_sqrd = false; } void AgentProgram::mutate() { // do mutate rule order occassionally: if (pafrand() % 20 == 0) { // rule order relies on putting rules into slots: for (int i = 0; i < 4; i++) { m_rule_order[i] = -1; } for (int j = 0; j < 4; j++) { int choice = pafrand() % (4 - j); for (int k = 0; k < choice + 1; k++) { if (m_rule_order[k] != -1) { choice++; } } m_rule_order[choice] = j; } } // mutate the rule threshold / probabilities for (int i = 0; i < 4; i++) { if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_threshold[i] = float(prandom() * 100.0); } if (pafrand() % 20 == 0) { // 5% mutation rate m_rule_probability[i] = float(prandom()); } } } AgentProgram crossover(const AgentProgram &prog_a, const AgentProgram &prog_b) { AgentProgram child; // either one rule priority order or the other (don't try to mix!) if (pafrand() % 2) { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_a.m_rule_order[i]; } } else { for (int i = 0; i < 4; i++) { child.m_rule_order[i] = prog_b.m_rule_order[i]; } } // for each rule, either one rule threshold / probability or the other: for (int i = 0; i < 4; i++) { if (pafrand() % 2) { child.m_rule_threshold[i] = prog_a.m_rule_threshold[i]; } else { child.m_rule_threshold[i] = prog_b.m_rule_threshold[i]; } if (pafrand() % 2) { child.m_rule_probability[i] = prog_a.m_rule_probability[i]; } else { child.m_rule_probability[i] = prog_b.m_rule_probability[i]; } } return child; } // TODO: Expose this functionality to the UIs void AgentProgram::save(const std::string &filename) { // standard ascii: std::ofstream file(filename.c_str()); file << "Destination selection: "; switch (m_sel_type) { case SEL_STANDARD: file << "Standard" << std::endl; break; case SEL_LENGTH: file << "Gibsonian Length" << std::endl; break; case SEL_OPTIC_FLOW: file << "Gibsonian Optic Flow" << std::endl; break; case SEL_COMPARATIVE_LENGTH: file << "Gibsonian Comparative Length" << std::endl; break; case SEL_COMPARATIVE_OPTIC_FLOW: file << "Gibsonian Comparative Optic Flow" << std::endl; break; default: file << "Unknown" << std::endl; } file << "Steps: " << m_steps << std::endl; file << "Bins: " << ((m_vbin == -1) ? 32 : m_vbin * 2 + 1) << std::endl; file << "Rule order: " << m_rule_order[0] << " " << m_rule_order[1] << " " << m_rule_order[2] << " " << m_rule_order[3] << std::endl; for (int i = 0; i < 4; i++) { file << "Rule " << i << " (Bin -" << 1 + (i * 2) << "/+" << 1 + (i * 2) << ")" << std::endl; file << "Threshold: " << m_rule_threshold[i] << std::endl; file << "Turn Probability: " << m_rule_probability[i] << std::endl; } file << "Fitness: " << m_fitness << std::endl; } bool AgentProgram::open(const std::string &filename) { // standard ascii: std::ifstream file(filename.c_str()); std::string line; file >> line; if (!line.empty()) { dXstring::toLower(line); if (line.substr(0, 22) != "destination selection:") { return false; } else { std::string method = line.substr(22); dXstring::ltrim(method); if (!method.empty()) { if (method == "standard") { m_sel_type = SEL_STANDARD; } else if (method == "gibsonian length") { m_sel_type = SEL_LENGTH; } else if (method == "gibsonian optic flow") { m_sel_type = SEL_OPTIC_FLOW; } else if (method == "gibsonian comparative length") { m_sel_type = SEL_COMPARATIVE_LENGTH; } else if (method == "gibsonian comparative optic flow") { m_sel_type = SEL_COMPARATIVE_OPTIC_FLOW; } file >> line; } else { return false; } } } else { return false; } bool foundsteps = false; bool foundbins = false; if (!line.empty()) { dXstring::toLower(line); if (line.substr(0, 6) == "steps:") { std::string steps = line.substr(6); dXstring::ltrim(steps); m_steps = stoi(steps); file >> line; foundsteps = true; } } else { return false; } if (!line.empty()) { dXstring::toLower(line); if (line.substr(0, 5) == "bins:") { std::string bins = line.substr(6); dXstring::ltrim(bins); int binx = stoi(bins); if (binx == 32) { m_vbin = -1; } else { m_vbin = (atoi(bins.c_str()) - 1) / 2; } file >> line; foundbins = true; } } if (m_sel_type == SEL_STANDARD) { if (foundbins && foundsteps) { return true; } else { return false; } } if (!line.empty()) { dXstring::toLower(line); if (line.substr(0, 11) == "rule order:") { std::string ruleorder = line.substr(11); dXstring::ltrim(ruleorder); auto orders = dXstring::split(ruleorder, ' '); if (orders.size() != 4) { return false; } for (int i = 0; i < 4; i++) { m_rule_order[i] = stoi(orders[i]); } file >> line; } else { return false; } } else { return false; } for (int i = 0; i < 4; i++) { if (!line.empty()) { dXstring::toLower(line); if (line.substr(0, 4) == "rule") { file >> line; } dXstring::toLower(line); if (line.substr(0, 10) == "threshold:") { auto threshold = line.substr(10); dXstring::ltrim(threshold); m_rule_threshold[i] = stof(threshold); file >> line; } else { return false; } dXstring::toLower(line); if (line.substr(0, 17) == "turn probability:") { auto prob = line.substr(17); dXstring::ltrim(prob); m_rule_probability[i] = stof(prob); file >> line; } else { return false; } } else { return false; } } return true; } ================================================ FILE: salalib/agents/agentprogram.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include struct AgentProgram { // comparative is comparative with current heading enum { SEL_LOS = 0x0001, SEL_LOS_OCC = 0x0002, SEL_TARGETTED = 0x1000, SEL_STANDARD = 0x1001, SEL_WEIGHTED = 0x1002, SEL_GIBSONIAN = 0x2000, SEL_LENGTH = 0x2001, SEL_OPTIC_FLOW = 0x2002, SEL_COMPARATIVE_LENGTH = 0x2003, SEL_COMPARATIVE_OPTIC_FLOW = 0x2004, SEL_GIBSONIAN2 = 0x4000, SEL_OPTIC_FLOW2 = 0x4001, SEL_OCCLUSION = 0x9000, SEL_OCC_ALL = 0x9001, SEL_OCC_BIN45 = 0x9002, SEL_OCC_BIN60 = 0x9003, SEL_OCC_STANDARD = 0x9004, SEL_OCC_WEIGHT_DIST = 0x9005, SEL_OCC_WEIGHT_ANG = 0x9006, SEL_OCC_WEIGHT_DIST_ANG = 0x9007, SEL_OCC_MEMORY = 0x9008 }; int m_sel_type; int m_steps; int m_vbin; // these three variables for evolved Gibsonian agents: int m_rule_order[4]; float m_rule_threshold[4]; float m_rule_probability[4]; // these are for optic flow 2 agents int m_vahead; // how wide your ahead vision is float m_ahead_threshold; // will turn if neg flow greater than this threshold (set in range 1/100 to 1) float m_feeler_threshold; // will turn if flow greater than this threshold (set in range 1 to 5) float m_feeler_probability; // turn with this much probability if a feeler triggers // // simple long range destinations: bool m_destination_directed; bool m_los_sqrd; // // if it is going to evolved, then have it remember its fitness: double m_fitness; // AgentProgram(); // // for evolution void mutate(); friend AgentProgram crossover(const AgentProgram &prog_a, const AgentProgram &prog_b); // to reload later: void save(const std::string &filename); bool open(const std::string &filename); std::vector> m_trails; }; ================================================ FILE: salalib/agents/agentset.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "agentset.h" #include "salalib/pixelref.h" AgentSet::AgentSet() { m_release_rate = 0.1; m_lifetime = 1000; } void AgentSet::init(int agent, int trail_num) { if (m_release_locations.size()) { int which = pafrand() % m_release_locations.size(); agents[agent].onInit(m_release_locations[which], trail_num); } else { const PointMap &map = agents[agent].getPointMap(); PixelRef pix; do { pix = map.pickPixel(prandom(m_release_locations_seed)); } while (!map.getPoint(pix).filled()); agents[agent].onInit(pix, trail_num); } } void AgentSet::move() { // go through backwards so remove does not affect later agents for (auto rev_iter = agents.rbegin(); rev_iter != agents.rend(); ++rev_iter) { rev_iter->onMove(); if (rev_iter->getFrame() >= m_lifetime) { agents.erase(std::next(rev_iter).base()); } } } ================================================ FILE: salalib/agents/agentset.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2019, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "agent.h" #include "agentprogram.h" struct AgentSet : public AgentProgram { std::vector agents; std::vector m_release_locations; int m_release_locations_seed = 0; double m_release_rate; int m_lifetime; AgentSet(); void move(); void init(int agent, int trail_num = -1); }; ================================================ FILE: salalib/alllinemap.cpp ================================================ #include "alllinemap.h" #include "salalib/axialminimiser.h" #include "salalib/tolerances.h" #include "genlib/exceptions.h" #include #include AllLineMap::AllLineMap(Communicator *comm, std::vector &drawingLayers, const Point2f& seed, const std::string& name): ShapeGraph(name, ShapeMap::ALLLINEMAP) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 3 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } // this has a nasty habit of crashing if reused... // reset everything at the top level, including any existing all-line map: m_polygons.clear(); m_poly_connections.clear(); m_radial_lines.clear(); // starting off... finding a polygon... // for ease, I'm just going to make a construction line set from all the visible lines... QtRegion region; std::vector lines; // add all visible layers to the set of polygon lines... for (const auto& pixelGroup: drawingLayers) { for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { if (region.atZero()) { region = pixel.getRegion(); } else { region = runion(region, pixel.getRegion()); } std::vector newLines = pixel.getAllShapesAsLines(); for (const auto& line: newLines) { lines.push_back(Line(line.start(), line.end())); } } } } region.grow(1.30); m_polygons.init(lines, region); m_polygons.m_handled_list.clear(); // find a corner visible from the seed: AxialVertexKey seedvertex = m_polygons.seedVertex( seed ); if (seedvertex == NoVertex) { // oops... can't find a visible vertex throw depthmapX::RuntimeException("No visible vertices found"); } // okay, we've got as far as finding a seed corner, now the real fun begins... // test outwards from corner, add other corners to // test set... std::vector axiallines; KeyVertices preaxialdata; // also poly_connections used in fewest line axial map construction: m_poly_connections.clear(); m_radial_lines.clear(); AxialVertex vertex = m_polygons.makeVertex(seedvertex, seed); if (!vertex.m_initialised) { // oops... can't init for some reason throw depthmapX::RuntimeException("Failed to initialise axial vertices"); } time_t atime = 0; int count = 0; if (comm) { qtimer( atime, 0 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); comm->CommPostMessage( Communicator::NUM_RECORDS, m_polygons.m_vertex_possibles.size() ); } std::set openvertices; openvertices.insert(vertex); while (!openvertices.empty()) { m_polygons.makeAxialLines(openvertices, axiallines, preaxialdata, m_poly_connections, m_radial_lines); count++; // if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage( Communicator::CURRENT_RECORD, count ); } } } if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 3 ); comm->CommPostMessage( Communicator::CURRENT_RECORD, 0 ); } // cut out duplicates: int removed = 0; // for testing purposes for (size_t j = 0; j < axiallines.size(); j++) { for (size_t k = axiallines.size() - 1; k > j; k--) { double maxdim = __max(region.width(),region.height()); if (approxeq(axiallines[j].start(), axiallines[k].start(), maxdim * TOLERANCE_B) && approxeq(axiallines[j].end(), axiallines[k].end(), maxdim * TOLERANCE_B)) { for (int preaxiali: preaxialdata[k]) { preaxialdata[j].insert(preaxiali); } preaxialdata.erase(preaxialdata.begin() + int(k)); axiallines.erase(axiallines.begin() + int(k)); removed++; } } } region.grow(0.99); // <- this paired with crop code below to prevent error init(axiallines.size(), m_polygons.getRegion()); // used to be double density here initialiseAttributesAxial(); for (size_t k = 0; k < axiallines.size(); k++) { axiallines[k].crop(region); // <- should be cropped anyway, but causing an error makeLineShape(axiallines[k]); } // n.b. make connections also initialises attributes // -> don't know what this was for: alllinemap.sortBins(m_poly_connections); makeConnections(preaxialdata); setKeyVertexCount(m_polygons.m_vertex_possibles.size()); } std::tuple, std::unique_ptr> AllLineMap::extractFewestLineMaps(Communicator *comm) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 2 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } pafsrand((unsigned int)time(NULL)); // make one rld for each radial line... std::map > radialdivisions; size_t i; for (auto& radial_line: m_radial_lines) { radialdivisions.insert(std::make_pair( (RadialKey) radial_line, std::set() )); } // also, a list of radial lines cut by each axial line std::map > ax_radial_cuts; std::map > ax_seg_cuts; for (auto shape: getAllShapes()) { ax_radial_cuts.insert(std::make_pair(shape.first, std::set())); ax_seg_cuts.insert(std::make_pair(shape.first, std::set())); } // make divisions -- this is the slow part and the comm updates makeDivisions(m_poly_connections, m_radial_lines, radialdivisions, ax_radial_cuts, comm); // the slow part is over, we're into the final straight... reset the current record flag: if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); comm->CommPostMessage( Communicator::CURRENT_RECORD, 0 ); } // a little further setting up is still required... std::map radialsegs; auto iter = m_radial_lines.begin(); if (iter != m_radial_lines.end()) { // now make radial segments from the radial lines... (note, start at 1) auto prevIter = m_radial_lines.begin(); ++iter; for (;iter != m_radial_lines.end();) { if (iter->vertex == prevIter->vertex && iter->ang != prevIter->ang) { radialsegs.insert(std::make_pair( (RadialKey)(*iter), (RadialSegment)(*prevIter))); } ++iter; ++prevIter; } } // and segment divisors from the axial lines... // TODO: (CS) Restructure this to get rid of all those brittle parallel data structure auto axIter = ax_radial_cuts.begin(); auto axSeg = ax_seg_cuts.begin(); for (i = 0; i < getAllShapes().size(); i++) { auto axRadCutIter = axIter->second.begin(); if(axRadCutIter != axIter->second.end()) { auto axRadCutIterPrev = axIter->second.begin(); ++axRadCutIter; for (size_t j = 1; j < axIter->second.size(); ++j) { // note similarity to loop above RadialKey& rk_end = m_radial_lines[size_t(*axRadCutIter)]; RadialKey& rk_start = m_radial_lines[size_t(*axRadCutIterPrev)]; if (rk_start.vertex == rk_end.vertex) { auto radialSegIter = radialsegs.find(rk_end); if (radialSegIter != radialsegs.end() && rk_start == radialSegIter->second.radial_b) { radialSegIter->second.indices.insert(axIter->first); axSeg->second.insert(std::distance(radialsegs.begin(), radialSegIter)); } } ++axRadCutIter; ++axRadCutIterPrev; } } axIter++; axSeg++; } // and a little more setting up: key vertex relationships std::vector > keyvertexconns; std::vector keyvertexcounts(static_cast(m_keyvertexcount), 0); // this sets up a two step relationship: looks for the key vertices for all lines connected to you for (size_t y = 0; y < m_connectors.size(); y++) { keyvertexconns.push_back(std::vector()); auto &conn = keyvertexconns.back(); Connector& axa = m_connectors[y]; for (size_t z = 0; z < axa.m_connections.size(); z++) { std::set& axb = m_keyvertices[axa.m_connections[z]]; for (int axbi: axb) { auto res = std::lower_bound(conn.begin(), conn.end(), axbi); if (res == conn.end() || axbi < *res ) { conn.insert(res, axbi); keyvertexcounts[axbi] += 1; } } } } // ok, after this fairly tedious set up, we are ready to go... // note axradialcuts aren't required anymore... AxialMinimiser minimiser(*this, ax_seg_cuts.size(), radialsegs.size()); std::vector lines_s, lines_m; minimiser.removeSubsets(ax_seg_cuts, radialsegs, radialdivisions, m_radial_lines, keyvertexconns, keyvertexcounts); // make new lines here (assumes line map has only lines) int k = -1; for (auto& shape: m_shapes) { k++; if (!minimiser.removed(k)) { lines_s.push_back( shape.second.getLine() ); } } minimiser.fewestLongest(ax_seg_cuts, radialsegs, radialdivisions, m_radial_lines, keyvertexconns, keyvertexcounts); // make new lines here (assumes line map has only lines for (int k = 0; k < int(getAllShapes().size()); k++) { if (!minimiser.removed(k)) { lines_m.push_back( depthmapX::getMapAtIndex(getAllShapes(), k)->second.getLine() ); } } std::unique_ptr fewestlinemap_subsets(new ShapeGraph("Fewest-Line Map (Subsets)", ShapeMap::AXIALMAP)); fewestlinemap_subsets->clearAll(); fewestlinemap_subsets->init(int(lines_s.size()),m_polygons.getRegion()); fewestlinemap_subsets->initialiseAttributesAxial(); for (size_t k = 0; k < lines_s.size(); k++) { fewestlinemap_subsets->makeLineShape(lines_s[k]); } fewestlinemap_subsets->makeConnections(); std::unique_ptr fewestlinemap_minimal(new ShapeGraph("Fewest-Line Map (Minimal)", ShapeMap::AXIALMAP)); fewestlinemap_minimal->clearAll(); fewestlinemap_minimal->init(int(lines_m.size()),m_polygons.getRegion()); // used to have a '2' for double pixel density fewestlinemap_minimal->initialiseAttributesAxial(); for (size_t k = 0; k < lines_m.size(); k++) { fewestlinemap_minimal->makeLineShape(lines_m[k]); } fewestlinemap_minimal->makeConnections(); return std::make_tuple(std::move(fewestlinemap_subsets), std::move(fewestlinemap_minimal)); } void AllLineMap::makeDivisions(const std::vector& polyconnections, const std::vector &radiallines, std::map >& radialdivisions, std::map > &axialdividers, Communicator *comm) { time_t atime = 0; if (comm) { qtimer( atime, 0 ); comm->CommPostMessage( Communicator::NUM_RECORDS, polyconnections.size() ); } for (size_t i = 0; i < polyconnections.size(); i++) { PixelRefVector pixels = pixelateLine(polyconnections[i].line); std::vector testedshapes; auto connIter = radialdivisions.find(polyconnections[i].key); size_t connindex = std::distance(radialdivisions.begin(), connIter); double tolerance = sqrt(TOLERANCE_A);// * polyconnections[i].line.length(); for (size_t j = 0; j < pixels.size(); j++) { PixelRef pix = pixels[j]; auto& shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); for (const ShapeRef& shape: shapes) { auto iter = depthmapX::findBinary( testedshapes, shape.m_shape_ref ); if (iter != testedshapes.end()) { continue; } testedshapes.insert(iter, int(shape.m_shape_ref)); const Line& line = m_shapes.find(shape.m_shape_ref)->second.getLine(); // if (intersect_region(line, polyconnections[i].line, tolerance * line.length()) ) { switch ( intersect_line_distinguish(line, polyconnections[i].line, tolerance * line.length()) ) { case 0: break; case 2: { size_t index = depthmapX::findIndexFromKey(axialdividers, (int) shape.m_shape_ref); if (index != shape.m_shape_ref) { throw 1; // for the code to work later this can't be true! } axialdividers[index].insert(connindex); connIter->second.insert(shape.m_shape_ref); } break; case 1: { size_t index = depthmapX::findIndexFromKey(axialdividers, (int) shape.m_shape_ref); if (index != shape.m_shape_ref) { throw 1; // for the code to work later this can't be true! } // // this makes sure actually crosses between the line and the openspace properly if (radiallines[connindex].cuts(line)) { axialdividers[index].insert(connindex); connIter->second.insert(shape.m_shape_ref); } } break; default: break; } } } } if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage( Communicator::CURRENT_RECORD, i ); } } } } ================================================ FILE: salalib/alllinemap.h ================================================ #pragma once #include "salalib/axialmap.h" #include "salalib/axialpolygons.h" class AllLineMap: public ShapeGraph { public: AllLineMap(Communicator *comm, std::vector &drawingLayers, const Point2f& seed, const std::string& name = "All-Line Map"); AllLineMap(const std::string& name = "All-Line Map"): ShapeGraph(name, ShapeMap::ALLLINEMAP) {} AxialPolygons m_polygons; std::vector m_poly_connections; std::vector m_radial_lines; void setKeyVertexCount(int keyvertexcount) { m_keyvertexcount = keyvertexcount; } std::tuple, std::unique_ptr> extractFewestLineMaps(Communicator *comm); void makeDivisions(const std::vector& polyconnections, const std::vector &radiallines, std::map > &radialdivisions, std::map > &axialdividers, Communicator *comm); }; ================================================ FILE: salalib/attributetable.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "attributetable.h" #include "displayparams.h" #include #include #include #include const std::string &AttributeColumnImpl::getName() const { return m_name; } bool AttributeColumnImpl::isLocked() const { return m_locked; } void AttributeColumnImpl::setLock(bool lock) { m_locked = lock; } bool AttributeColumnImpl::isHidden() const { return m_hidden; } void AttributeColumnImpl::setHidden(bool hidden) { m_hidden = hidden; } void AttributeColumnImpl::setFormula(std::string newFormula) { m_formula = newFormula; } const std::string &AttributeColumnImpl::getFormula() const { return m_formula; } const AttributeColumnStats &AttributeColumnImpl::getStats() const { return m_stats; } void AttributeColumnImpl::updateStats(float val, float oldVal) const { if (m_stats.total < 0) { m_stats.total = val; } else { m_stats.total += val; m_stats.total -= oldVal; } if (val > m_stats.max) { m_stats.max = val; } if (m_stats.min < 0 || val < m_stats.min) { m_stats.min = val; } } void AttributeColumnImpl::setName(const std::string &name) { m_name = name; } size_t AttributeColumnImpl::read(std::istream &stream) { m_name = dXstring::readString(stream); float val; stream.read((char *)&val, sizeof(float)); m_stats.min = val; stream.read((char *)&val, sizeof(float)); m_stats.max = val; stream.read((char *)&m_stats.total, sizeof(double)); int physical_column; stream.read((char *)&physical_column, sizeof(int)); // physical column is obsolete stream.read((char *)&m_hidden, sizeof(bool)); stream.read((char *)&m_locked, sizeof(bool)); stream.read((char*)&m_displayParams,sizeof(DisplayParams)); m_formula = dXstring::readString(stream); return physical_column; } void AttributeColumnImpl::write(std::ostream &stream, int physicalCol) { dXstring::writeString(stream, m_name); float min = (float)m_stats.min; float max = (float)m_stats.max; stream.write((char *)&min, sizeof(float)); stream.write((char *)&max, sizeof(float)); stream.write((char *)&m_stats.total, sizeof(m_stats.total)); stream.write((char *)&physicalCol, sizeof(int)); stream.write((char *)&m_hidden, sizeof(bool)); stream.write((char *)&m_locked, sizeof(bool)); stream.write((char *)&m_displayParams, sizeof(DisplayParams)); dXstring::writeString(stream, m_formula); } // AttributeRow implementation float AttributeRowImpl::getValue(const std::string &column) const { return getValue(m_colManager.getColumnIndex(column)); } float AttributeRowImpl::getValue(size_t index) const { checkIndex(index); return m_data[index]; } float AttributeRowImpl::getNormalisedValue(size_t index) const { checkIndex(index); auto& colStats = m_colManager.getColumn(index).getStats(); if (colStats.max == colStats.min) { return 0.5f; } return m_data[index] < 0 ? -1.0f : float((m_data[index] - colStats.min)/(colStats.max - colStats.min)); } AttributeRow& AttributeRowImpl::setValue(const std::string &column, float value) { return setValue(m_colManager.getColumnIndex(column), value); } AttributeRow& AttributeRowImpl::setValue(size_t index, float value) { checkIndex(index); float oldVal = m_data[index]; m_data[index] = value; if (oldVal < 0.0f) { oldVal = 0.0f; } m_colManager.getColumn(index).updateStats(value, oldVal); return *this; } AttributeRow& AttributeRowImpl::setSelection(bool selected) { m_selected = selected; return *this; } bool AttributeRowImpl::isSelected() const { return m_selected; } void AttributeRowImpl::addColumn() { m_data.push_back(-1); } void AttributeRowImpl::removeColumn(size_t index) { checkIndex(index); m_data.erase(m_data.begin() + index); } void AttributeRowImpl::read(std::istream &stream) { stream.read((char *)&m_layerKey, sizeof(m_layerKey)); dXreadwrite::readIntoVector(stream, m_data); } void AttributeRowImpl::write(std::ostream &stream) { stream.write((char *)&m_layerKey, sizeof(m_layerKey)); dXreadwrite::writeVector(stream, m_data); } void AttributeRowImpl::checkIndex(size_t index) const { if( index >= m_data.size()) { throw std::out_of_range("AttributeColumn index out of range"); } } AttributeRow &AttributeRowImpl::incrValue(size_t index, float value) { checkIndex(index); float val = m_data[index]; if ( val < 0) { setValue(index, value); } else { setValue(index, val + value); } return *this; } AttributeRow &AttributeRowImpl::incrValue(const std::string &colName, float value) { return incrValue(m_colManager.getColumnIndex(colName), value); } AttributeRow &AttributeTable::getRow(const AttributeKey &key) { auto* row = getRowPtr(key); if (row == 0) { throw std::out_of_range("Invalid row key"); } return *row; } const AttributeRow& AttributeTable::getRow(const AttributeKey &key) const { auto* row = getRowPtr(key); if (row == 0) { throw std::out_of_range("Invalid row key"); } return *row; } AttributeRow *AttributeTable::getRowPtr(const AttributeKey &key) { auto iter = m_rows.find(key); if (iter == m_rows.end()) { return 0; } return iter->second.get(); } const AttributeRow *AttributeTable::getRowPtr(const AttributeKey &key) const { auto iter = m_rows.find(key); if (iter == m_rows.end()) { return 0; } return iter->second.get(); } AttributeRow &AttributeTable::addRow(const AttributeKey &key) { auto iter = m_rows.find(key); if (iter != m_rows.end()) { throw new std::invalid_argument("Duplicate key"); } auto res = m_rows.insert(std::make_pair(key, std::unique_ptr(new AttributeRowImpl(*this)))); return *res.first->second; } void AttributeTable::removeRow(const AttributeKey &key) { auto iter = m_rows.find(key); if (iter == m_rows.end()) { throw new std::invalid_argument("Row does not exist"); } m_rows.erase(iter); } AttributeColumn &AttributeTable::getColumn(size_t index) { if(index == size_t(-1)) { return m_keyColumn; } checkColumnIndex(index); return m_columns[index]; } size_t AttributeTable::insertOrResetColumn(const std::string &columnName, const std::string &formula) { auto iter = m_columnMapping.find(columnName); if (iter == m_columnMapping.end()) { return addColumnInternal(columnName, formula); } // it exists - we need to reset it m_columns[iter->second].m_stats = AttributeColumnStats(); m_columns[iter->second].setLock(false); for (auto& row : m_rows) { row.second->setValue(iter->second, -1.0f); } return iter->second; } size_t AttributeTable::insertOrResetLockedColumn(const std::string &columnName, const std::string &formula) { size_t index = insertOrResetColumn(columnName, formula); m_columns[index].setLock(true); return index; } size_t AttributeTable::getOrInsertColumn(const std::string &columnName, const std::string &formula) { auto iter = m_columnMapping.find(columnName); if ( iter != m_columnMapping.end()) { return iter->second; } return addColumnInternal(columnName, formula); } size_t AttributeTable::getOrInsertLockedColumn(const std::string &columnName, const std::string &formula) { size_t index = getOrInsertColumn(columnName, formula); m_columns[index].setLock(true); return index; } void AttributeTable::removeColumn(size_t colIndex) { checkColumnIndex(colIndex); const std::string& name = m_columns[colIndex].getName(); auto iter = m_columnMapping.find(name); m_columnMapping.erase(iter); for (auto& elem : m_columnMapping) { if (elem.second > colIndex) { elem.second--; } } m_columns.erase(m_columns.begin()+colIndex); for (auto& row : m_rows) { row.second->removeColumn(colIndex); } } void AttributeTable::renameColumn(const std::string &oldName, const std::string &newName) { auto iter = m_columnMapping.find(oldName); if (iter == m_columnMapping.end()) { throw std::out_of_range("Invalid column name"); } size_t colIndex = iter->second; m_columns[colIndex].setName(newName); m_columnMapping.erase(iter); m_columnMapping[newName] = colIndex; } void AttributeTable::deselectAllRows() { for (auto& row : m_rows) { row.second->setSelection(false); } } void AttributeTable::setDisplayParamsForAllAttributes(const DisplayParams ¶ms) { for (auto& col: m_columns) { col.setDisplayParams(params); } } void AttributeTable::read(std::istream &stream, LayerManager &layerManager) { layerManager.read(stream); int colcount; stream.read((char *)&colcount, sizeof(colcount)); std::map tmp; for (int j = 0; j < colcount; j++) { AttributeColumnImpl col(""); tmp[col.read(stream)] = col; } for (auto & c : tmp) { m_columnMapping[c.second.getName()] = m_columns.size(); m_columns.push_back(c.second); } int rowcount, rowkey; stream.read((char *)&rowcount, sizeof(rowcount)); for (int i = 0; i < rowcount; i++) { stream.read((char *)&rowkey, sizeof(rowkey)); auto row = std::unique_ptr(new AttributeRowImpl(*this)); row->read(stream); m_rows.insert(std::make_pair(AttributeKey(rowkey),std::move(row))); } // ref column display params stream.read((char *)&m_displayParams,sizeof(DisplayParams)); } void AttributeTable::write(std::ostream &stream, const LayerManager &layerManager) { layerManager.write(stream); int colCount = (int)m_columns.size(); stream.write((char *)&colCount, sizeof(int)); // TODO: For binary compatibility write the columns in alphabetical order // but the physical columns in the order inserted std::vector indices(m_columns.size()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return m_columns[a].getName() < m_columns[b].getName(); }); for (int idx: indices) { m_columns[idx].write(stream, m_columnMapping[m_columns[idx].getName()]); } int rowcount = (int)m_rows.size(); stream.write((char *)&rowcount, sizeof(int)); for ( auto &kvp : m_rows) { kvp.first.write(stream); kvp.second->write(stream); } stream.write((const char *)&m_displayParams, sizeof(DisplayParams)); } void AttributeTable::clear() { m_rows.clear(); m_columns.clear(); m_columnMapping.clear(); } size_t AttributeTable::getColumnIndex(const std::string &name) const { auto iter = m_columnMapping.find(name); if (iter == m_columnMapping.end()) { std::stringstream message; message << "Unknown column name " << name; throw std::out_of_range(message.str()); } return iter->second; } // TODO: Compatibility. Method to retreive a column's index // if the set of columns was sorted size_t AttributeTable::getColumnSortedIndex(size_t index) const { if(index == size_t(-1) || index == size_t(-2)) return index; if(index >= m_columns.size()) return -1; return std::distance(m_columnMapping.begin(), m_columnMapping.find(getColumnName(index))); } const AttributeColumn &AttributeTable::getColumn(size_t index) const { if(index == size_t(-1)) { return m_keyColumn; } checkColumnIndex(index); return m_columns[index]; } const std::string &AttributeTable::getColumnName(size_t index) const { return getColumn(index).getName(); } size_t AttributeTable::getNumColumns() const { return m_columns.size(); } bool AttributeTable::hasColumn(const std::string &name) const { auto iter = m_columnMapping.find(name); return(iter != m_columnMapping.end()); } void AttributeTable::checkColumnIndex(size_t index) const { if (index >= m_columns.size()) { throw std::out_of_range("ColumnIndex out of range"); } } size_t AttributeTable::addColumnInternal(const std::string &name, const std::string &formula) { size_t colIndex = m_columns.size(); m_columns.push_back(AttributeColumnImpl(name, formula)); m_columnMapping[name] = colIndex; for (auto& elem : m_rows) { elem.second->addColumn(); } return colIndex; } ================================================ FILE: salalib/attributetable.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "layermanager.h" #include #include #include #include #include #include #include #include #include /// /// Namespace to hold known attributes /// namespace AttributeName { const char * const REF = "Ref"; } /// /// Interface to an attribute row /// class AttributeRow : public LayerAware { public: virtual float getValue(const std::string &column) const = 0; virtual float getValue(size_t index) const = 0; virtual float getNormalisedValue(size_t index) const = 0; virtual AttributeRow& setValue(const std::string &column, float value ) = 0; virtual AttributeRow& setValue(size_t index, float value) = 0; virtual AttributeRow& incrValue(size_t index, float value = 1.0f) = 0; virtual AttributeRow& incrValue(const std::string &colName, float value = 1.0f) = 0; virtual AttributeRow& setSelection(bool selected) = 0; virtual bool isSelected() const = 0; virtual ~AttributeRow(){} }; /// /// Container for attribute column stats - really just POD to pass them around /// struct AttributeColumnStats { AttributeColumnStats( double minimum, double maximum, double tot, double vTot, double vMin, double vMax ): min(minimum), max(maximum), total(tot), visibleTotal(vTot), visibleMin(vMin), visibleMax(vMax) {} AttributeColumnStats() : AttributeColumnStats(-1.0, -1.0, -1.0, -1.0, -1.0, -1.0) { } double min; double max; double total; double visibleTotal; double visibleMin; double visibleMax; }; /// /// Interface to an attribute column /// class AttributeColumn { public: virtual const std::string& getName() const = 0; virtual bool isLocked() const = 0; virtual void setLock(bool lock) = 0; virtual bool isHidden() const = 0; virtual void setHidden(bool hidden) = 0; virtual void setDisplayParams(const DisplayParams& params ) = 0; virtual const DisplayParams& getDisplayParams() const = 0; virtual const std::string& getFormula() const = 0; virtual void setFormula(std::string newFormula) = 0; virtual const AttributeColumnStats& getStats() const = 0; // stats are mutable - we need to be able to update them all the time, // even when not allowed to modify the column settings virtual void updateStats(float val, float oldVal = 0.0f) const = 0; virtual ~AttributeColumn(){} }; /// /// Interface to an Attribute Column Manager /// This handles the mapping from column name to index and actually storing the column implementations /// Implemented by AttributeTable /// class AttributeColumnManager { public: virtual size_t getNumColumns() const = 0; virtual size_t getColumnIndex(const std::string& name) const = 0; virtual const AttributeColumn& getColumn(size_t index) const = 0; virtual const std::string& getColumnName(size_t index) const = 0; }; // Implementation of AttributeColumn class AttributeColumnImpl: public AttributeColumn, AttributeColumnStats { // AttributeColumn interface public: AttributeColumnImpl(const std::string &name, const std::string &formula = std::string()) : m_name(name), m_locked(false), m_hidden(false), m_formula(formula) { } AttributeColumnImpl() : m_locked(false), m_hidden(false) {} virtual const std::string &getName() const; virtual bool isLocked() const; virtual void setLock(bool lock); virtual bool isHidden() const; virtual void setHidden(bool hidden); virtual const std::string &getFormula() const; virtual void setFormula(std::string newFormula); virtual const AttributeColumnStats& getStats() const; virtual void setDisplayParams(const DisplayParams ¶ms){ m_displayParams = params; } virtual const DisplayParams &getDisplayParams() const{return m_displayParams;} virtual void updateStats(float val, float oldVal = 0.0f) const; public: // stats are mutable - we need to be able to update them all the time, // even when not allowed to modify the column settings mutable AttributeColumnStats m_stats; void setName(const std::string &name); // returns the physical column for comaptibility with the old attribute table size_t read(std::istream &stream); void write(std::ostream& stream, int physicalCol); private: std::string m_name; bool m_locked; bool m_hidden; std::string m_formula; DisplayParams m_displayParams; }; // Implementation of AttributeColumn that actually links to the keys of the table class KeyColumn : public AttributeColumnImpl { public: KeyColumn() : AttributeColumnImpl() { setName(AttributeName::REF); } }; // Implementation of AttributeRow class AttributeRowImpl : public AttributeRow { public: AttributeRowImpl(const AttributeColumnManager& colManager) : m_data(colManager.getNumColumns(), -1.0), m_colManager(colManager), m_selected(false) { m_layerKey = 1; } // AttributeRow interface public: virtual float getValue(const std::string &column) const; virtual float getValue(size_t index) const; virtual float getNormalisedValue(size_t index) const; virtual AttributeRow& setValue(const std::string &column, float value); virtual AttributeRow& setValue(size_t index, float value); virtual AttributeRow& incrValue(const std::string &column, float value); virtual AttributeRow& incrValue(size_t index, float value); virtual AttributeRow& setSelection(bool selected); virtual bool isSelected() const; void addColumn(); void removeColumn(size_t index); void read(std::istream &stream); void write(std::ostream &stream); private: std::vector m_data; const AttributeColumnManager& m_colManager; bool m_selected; void checkIndex(size_t index) const; }; /// /// \brief Small struct to make an attribute key distinguishable from an int /// PixelRefs are serialised into an int (2 bytes x, 2 bytes y) for historic reason. This seems dangerous /// and confusing as these are by no means indices, but look the same to the compiler and the reader. /// This struct should disambiguate this... /// struct AttributeKey { explicit AttributeKey(int val) : value(val) {} int value; bool operator < (const AttributeKey& other ) const { return value < other.value; } void write(std::ostream &stream) const { stream.write((char *)&value, sizeof(int)); } void read(std::istream &stream) { stream.read((char *)&value, sizeof(int)); } }; /// /// AttributeTable /// class AttributeTable : public AttributeColumnManager { // AttributeTable "interface" - the actual table handling public: AttributeTable(){} virtual ~AttributeTable(){} AttributeTable(AttributeTable&&) = default; AttributeTable& operator =(AttributeTable&&) = default; AttributeTable(const AttributeTable& ) = delete; AttributeTable& operator =(const AttributeTable&) = delete; /// /// \brief Get a row reference /// \param key of the row /// \return reference to row, throws if key not found /// AttributeRow& getRow(const AttributeKey& key ); /// /// \brief Get a row const reference /// \param key of the row /// \return const reference to row, throws if key not found /// const AttributeRow& getRow(const AttributeKey& key) const; /// /// \brief Get a row pointer /// \param key of the row /// \return pointer to row, null if key not found /// AttributeRow* getRowPtr(const AttributeKey& key); /// /// \brief Get a row const pointer /// \param key of the row /// \return const pointer to row, null if key not found /// const AttributeRow* getRowPtr(const AttributeKey& key)const; AttributeRow &addRow(const AttributeKey& key); AttributeColumn& getColumn(size_t index); size_t insertOrResetColumn(const std::string& columnName, const std::string &formula = std::string()); size_t insertOrResetLockedColumn(const std::string& columnName, const std::string &formula = std::string()); size_t getOrInsertColumn(const std::string& columnName, const std::string &formula = std::string()); size_t getOrInsertLockedColumn(const std::string& columnName, const std::string &formula = std::string()); void removeRow(const AttributeKey& key); void removeColumn(size_t colIndex); void renameColumn(const std::string& oldName, const std::string& newName); size_t getNumRows() const { return m_rows.size(); } void deselectAllRows(); const DisplayParams& getDisplayParams() const { return m_displayParams; } void setDisplayParams(const DisplayParams& params){m_displayParams = params;} void setDisplayParamsForAllAttributes(const DisplayParams& params); void read(std::istream &stream, LayerManager &layerManager); void write(std::ostream &stream, const LayerManager &layerManager); void clear(); float getSelAvg(size_t columnIndex) { float selTotal = 0; int selNum = 0; for(auto& pair: m_rows) { if(pair.second->isSelected()) { selTotal += pair.second->getValue(columnIndex); selNum++; } } if(selNum == 0) { return(-1); } return(selTotal/selNum); } // interface AttributeColumnManager public: virtual size_t getColumnIndex(const std::string& name) const; virtual const AttributeColumn& getColumn(size_t index) const; virtual const std::string& getColumnName(size_t index) const; virtual size_t getNumColumns() const; virtual bool hasColumn(const std::string &name) const; // TODO: Compatibility. Very inefficient method to retreive a column's index // if the set of columns was sorted size_t getColumnSortedIndex(size_t index) const; private: typedef std::map> StorageType; StorageType m_rows; std::map m_columnMapping; std::vector m_columns; KeyColumn m_keyColumn; DisplayParams m_displayParams; private: void checkColumnIndex(size_t index) const; size_t addColumnInternal(const std::string &name, const std::string &formula); // warning - here be dragons! // This is the implementation of stl style iterators on attribute table, allowing efficient // iteration of rows without resorting to log(n) access via the map public: /// /// \brief The iterator_item class /// The value of an iterator over the table - we want to hide the actual storage details and just /// return references to rows and keys. class iterator_item { public: virtual const AttributeKey& getKey() const = 0; virtual const AttributeRow& getRow() const = 0; virtual AttributeRow& getRow() = 0; virtual ~iterator_item(){} }; private: // implementation of the iterator_item, templated on iterator type to allow const and non-const iterator template class iterator_item_impl : public iterator_item { public: iterator_item_impl( const iterator_type & iter) : m_iter(iter) {} template iterator_item_impl(const iterator_item_impl& other) : m_iter(other.m_iter) {} template iterator_item_impl& operator = (const iterator_item_impl& other) { m_iter = other.m_iter; return *this; } const AttributeKey& getKey() const { return m_iter->first; } const AttributeRow& getRow() const { return *m_iter->second; } AttributeRow& getRow() { return *m_iter->second; } void forward() const { ++m_iter; } void back() const { --m_iter; } template bool operator == (const iterator_item_impl &other) const { return m_iter == other.m_iter; } public: mutable iterator_type m_iter; }; // iterator implementation - templated on iterator type for const/non-const template class const_iterator_impl : public std::iterator { template friend class const_iterator_impl; public: const_iterator_impl( const iterator_type& iter) : m_item(iter) {} template const_iterator_impl(const const_iterator_impl& other) : m_item(other.m_item) {} template const_iterator_impl& operator =(const const_iterator_impl &other) { m_item = other.m_item; return *this; } const_iterator_impl& operator++() {m_item.forward();return *this;} const_iterator_impl operator++(int) {const_iterator_impl tmp(*this); operator++(); return tmp;} const_iterator_impl& operator--() {m_item.back();return *this;} const_iterator_impl operator--(int) {const_iterator_impl tmp(*this); operator--(); return tmp;} template bool operator==(const const_iterator_impl& rhs) const {return m_item == rhs.m_item;} template bool operator!=(const const_iterator_impl& rhs) const {return !(m_item==rhs.m_item);} const iterator_item& operator*() const {return m_item;} const iterator_item* operator->() const {return &m_item;} protected: iterator_item_impl m_item; }; public: // const iterator is just a typedef on the impl typedef const_iterator_impl const_iterator; // non const iterator needs some extra methods class iterator : public const_iterator_impl { public: iterator(const typename StorageType::iterator& iter) : const_iterator_impl(iter) {} template iterator(const const_iterator_impl& other) : const_iterator_impl(other.item){ // m_item = other.m_item; } template iterator& operator =(const const_iterator_impl &other) { const_iterator_impl::m_item = other.m_item; return *this; } iterator_item& operator*() {return const_iterator_impl::m_item;} iterator_item* operator->() {return &(const_iterator_impl::m_item);} }; // stl style iteration methods const_iterator begin() const { return const_iterator(m_rows.begin()); } iterator begin() { return iterator(m_rows.begin()); } const_iterator end() const { return const_iterator(m_rows.end()); } iterator end() { return iterator(m_rows.end()); } iterator find(AttributeKey key) { return iterator(m_rows.find(key)); } std::pair>& back() { return *m_rows.rbegin(); } }; ================================================ FILE: salalib/attributetablehelpers.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "attributetable.h" #include "attributetableview.h" #include "pafcolor.h" #include "mgraph_consts.h" namespace dXreimpl{ inline void pushSelectionToLayer(AttributeTable &table, LayerManager& layerManager, const std::string &layerName) { size_t layerIndex = layerManager.addLayer(layerName); LayerManager::KeyType layerKey = layerManager.getKey(layerIndex); for (auto & item: table) { auto& row = item.getRow(); if (isObjectVisible(layerManager, row) && row.isSelected()) { addLayerToObject(item.getRow(), layerKey); } } layerManager.setLayerVisible(layerIndex); } inline PafColor getDisplayColor( const AttributeKey& key, const AttributeRow& row, const AttributeTableView& tableView, bool checkSelectionStatus = false) { if ( checkSelectionStatus && row.isSelected()) { return PafColor(SALA_SELECTED_COLOR); } PafColor color; return color.makeColor(tableView.getNormalisedValue(key, row), tableView.getDisplayParams()); } } struct OrderedIntPair { int a; int b; OrderedIntPair(int x = -1, int y = -1) { a = (int) x < y ? x : y; b = (int) x < y ? y : x; } // inlined at end of file friend bool operator == (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator != (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator < (const OrderedIntPair& x, const OrderedIntPair& y); friend bool operator > (const OrderedIntPair& x, const OrderedIntPair& y); }; // note: these are made with a is always less than b inline bool operator == (const OrderedIntPair& x, const OrderedIntPair& y) { return (x.a == y.a && x.b == y.b); } inline bool operator != (const OrderedIntPair& x, const OrderedIntPair& y) { return (x.a != y.a || x.b != y.b); } inline bool operator < (const OrderedIntPair& x, const OrderedIntPair& y) { return ( (x.a == y.a) ? x.b < y.b : x.a < y.a ); } inline bool operator > (const OrderedIntPair& x, const OrderedIntPair& y) { return ( (x.a == y.a) ? x.b > y.b : x.a > y.a ); } ================================================ FILE: salalib/attributetableindex.cpp ================================================ // Copyright (C) 2018 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/attributetableindex.h" std::vector makeAttributeIndex(const AttributeTable &table, int colIndex) { std::vector index; size_t numRows = table.getNumRows(); if (numRows == 0) { return index; } index.reserve(numRows); // perturb the values to be sorted by so same values will be in order of appearence in the map size_t idx = 0; if ( colIndex == -1 ) { double perturbationFactor = 1e-9 / numRows; for (auto& item: table) { double value = (double)item.getKey().value; value += idx * perturbationFactor; index.push_back(ConstAttributeIndexItem(item.getKey(), value, item.getRow())); ++idx; } } else if (colIndex >= 0 ) { double perturbationFactor = table.getColumn(colIndex).getStats().max * 1e-9 / numRows; for (auto & item : table) { double value = item.getRow().getValue(colIndex); value += idx * perturbationFactor; index.push_back(ConstAttributeIndexItem(item.getKey(), value, item.getRow())); ++idx; } } else { throw std::out_of_range("Column index out of range"); } std::sort(index.begin(), index.end()); return index; } std::vector makeAttributeIndex(AttributeTable &table, int colIndex) { std::vector index; size_t numRows = table.getNumRows(); if (numRows == 0) { return index; } index.reserve(numRows); // perturb the values to be sorted by so same values will be in order of appearence in the map size_t idx = 0; if ( colIndex == -1 ) { double perturbationFactor = 1e-9 / numRows; for (auto& item: table) { double value = (double)item.getKey().value; value += idx * perturbationFactor; index.push_back(AttributeIndexItem(item.getKey(), value, item.getRow())); ++idx; } } else if (colIndex >= 0 ) { double perturbationFactor = table.getColumn(colIndex).getStats().max * 1e-9 / numRows; for (auto & item : table) { double value = item.getRow().getValue(colIndex); value += idx * perturbationFactor; index.push_back(AttributeIndexItem(item.getKey(), value, item.getRow())); ++idx; } } else { throw std::out_of_range("Column index out of range"); } std::sort(index.begin(), index.end()); return index; } std::pair::iterator, std::vector::iterator> getIndexItemsInValueRange(std::vector &index, AttributeTable &table, float fromValue, float toValue) { AttributeKey dummykey(-1); AttributeRowImpl dummyrow(table); return std::pair::iterator, std::vector::iterator>( std::lower_bound(index.begin(), index.end(), AttributeIndexItem(dummykey, fromValue, dummyrow)), std::upper_bound(index.begin(), index.end(), AttributeIndexItem(dummykey, toValue, dummyrow))); } ================================================ FILE: salalib/attributetableindex.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "attributetable.h" #include class ConstAttributeIndexItem { public: ConstAttributeIndexItem(const AttributeKey &k, double v, const AttributeRow &r) : key(k), value(v), row(&r) {} ConstAttributeIndexItem(const ConstAttributeIndexItem& other) : key(other.key), value(other.value), row(other.row) {} ConstAttributeIndexItem &operator = (const ConstAttributeIndexItem& other) { if ( this == &other) { return *this; } key = other.key; value = other.value; row = other.row; return *this; } AttributeKey key; double value; const AttributeRow * row; }; class AttributeIndexItem : public ConstAttributeIndexItem { public: AttributeIndexItem( const AttributeKey &k, double v, AttributeRow &r) : ConstAttributeIndexItem(k,v,r), mutable_row(&r) {} AttributeIndexItem( const AttributeIndexItem &other) : ConstAttributeIndexItem(other), mutable_row(other.mutable_row) {} AttributeIndexItem &operator = (const AttributeIndexItem &other) { if ( this == &other) { return *this; } ConstAttributeIndexItem::operator =(other); mutable_row = other.mutable_row; return *this; } AttributeRow *mutable_row; }; inline bool operator < (const ConstAttributeIndexItem &lhs, const ConstAttributeIndexItem &rhs) { return lhs.value < rhs.value; } std::vector makeAttributeIndex(const AttributeTable &table, int colIndex); std::vector makeAttributeIndex(AttributeTable &table, int colIndex); std::pair::iterator, std::vector::iterator> getIndexItemsInValueRange(std::vector &index, AttributeTable &table, float fromValue, float toValue); ================================================ FILE: salalib/attributetableview.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "attributetableview.h" AttributeTableView::AttributeTableView(const AttributeTable &table) : m_table(table), m_displayColumn(-1) {} void AttributeTableView::setDisplayColIndex(int columnIndex){ if (columnIndex < -1) { m_displayColumn = -2; m_index.clear(); return; } // recalculate the index even if it's the same column in case stuff has changed m_index = makeAttributeIndex(m_table, columnIndex); m_displayColumn = columnIndex; } float AttributeTableView::getNormalisedValue(const AttributeKey &key, const AttributeRow &row) const { if ( m_displayColumn < 0) { auto endIter = m_table.end(); --endIter; return (float)key.value /(float) endIter->getKey().value; } return row.getNormalisedValue(m_displayColumn); } const DisplayParams &AttributeTableView::getDisplayParams() const { if (m_displayColumn < 0) { return m_table.getDisplayParams(); } return m_table.getColumn(m_displayColumn).getDisplayParams(); } void AttributeTableHandle::setDisplayColIndex(int columnIndex){ if (columnIndex < -1) { m_mutableIndex.clear(); } else { // recalculate the index even if it's the same column in case stuff has changed m_mutableIndex = makeAttributeIndex(m_mutableTable, columnIndex); } AttributeTableView::setDisplayColIndex(columnIndex); } int AttributeTableHandle::findInIndex(const AttributeKey &key) { auto iter = std::find_if(m_mutableIndex.begin(), m_mutableIndex.end(), index_item_key(key)); if (iter != m_mutableIndex.end()) { return(std::distance(m_mutableIndex.begin(), iter)); } return -1; } ================================================ FILE: salalib/attributetableview.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "attributetable.h" #include "attributetableindex.h" #include class AttributeTableView { public: AttributeTableView(const AttributeTable& table ); const AttributeTable &m_table; // columnIndex < 0 -> not set virtual void setDisplayColIndex(int columnIndex); int getDisplayColIndex() const{ return m_displayColumn;} float getNormalisedValue(const AttributeKey& key, const AttributeRow &row) const; const DisplayParams& getDisplayParams() const; typedef std::vector ConstIndex; const ConstIndex& getConstTableIndex() const{return m_index;} const AttributeColumn& getDisplayedColumn() const; private: ConstIndex m_index; int m_displayColumn; }; class AttributeTableHandle : public AttributeTableView { public: AttributeTableHandle(AttributeTable &table) : AttributeTableView(table), m_mutableTable(table){} virtual ~AttributeTableHandle(){} typedef std::vector Index; const Index& getTableIndex() const {return m_mutableIndex;} virtual void setDisplayColIndex(int columnIndex); int findInIndex(const AttributeKey &key); private: AttributeTable& m_mutableTable; Index m_mutableIndex; }; struct index_item_key : public std::function { explicit index_item_key(const AttributeKey &baseline) : m_baseline(baseline) {} bool operator() (const AttributeIndexItem &arg) { return arg.key.value == m_baseline.value; } const AttributeKey& m_baseline; }; ================================================ FILE: salalib/axialmap.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #include "salalib/axialmap.h" #include "salalib/alllinemap.h" #include "salalib/tolerances.h" #include "salalib/pointdata.h" // need the pointdata for the convert boundary graph to axial map routine #include "salalib/ngraph.h" // ditto ngraph #include "salalib/parsers/mapinfodata.h" #include "genlib/comm.h" // For communicator #include "genlib/stringutils.h" #include "genlib/containerutils.h" #include "genlib/readwritehelpers.h" #include "genlib/pflipper.h" #include #include #include #ifndef _WIN32 #define _finite finite #endif //////////////////////////////////////////////////////////////////////////////////////////// ShapeGraph::ShapeGraph(const std::string& name, int type) : ShapeMap(name,type) { m_keyvertexcount = 0; m_hasgraph = true; } //////////////////////////////////////////////////////////////////////////////////////////////////////// void ShapeGraph::initialiseAttributesAxial() { m_attributes->clear(); // note, expects these to be numbered 0, 1... m_attributes->insertOrResetLockedColumn("Connectivity"); m_attributes->insertOrResetLockedColumn("Line Length"); } void ShapeGraph::makeConnections(const KeyVertices &keyvertices) { m_connectors.clear(); m_links.clear(); m_unlinks.clear(); m_keyvertices.clear(); // note, expects these to be numbered 0, 1... int conn_col = m_attributes->getColumnIndex("Connectivity"); int leng_col = m_attributes->getColumnIndex("Line Length"); int i = -1; for (auto shape: m_shapes) { i++; int key = shape.first; AttributeRow &row = m_attributes->getRow(AttributeKey(key)); // all indices should match... m_connectors.push_back( Connector() ); m_connectors[i].m_connections = getLineConnections( key, TOLERANCE_B*__max(m_region.height(),m_region.width())); row.setValue(conn_col, float(m_connectors[i].m_connections.size()) ); row.setValue(leng_col, float(shape.second.getLine().length()) ); if (keyvertices.size()) { // note: depends on lines being recorded in same order as keyvertices... m_keyvertices.push_back( keyvertices[i] ); } } m_displayed_attribute = -1; // <- override if it's already showing setDisplayedAttribute(conn_col); } ///////////////////////////////////////////////////////////////////////////////////////// bool ShapeGraph::outputMifPolygons(std::ostream& miffile, std::ostream& midfile) const { // take lines from lines layer and make into regions (using the axial polygons) std::vector lines; for (auto shape: m_shapes) { lines.push_back(shape.second.getLine()); } AxialPolygons polygons; polygons.init(lines, m_region); std::vector> newpolygons; polygons.makePolygons(newpolygons); MapInfoData mapinfodata; if (m_hasMapInfoData) { mapinfodata.m_coordsys = m_mapinfodata.m_coordsys; mapinfodata.m_bounds = m_mapinfodata.m_bounds; } mapinfodata.exportPolygons(miffile, midfile, newpolygons, m_region); return true; } void ShapeGraph::outputNet(std::ostream& netfile) const { double maxdim = __max(m_region.width(),m_region.height()); Point2f offset = Point2f((maxdim - m_region.width())/(2.0*maxdim),(maxdim - m_region.height())/(2.0*maxdim)); if (isSegmentMap()) { netfile << "*Vertices " << m_shapes.size() * 2 << std::endl; int i = -1; for (auto shape: m_shapes) { i++; Line li = shape.second.getLine(); Point2f p1 = li.start(); Point2f p2 = li.end(); p1.x = offset.x + (p1.x - m_region.bottom_left.x) / maxdim; p2.x = offset.x + (p2.x - m_region.bottom_left.x) / maxdim; p1.y = 1.0 - (offset.y + (p1.y - m_region.bottom_left.y) / maxdim); p2.y = 1.0 - (offset.y + (p2.y - m_region.bottom_left.y) / maxdim); netfile << (i * 2 + 1) << " \"" << i << "a\" " << p1.x << " " << p1.y << std::endl; netfile << (i * 2 + 2) << " \"" << i << "b\" " << p2.x << " " << p2.y << std::endl; } netfile << "*Edges" << std::endl; for (size_t i = 0; i < m_shapes.size(); i++) { netfile << (i * 2 + 1) << " " << (i * 2 + 2) << " 2" << std::endl; } netfile << "*Arcs" << std::endl; // this makes an assumption about which is the "start" and which is the "end" // it works for an automatically converted axial map, I'm not sure it works for others... for (size_t j = 0; j < m_connectors.size(); j++) { const Connector& conn = m_connectors[j]; for (auto& segconn: conn.m_forward_segconns) { SegmentRef ref = segconn.first; float weight = segconn.second; netfile << (j * 2 + 1) << " " << (ref.ref * 2 + ((ref.dir == 1) ? 1 : 2)) << " " << weight << std::endl; } for (auto& segconn: conn.m_back_segconns) { SegmentRef ref = segconn.first; float weight = segconn.second; netfile << (j * 2 + 2) << " " << (ref.ref * 2 + ((ref.dir == 1) ? 1 : 2)) << " " << weight << std::endl; } } } else { netfile << "*Vertices " << m_shapes.size() << std::endl; int i = -1; for (auto shape: m_shapes) { i++; Point2f p = shape.second.getCentroid(); p.x = offset.x + (p.x - m_region.bottom_left.x) / maxdim; p.y = 1.0 - (offset.y + (p.y - m_region.bottom_left.y) / maxdim); netfile << (i + 1) << " \"" << i << "\" " << p.x << " " << p.y << std::endl; } netfile << "*Edges" << std::endl; for (size_t j = 0; j < m_connectors.size(); j++) { const Connector& conn = m_connectors[j]; for (size_t k = 0; k < conn.m_connections.size(); k++) { size_t to = conn.m_connections[k]; if (j < to) { netfile << (j+1) << " " << (to + 1) << " 1" << std::endl; } } } } } bool ShapeGraph::read(std::istream &stream) { m_attributes->clear(); m_connectors.clear(); m_map_type = ShapeMap::EMPTYMAP; // note that keyvertexcount and keyvertices are different things! (length keyvertices not the same as keyvertexcount!) stream.read((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); int size; stream.read((char *)&size,sizeof(size)); for (int i = 0; i < size; i++) { std::vector tempVec; dXreadwrite::readIntoVector(stream, tempVec); m_keyvertices.push_back(std::set(tempVec.begin(), tempVec.end())); } // now base class read: ShapeMap::read(stream); return true; } bool ShapeGraph::readold( std::istream& stream) { // read in from old base class SpacePixel linemap; linemap.read(stream); const std::map& lines = linemap.getAllLines(); m_name = linemap.getName(); // now copy to new base class: init(lines.size(),linemap.getRegion()); for (auto line: lines) { makeLineShape(line.second.line); } // n.b., we now have to reclear attributes! m_attributes->clear(); // continue old read: int pushmap = -1; char segmentmapc = stream.get(); if (segmentmapc == '1') { m_map_type = ShapeMap::SEGMENTMAP; } else { m_map_type = ShapeMap::AXIALMAP; } char gatemapc = stream.get(); if (gatemapc == '1') { m_map_type = ShapeMap::DATAMAP; } stream.read((char *)&pushmap,sizeof(pushmap)); int displayed_attribute; // n.b., temp variable necessary to force recalc below stream.read((char *)&displayed_attribute,sizeof(displayed_attribute)); m_attributes->read(stream, m_layers); int size; stream.read((char *)&size,sizeof(size)); for (int j = 0; j < size; j++) { m_keyvertices.push_back(std::set()); // <- these were stored with the connector int key; stream.read((char *)&key,sizeof(key)); // <- key deprecated m_connectors.push_back(Connector()); m_connectors[size_t(j)].read(stream); } stream.read((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); dXreadwrite::readIntoVector(stream,m_links); dXreadwrite::readIntoVector(stream,m_unlinks); char x = stream.get(); if (x == 'm') { m_mapinfodata = MapInfoData(); m_mapinfodata.read(stream); m_hasMapInfoData = true; } // now, as soon as loaded, must recalculate our screen display: // note m_displayed_attribute should be -2 in order to force recalc... m_displayed_attribute = -2; setDisplayedAttribute(displayed_attribute); return true; } bool ShapeGraph::write( std::ofstream& stream ) { // note keyvertexcount and keyvertices are different things! (length keyvertices not the same as keyvertexcount!) stream.write((char *)&m_keyvertexcount,sizeof(m_keyvertexcount)); int size = m_keyvertices.size(); stream.write((char *)&size,sizeof(size)); for (size_t i = 0; i < m_keyvertices.size(); i++) { dXreadwrite::writeVector(stream, std::vector( m_keyvertices[i].begin(), m_keyvertices[i].end() )); } // now simply run base class write: ShapeMap::write(stream); return true; } void ShapeGraph::writeAxialConnectionsAsDotGraph(std::ostream &stream) { const std::vector& connectors = ShapeMap::getConnections(); stream << "strict graph {" << std::endl; stream.precision(12); for (size_t i = 0; i < connectors.size(); i++) { const std::vector& connections = connectors[i].m_connections; for (int connection: connections) { stream << " " << i << " -- " << connection << std::endl; } } stream << "}" << std::endl; } void ShapeGraph::writeLinksUnlinksAsPairsCSV(std::ostream &stream, char delimiter) { stream.precision(12); stream << "refA" << delimiter << "refB" << delimiter << "link" << std::endl; for (auto &link : m_links) { stream << depthmapX::getMapAtIndex(m_shapes, link.a)->first << delimiter << depthmapX::getMapAtIndex(m_shapes, link.b)->first << delimiter << "1" << std::endl; } for (auto &unlink : m_unlinks) { stream << depthmapX::getMapAtIndex(m_shapes, unlink.a)->first << delimiter << depthmapX::getMapAtIndex(m_shapes, unlink.b)->first << delimiter << "0" << std::endl; } } void ShapeGraph::writeAxialConnectionsAsPairsCSV(std::ostream &stream) { const std::vector& connectors = ShapeMap::getConnections(); stream.precision(12); stream << "refA,refB" << std::endl; for (size_t i = 0; i < connectors.size(); i++) { auto& connections = connectors[i].m_connections; if (i != 0) stream << std::endl; for (auto iter = connections.begin(); iter != connections.end(); ++iter) { if (iter != connections.begin()) stream << std::endl; stream << i << "," << *iter; } } } void ShapeGraph::writeSegmentConnectionsAsPairsCSV(std::ostream &stream) { const std::vector& connectors = ShapeMap::getConnections(); stream.precision(12); stream << "refA,refB,ss_weight,for_back,dir"; // directed links for (size_t i = 0; i < connectors.size(); i++) { for (auto& segconn: connectors[i].m_forward_segconns) { stream << std::endl; stream << i << "," << segconn.first.ref << "," << segconn.second << "," << 0 // forward << "," << int(segconn.first.dir); } for (auto& segconn: connectors[i].m_back_segconns) { stream << std::endl; stream << i << "," << segconn.first.ref << "," << segconn.second << "," << 1 // back << "," << int(segconn.first.dir); } } } void ShapeGraph::unlinkAtPoint(const Point2f& unlinkPoint) { std::vector closepoints; std::vector> intersections; PixelRef pix = pixelate(unlinkPoint); std::vector& pix_shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); auto iter = pix_shapes.begin(); for (; iter != pix_shapes.end(); ++iter) { for (auto jter = iter; jter != pix_shapes.end(); ++jter) { auto aIter = m_shapes.find(int(iter->m_shape_ref)); auto bIter = m_shapes.find(int(jter->m_shape_ref)); int a = int(std::distance(m_shapes.begin(), aIter)); int b = int(std::distance(m_shapes.begin(), bIter)); auto& connections = m_connectors[size_t(a)].m_connections; if (aIter != m_shapes.end() && bIter != m_shapes.end() && aIter->second.isLine() && bIter->second.isLine() && std::find(connections.begin(), connections.end(), b) != connections.end()) { closepoints.push_back( intersection_point(aIter->second.getLine(), bIter->second.getLine(), TOLERANCE_A) ); intersections.push_back( std::pair(a,b) ); } } } double mindist = -1.0; int minpair = -1; int j = 0; for (auto& closepoint: closepoints) { if (minpair == -1 || dist(unlinkPoint,closepoint) < mindist) { mindist = dist(unlinkPoint,closepoint); minpair = j; } j++; } if (minpair != -1) { auto& intersection = intersections[size_t(minpair)]; unlinkShapes(intersection.first, intersection.second, false); } else { std::cerr << "eek!"; } } //////////////////////////////////////////////////////////////////////////// // this unlink options was originally excised on the version 7 recode // however, it is *very specific* to axial maps, and so have been reincluded here void ShapeGraph::unlinkFromShapeMap(const ShapeMap& shapemap) { // used to make a shape map from every axial intersection, // find lines in rough vincinity of unlink point, and check for the closest // pair to unlink: const std::map& polygons = shapemap.getAllShapes(); for (auto polygon: polygons) { // just use the points: if (polygon.second.isPoint()) { unlinkAtPoint(polygon.second.getPoint()); } } // reset displayed attribute if it happens to be "Connectivity": int conn_col = m_attributes->getColumnIndex("Connectivity"); if (getDisplayedAttribute() == conn_col) { invalidateDisplayedAttribute(); setDisplayedAttribute(conn_col); // <- reflect changes to connectivity counts } } /////////////////////////////////////////////////////////////////////////////// // Two ways to make a segment map // Method 1: direct linkage of endpoints where they touch void ShapeGraph::makeNewSegMap(Communicator *comm) { // now make a connection set from the ends of lines: struct LineConnector { const Line &m_line; Connector &m_connector; int m_index; LineConnector(const Line &line, Connector &connector, int index) : m_line(line), m_connector(connector), m_index(index) {} }; std::vector connectionset; for (auto &shape : m_shapes) { if (shape.second.isLine()) { connectionset.emplace_back(); } } std::map lineConnectors; auto connectionIter = connectionset.begin(); int connectionIdx = 0; for (auto &shape : m_shapes) { if (shape.second.isLine()) { lineConnectors.insert(std::make_pair( shape.first, LineConnector(shape.second.getLine(), *connectionIter, connectionIdx))); connectionIter++; connectionIdx++; } } time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, lineConnectors.size()); } double maxdim = __max(m_region.width(), m_region.height()); int count = 0; for (auto &lineConnector_a : lineConnectors) { Connector &connectionset_a = lineConnector_a.second.m_connector; const Line &line_a = lineConnector_a.second.m_line; int idx_a = lineConnector_a.second.m_index; // n.b., vector() is based on t_start and t_end, so we must use t_start and t_end here and throughout PixelRef pix1 = pixelate(line_a.t_start()); std::vector &shapes1 = m_pixel_shapes(static_cast(pix1.y), static_cast(pix1.x)); for (auto &shape : shapes1) { auto lineConnector_b = lineConnectors.find(shape.m_shape_ref); if (lineConnector_b != lineConnectors.end() && idx_a < lineConnector_b->second.m_index) { Connector &connectionset_b = lineConnector_b->second.m_connector; const Line &line_b = lineConnector_b->second.m_line; int idx_b = lineConnector_b->second.m_index; Point2f alpha = line_a.vector(); Point2f beta = line_b.vector(); alpha.normalise(); beta.normalise(); if (approxeq(line_a.t_start(), line_b.t_start(), (maxdim * TOLERANCE_B))) { float x = float(2.0 * acos(__min(__max(-dot(alpha, beta), -1.0), 1.0)) / M_PI); depthmapX::addIfNotExists(connectionset_a.m_back_segconns, SegmentRef(1, idx_b), x); depthmapX::addIfNotExists(connectionset_b.m_back_segconns, SegmentRef(1, idx_a), x); } if (approxeq(line_a.t_start(), line_b.t_end(), (maxdim * TOLERANCE_B))) { float x = float(2.0 * acos(__min(__max(-dot(alpha, -beta), -1.0), 1.0)) / M_PI); depthmapX::addIfNotExists(connectionset_a.m_back_segconns, SegmentRef(-1, idx_b), x); depthmapX::addIfNotExists(connectionset_b.m_forward_segconns, SegmentRef(1, idx_a), x); } } } PixelRef pix2 = pixelate(line_a.t_end()); std::vector &shapes2 = m_pixel_shapes(static_cast(pix2.y), static_cast(pix2.x)); for (auto &shape : shapes2) { auto lineConnector_b = lineConnectors.find(shape.m_shape_ref); if (lineConnector_b != lineConnectors.end() && idx_a < lineConnector_b->second.m_index) { Connector &connectionset_b = lineConnector_b->second.m_connector; const Line &line_b = lineConnector_b->second.m_line; int idx_b = lineConnector_b->second.m_index; Point2f alpha = line_a.vector(); Point2f beta = line_b.vector(); alpha.normalise(); beta.normalise(); if (approxeq(line_a.t_end(), line_b.t_start(), (maxdim * TOLERANCE_B))) { float x = float(2.0 * acos(__min(__max(-dot(-alpha, beta), -1.0), 1.0)) / M_PI); depthmapX::addIfNotExists(connectionset_a.m_forward_segconns, SegmentRef(1, idx_b), x); depthmapX::addIfNotExists(connectionset_b.m_back_segconns, SegmentRef(-1, idx_a), x); } if (approxeq(line_a.t_end(), line_b.t_end(), (maxdim * TOLERANCE_B))) { float x = float(2.0 * acos(__min(__max(-dot(-alpha, -beta), -1.0), 1.0)) / M_PI); depthmapX::addIfNotExists(connectionset_a.m_forward_segconns, SegmentRef(-1, idx_b), x); depthmapX::addIfNotExists(connectionset_b.m_forward_segconns, SegmentRef(-1, idx_a), x); } } } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } count++; } // initialise attributes now separated from making the connections makeSegmentConnections(connectionset); } // Method 2: Making a segment map (in two stages) // One: take the original axial map and split it up // (note: you need to start from an axial map, // but the map could have been created from a road-centre-line // graph or equivalent -- reason is that you might want to // preserve unlinks in your angular mapping) // A "linetest" is used in order to use the test component to // identify the original axial line this line segment is // associated with void ShapeGraph::makeSegmentMap(std::vector& lines, std::vector& connectors, double stubremoval) { // the first (key) pair is the line / line intersection, second is the pair of associated segments for the first line std::map> segmentlist; // this code relies on the polygon order being the same as the connections auto iter = m_shapes.begin(); for (size_t i = 0; i < m_connectors.size(); i++) { auto shape = iter->second; int axialRef = iter->first; iter++; if (!shape.isLine()) { continue; } const Line& line = shape.getLine(); std::vector > breaks; // this is a vector instead of a map because the // original code allowed for duplicate keys int axis = line.width() >= line.height() ? XAXIS : YAXIS; // we need the breaks ordered from start to end of the line // this is automatic for XAXIS, but on YAXIS, need to know // if the line is ascending or decending int parity = (axis == XAXIS) ? 1 : line.sign(); auto& connections = m_connectors[i].m_connections; for (size_t j = 0; j < connections.size(); j++) { // find the intersection point and add... // note: more than one break at the same place allowed auto shapeJ = depthmapX::getMapAtIndex(m_shapes, connections[j])->second; if (static_cast(i) != connections[j] && shapeJ.isLine()) { breaks.push_back(std::make_pair(parity * line.intersection_point( shapeJ.getLine(), axis, TOLERANCE_A ), connections[j])); } } std::sort(breaks.begin(), breaks.end()); // okay, now we have a list from one end of the other of lines this line connects with Point2f lastpoint = line.start(); int seg_a = -1, seg_b = -1; double neardist; // TOLERANCE_C is introduced as of 01.08.2008 although it is a fix to a bug first // found in July 2006. It has been set "high" deliberately (1e-6 = a millionth of the line height / width) // in order to catch small errors made by operators or floating point errors in other systems // when drawing, for example, three axial lines intersecting if (stubremoval == 0.0) { // if 0, convert to tolerance stubremoval = TOLERANCE_C; } neardist = (axis == XAXIS) ? (line.width() * stubremoval) : (line.height() * stubremoval); double overlapdist = (axis == XAXIS) ? (line.width() * TOLERANCE_C) : (line.height() * TOLERANCE_C); // for (auto breaksIter = breaks.begin(); breaksIter != breaks.end();) { std::vector keylist; if (seg_a == -1) { Point2f thispoint = line.point_on_line(parity * breaksIter->first,axis); if (fabs(parity * breaksIter->first - line.start()[axis]) < neardist) { seg_a = -1; lastpoint = thispoint; } else { Line segment_a(line.start(),thispoint); lines.push_back(segment_a); connectors.push_back(Connector(axialRef)); seg_a = lines.size() - 1; } lastpoint = thispoint; } // double here = parity * breaksIter->first; while (breaksIter != breaks.end() && fabs(parity * breaksIter->first - here) < overlapdist) { keylist.push_back(breaksIter->second); ++breaksIter; } // if (breaksIter == breaks.end() && fabs(line.end()[axis] - parity * breaks.rbegin()->first) < neardist) { seg_b = -1; } else { Point2f thispoint; if (breaksIter != breaks.end()) { thispoint = line.point_on_line(parity * breaksIter->first,axis); } else { thispoint = line.end(); } Line segment_b(lastpoint,thispoint); lines.push_back(segment_b); connectors.push_back(Connector(axialRef)); seg_b = lines.size() - 1; // lastpoint = thispoint; } // for (size_t j = 0; j < keylist.size(); j++) { // if (keylist[j] < (int)i) { // other line already segmented, look up in segment list, // and join segments together nicely auto segIter = segmentlist.find(OrderedIntPair(keylist[j],i)); if (segIter != segmentlist.end()) { // <- if it isn't -1 something has gone badly wrong! int seg_1 = segIter->second.first; int seg_2 = segIter->second.second; if (seg_a != -1) { if (seg_1 != -1) { Point2f alpha = lines[size_t(seg_a)].start() - lines[size_t(seg_a)].end(); Point2f beta = lines[size_t(seg_1)].start() - lines[size_t(seg_1)].end(); alpha.normalise(); beta.normalise(); float x = float(2.0 * acos(__min(__max(-dot(alpha,beta),-1.0),1.0)) / M_PI); depthmapX::addIfNotExists(connectors[size_t(seg_a)].m_forward_segconns, SegmentRef(-1,seg_1), x); depthmapX::addIfNotExists(connectors[size_t(seg_1)].m_forward_segconns, SegmentRef(-1,seg_a), x); } if (seg_2 != -1) { Point2f alpha = lines[size_t(seg_a)].start() - lines[size_t(seg_a)].end(); Point2f beta = lines[size_t(seg_2)].end() - lines[size_t(seg_2)].start(); alpha.normalise(); beta.normalise(); float x = float(2.0 * acos(__min(__max(-dot(alpha,beta),-1.0),1.0)) / M_PI); depthmapX::addIfNotExists(connectors[size_t(seg_a)].m_forward_segconns, SegmentRef(1,seg_2), x); depthmapX::addIfNotExists(connectors[size_t(seg_2)].m_back_segconns, SegmentRef(-1,seg_a), x); } } if (seg_b != -1) { if (seg_1 != -1) { Point2f alpha = lines[size_t(seg_b)].end() - lines[size_t(seg_b)].start(); Point2f beta = lines[size_t(seg_1)].start() - lines[size_t(seg_1)].end(); alpha.normalise(); beta.normalise(); float x = float(2.0 * acos(__min(__max(-dot(alpha,beta),-1.0),1.0)) / M_PI); depthmapX::addIfNotExists(connectors[size_t(seg_b)].m_back_segconns, SegmentRef(-1,seg_1), x); depthmapX::addIfNotExists(connectors[size_t(seg_1)].m_forward_segconns, SegmentRef(1,seg_b), x); } if (seg_2 != -1) { Point2f alpha = lines[size_t(seg_b)].end() - lines[size_t(seg_b)].start(); Point2f beta = lines[size_t(seg_2)].end() - lines[size_t(seg_2)].start(); alpha.normalise(); beta.normalise(); float x = float(2.0 * acos(__min(__max(-dot(alpha,beta),-1.0),1.0)) / M_PI); depthmapX::addIfNotExists(connectors[size_t(seg_b)].m_back_segconns, SegmentRef(1,seg_2), x); depthmapX::addIfNotExists(connectors[size_t(seg_2)].m_back_segconns, SegmentRef(1,seg_b), x); } } } } else { // other line still to be segmented, add ourselves to segment list // to be added later segmentlist.insert(std::make_pair( OrderedIntPair(i,keylist[j]), std::pair(seg_a,seg_b) )); } } if (seg_a != -1 && seg_b != -1) { depthmapX::addIfNotExists(connectors[size_t(seg_a)].m_forward_segconns, SegmentRef(1,seg_b), 0.0f); depthmapX::addIfNotExists(connectors[size_t(seg_b)].m_back_segconns, SegmentRef(-1,seg_a), 0.0f); } seg_a = seg_b; } } } void ShapeGraph::initialiseAttributesSegment() { m_attributes->clear(); // note, expects these in alphabetical order to preserve numbering: m_attributes->insertOrResetLockedColumn("Axial Line Ref"); m_attributes->insertOrResetLockedColumn("Segment Length"); } // now segments and connections are listed separately... // put them together in a new map void ShapeGraph::makeSegmentConnections(std::vector& connectionset) { m_connectors.clear(); // note, expects these in alphabetical order to preserve numbering: int w_conn_col = m_attributes->getOrInsertColumn("Angular Connectivity"); int uw_conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); int ref_col = m_attributes->getColumnIndex("Axial Line Ref"); int leng_col = m_attributes->getColumnIndex("Segment Length"); int i = -1; for (auto shape: m_shapes) { i++; Connector& connector = connectionset[size_t(i)]; AttributeRow& row = m_attributes->getRow(AttributeKey(shape.first)); row.setValue(ref_col, float(connector.m_segment_axialref)); row.setValue(leng_col, float(shape.second.getLine().length())); // all indices should match... (including lineset/connectionset versus m_shapes) m_connectors.push_back( connector ); float total_weight = 0.0f; for (auto iter = connector.m_forward_segconns.begin(); iter != connector.m_forward_segconns.end(); ++iter) { total_weight += iter->second; } for (auto iter = connector.m_back_segconns.begin(); iter != connector.m_back_segconns.end(); ++iter) { total_weight += iter->second; } row.setValue(w_conn_col, float(total_weight)); row.setValue(uw_conn_col, float(connector.m_forward_segconns.size() + connector.m_back_segconns.size())); // free up connectionset as we go along: connectionset[size_t(i)] = Connector(); } m_displayed_attribute = -2; // <- override if it's already showing setDisplayedAttribute(uw_conn_col); } // this pushes axial map values to a segment map // the segment map is 'this', the axial map is passed: void ShapeGraph::pushAxialValues(ShapeGraph& axialmap) { if (!m_attributes->hasColumn("Axial Line Ref")) { // this should never happen // AT: I am converting this to throw an error throw depthmapX::RuntimeException("Axial line ref does not exist"); } std::vector colindices; for (size_t i = 0; i < axialmap.m_attributes->getNumColumns(); i++) { std::string colname = std::string("Axial ") + axialmap.m_attributes->getColumnName(i); colindices.push_back(m_attributes->getOrInsertColumn(colname)); } for (auto iter = m_attributes->begin(); iter != m_attributes->end(); iter++) { int axialref = (int) iter->getRow().getValue("Axial Line Ref"); // P.K: The original code here got the index of the row, but the column // "Axial Line Ref" should actually contain keys, not indices AttributeRow& row = axialmap.m_attributes->getRow(AttributeKey(axialref)); for (size_t k = 0; k < axialmap.m_attributes->getNumColumns(); k++) { float val = row.getValue(k); // need to look up the column index: iter->getRow().setValue(colindices[k],val); } } } ================================================ FILE: salalib/axialmap.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/spacepixfile.h" #include "salalib/spacepix.h" #include "salalib/connector.h" struct AxialVertex; struct AxialVertexKey; struct RadialLine; struct PolyConnector; // used during angular analysis struct AnalysisInfo { // lists used for multiple radius analysis bool leaf; bool choicecovered; SegmentRef previous; int depth; double choice; double weighted_choice; double weighted_choice2; //EFEF AnalysisInfo() { choicecovered = false; leaf = true; previous = SegmentRef(); depth = 0; choice = 0.0; weighted_choice = 0.0; weighted_choice2 = 0.0; } void clearLine() { choicecovered = false; leaf = true; previous = SegmentRef(); depth = 0; // choice values are cummulative and not cleared } }; class MapInfoData; typedef std::vector> KeyVertices; class ShapeGraph : public ShapeMap { friend class AxialMinimiser; friend class MapInfoData; protected: KeyVertices m_keyvertices; // but still need to return keyvertices here int m_keyvertexcount; protected: public: bool outputMifPolygons(std::ostream& miffile, std::ostream& midfile) const; void outputNet(std::ostream& netfile) const; public: ShapeGraph(const std::string& name = "", int type = ShapeMap::AXIALMAP); virtual ~ShapeGraph() {;} void initialiseAttributesAxial(); void makeConnections(const KeyVertices &keyvertices = KeyVertices()); bool stepdepth(Communicator *comm = NULL); // lineset and connectionset are filled in by segment map void makeNewSegMap(Communicator *comm); void makeSegmentMap(std::vector &lines, std::vector &connectors, double stubremoval); void initialiseAttributesSegment(); void makeSegmentConnections(std::vector &connectionset); void pushAxialValues(ShapeGraph& axialmap); // virtual bool read(std::istream& stream); bool readold(std::istream& stream); virtual bool write(std::ofstream& stream); void writeAxialConnectionsAsDotGraph(std::ostream &stream); void writeAxialConnectionsAsPairsCSV(std::ostream &stream); void writeSegmentConnectionsAsPairsCSV(std::ostream &stream); void writeLinksUnlinksAsPairsCSV(std::ostream &stream, char delimiter = ','); void unlinkAtPoint(const Point2f& unlinkPoint); void unlinkFromShapeMap(const ShapeMap& shapemap); }; ================================================ FILE: salalib/axialminimiser.cpp ================================================ #include "salalib/axialminimiser.h" #include "salalib/tolerances.h" static int compareValueTriplet(const void *p1, const void *p2) { ValueTriplet *vp1 = (ValueTriplet *) p1; ValueTriplet *vp2 = (ValueTriplet *) p2; return (vp1->value1 > vp2->value1 ? 1 : vp1->value1 < vp2->value1 ? -1 : (vp1->value2 > vp2->value2 ? 1 : vp1->value2 < vp2->value2 ? -1 : 0)); } AxialMinimiser::AxialMinimiser(const AllLineMap& alllinemap, int no_of_axsegcuts, int no_of_radialsegs) { m_alllinemap = (AllLineMap *) &alllinemap; m_vps = new ValueTriplet[no_of_axsegcuts]; m_removed = new bool [no_of_axsegcuts]; m_affected = new bool [no_of_axsegcuts]; m_vital = new bool [no_of_axsegcuts]; m_radialsegcounts = new int [no_of_radialsegs]; } AxialMinimiser::~AxialMinimiser() { delete [] m_vital; delete [] m_affected; delete [] m_radialsegcounts; delete [] m_vps; delete [] m_removed; } // Alan and Bill's algo... void AxialMinimiser::removeSubsets(std::map >& axsegcuts, std::map& radialsegs, std::map > &rlds, std::vector &radial_lines, std::vector >& keyvertexconns, std::vector& keyvertexcounts) { bool removedflag = true; m_axialconns = m_alllinemap->m_connectors; for (size_t x = 0; x < radialsegs.size(); x++) { m_radialsegcounts[x] = 0; } int y = -1; for (auto axSegCut: axsegcuts) { y++; for (int cut: axSegCut.second) { m_radialsegcounts[cut] += 1; } m_removed[y] = false; m_vital[y] = false; m_affected[y] = true; m_vps[y].index = y; double length = m_axialconns[y].m_connections.size(); m_vps[y].value1 = (int) length; length = depthmapX::getMapAtIndex(m_alllinemap->m_shapes, y)->second.getLine().length(); m_vps[y].value2 = (float) length; } // sort according to number of connections then length qsort(m_vps,m_axialconns.size(),sizeof(ValueTriplet),compareValueTriplet); while (removedflag) { removedflag = false; for (size_t i = 0; i < m_axialconns.size(); i++) { int ii = m_vps[i].index; if (m_removed[ii] || !m_affected[ii] || m_vital[ii]) { continue; } // vital connections code (uses original unaltered connections) { bool vitalconn = false; for (size_t j = 0; j < keyvertexconns[ii].size(); j++) { // first check to see if removing this line will cause elimination of a vital connection if (keyvertexcounts[keyvertexconns[ii][j]] <= 1) { // connect vital... just go on to the next one: vitalconn = true; break; } } if (vitalconn) { m_vital[ii] = true; continue; } } // Connector& axa = m_axialconns[ii]; m_affected[ii] = false; bool subset = false; for (size_t j = 0; j < axa.m_connections.size(); j++) { int indextob = axa.m_connections[j]; if (indextob == ii || m_removed[indextob]) { // <- removed[indextob] should never happen as it should have been removed below continue; } Connector& axb = m_axialconns[indextob]; if (axa.m_connections.size() <= axb.m_connections.size()) { // change to 10.08, coconnecting is 1 -> connection to other line is implicitly handled int coconnecting = 1; // first check it's a connection subset // note that changes in 10.08 mean that lines no longer connect to themselves // this means that the subset 1 connects {2,3} and 2 connects {1,3} are equivalent for (size_t axai = 0, axbi = 0; axai < axa.m_connections.size() && axbi < axb.m_connections.size(); axai++, axbi++) { // extra 10.08 -> step over connection to b if (axa.m_connections[axai] == indextob) { axai++; } // extra 10.08 add axb.m_connections[axbi] == ii -> step over connection to a while (axbi < axb.m_connections.size() && (axb.m_connections[axbi] == ii || axa.m_connections[axai] > axb.m_connections[axbi])) { axbi++; } if (axbi >= axb.m_connections.size()) { break; } else if (axa.m_connections[axai] == axb.m_connections[axbi]) { coconnecting++; } else if (axa.m_connections[axai] < axb.m_connections[axbi]) { break; } } if (coconnecting >= (int)axa.m_connections.size()) { subset = true; break; } } } if (subset) { size_t removeindex = ii; // now check removing it won't break any topological loops bool presumedvital = false; auto& axSegCut = depthmapX::getMapAtIndex(axsegcuts, removeindex)->second; for (int cut: axSegCut) { if (m_radialsegcounts[cut] <= 1) { presumedvital = true; break; } } if (presumedvital) { presumedvital = checkVital(removeindex,axSegCut,radialsegs,rlds,radial_lines); } if (presumedvital) { m_vital[removeindex] = true; } // if not, remove it... if (!m_vital[removeindex]) { m_removed[removeindex] = true; auto& affectedconnections = m_axialconns[removeindex].m_connections; for (auto affectedconnection: affectedconnections) { if (!m_removed[affectedconnection]) { auto& connections = m_axialconns[affectedconnection].m_connections; depthmapX::findAndErase(connections, int(removeindex)); m_affected[affectedconnection] = true; } } removedflag = true; for (int cut: axSegCut) { m_radialsegcounts[cut] -= 1; } // vital connections for (size_t k = 0; k < keyvertexconns[removeindex].size(); k++) { keyvertexcounts[keyvertexconns[removeindex][k]] -= 1; } } } } } } /////////////////////////////////////////////////////////////////////////////////////////// // My algo... v. simple... fewest longest void AxialMinimiser::fewestLongest(std::map > &axsegcuts, std::map& radialsegs, std::map > &rlds, std::vector &radial_lines, std::vector > &keyvertexconns, std::vector& keyvertexcounts) { //m_axialconns = m_alllinemap->m_connectors; int livecount = 0; for (size_t y = 0; y < m_axialconns.size(); y++) { if (!m_removed[y] && !m_vital[y]) { m_vps[livecount].index = (int) y; m_vps[livecount].value1 = (int) m_axialconns[y].m_connections.size(); m_vps[livecount].value2 = (float) depthmapX::getMapAtIndex(m_alllinemap->m_shapes, y)->second.getLine().length(); livecount++; } } qsort(m_vps,livecount,sizeof(ValueTriplet),compareValueTriplet); for (int i = 0; i < livecount; i++) { int j = m_vps[i].index; // vital connections code (uses original unaltered connections) bool vitalconn = false; size_t k; for (k = 0; k < keyvertexconns[j].size(); k++) { // first check to see if removing this line will cause elimination of a vital connection if (keyvertexcounts[keyvertexconns[j][k]] <= 1) { // connect vital... just go on to the next one: vitalconn = true; break; } } if (vitalconn) { continue; } // bool presumedvital = false; auto &axSegCut = depthmapX::getMapAtIndex(axsegcuts, j)->second; for (int cut: axSegCut) { if (m_radialsegcounts[cut] <= 1) { presumedvital = true; break; } } if (presumedvital) { presumedvital = checkVital(j,axSegCut,radialsegs,rlds,radial_lines); } if (!presumedvital) { // don't let anything this is connected to go down to zero connections auto& affectedconnections = m_axialconns[j].m_connections; for (auto affectedconnection: affectedconnections) { if (!m_removed[affectedconnection]) { auto& connections = m_axialconns[size_t(affectedconnection)].m_connections; if (connections.size() <= 2) { // <- note number of connections includes itself... so you and one other presumedvital = true; break; } } } } if (!presumedvital) { m_removed[j] = true; auto& affectedconnections = m_axialconns[size_t(j)].m_connections; for (auto affectedconnection: affectedconnections) { if (!m_removed[affectedconnection]) { auto& connections = m_axialconns[size_t(affectedconnection)].m_connections; depthmapX::findAndErase(connections, int(j)); m_affected[affectedconnection] = true; } } for (auto cut: axSegCut) { m_radialsegcounts[cut] -= 1; } // vital connections for (size_t k = 0; k < keyvertexconns[j].size(); k++) { keyvertexcounts[keyvertexconns[j][k]] -= 1; } } } } /////////////////////////////////////////////////////////////////////////////////////////// bool AxialMinimiser::checkVital(int checkindex, std::set &axSegCut, std::map& radialsegs, std::map > &rlds, std::vector& radial_lines) { std::map& axiallines = m_alllinemap->m_shapes; bool presumedvital = true; int nonvitalcount = 0, vitalsegs = 0; // again, this time more rigourously... check any connected pairs don't cover the link... for (int cut: axSegCut) { if (m_radialsegcounts[cut] <= 1) { bool nonvitalseg = false; vitalsegs++; auto radialSegIter = depthmapX::getMapAtIndex(radialsegs, cut); const RadialKey& key = radialSegIter->first; RadialSegment& seg = radialSegIter->second; std::set& divisorsa = rlds.find(key)->second; std::set& divisorsb = rlds.find(seg.radial_b)->second; auto iterKey = std::find(radial_lines.begin(), radial_lines.end(), key); if(iterKey == radial_lines.end()) { throw depthmapX::RuntimeException("Radial key not found in radial lines"); } const RadialLine& rlinea = *iterKey; auto iterSegB = std::find(radial_lines.begin(), radial_lines.end(), seg.radial_b); if(iterSegB == radial_lines.end()) { throw depthmapX::RuntimeException("Radial key not found in radial lines"); } const RadialLine& rlineb = *iterSegB; for (int diva: divisorsa) { if (diva == checkindex || m_removed[diva]) { continue; } for (int divb: divisorsb) { if (divb == checkindex || m_removed[divb]) { continue; } auto& connections = m_axialconns[size_t(diva)].m_connections; if (std::find(connections.begin(), connections.end(), divb) != connections.end()) { // as a further challenge, they must link within in the zone of interest, not on the far side of it... arg! Point2f p = intersection_point(axiallines[diva].getLine(),axiallines[divb].getLine(),TOLERANCE_A); if (p.insegment(rlinea.keyvertex,rlinea.openspace,rlineb.openspace,TOLERANCE_A)) { nonvitalseg = true; } } } } if (nonvitalseg) { nonvitalcount++; } } } if (nonvitalcount == vitalsegs) { presumedvital = false; } return presumedvital; } ================================================ FILE: salalib/axialminimiser.h ================================================ #pragma once #include "salalib/alllinemap.h" struct ValueTriplet { int value1; float value2; int index; }; class AxialMinimiser { protected: AllLineMap *m_alllinemap; // ValueTriplet *m_vps; bool *m_removed; bool *m_affected; bool *m_vital; int *m_radialsegcounts; int *m_keyvertexcounts; std::vector m_axialconns; // <- uses a copy of axial lines as it will remove connections public: AxialMinimiser(const AllLineMap& alllinemap, int no_of_axsegcuts, int no_of_radialsegs); ~AxialMinimiser(); void removeSubsets(std::map > &axsegcuts, std::map& radialsegs, std::map >& rlds, std::vector &radial_lines, std::vector > &keyvertexconns, std::vector& keyvertexcounts); void fewestLongest(std::map >& axsegcuts, std::map& radialsegs, std::map > &rlds, std::vector& radial_lines, std::vector >& keyvertexconns, std::vector& keyvertexcounts); // advanced topological testing: bool checkVital(int checkindex, std::set &axSegCut, std::map& radialsegs, std::map > &rlds, std::vector &radial_lines); // bool removed(int i) const { return m_removed[i]; } }; ================================================ FILE: salalib/axialmodules/CMakeLists.txt ================================================ target_sources(salalib PRIVATE axialintegration.cpp axialstepdepth.cpp PUBLIC axialintegration.h axialstepdepth.h) ================================================ FILE: salalib/axialmodules/axialintegration.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/axialmodules/axialintegration.h" #include "genlib/pflipper.h" #include "genlib/stringutils.h" bool AxialIntegration::run(Communicator *comm, ShapeGraph &map, bool simple_version) { // note, from 10.0, Depthmap no longer includes *self* connections on axial lines // self connections are stripped out on loading graph files, as well as no longer made time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getShapeCount()); } AttributeTable &attributes = map.getAttributeTable(); // note: radius must be sorted lowest to highest, but if -1 occurs ("radius n") it needs to be last... // ...to ensure no mess ups, we'll re-sort here: bool radius_n = false; std::vector radii; for (double radius : m_radius_set) { if (radius < 0) { radius_n = true; } else { radii.push_back(static_cast(radius)); } } if (radius_n) { radii.push_back(-1); } // retrieve weighted col data, as this may well be overwritten in the new analysis: std::vector weights; std::string weighting_col_text; if (m_weighted_measure_col != -1) { weighting_col_text = attributes.getColumnName(m_weighted_measure_col); for (size_t i = 0; i < map.getShapeCount(); i++) { weights.push_back(map.getAttributeRowFromShapeIndex(i).getValue(m_weighted_measure_col)); } } // first enter the required attribute columns: for (int radius : radii) { std::string radius_text; if (radius != -1) { radius_text = dXstring::formatString(radius, " R%d"); } if (m_choice) { std::string choice_col_text = std::string("Choice") + radius_text; attributes.insertOrResetColumn(choice_col_text.c_str()); std::string n_choice_col_text = std::string("Choice [Norm]") + radius_text; attributes.insertOrResetColumn(n_choice_col_text.c_str()); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = std::string("Choice [") + weighting_col_text + " Wgt]" + radius_text; attributes.insertOrResetColumn(w_choice_col_text.c_str()); std::string nw_choice_col_text = std::string("Choice [") + weighting_col_text + " Wgt][Norm]" + radius_text; attributes.insertOrResetColumn(nw_choice_col_text.c_str()); } } if (!simple_version) { std::string entropy_col_text = std::string("Entropy") + radius_text; attributes.insertOrResetColumn(entropy_col_text.c_str()); } std::string integ_dv_col_text = std::string("Integration [HH]") + radius_text; attributes.insertOrResetColumn(integ_dv_col_text.c_str()); if (!simple_version) { std::string integ_pv_col_text = std::string("Integration [P-value]") + radius_text; attributes.insertOrResetColumn(integ_pv_col_text.c_str()); std::string integ_tk_col_text = std::string("Integration [Tekl]") + radius_text; attributes.insertOrResetColumn(integ_tk_col_text.c_str()); std::string intensity_col_text = std::string("Intensity") + radius_text; attributes.insertOrResetColumn(intensity_col_text.c_str()); std::string harmonic_col_text = std::string("Harmonic Mean Depth") + radius_text; attributes.insertOrResetColumn(harmonic_col_text.c_str()); } std::string depth_col_text = std::string("Mean Depth") + radius_text; attributes.insertOrResetColumn(depth_col_text.c_str()); std::string count_col_text = std::string("Node Count") + radius_text; attributes.insertOrResetColumn(count_col_text.c_str()); if (!simple_version) { std::string rel_entropy_col_text = std::string("Relativised Entropy") + radius_text; attributes.insertOrResetColumn(rel_entropy_col_text); } if (m_weighted_measure_col != -1) { std::string w_md_col_text = std::string("Mean Depth [") + weighting_col_text + " Wgt]" + radius_text; attributes.insertOrResetColumn(w_md_col_text.c_str()); std::string total_weight_text = std::string("Total ") + weighting_col_text + radius_text; attributes.insertOrResetColumn(total_weight_text.c_str()); } if (m_fulloutput) { if (!simple_version) { std::string penn_norm_text = std::string("RA [Penn]") + radius_text; attributes.insertOrResetColumn(penn_norm_text); } std::string ra_col_text = std::string("RA") + radius_text; attributes.insertOrResetColumn(ra_col_text.c_str()); if (!simple_version) { std::string rra_col_text = std::string("RRA") + radius_text; attributes.insertOrResetColumn(rra_col_text.c_str()); } std::string td_col_text = std::string("Total Depth") + radius_text; attributes.insertOrResetColumn(td_col_text.c_str()); } // } if (m_local) { if (!simple_version) { attributes.insertOrResetColumn("Control"); attributes.insertOrResetColumn("Controllability"); } } // then look up all the columns... eek: std::vector choice_col, n_choice_col, w_choice_col, nw_choice_col, entropy_col, integ_dv_col, integ_pv_col, integ_tk_col, intensity_col, depth_col, count_col, rel_entropy_col, penn_norm_col, w_depth_col, total_weight_col, ra_col, rra_col, td_col, harmonic_col; for (int radius : radii) { std::string radius_text; if (radius != -1) { radius_text = std::string(" R") + dXstring::formatString(int(radius), "%d"); } if (m_choice) { std::string choice_col_text = std::string("Choice") + radius_text; choice_col.push_back(attributes.getColumnIndex(choice_col_text.c_str())); std::string n_choice_col_text = std::string("Choice [Norm]") + radius_text; n_choice_col.push_back(attributes.getColumnIndex(n_choice_col_text.c_str())); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = std::string("Choice [") + weighting_col_text + " Wgt]" + radius_text; w_choice_col.push_back(attributes.getColumnIndex(w_choice_col_text.c_str())); std::string nw_choice_col_text = std::string("Choice [") + weighting_col_text + " Wgt][Norm]" + radius_text; nw_choice_col.push_back(attributes.getColumnIndex(nw_choice_col_text.c_str())); } } if (!simple_version) { std::string entropy_col_text = std::string("Entropy") + radius_text; entropy_col.push_back(attributes.getColumnIndex(entropy_col_text.c_str())); } std::string integ_dv_col_text = std::string("Integration [HH]") + radius_text; integ_dv_col.push_back(attributes.getColumnIndex(integ_dv_col_text.c_str())); if (!simple_version) { std::string integ_pv_col_text = std::string("Integration [P-value]") + radius_text; integ_pv_col.push_back(attributes.getColumnIndex(integ_pv_col_text.c_str())); std::string integ_tk_col_text = std::string("Integration [Tekl]") + radius_text; integ_tk_col.push_back(attributes.getColumnIndex(integ_tk_col_text.c_str())); std::string intensity_col_text = std::string("Intensity") + radius_text; intensity_col.push_back(attributes.getColumnIndex(intensity_col_text.c_str())); std::string harmonic_col_text = std::string("Harmonic Mean Depth") + radius_text; harmonic_col.push_back(attributes.getColumnIndex(harmonic_col_text.c_str())); } std::string depth_col_text = std::string("Mean Depth") + radius_text; depth_col.push_back(attributes.getColumnIndex(depth_col_text.c_str())); std::string count_col_text = std::string("Node Count") + radius_text; count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); if (!simple_version) { std::string rel_entropy_col_text = std::string("Relativised Entropy") + radius_text; rel_entropy_col.push_back(attributes.getColumnIndex(rel_entropy_col_text.c_str())); } if (m_weighted_measure_col != -1) { std::string w_md_col_text = std::string("Mean Depth [") + weighting_col_text + " Wgt]" + radius_text; w_depth_col.push_back(attributes.getColumnIndex(w_md_col_text.c_str())); std::string total_weight_col_text = std::string("Total ") + weighting_col_text + radius_text; total_weight_col.push_back(attributes.getColumnIndex(total_weight_col_text.c_str())); } if (m_fulloutput) { std::string ra_col_text = std::string("RA") + radius_text; ra_col.push_back(attributes.getColumnIndex(ra_col_text.c_str())); if (!simple_version) { std::string penn_norm_text = std::string("RA [Penn]") + radius_text; penn_norm_col.push_back(attributes.getColumnIndex(penn_norm_text)); std::string rra_col_text = std::string("RRA") + radius_text; rra_col.push_back(attributes.getColumnIndex(rra_col_text.c_str())); } std::string td_col_text = std::string("Total Depth") + radius_text; td_col.push_back(attributes.getColumnIndex(td_col_text.c_str())); } } int control_col = -1, controllability_col = -1; if (m_local) { if (!simple_version) { control_col = attributes.getColumnIndex("Control"); controllability_col = attributes.getColumnIndex("Controllability"); } } // for choice AnalysisInfo **audittrail; if (m_choice) { audittrail = new AnalysisInfo *[map.getShapeCount()]; for (size_t i = 0; i < map.getShapeCount(); i++) { audittrail[i] = new AnalysisInfo[radii.size()]; } } // n.b., for this operation we assume continuous line referencing from zero (this is silly?) // has already failed due to this! when intro hand drawn fewest line (where user may have deleted) // it's going to get worse... bool *covered = new bool[map.getShapeCount()]; size_t i = -1; for (auto & iter : attributes) { i++; AttributeRow &row = iter.getRow(); for (size_t j = 0; j < map.getShapeCount(); j++) { covered[j] = false; } if (m_choice) { for (size_t k = 0; k < map.getShapeCount(); k++) { audittrail[k][0].previous.ref = -1; // note, 0th member used as radius doesn't matter // note, choice columns are not cleared, but cummulative over all shortest path pairs } } if (m_local) { double control = 0.0; const std::vector &connections = map.getConnections()[i].m_connections; std::vector totalneighbourhood; for (int connection : connections) { // n.b., as of Depthmap 10.0, connections[j] and i cannot coexist // if (connections[j] != i) { depthmapX::addIfNotExists(totalneighbourhood, connection); int retro_size = 0; auto &retconnectors = map.getConnections()[size_t(connection)].m_connections; for (auto retconnector : retconnectors) { retro_size++; depthmapX::addIfNotExists(totalneighbourhood, retconnector); } control += 1.0 / double(retro_size); //} } if (!simple_version) { if (connections.size() > 0) { row.setValue(control_col, float(control)); row.setValue(controllability_col, float(double(connections.size()) / double(totalneighbourhood.size() - 1))); } else { row.setValue(control_col, -1); row.setValue(controllability_col, -1); } } } std::vector depthcounts; depthcounts.push_back(0); pflipper>> foundlist; foundlist.a().push_back(std::pair(i, -1)); covered[i] = true; int total_depth = 0, depth = 1, node_count = 1, pos = -1, previous = -1; // node_count includes this 1 double weight = 0.0, rootweight = 0.0, total_weight = 0.0, w_total_depth = 0.0; if (m_weighted_measure_col != -1) { rootweight = weights[i]; // include this line in total weights (as per nodecount) total_weight += rootweight; } int index = -1; int r = 0; for (int radius : radii) { while (foundlist.a().size()) { if (!m_choice) { index = foundlist.a().back().first; } else { pos = pafrand() % foundlist.a().size(); index = foundlist.a().at(pos).first; previous = foundlist.a().at(pos).second; audittrail[index][0].previous.ref = previous; // note 0th member used here: can be used individually different radius previous } Connector &line = map.getConnections()[index]; for (size_t k = 0; k < line.m_connections.size(); k++) { if (!covered[line.m_connections[k]]) { covered[line.m_connections[k]] = true; foundlist.b().push_back(std::pair(line.m_connections[k], index)); if (m_weighted_measure_col != -1) { // the weight is taken from the discovered node: weight = weights[line.m_connections[k]]; total_weight += weight; w_total_depth += depth * weight; } if (m_choice && previous != -1) { // both directional paths are now recorded for choice // (coincidentally fixes choice problem which was completely wrong) size_t here = index; // note: start counting from index as actually looking ahead here while (here != i) { // not i means not the current root for the path audittrail[here][r].choice += 1; audittrail[here][r].weighted_choice += weight * rootweight; here = audittrail[here][0].previous.ref; // <- note, just using 0th position: radius for // the previous doesn't matter in this analysis } if (m_weighted_measure_col != -1) { // in weighted choice, root node and current node receive values: audittrail[i][r].weighted_choice += (weight * rootweight) * 0.5; audittrail[line.m_connections[k]][r].weighted_choice += (weight * rootweight) * 0.5; } } total_depth += depth; node_count++; depthcounts.back() += 1; } } if (!m_choice) foundlist.a().pop_back(); else foundlist.a().erase(foundlist.a().begin() + pos); if (!foundlist.a().size()) { foundlist.flip(); depth++; depthcounts.push_back(0); if (radius != -1 && depth > radius) { break; } } } // set the attributes for this node: row.setValue(count_col[r], float(node_count)); if (m_weighted_measure_col != -1) { row.setValue(total_weight_col[r], float(total_weight)); } // node count > 1 to avoid divide by zero (was > 2) if (node_count > 1) { // note -- node_count includes this one -- mean depth as per p.108 Social Logic of Space double mean_depth = double(total_depth) / double(node_count - 1); row.setValue(depth_col[r], float(mean_depth)); if (m_weighted_measure_col != -1) { // weighted mean depth: row.setValue(w_depth_col[r], float(w_total_depth / total_weight)); } // total nodes > 2 to avoid divide by 0 (was > 3) if (node_count > 2 && mean_depth > 1.0) { double ra = 2.0 * (mean_depth - 1.0) / double(node_count - 2); // d-value / p-value from Depthmap 4 manual, note: node_count includes this one double rra_d = ra / dvalue(node_count); double rra_p = ra / dvalue(node_count); double integ_tk = teklinteg(node_count, total_depth); row.setValue(integ_dv_col[r], float(1.0 / rra_d)); if (!simple_version) { row.setValue(integ_pv_col[r], float(1.0 / rra_p)); if (total_depth - node_count + 1 > 1) { row.setValue(integ_tk_col[r], float(integ_tk)); } else { row.setValue(integ_tk_col[r], -1.0f); } } if (m_fulloutput) { row.setValue(ra_col[r], float(ra)); if (!simple_version) { row.setValue(rra_col[r], float(rra_d)); } row.setValue(td_col[r], float(total_depth)); if (!simple_version) { // alan's palm-tree normalisation: palmtree double dmin = node_count - 1; double dmax = palmtree(node_count, depth - 1); if (dmax != dmin) { row.setValue(penn_norm_col[r], float((dmax - total_depth) / (dmax - dmin))); } } } } else { row.setValue(integ_dv_col[r], -1.0f); if (!simple_version) { row.setValue(integ_pv_col[r], -1.0f); row.setValue(integ_tk_col[r], -1.0f); } if (m_fulloutput) { row.setValue(ra_col[r], -1.0f); if (!simple_version) { row.setValue(rra_col[r], -1.0f); } row.setValue(td_col[r], -1.0f); if (!simple_version) { row.setValue(penn_norm_col[r], -1.0f); } } } if (!simple_version) { double entropy = 0.0, intensity = 0.0, rel_entropy = 0.0, factorial = 1.0, harmonic = 0.0; for (size_t k = 0; k < depthcounts.size(); k++) { if (depthcounts[k] != 0) { // some debate over whether or not this should be node count - 1 // (i.e., including or not including the node itself) double prob = double(depthcounts[k]) / double(node_count); entropy -= prob * log2(prob); // Formula from Turner 2001, "Depthmap" factorial *= double(k + 1); double q = (pow(mean_depth, double(k)) / double(factorial)) * exp(-mean_depth); rel_entropy += (double)prob * log2(prob / q); // harmonic += 1.0 / double(depthcounts[k]); } } harmonic = double(depthcounts.size()) / harmonic; if (total_depth > node_count) { intensity = node_count * entropy / (total_depth - node_count); } else { intensity = -1; } row.setValue(entropy_col[r], float(entropy)); row.setValue(rel_entropy_col[r], float(rel_entropy)); row.setValue(intensity_col[r], float(intensity)); row.setValue(harmonic_col[r], float(harmonic)); } } else { row.setValue(depth_col[r], -1.0f); row.setValue(integ_dv_col[r], -1.0f); if (!simple_version) { row.setValue(integ_pv_col[r], -1.0f); row.setValue(integ_tk_col[r], -1.0f); row.setValue(entropy_col[r], -1.0f); row.setValue(rel_entropy_col[r], -1.0f); row.setValue(harmonic_col[r], -1.0f); } } ++r; } // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { delete[] covered; throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, i); } } } delete[] covered; if (m_choice) { i = -1; for (auto & iter: attributes) { i++; AttributeRow &row = iter.getRow(); double total_choice = 0.0, w_total_choice = 0.0; for (size_t r = 0; r < radii.size(); r++) { total_choice += audittrail[i][r].choice; w_total_choice += audittrail[i][r].weighted_choice; // n.b., normalise choice according to (n-1)(n-2)/2 (maximum possible through routes) double node_count = row.getValue(count_col[r]); double total_weight = 0; if (m_weighted_measure_col != -1) { total_weight = row.getValue(total_weight_col[r]); } if (node_count > 2) { row.setValue(choice_col[r], float(total_choice)); row.setValue(n_choice_col[r], float(2.0 * total_choice / ((node_count - 1) * (node_count - 2)))); if (m_weighted_measure_col != -1) { row.setValue(w_choice_col[r], float(w_total_choice)); row.setValue(nw_choice_col[r], float(2.0 * w_total_choice / (total_weight * total_weight))); } } else { row.setValue(choice_col[r], -1); row.setValue(n_choice_col[r], -1); if (m_weighted_measure_col != -1) { row.setValue(w_choice_col[r], -1); row.setValue(nw_choice_col[r], -1); } } } } for (size_t i = 0; i < map.getShapeCount(); i++) { delete[] audittrail[i]; } delete[] audittrail; } map.setDisplayedAttribute(-1); // <- override if it's already showing map.setDisplayedAttribute(integ_dv_col.back()); return true; } ================================================ FILE: salalib/axialmodules/axialintegration.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/iaxial.h" class AxialIntegration : IAxial { private: std::set m_radius_set; int m_weighted_measure_col; bool m_choice; bool m_fulloutput; bool m_local; public: std::string getAnalysisName() const override { return "Angular Analysis"; } bool run(Communicator *, ShapeGraph &map, bool) override; AxialIntegration(std::set radius_set, int weighted_measure_col, bool choice, bool fulloutput, bool local) : m_radius_set(radius_set), m_weighted_measure_col(weighted_measure_col), m_choice(choice), m_fulloutput(fulloutput), m_local(local) {} }; ================================================ FILE: salalib/axialmodules/axialstepdepth.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/axialmodules/axialstepdepth.h" #include "genlib/pflipper.h" #include "genlib/stringutils.h" bool AxialStepDepth::run(Communicator *, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); std::string stepdepth_col_text = std::string("Step Depth"); int stepdepth_col = attributes.insertOrResetColumn(stepdepth_col_text.c_str()); bool *covered = new bool [map.getConnections().size()]; for (size_t i = 0; i < map.getConnections().size(); i++) { covered[i] = false; } pflipper > foundlist; for(auto& lineindex: map.getSelSet()) { foundlist.a().push_back(lineindex); covered[lineindex] = true; map.getAttributeRowFromShapeIndex(lineindex).setValue(stepdepth_col,0.0f); } int depth = 1; while (foundlist.a().size()) { Connector& line = map.getConnections()[foundlist.a().back()]; for (size_t k = 0; k < line.m_connections.size(); k++) { if (!covered[line.m_connections[k]]) { covered[line.m_connections[k]] = true; foundlist.b().push_back(line.m_connections[k]); map.getAttributeRowFromShapeIndex(line.m_connections[k]).setValue(stepdepth_col,float(depth)); } } foundlist.a().pop_back(); if (!foundlist.a().size()) { foundlist.flip(); depth++; } } delete [] covered; map.setDisplayedAttribute(-1); // <- override if it's already showing map.setDisplayedAttribute(stepdepth_col); return true; } ================================================ FILE: salalib/axialmodules/axialstepdepth.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/iaxial.h" class AxialStepDepth : IAxial { public: std::string getAnalysisName() const override { return "Angular Analysis"; } bool run(Communicator *comm, ShapeGraph &map, bool simple_version) override; }; ================================================ FILE: salalib/axialpolygons.cpp ================================================ #include "salalib/axialpolygons.h" #include "salalib/tidylines.h" #include "salalib/tolerances.h" #include "genlib/containerutils.h" AxialVertex AxialPolygons::makeVertex(const AxialVertexKey& vertexkey, const Point2f& openspace) { auto vertPossIter = depthmapX::getMapAtIndex(m_vertex_possibles, vertexkey.m_ref_key); AxialVertex av(vertexkey, vertPossIter->first, openspace); // n.b., at this point, vertex key m_a and m_b are unfixed std::vector& pointlist = vertPossIter->second; if (pointlist.size() < 2) { return av; } Point2f o = av.m_point - av.m_openspace; // using an anglemap means that there are now no anti-clockwise vertices... // TODO: (CS) Double as key is problematic - books have been written about double equality... std::map anglemap; for (size_t i = 0; i < pointlist.size(); ++i) { anglemap.insert(std::make_pair( angle(openspace,av.m_point, pointlist[i]), i )); } av.m_ref_a = anglemap.begin()->second; // TODO: is this supposed to be av.m_ref_b? av.m_ref_a = anglemap.rbegin()->second; Point2f a = av.m_point - pointlist[size_t(anglemap.begin()->second)]; Point2f b = pointlist[size_t(anglemap.rbegin()->second)] - av.m_point; av.m_a = a; av.m_b = b; a.normalise(); b.normalise(); double oa = det(o,a); double ob = det(o,b); double ab = det(a,b); // can't handle these cases if (fabs(oa) < TOLERANCE_A || fabs(ob) < TOLERANCE_A || fabs(ab) < TOLERANCE_A) { // although note that if ab == 0 and you've already checked intersection, it can't be convex return av; } // ADDED 4-Nov-04 -- In order to stop too many lines being generated, don't include // points that do not change surface direction: -- notice: will create problems with circles if (fabs(dot(a,b)) > 0.999) { return av; } if (sgn(oa) == sgn(ob)) { // headon collision if (sgn(oa) == 1) { if (sgn(ab) == 1) { // convex clockwise av.m_convex = true; av.m_clockwise = true; av.m_axial = true; } else { // n.b., these are turned away for axial formation // concave clockwise av.m_convex = false; av.m_clockwise = true; av.m_axial = false; } } } else { // glancing blow // concave clockwise av.m_convex = false; av.m_clockwise = true; av.m_axial = true; } av.m_initialised = true; return av; } /////////////////////////////////////////////////////////////////////////////////////////////// void AxialPolygons::clear() { // clear any existing data m_vertex_possibles.clear(); m_vertex_polys.clear(); m_handled_list.clear(); m_pixel_polys.reset(0,0); } void AxialPolygons::init(std::vector& lines, const QtRegion& region) { // init pixelbase members m_region = region; // now tidy TidyLines tidier; tidier.tidy(lines, m_region); // for easier debugging, the axial code is reused to make segments ShapeGraph firstpass; firstpass.init(lines.size(),m_region); // used to be double density firstpass.initialiseAttributesAxial(); size_t i; for (i = 0; i < lines.size(); i++) { firstpass.makeLineShape(lines[i]); } firstpass.makeConnections(); lines.clear(); std::vector connectionset; // interesting... 1.0 may or may not work as intended firstpass.makeSegmentMap(lines, connectionset, 1.0); // now we have a set of lines and a set of connections... // ...for the second pass, a bit of retro fitting to my original code is // required makeVertexPossibles(lines, connectionset); initLines(lines.size(), m_region.bottom_left, m_region.top_right, 2); // need to init before making pixel polys... makePixelPolys(); // now also add lines for (auto& vertexPoss: m_vertex_possibles) { for (auto poss: vertexPoss.second) { addLine(Line(vertexPoss.first,poss)); } } sortPixelLines(); } void AxialPolygons::makeVertexPossibles(const std::vector& lines, const std::vector& connectionset) { m_vertex_possibles.clear(); m_vertex_polys.clear(); size_t i = 0; // TODO: (CS) these should be vectors, not raw pointers. depthmapX::RowMatrix found(2, lines.size()); for (i = 0; i < lines.size(); i++) { found(0, i) = -1; found(1, i) = -1; } std::vector pointlookup; // three pass operation: (1) stack the lines for (i = 0; i < lines.size(); i++) { if (found(0, i) == -1) { pointlookup.push_back(lines[i].start()); m_vertex_possibles.insert(std::make_pair(pointlookup.back(),std::vector())); m_vertex_polys.push_back(-1); // <- n.b., dummy entry for now, maintain with vertex possibles found(0, i) = static_cast(pointlookup.size() - 1); for (auto& segconn: connectionset[i].m_back_segconns) { int forwback = (segconn.first.dir == 1) ? 0 : 1; found(static_cast(forwback), static_cast(segconn.first.ref)) = found(0, i); } } if (found(1, i) == -1) { pointlookup.push_back(lines[i].end()); m_vertex_possibles.insert(std::make_pair(pointlookup.back(),std::vector())); m_vertex_polys.push_back(-1); // <- n.b., dummy entry for now, maintain with vertex possibles found(1, i) = static_cast(pointlookup.size() - 1); for (auto& segconn: connectionset[i].m_forward_segconns) { int forwback = (segconn.first.dir == 1) ? 0 : 1; found(static_cast(forwback), static_cast(segconn.first.ref)) = found(1, i); } } } // three pass operation: (2) connect up vertex possibles for (i = 0; i < lines.size(); i++) { if (found(0, i) == -1 || found(1, i) == -1) { // TODO: (CS) What are these integers being thrown?! throw 1; } auto index0 = m_vertex_possibles.find(pointlookup[size_t(found(0, i))]); auto index1 = m_vertex_possibles.find(pointlookup[size_t(found(1, i))]); if (index0 == m_vertex_possibles.end() || index1 == m_vertex_possibles.end()) { // TODO: (CS) What are these integers being thrown?! throw 2; } index0->second.push_back(pointlookup[size_t(found(1, i))]); index1->second.push_back(pointlookup[size_t(found(0, i))]); } for(auto& possible: m_vertex_possibles) { sort( possible.second.begin(), possible.second.end() ); possible.second.erase( unique( possible.second.begin(), possible.second.end() ), possible.second.end() ); } // three pass operation: (3) create vertex poly entries int current_poly = -1; for (i = 0; i < m_vertex_possibles.size(); i++) { if (m_vertex_polys[i] == -1) { current_poly++; std::vector addlist; addlist.push_back(int(i)); while (addlist.size()) { m_vertex_polys[size_t(addlist.back())] = current_poly; std::vector& connections = depthmapX::getMapAtIndex(m_vertex_possibles, addlist.back())->second; addlist.pop_back(); for (size_t j = 0; j < connections.size(); j++) { int index = depthmapX::findIndexFromKey(m_vertex_possibles, connections[j]); if (index == -1) { throw 3; } if (m_vertex_polys[size_t(index)] == -1) { addlist.push_back(index); } } } } } } void AxialPolygons::makePixelPolys() { // record all of this onto the pixel polygons m_pixel_polys = depthmapX::ColumnMatrix>(m_rows, m_cols); // now register the vertices in each pixel... int j = -1; for (auto vertPoss: m_vertex_possibles) { j++; PixelRef pix = pixelate(vertPoss.first); m_pixel_polys(static_cast(pix.y), static_cast(pix.x)).push_back(j); } } /////////////////////////////////////////////////////////////////////////////////////////////// // almost identical to original! AxialVertexKey AxialPolygons::seedVertex(const Point2f& seed) { AxialVertexKey seedvertex = NoVertex; PixelRef seedref = pixelate(seed); bool foundvertex = false; // for spiralling outwards to find a vertex: int dir = PixelRef::HORIZONTAL; int sidelength = 1; int runlength = 0; int allboundaries = 0; while (!foundvertex) { for (int vertexref: m_pixel_polys(static_cast(seedref.y), static_cast(seedref.x))) { const Point2f& trialpoint = depthmapX::getMapAtIndex(m_vertex_possibles, vertexref)->first; if (!intersect_exclude(Line(seed,trialpoint))) { // yay... ...but wait... we need to see if it's a proper polygon vertex first... seedvertex = vertexref; foundvertex = true; } } if (!foundvertex) { seedref = seedref.move(dir); // spiral outwards: if (++runlength == sidelength) { switch (dir) { case PixelRef::HORIZONTAL: dir = PixelRef::VERTICAL; runlength = 0; break; case PixelRef::VERTICAL: dir = PixelRef::NEGHORIZONTAL; runlength = 0; sidelength++; break; case PixelRef::NEGHORIZONTAL: dir = PixelRef::NEGVERTICAL; runlength = 0; break; case PixelRef::NEGVERTICAL: dir = PixelRef::HORIZONTAL; runlength = 0; sidelength++; break; } } // check to make sure not off edge of system: if (seedref.x < 0) { allboundaries |= 0x01; seedref.x = 0; } if (seedref.y < 0) { allboundaries |= 0x02; seedref.y = 0; } if (seedref.x >= static_cast(m_cols)) { allboundaries |= 0x04; seedref.x = m_cols - 1; } if (seedref.y >= static_cast(m_rows)) { allboundaries |= 0x08; seedref.y = m_rows - 1; } if (allboundaries == 0x0f) { return NoVertex; } } } return seedvertex; } // adds any axial lines from this point to the list of lines, adds any unhandled visible vertices it finds to the openvertices list // axial lines themselves are added to the lines list - the axial line is only there to record the key vertices that comprise the line void AxialPolygons::makeAxialLines(std::set& openvertices, std::vector& lines, KeyVertices& keyvertices, std::vector& poly_connections, std::vector& radial_lines) { auto it = openvertices.rbegin(); AxialVertex vertex = *it; openvertices.erase(std::next(it).base()); m_handled_list.insert(vertex); int i = -1; for (auto vertPoss: m_vertex_possibles) { i++; if (i == vertex.m_ref_key) { continue; } bool possible = false, stubpossible = false; Point2f p = vertPoss.first - vertex.m_point; if (vertex.m_convex) { if (det(vertex.m_a,p) > 0 && det(vertex.m_b,p) > 0) { possible = true; } } else { // left of b and right of a or left of a and right of b if (det(p,vertex.m_a) * det(p,vertex.m_b) < 0) { possible = true; } else if (det(p,vertex.m_a) < TOLERANCE_A && det(p,vertex.m_b) < TOLERANCE_A) { stubpossible = true; } } if (possible || stubpossible) { Line line(vertPoss.first,vertex.m_point); if (!intersect_exclude(line)) { AxialVertex next_vertex = makeVertex(AxialVertexKey(i),vertex.m_point); if (next_vertex.m_initialised && std::find(m_handled_list.begin(), m_handled_list.end(), next_vertex) == m_handled_list.end()) { openvertices.insert(next_vertex); // <- note, add ignores duplicate adds (each vertex tends to be added multiple times before this vertex is handled itself) bool shortline_segend = false; Line shortline = line; if (!vertex.m_convex && possible) { Line ext(line.t_end(), line.t_end() + (line.t_end() - line.t_start())); ext.ray(1, m_region); cutLine(ext, 1); line = Line(line.t_start(), ext.t_end()); // for radial line segend calc: if (det(-p,vertex.m_b) < 0) { shortline_segend = true; } } if (m_vertex_polys[vertex.m_ref_key] != m_vertex_polys[next_vertex.m_ref_key]) { // must be on separate polygons // radial line(s) (for new point) RadialLine radialshort(next_vertex, shortline_segend, vertex.m_point,next_vertex.m_point,next_vertex.m_point+next_vertex.m_b); poly_connections.push_back( PolyConnector(shortline, (RadialKey)radialshort) ); radial_lines.push_back(radialshort); if (!vertex.m_convex && possible) { Line longline = Line(vertPoss.first,line.t_end()); RadialLine radiallong(radialshort); radiallong.segend = shortline_segend ? 0 : 1; poly_connections.push_back( PolyConnector(longline, (RadialKey)radiallong) ); radial_lines.push_back(radiallong); } } shortline_segend = false; if (!next_vertex.m_convex && next_vertex.m_axial) { Line ext(line.t_start() - (line.t_end() - line.t_start()), line.t_start()); ext.ray(0, m_region); cutLine(ext, 0); line = Line(ext.t_start(), line.t_end()); // for radial line segend calc: if (det(p,next_vertex.m_b) < 0) { shortline_segend = true; } } if (m_vertex_polys[vertex.m_ref_key] != m_vertex_polys[next_vertex.m_ref_key]) { // must be on separate polygons // radial line(s) (for original point) RadialLine radialshort(vertex, shortline_segend, next_vertex.m_point,vertex.m_point,vertex.m_point+vertex.m_b); poly_connections.push_back( PolyConnector(shortline, (RadialKey)radialshort) ); radial_lines.push_back(radialshort); if (!next_vertex.m_convex && next_vertex.m_axial) { Line longline = Line(line.t_start(),vertex.m_point); RadialLine radiallong(radialshort); radiallong.segend = shortline_segend ? 0 : 1; poly_connections.push_back( PolyConnector(longline, (RadialKey)radiallong) ); radial_lines.push_back(radiallong); } } if (possible && next_vertex.m_axial) { // axial line lines.push_back(line); keyvertices.push_back(std::set()); if (vertex.m_convex) { keyvertices.back().insert(vertex.m_ref_key); } if (next_vertex.m_convex) { keyvertices.back().insert(next_vertex.m_ref_key); } } } } } } std::sort( radial_lines.begin(), radial_lines.end() ); radial_lines.erase( std::unique( radial_lines.begin(), radial_lines.end() ), radial_lines.end() ); } /////////////////////////////////////////////////////////////////////////////////////////// // not really used as yet, a feature to make all the polygons from the vertex // possibles list void AxialPolygons::makePolygons(std::vector>& polygons) { std::vector > handled_list; for (size_t j = 0; j < m_vertex_possibles.size(); j++) { handled_list.push_back(std::vector()); } int i = -1; for (auto vertPoss: m_vertex_possibles) { i++; std::vector& currList = handled_list[size_t(i)]; if (vertPoss.second.size() == 1) { continue; } for (size_t j = 0; j < vertPoss.second.size(); j++) { if (std::find(currList.begin(), currList.end(), j) != currList.end()) { continue; } currList.push_back(int(j)); const Point2f& key = vertPoss.first; std::vector polygon; polygon.push_back(key); Point2f curr = vertPoss.second.at(j); Point2f last = key; bool good = true; while (curr != key) { auto vertPossIter = m_vertex_possibles.find(curr); polygon.push_back(curr); // hunt down left most int winner = -1, wayback = -1; double minangle = 2 * M_PI; for (size_t k = 0; k < vertPossIter->second.size(); k++) { Point2f next = vertPossIter->second.at(k); if (last != next) { double thisangle = angle(last,curr,next); if (thisangle < minangle) { // check not going to a dead end: if (m_vertex_possibles.find(vertPossIter->second.at(k))->second.size() > 1) { minangle = thisangle; winner = k; } } } else { wayback = k; } } if (winner == -1) { // this happens when you follow a false trail -- go back the way you came! winner = wayback; } handled_list[std::distance(m_vertex_possibles.begin(), vertPossIter)].push_back(winner); last = curr; curr = vertPossIter->second.at(winner); } if (good) { polygons.push_back(polygon); } good = true; } } } /////////////////////////////////////////////////////////////////////////////////////////// bool RadialLine::cuts(const Line& l) const { if (fabs(det(l.end() - keyvertex,l.end() - l.start())) < TOLERANCE_A) { // point on line, check that openspace and next vertex are on opposite sides of the line Point2f x = l.end() - keyvertex; Point2f y = nextvertex - keyvertex; Point2f z = openspace - keyvertex; x.normalise(); y.normalise(); z.normalise(); if (sgn(det(x, y)) == sgn(det(x, z)) && fabs(det(x, z)) > TOLERANCE_A) { return false; } } // keyvertex not on line... the line's been cut: return true; } ================================================ FILE: salalib/axialpolygons.h ================================================ #pragma once #include "salalib/spacepix.h" #include "salalib/axialmap.h" #include "salalib/connector.h" #include "genlib/simplematrix.h" #include "genlib/p2dpoly.h" struct AxialVertexKey { int m_ref_key; short m_ref_a; short m_ref_b; AxialVertexKey(int ref = -1, short a = -1, short b = -1) { m_ref_key = ref; m_ref_a = a; m_ref_b = b; } friend bool operator == (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator != (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator > (const AxialVertexKey& a, const AxialVertexKey& b); friend bool operator < (const AxialVertexKey& a, const AxialVertexKey& b); }; inline bool operator == (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key == b.m_ref_key && a.m_ref_a == b.m_ref_a && a.m_ref_b == b.m_ref_b); } inline bool operator != (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key != b.m_ref_key || a.m_ref_a != b.m_ref_a || a.m_ref_b != b.m_ref_b); } inline bool operator > (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key > b.m_ref_key || (a.m_ref_key == b.m_ref_key && (a.m_ref_a > b.m_ref_a || (a.m_ref_a == b.m_ref_a && a.m_ref_b > b.m_ref_b)))); } inline bool operator < (const AxialVertexKey& a, const AxialVertexKey& b) { return (a.m_ref_key < b.m_ref_key || (a.m_ref_key == b.m_ref_key && (a.m_ref_a < b.m_ref_a || (a.m_ref_a == b.m_ref_a && a.m_ref_b < b.m_ref_b)))); } const AxialVertexKey NoVertex(-1,-1,-1); struct AxialVertex : public AxialVertexKey { Point2f m_point; Point2f m_openspace; Point2f m_a; Point2f m_b; bool m_clockwise; bool m_convex; bool m_initialised; bool m_axial; AxialVertex(const AxialVertexKey& vertex_key = NoVertex, const Point2f& point = Point2f(), const Point2f& openspace = Point2f()) : AxialVertexKey(vertex_key) { m_point = point; m_openspace = openspace; m_initialised = false; m_axial = false; } }; struct RadialKey { AxialVertexKey vertex; float ang; bool segend; // padding the remaining three bytes behind the bool - don't use int : 24 as this will grab the next 4 byte block char pad1 : 8; short pad2 : 16; RadialKey(const AxialVertexKey& v = NoVertex, float a = -1.0f, bool se = false) : pad1(0), pad2(0) { vertex = v; ang = a; segend = se; } RadialKey(const RadialKey& rk) : pad1(0), pad2(0) { vertex = rk.vertex; ang = rk.ang; segend = rk.segend; } }; inline bool operator < (const RadialKey& a, const RadialKey& b) { return a.vertex < b.vertex || (a.vertex == b.vertex && (a.ang < b.ang || (a.ang == b.ang && a.segend < b.segend))); } inline bool operator > (const RadialKey& a, const RadialKey& b) { return a.vertex > b.vertex || (a.vertex == b.vertex && (a.ang > b.ang || (a.ang == b.ang && a.segend > b.segend))); } inline bool operator == (const RadialKey& a, const RadialKey& b) { return a.vertex == b.vertex && a.ang == b.ang && a.segend == b.segend; } struct RadialLine : public RadialKey { Point2f openspace; Point2f keyvertex; Point2f nextvertex; RadialLine(const RadialKey& rk = RadialKey()) : RadialKey(rk) {;} RadialLine(const AxialVertexKey& v, bool se, const Point2f& o, const Point2f& k, const Point2f& n) { vertex = v; ang = (float) angle(o,k,n); segend = se; openspace = o; keyvertex = k; nextvertex = n; } RadialLine(const RadialLine& rl) : RadialKey(rl) { openspace = rl.openspace; keyvertex = rl.keyvertex; nextvertex = rl.nextvertex; } bool cuts(const Line& l) const; }; struct RadialSegment { std::set indices; RadialKey radial_b; RadialSegment(RadialKey& rb) { radial_b = rb; } RadialSegment(const RadialKey& rb) { radial_b = rb; } RadialSegment() { radial_b = RadialKey(); } }; struct PolyConnector { Line line; RadialKey key; PolyConnector(const Line& l = Line(), const RadialKey& k = RadialKey()) { line = l; key = k; } }; class AxialPolygons : public SpacePixel { friend class ShapeGraphs; protected: std::vector m_vertex_polys; depthmapX::ColumnMatrix > m_pixel_polys; public: AxialPolygons(): m_pixel_polys(0,0) {} std::set m_handled_list; std::map> m_vertex_possibles; void clear(); void init(std::vector &lines, const QtRegion& region); void makeVertexPossibles(const std::vector &lines, const std::vector &connectionset); void makePixelPolys(); // AxialVertex makeVertex(const AxialVertexKey& vertexkey, const Point2f& openspace); // find a polygon corner visible from seed: AxialVertexKey seedVertex(const Point2f& seed); // make axial lines from corner vertices, visible from openspace void makeAxialLines(std::set &openvertices, std::vector& lines, KeyVertices &keyvertices, std::vector& poly_connections, std::vector &radial_lines); // extra: make all the polygons possible from the set of m_vertex_possibles void makePolygons(std::vector > &polygons); }; ================================================ FILE: salalib/connector.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/connector.h" #include "genlib/containerutils.h" #include "genlib/readwritehelpers.h" #include "genlib/comm.h" // for communicator #include #include #include bool Connector::read( std::istream& stream) { m_connections.clear(); m_forward_segconns.clear(); m_back_segconns.clear(); // n.b., must set displayed attribute as soon as loaded... dXreadwrite::readIntoVector(stream, m_connections); stream.read((char *)&m_segment_axialref, sizeof(m_segment_axialref)); dXreadwrite::readIntoMap(stream, m_forward_segconns); dXreadwrite::readIntoMap(stream, m_back_segconns); return true; } bool Connector::write( std::ofstream& stream ) { // n.b., must set displayed attribute as soon as loaded... dXreadwrite::writeVector(stream, m_connections); stream.write((char *)&m_segment_axialref, sizeof(m_segment_axialref)); dXreadwrite::writeMap(stream, m_forward_segconns); dXreadwrite::writeMap(stream, m_back_segconns); return true; } ///////////////////////////////////////////////////////////////////////////////// // Cursor extras int Connector::count(int mode) const { int c = 0; switch (mode) { case CONN_ALL: c = m_connections.size(); break; case SEG_CONN_ALL: c = m_back_segconns.size() + m_forward_segconns.size(); break; case SEG_CONN_FW: c = m_forward_segconns.size(); break; case SEG_CONN_BK: c = m_back_segconns.size(); break; } return c; } int Connector::getConnectedRef(int cursor, int mode) const { int cur = -1; if (cursor != -1) { switch (mode) { case CONN_ALL: if (cursor < int(m_connections.size())) { cur = m_connections[size_t(cursor)]; } break; case SEG_CONN_ALL: if (cursor < int(m_back_segconns.size())) { cur = depthmapX::getMapAtIndex(m_back_segconns, cursor)->first.ref; } else if (size_t(cursor) - m_back_segconns.size() < m_forward_segconns.size()) { cur = depthmapX::getMapAtIndex(m_forward_segconns, cursor - int(m_back_segconns.size()))->first.ref; } break; case SEG_CONN_FW: if (cursor < int(m_forward_segconns.size())) { cur = depthmapX::getMapAtIndex(m_forward_segconns, cursor)->first.ref; } break; case SEG_CONN_BK: if (cursor < int(m_back_segconns.size())) { cur = depthmapX::getMapAtIndex(m_back_segconns, cursor)->first.ref; } break; } } return cur; } int Connector::direction(int cursor, int mode) const { int direction = 0; if (cursor != -1) { switch (mode) { case SEG_CONN_ALL: if (cursor < (int)m_back_segconns.size()) { direction = depthmapX::getMapAtIndex(m_back_segconns, cursor)->first.dir; } else if (size_t(cursor) - m_back_segconns.size() < m_forward_segconns.size()) { direction = depthmapX::getMapAtIndex(m_forward_segconns, cursor - int(m_back_segconns.size()))->first.dir; } break; case SEG_CONN_FW: direction = depthmapX::getMapAtIndex(m_forward_segconns, cursor)->first.dir; break; case SEG_CONN_BK: direction = depthmapX::getMapAtIndex(m_back_segconns, cursor)->first.dir; break; } } return direction; } float Connector::weight(int cursor, int mode) const { float weight = 0.0f; if (cursor != -1) { switch (mode) { case SEG_CONN_ALL: if (cursor < int(m_back_segconns.size())) { weight = depthmapX::getMapAtIndex(m_back_segconns, cursor)->second; } else if (size_t(cursor) - m_back_segconns.size() < m_forward_segconns.size()) { weight = depthmapX::getMapAtIndex(m_forward_segconns, cursor - int(m_back_segconns.size()))->second; } break; case SEG_CONN_FW: weight = depthmapX::getMapAtIndex(m_forward_segconns, cursor)->second; break; case SEG_CONN_BK: weight = depthmapX::getMapAtIndex(m_back_segconns, cursor)->second; break; } } return weight; } ================================================ FILE: salalib/connector.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include #include ///////////////////////////////////////////////////////////////////////////// // Additional for segment analysis struct SegmentRef { char dir; // padding the remaining three bytes behind the char char pad1 : 8; short pad2 : 16; int ref; SegmentRef(char d = 0, int r = -1): pad1(0), pad2(0) { dir = d; ref = r; } }; // note, the dir is only a direction indicator, the ref should always be unique inline bool operator < (SegmentRef a, SegmentRef b) { return a.ref < b.ref; } inline bool operator > (SegmentRef a, SegmentRef b) { return a.ref > b.ref; } inline bool operator == (SegmentRef a, SegmentRef b) { return a.ref == b.ref; } inline bool operator != (SegmentRef a, SegmentRef b) { return a.ref != b.ref; } // used during angular analysis struct SegmentData : public SegmentRef { SegmentRef previous; int segdepth; float metricdepth; unsigned int coverage; SegmentData(char d = 0, int r = -1, SegmentRef p = SegmentRef(), int sd = 0, float md = 0.0f, unsigned int cv = 0xffffffff) { dir = d; ref = r; previous = p; segdepth = sd; metricdepth = md; coverage = cv; } SegmentData(SegmentRef ref, SegmentRef p = SegmentRef(), int sd = 0, float md = 0.0f, unsigned int cv = 0xffffffff) : SegmentRef(ref) { previous = p; segdepth = sd; metricdepth = md; coverage = cv; } friend bool operator < (SegmentData a, SegmentData b); friend bool operator > (SegmentData a, SegmentData b); friend bool operator == (SegmentData a, SegmentData b); friend bool operator != (SegmentData a, SegmentData b); }; // note, these are stored in reverse metric depth order (i.e., metric shorter paths are taken off the end of the list first) inline bool operator < (SegmentData a, SegmentData b) { return a.metricdepth > b.metricdepth; } inline bool operator > (SegmentData a, SegmentData b) { return a.metricdepth < b.metricdepth; } inline bool operator == (SegmentData a, SegmentData b) { return a.metricdepth == b.metricdepth; } inline bool operator != (SegmentData a, SegmentData b) { return a.metricdepth != b.metricdepth; } /////////////////////////////////////////////////////////////////////////// // Main connector class for segments, convex spaces or axial lines struct Connector { // if this is a segment, this is the key for the axial line: int m_segment_axialref; // use one or other of these std::vector m_connections; // std::map m_back_segconns; std::map m_forward_segconns; // Connector(int axialref = -1) { m_segment_axialref = axialref; } void clear() { m_connections.clear(); m_back_segconns.clear(); m_forward_segconns.clear(); } // bool read(std::istream &stream); bool write( std::ofstream& stream ); // // Cursor extras enum { CONN_ALL, SEG_CONN_ALL, SEG_CONN_FW, SEG_CONN_BK }; // PK: These functions have been stripped of state and left // here for salaprogram which seems to be the only place they // are used. salaprogram seems to also be the only place where // the last two modes (SEG_CONN_FW, SEG_CONN_BK) are used int count(int mode = CONN_ALL) const; int getConnectedRef(int cursor, int mode = CONN_ALL) const; int direction(int cursor, int mode = SEG_CONN_ALL) const; float weight(int cursor, int mode = SEG_CONN_ALL) const; }; ================================================ FILE: salalib/displayparams.h ================================================ #pragma once struct DisplayParams { enum { AXMANESQUE = 0, GREYSCALE = 1, MONOCHROME = 2, DEPTHMAPCLASSIC = 3, PURPLEORANGE = 4, BLUERED = 5, HUEONLYAXMANESQUE = 6 }; float blue; float red; int colorscale; DisplayParams() { blue = 0.0f; red = 1.0f; colorscale = 0; } }; ================================================ FILE: salalib/entityparsing.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "entityparsing.h" #include #include #include #include "genlib/stringutils.h" namespace EntityParsing { std::vector parseLines(std::istream& stream, char delimiter = '\t') { std::vector lines; std::string inputline; std::getline(stream, inputline); std::vector strings = dXstring::split(inputline, delimiter); if (strings.size() < 4) { throw EntityParseException("Badly formatted header (should contain x1, y1, x2 and y2)"); } size_t i; for (i = 0; i < strings.size(); i++) { if (!strings[i].empty()) { std::transform(strings[i].begin(), strings[i].end(), strings[i].begin(), ::tolower); //strings[i].ltrim('\"'); //strings[i].rtrim('\"'); } } int x1col = -1, y1col = -1, x2col = -1, y2col = -1; for (i = 0; i < strings.size(); i++) { if (strings[i] == "x1") { x1col = i; } else if (strings[i] == "x2") { x2col = i; } else if (strings[i] == "y1") { y1col = i; } else if (strings[i] == "y2") { y2col = i; } } if(x1col == -1 || y1col == -1 || x2col == -1 || y2col == -1) { throw EntityParseException("Badly formatted header (should contain x1, y1, x2 and y2)"); } Point2f p1, p2; while (!stream.eof()) { std::getline(stream, inputline); if (!inputline.empty()) { strings = dXstring::split(inputline, delimiter); if (!strings.size()) { continue; } if (strings.size() < 4) { std::stringstream message; message << "Error parsing line: " << inputline << std::flush; throw EntityParseException(message.str().c_str()); } for (i = 0; i < strings.size(); i++) { if (static_cast(i) == x1col) { p1.x = std::atof(strings[i].c_str()); } else if (static_cast(i) == y1col) { p1.y = std::atof(strings[i].c_str()); } else if (static_cast(i) == x2col) { p2.x = std::atof(strings[i].c_str()); } else if (static_cast(i) == y2col) { p2.y = std::atof(strings[i].c_str()); } } lines.push_back(Line(p1,p2)); } } return lines; } std::vector parsePoints(std::istream& stream, char delimiter = '\t') { std::vector points; std::string inputline; std::getline(stream, inputline); std::vector strings = dXstring::split(inputline, delimiter); if (strings.size() < 2) { throw EntityParseException("Badly formatted header (should contain x and y)"); } size_t i; for (i = 0; i < strings.size(); i++) { if (!strings[i].empty()) { std::transform(strings[i].begin(), strings[i].end(), strings[i].begin(), ::tolower); //strings[i].ltrim('\"'); //strings[i].rtrim('\"'); } } int xcol = -1, ycol = -1; for (i = 0; i < strings.size(); i++) { if (strings[i] == "x") { xcol = i; } else if (strings[i] == "y") { ycol = i; } } if(xcol == -1 || ycol == -1) { throw EntityParseException("Badly formatted header (should contain x and y)"); } Point2f p; while (!stream.eof()) { std::getline(stream, inputline); if (!inputline.empty()) { strings = dXstring::split(inputline, delimiter); if (!strings.size()) { continue; } if (strings.size() < 2) { std::stringstream message; message << "Error parsing line: " << inputline << std::flush; throw EntityParseException(message.str().c_str()); } for (i = 0; i < strings.size(); i++) { if (static_cast(i) == xcol) { p.x = std::atof(strings[i].c_str()); } else if (static_cast(i) == ycol) { p.y = std::atof(strings[i].c_str()); } } points.push_back(p); } } return points; } Point2f parsePoint(const std::string &point, char delimiter) { std::vector strings = dXstring::split(point, delimiter); if (strings.size() != 2) { std::stringstream message; message << "Badly formatted point data, should be " << delimiter << ", was " << point << std::flush; throw EntityParseException(message.str()); } return Point2f(atof(strings[0].c_str()), atof(strings[1].c_str())); } std::vector parseIsovists(std::istream &stream, char delimiter) { std::vector isovists; std::string inputline; std::getline(stream, inputline); std::vector strings = dXstring::split(inputline, delimiter); if (strings.size() < 2) { throw EntityParseException("Badly formatted header (should contain x, y, can also have angle and viewangle for partial isovists)"); } size_t i; for (i = 0; i < strings.size(); i++) { if (!strings[i].empty()) { std::transform(strings[i].begin(), strings[i].end(), strings[i].begin(), ::tolower); } } int xcol = -1, ycol = -1, anglecol = -1, viewcol = -1; for (i = 0; i < strings.size(); i++) { if (strings[i] == "x") { xcol = i; } else if (strings[i] == "y") { ycol = i; } else if (strings[i] == "angle") { anglecol = i; } else if (strings[i] == "viewangle") { viewcol = i; } } if(xcol == -1 || ycol == -1 ) { throw EntityParseException("Badly formatted header (should contain x and y, might also have angle and viewangle for partial isovists)"); } bool partialIsovists = anglecol != -1 && viewcol != -1; int maxCol = std::max({xcol, ycol, anglecol, viewcol}); while ( !stream.eof()) { std::getline(stream, inputline); if (!inputline.empty()) { strings = dXstring::split(inputline, delimiter); if (!strings.size()) { continue; } if (static_cast(strings.size()) <= maxCol) { std::stringstream message; message << "Error parsing line: " << inputline << std::flush; throw EntityParseException(message.str().c_str()); } double x = std::atof(strings[xcol].c_str()); double y = std::atof(strings[ycol].c_str()); if (partialIsovists) { double angle = std::atof(strings[anglecol].c_str()) / 180.0 * M_PI; double viewAngle = std::atof(strings[viewcol].c_str())/180.0 * M_PI; isovists.push_back(IsovistDefinition(x,y,angle,viewAngle)); } else { isovists.push_back(IsovistDefinition(x,y)); } } } return isovists; } IsovistDefinition parseIsovist(const std::string &isovist) { auto parts = dXstring::split(isovist, ','); if (parts.size() == 2) { return IsovistDefinition(std::atof(parts[0].c_str()), std::atof(parts[1].c_str())); } else if (parts.size() == 4) { double angle = std::atof(parts[2].c_str()) / 180.0 * M_PI; double viewAngle = std::atof(parts[3].c_str())/180.0 * M_PI; return IsovistDefinition(std::atof(parts[0].c_str()), std::atof(parts[1].c_str()), angle, viewAngle); } std::stringstream message; message << "Failed to parse '" << isovist << "' to an isovist definition"; throw EntityParseException(message.str()); } std::vector > parseRefPairs(std::istream& stream, char delimiter = '\t') { std::vector > pairs; std::string inputline; std::getline(stream, inputline); std::vector strings = dXstring::split(inputline, delimiter); if (strings.size() < 2) { throw EntityParseException("Badly formatted header (should contain reffrom and refto)"); } size_t i; for (i = 0; i < strings.size(); i++) { if (!strings[i].empty()) { std::transform(strings[i].begin(), strings[i].end(), strings[i].begin(), ::tolower); //strings[i].ltrim('\"'); //strings[i].rtrim('\"'); } } int fromcol = -1, tocol = -1; for (i = 0; i < strings.size(); i++) { if (strings[i] == "reffrom") { fromcol = int(i); } else if (strings[i] == "refto") { tocol = int(i); } } if(fromcol == -1 || tocol == -1) { throw EntityParseException("Badly formatted header (should contain reffrom and refto)"); } while (!stream.eof()) { std::getline(stream, inputline); if (!inputline.empty()) { strings = dXstring::split(inputline, delimiter); if (!strings.size()) { continue; } if (strings.size() < 2) { std::stringstream message; message << "Error parsing line: " << inputline << std::flush; throw EntityParseException(message.str().c_str()); } int from = -1, to = -1; for (i = 0; i < strings.size(); i++) { if (i == size_t(fromcol)) { from = std::atoi(strings[i].c_str()); } else if (i == size_t(tocol)) { to = std::atoi(strings[i].c_str()); } } pairs.push_back(std::make_pair(from, to)); } } return pairs; } } ================================================ FILE: salalib/entityparsing.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef ENTITYPARSING_H #define ENTITYPARSING_H #include "genlib/p2dpoly.h" #include "genlib/exceptions.h" #include "isovistdef.h" #include #include #include namespace EntityParsing { class EntityParseException : public depthmapX::BaseException { public: EntityParseException(std::string message) : depthmapX::BaseException(message) {} }; std::vector split(const std::string &s, char delim); std::vector parseLines(std::istream& stream, char delimiter); std::vector parsePoints(std::istream& stream, char delimiter); Point2f parsePoint(const std::string &point, char delimiter = ','); std::vector parseIsovists(std::istream &stream, char delimiter); IsovistDefinition parseIsovist(const std::string &isovist); std::vector > parseRefPairs(std::istream& stream, char delimiter); } #endif // ENTITYPARSING_H ================================================ FILE: salalib/fileproperties.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __FILEPROPERTIES_H__ #define __FILEPROPERTIES_H__ #include "genlib/stringutils.h" class FileProperties { protected: std::string m_create_person; std::string m_create_organization; std::string m_create_date; std::string m_create_program; std::string m_title; std::string m_location; std::string m_description; public: FileProperties() {;} virtual ~FileProperties() {;} // void setProperties(const std::string& person, const std::string& organization, const std::string& date, const std::string& program) { m_create_person = person; m_create_organization = organization; m_create_date = date; m_create_program = program; } void setTitle(const std::string& title) { m_title = title; } void setLocation(const std::string& location) { m_location = location; } void setDescription(const std::string& description) { m_description = description; } // const std::string& getPerson() const { return m_create_person; } const std::string& getOrganization() const { return m_create_organization; } const std::string& getDate() const { return m_create_date; } const std::string& getProgram() const { return m_create_program; } const std::string& getTitle() const { return m_title; } const std::string& getLocation() const { return m_location; } const std::string& getDescription() const { return m_description; } // bool read(std::istream &stream); bool write(std::ostream& stream); }; inline bool FileProperties::read(std::istream& stream) { m_create_person=dXstring::readString(stream); m_create_organization=dXstring::readString(stream); m_create_date=dXstring::readString(stream); m_create_program=dXstring::readString(stream); m_title=dXstring::readString(stream); m_location=dXstring::readString(stream); m_description=dXstring::readString(stream); return true; } inline bool FileProperties::write(std::ostream& stream) { dXstring::writeString(stream, m_create_person); dXstring::writeString(stream, m_create_organization); dXstring::writeString(stream, m_create_date); dXstring::writeString(stream, m_create_program); dXstring::writeString(stream, m_title); dXstring::writeString(stream, m_location); dXstring::writeString(stream, m_description); return true; } #endif ================================================ FILE: salalib/geometrygenerators.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "geometrygenerators.h" std::vector GeometryGenerators::generateDiskTriangles(int sides, float radius, Point2f position) { std::vector diskTriangles; for(int i = 0; i < sides; i++) { diskTriangles.push_back(Point2f(position.x, position.y)); diskTriangles.push_back(Point2f(position.x + radius*sin(2*M_PI*(i+1)/sides), position.y + radius*cos(2*M_PI*(i+1)/sides))); diskTriangles.push_back(Point2f(position.x + radius*sin(2*M_PI*i/sides), position.y + radius*cos(2*M_PI*i/sides))); } return diskTriangles; } std::vector GeometryGenerators::generateMultipleDiskTriangles(int sides, float radius, std::vector positions) { std::vector diskTriangles = generateDiskTriangles(sides , radius); std::vector mulitpleDiskTriangles; std::vector::const_iterator iter = positions.begin(), end = positions.end(); for ( ; iter != end; ++iter ) { Point2f position = *iter; std::vector::const_iterator iterDiskVertices = diskTriangles.begin(), endDiskPoints = diskTriangles.end(); for ( ; iterDiskVertices != endDiskPoints; ++iterDiskVertices ) { Point2f vertex = *iterDiskVertices; mulitpleDiskTriangles.push_back(Point2f(position.x + vertex.x,position.y + vertex.y)); } } return mulitpleDiskTriangles; } std::vector GeometryGenerators::generateCircleLines(int sides, float radius, Point2f position) { std::vector cirleLines; for(int i = 0; i < sides; i++) { cirleLines.push_back(SimpleLine( Point2f(position.x + radius*sin(2*M_PI*(i+1)/sides), position.y + radius*cos(2*M_PI*(i+1)/sides)), Point2f(position.x + radius*sin(2*M_PI*i/sides), position.y + radius*cos(2*M_PI*i/sides)) )); } return cirleLines; } std::vector GeometryGenerators::generateMultipleCircleLines(int sides, float radius, std::vector positions) { std::vector circleLines = generateCircleLines(sides , radius); std::vector mulitpleCircleLines; std::vector::const_iterator iter = positions.begin(), end = positions.end(); for ( ; iter != end; ++iter ) { Point2f position = *iter; std::vector::const_iterator iterCircleLines = circleLines.begin(), endCircleLines = circleLines.end(); for ( ; iterCircleLines != endCircleLines; ++iterCircleLines ) { SimpleLine line = *iterCircleLines; mulitpleCircleLines.push_back(SimpleLine( Point2f(position.x + line.start().x, position.y + line.start().y), Point2f(position.x + line.end().x, position.y + line.end().y) )); } } return mulitpleCircleLines; } ================================================ FILE: salalib/geometrygenerators.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include class GeometryGenerators { public: static std::vector generateDiskTriangles(int sides, float radius, Point2f position = Point2f(0,0)); static std::vector generateMultipleDiskTriangles(int sides, float radius, std::vector positions); static std::vector generateCircleLines(int sides, float radius, Point2f position = Point2f(0,0)); static std::vector generateMultipleCircleLines(int sides, float radius, std::vector positions); }; ================================================ FILE: salalib/gridproperties.cpp ================================================ #include "gridproperties.h" #include GridProperties::GridProperties(double maxDimension) { int maxexponent = (int) floor(log10(maxDimension)) - 1; int minexponent = maxexponent - 2; int mantissa = (int) floor(maxDimension / pow(10.0,double(maxexponent+1))); m_default = (double) mantissa * pow(10.0, double(maxexponent - 1)); m_max = (double) 2 * mantissa * pow(10.0, double(maxexponent)); m_min = (double) mantissa * pow(10.0, double(minexponent)); } ================================================ FILE: salalib/gridproperties.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once class GridProperties { public: GridProperties(double maxDimension); double getMin() const{return m_min;} double getMax() const{return m_max;} double getDefault() const{return m_default;} private: double m_max; double m_min; double m_default; }; ================================================ FILE: salalib/ianalysis.h ================================================ // Copyright (C) 2020 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/mgraph.h" #include "salalib/pointdata.h" #include "genlib/comm.h" class IAnalysis { public: virtual std::string getAnalysisName() const = 0; virtual bool run(Communicator *comm) = 0; virtual ~IAnalysis() {} }; ================================================ FILE: salalib/iaxial.h ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Interface to handle different kinds of Axial analysis #include "salalib/axialmap.h" #include "genlib/comm.h" #include class IAxial { public: virtual std::string getAnalysisName() const = 0; virtual bool run(Communicator *comm, ShapeGraph &map, bool simple_version) = 0; virtual ~IAxial(){} }; ================================================ FILE: salalib/importtypedefs.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include #include namespace depthmapX { typedef std::vector ColumnData; typedef std::map Table; class Polyline : public QtRegion { public: std::vector m_vertices; bool m_closed = false; Polyline(std::vector vertices, bool closed) : m_vertices(vertices), m_closed(closed) { } }; enum ImportType { DRAWINGMAP, DATAMAP }; enum ImportFileType { CSV, TSV, DXF }; } ================================================ FILE: salalib/importutils.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "importutils.h" #include "genlib/stringutils.h" #include namespace depthmapX { const int DXFCIRCLERES = 36; bool importFile(MetaGraph &mgraph, std::istream &stream, Communicator *communicator, std::string name, ImportType mapType, ImportFileType fileType) { // This function is still too fiddly but at least it shows the common interface for // drawing and data maps and how different file types may be parsed to be imported // into them int state = MetaGraph::NONE; int viewClass = MetaGraph::NONE; switch (mapType) { case DRAWINGMAP: { state = MetaGraph::LINEDATA; viewClass = MetaGraph::SHOWSHAPETOP; break; } case DATAMAP: { state = MetaGraph::DATAMAPS; viewClass = MetaGraph::SHOWSHAPETOP; break; } } int oldstate = mgraph.getState(); mgraph.setState(oldstate & ~state); // Currently the drawing shapemaps are understood as two-level trees (file -> layers) // while the data shapemaps are flat. Therefore, for the moment, when we load dxfs as // drawing shapemaps then we let the filename be the parent and the layers the children. // For text files (csv, tsv) we create an artificial parent with the relevant name // Drawing shapemaps also carry region data that needs to be initialised and their parents // updated when they are created. // Ideally datamaps and drawingmaps should be more similar. if (mapType == DRAWINGMAP) { mgraph.m_drawingFiles.emplace_back(name); } bool parsed = false; switch (fileType) { case CSV: { ShapeMap &shapeMap = mgraph.createNewShapeMap(mapType, name); int newMapIdx = mgraph.getMapRef(mgraph.getDataMaps(), shapeMap.getName()); parsed = importTxt(shapeMap, stream, ','); if (!parsed) { mgraph.deleteShapeMap(mapType, shapeMap); break; } if (mapType == DRAWINGMAP) { mgraph.updateParentRegions(shapeMap); } else if (mapType == DATAMAP) { mgraph.setDisplayedDataMapRef(newMapIdx); } break; } case TSV: { ShapeMap &shapeMap = mgraph.createNewShapeMap(mapType, name); int newMapIdx = mgraph.getMapRef(mgraph.getDataMaps(), shapeMap.getName()); parsed = importTxt(shapeMap, stream, '\t'); if (!parsed) { mgraph.deleteShapeMap(mapType, shapeMap); break; } if (mapType == DRAWINGMAP) { mgraph.updateParentRegions(shapeMap); } else if (mapType == DATAMAP) { mgraph.setDisplayedDataMapRef(newMapIdx); } break; } case DXF: { DxfParser dp; if (communicator) { dp = DxfParser(communicator); try { stream >> dp; } catch (Communicator::CancelledException) { return 0; } catch (std::logic_error &) { return -1; } if (communicator->IsCancelled()) { return 0; } } else { dp.open(stream); } for (auto &layer : dp.getLayers()) { const DxfLayer &dxfLayer = layer.second; if (dxfLayer.empty()) { continue; } ShapeMap &shapeMap = mgraph.createNewShapeMap(mapType, layer.first); parsed = importDxfLayer(dxfLayer, shapeMap); if (!parsed) { mgraph.deleteShapeMap(mapType, shapeMap); break; } if (mapType == DRAWINGMAP) { mgraph.updateParentRegions(shapeMap); } } break; } } if (parsed) { mgraph.setState(mgraph.getState() | state); mgraph.setViewClass(viewClass); return true; } else { mgraph.setState(oldstate); return false; } } bool importTxt(ShapeMap &shapeMap, std::istream &stream, char delimiter = '\t') { Table table = csvToTable(stream, delimiter); std::vector columns; int xcol = -1, ycol = -1, x1col = -1, y1col = -1, x2col = -1, y2col = -1, refcol = -1; for (auto const &column : table) { if (column.first == "x" || column.first == "easting") xcol = columns.size(); else if (column.first == "y" || column.first == "northing") ycol = columns.size(); else if (column.first == "x1") x1col = columns.size(); else if (column.first == "x2") x2col = columns.size(); else if (column.first == "y1") y1col = columns.size(); else if (column.first == "y2") y2col = columns.size(); else if (column.first == "Ref") refcol = columns.size(); columns.push_back(column.first); } if (xcol != -1 && ycol != -1 && refcol != -1) { std::map points = extractPointsWithRefs(table[columns[xcol]], table[columns[ycol]], table[columns[refcol]]); table.erase(table.find(columns[xcol])); table.erase(table.find(columns[ycol])); table.erase(table.find(columns[refcol])); QtRegion region; for (auto &point : points) { if (region.atZero()) { region = point.second; } else { region = runion(region, point.second); } } shapeMap.init(points.size(), region); shapeMap.importPointsWithRefs(points, table); } else if (xcol != -1 && ycol != -1) { std::vector points = extractPoints(table[columns[xcol]], table[columns[ycol]]); table.erase(table.find(columns[xcol])); table.erase(table.find(columns[ycol])); QtRegion region; for (auto &point : points) { if (region.atZero()) { region = point; } else { region = runion(region, point); } } shapeMap.init(points.size(), region); shapeMap.importPoints(points, table); } else if (x1col != -1 && y1col != -1 && x2col != -1 && y2col != -1 && refcol != -1) { std::map lines = extractLinesWithRef(table[columns[x1col]], table[columns[y1col]], table[columns[x2col]], table[columns[y2col]], table[columns[refcol]]); table.erase(table.find(columns[x1col])); table.erase(table.find(columns[y1col])); table.erase(table.find(columns[x2col])); table.erase(table.find(columns[y2col])); table.erase(table.find(columns[refcol])); QtRegion region; for (auto &line : lines) { if (region.atZero()) { region = line.second; } else { region = runion(region, line.second); } } shapeMap.init(lines.size(), region); shapeMap.importLinesWithRefs(lines, table); } else if (x1col != -1 && y1col != -1 && x2col != -1 && y2col != -1) { std::vector lines = extractLines(table[columns[x1col]], table[columns[y1col]], table[columns[x2col]], table[columns[y2col]]); table.erase(table.find(columns[x1col])); table.erase(table.find(columns[y1col])); table.erase(table.find(columns[x2col])); table.erase(table.find(columns[y2col])); QtRegion region; for (auto &line : lines) { if (region.atZero()) { region = line; } else { region = runion(region, line); } } shapeMap.init(lines.size(), region); shapeMap.importLines(lines, table); } return true; } Table csvToTable(std::istream &stream, char delimiter = '\t') { Table table; std::vector columns; std::string inputline; std::getline(stream, inputline); // check for a matching delimited header line... auto strings = dXstring::split(inputline, delimiter); if (strings.size() < 2) { // throw exception return table; } for (auto &columnName : strings) { if (!columnName.empty()) { dXstring::ltrim(columnName, '\"'); dXstring::rtrim(columnName, '\"'); } table.insert(std::make_pair(columnName, std::vector())); columns.push_back(columnName); } while (!stream.eof()) { std::getline(stream, inputline); if (!inputline.empty()) { auto strings = dXstring::split(inputline, delimiter); if (strings.size() != columns.size()) { std::stringstream message; message << "Cells in line " << inputline << "not the same number as the columns" << std::flush; throw RuntimeException(message.str().c_str()); } if (!strings.size()) { continue; } for (size_t i = 0; i < strings.size(); i++) { table[columns[i]].push_back(strings[i]); } } } return table; } std::vector extractLines(ColumnData &x1col, ColumnData &y1col, ColumnData &x2col, ColumnData &y2col) { std::vector lines; for (size_t i = 0; i < x1col.size(); i++) { double x1 = stod(x1col[i]); double y1 = stod(y1col[i]); double x2 = stod(x2col[i]); double y2 = stod(y2col[i]); lines.push_back(Line(Point2f(x1, y1), Point2f(x2, y2))); } return lines; } std::map extractLinesWithRef(ColumnData &x1col, ColumnData &y1col, ColumnData &x2col, ColumnData &y2col, ColumnData &refcol) { std::map lines; for (size_t i = 0; i < x1col.size(); i++) { double x1 = stod(x1col[i]); double y1 = stod(y1col[i]); double x2 = stod(x2col[i]); double y2 = stod(y2col[i]); int ref = stoi(refcol[i]); lines.insert(std::make_pair(ref, Line(Point2f(x1, y1), Point2f(x2, y2)))); } return lines; } std::vector extractPoints(ColumnData &x, ColumnData &y) { std::vector points; for (size_t i = 0; i < x.size(); i++) { points.push_back(Point2f(stod(x[i]), stod(y[i]))); } return points; } std::map extractPointsWithRefs(ColumnData &x, ColumnData &y, ColumnData &ref) { std::map points; for (size_t i = 0; i < x.size(); i++) { points.insert(std::make_pair(stoi(ref[i]), Point2f(stod(x[i]), stod(y[i])))); } return points; } bool importDxfLayer(const DxfLayer &dxfLayer, ShapeMap &shapeMap) { std::vector points; std::vector lines; std::vector polylines; for (size_t jp = 0; jp < dxfLayer.numPoints(); jp++) { const DxfVertex &dxf_point = dxfLayer.getPoint(jp); points.push_back(Point2f(dxf_point.x, dxf_point.y)); } for (size_t j = 0; j < dxfLayer.numLines(); j++) { const DxfLine &dxf_line = dxfLayer.getLine(j); Line line = Line(Point2f(dxf_line.getStart().x, dxf_line.getStart().y), Point2f(dxf_line.getEnd().x, dxf_line.getEnd().y)); lines.push_back(line); } for (size_t k = 0; k < dxfLayer.numPolyLines(); k++) { const DxfPolyLine &poly = dxfLayer.getPolyLine(k); std::vector vertices; for (size_t m = 0; m < poly.numVertices(); m++) { DxfVertex v = poly.getVertex(m); vertices.push_back(Point2f(v.x, v.y)); } polylines.push_back( depthmapX::Polyline(vertices, (poly.getAttributes() & DxfPolyLine::CLOSED) == DxfPolyLine::CLOSED)); } for (size_t l = 0; l < dxfLayer.numSplines(); l++) { const DxfSpline &poly = dxfLayer.getSpline(l); std::vector vertices; for (size_t m = 0; m < poly.numVertices(); m++) { DxfVertex v = poly.getVertex(m); vertices.push_back(Point2f(v.x, v.y)); } polylines.push_back( depthmapX::Polyline(vertices, (poly.getAttributes() & DxfPolyLine::CLOSED) == DxfPolyLine::CLOSED)); } for (size_t n = 0; n < dxfLayer.numArcs(); n++) { const DxfArc &circ = dxfLayer.getArc(n); std::vector vertices; size_t segments = circ.numSegments(DXFCIRCLERES); if (segments > 1) { for (size_t m = 0; m <= segments; m++) { DxfVertex v = circ.getVertex(m, segments); vertices.push_back(Point2f(v.x, v.y)); } } polylines.push_back(depthmapX::Polyline(vertices, false)); } for (size_t n = 0; n < dxfLayer.numEllipses(); n++) { const DxfEllipse &ellipse = dxfLayer.getEllipse(n); std::vector vertices; size_t segments = ellipse.numSegments(DXFCIRCLERES); if (segments > 1) { for (size_t m = 0; m <= segments; m++) { DxfVertex v = ellipse.getVertex(m, segments); vertices.push_back(Point2f(v.x, v.y)); } } polylines.push_back(depthmapX::Polyline(vertices, false)); } for (size_t nc = 0; nc < dxfLayer.numCircles(); nc++) { const DxfCircle &circ = dxfLayer.getCircle(nc); std::vector vertices; for (int m = 0; m < DXFCIRCLERES; m++) { DxfVertex v = circ.getVertex(m, DXFCIRCLERES); vertices.push_back(Point2f(v.x, v.y)); } polylines.push_back(depthmapX::Polyline(vertices, true)); } DxfVertex layerMin = dxfLayer.getExtMin(); DxfVertex layerMax = dxfLayer.getExtMax(); QtRegion region = QtRegion(Point2f(layerMin.x, layerMin.y), Point2f(layerMax.x, layerMax.y)); shapeMap.init(points.size() + lines.size() + polylines.size(), region); // parameters could be passed in the Table here such as the layer/block/colour/linetype etc. shapeMap.importPoints(points, Table()); shapeMap.importLines(lines, Table()); shapeMap.importPolylines(polylines, Table()); return true; } bool importAttributes(AttributeTable &attributes, std::istream &stream, char delimiter = '\t') { Table table = csvToTable(stream, delimiter); std::vector outColumns; int refcol = -1; for (auto const &column : table) { if (column.first == "Ref") refcol = outColumns.size(); else outColumns.push_back(column.first); } if(table.size() == 0) { throw RuntimeException("No usable data found in file"); } if(refcol == -1) { throw RuntimeException("The \"Ref\" column is reqired"); } if(outColumns.size() < 1) { throw RuntimeException("No data found to join"); } std::vector inRows; for(const auto& refInFile: table["Ref"]) { int ref = std::stoi(refInFile); auto iter = attributes.find(AttributeKey(ref)); if(iter == attributes.end()) { std::stringstream message; message << "Key " << ref << "not found in attribute table" << std::flush; throw RuntimeException(message.str().c_str()); } inRows.push_back(&(iter->getRow())); } // Up until this point we have not touched the attribute table // so no need for corrective measures yet for(const std::string& column: outColumns) { int colIdx = attributes.insertOrResetColumn(column); auto outRowIter = table[column].begin(); for(auto inRowIter = inRows.begin(); inRowIter != inRows.end(); inRowIter++, outRowIter++) { (*inRowIter)->setValue(colIdx, std::stof(*outRowIter)); } } return true; } } // namespace depthmapX ================================================ FILE: salalib/importutils.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/importtypedefs.h" #include "salalib/mgraph.h" #include "salalib/parsers/dxfp.h" #include #include namespace depthmapX { bool importFile(MetaGraph &mgraph, std::istream &stream, Communicator *communicator, std::string name, ImportType mapType, ImportFileType fileType); bool importTxt(ShapeMap &shapeMap, std::istream &stream, char delimiter); depthmapX::Table csvToTable(std::istream &stream, char delimiter); std::vector extractLines(ColumnData &x1col, ColumnData &y1col, ColumnData &x2col, ColumnData &y2col); std::map extractLinesWithRef(ColumnData &x1col, ColumnData &y1col, ColumnData &x2col, ColumnData &y2col, ColumnData &refcol); std::vector extractPoints(ColumnData &x, ColumnData &y); std::map extractPointsWithRefs(ColumnData &x, ColumnData &y, ColumnData &ref); bool importDxfLayer(const DxfLayer &dxfLayer, ShapeMap &shapeMap); bool importAttributes(AttributeTable &attributes, std::istream &stream, char delimiter); } // namespace depthmapX ================================================ FILE: salalib/isegment.h ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Interface to handle different kinds of VGA analysis #include "salalib/axialmap.h" #include "salalib/options.h" #include "genlib/comm.h" #include class ISegment { public: virtual std::string getAnalysisName() const = 0; virtual bool run(Communicator *comm, ShapeGraph &map, bool simple_version) = 0; virtual ~ISegment(){} // Axial map helper: convert a radius for angular analysis static std::string makeFloatRadiusText(double radius) { std::string radius_text; if (radius > 100.0) { radius_text = dXstring::formatString(radius,"%.f"); } else if (radius < 0.1) { radius_text = dXstring::formatString(radius,"%.4f"); } else { radius_text = dXstring::formatString(radius,"%.2f"); } return radius_text; } static std::string makeRadiusText(int radius_type, double radius) { std::string radius_text; if (radius != -1) { if (radius_type == Options::RADIUS_STEPS) { radius_text = std::string(" R") + dXstring::formatString(int(radius),"%d") + " step"; } else if (radius_type == Options::RADIUS_METRIC) { radius_text = std::string(" R") + makeFloatRadiusText(radius) + " metric"; } else { // radius angular radius_text = std::string(" R") + makeFloatRadiusText(radius); } } return radius_text; } }; ================================================ FILE: salalib/isovist.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/isovist.h" #include #include #include /////////////////////////////////////////////////////////////////////// // Interestingly, apparently ray tracing is faster using voxel techniques than octrees etc: // Akira Fujimotot, Takayuki Tanaka, and Kansei Iwata. ARTS: Accelerated ray-tracing system. IEEE Computer Graphics and Applications, 6(4):16--26, April 1986 // This uses BSP trees, and appears to be superfast once the tree is built void Isovist::makeit(BSPNode *root, const Point2f& p, const QtRegion& region, double startangle, double endangle) { // region is used to give an idea of scale, so isovists can be linked when there is floating point error double tolerance = std::max(region.width(),region.height()) * 1e-9; m_centre = p; m_blocks.clear(); m_gaps.clear(); // still doesn't work when need centre point, but this will work for 180 degree isovists bool complete = false; if (startangle == endangle || (startangle == 0.0 && endangle == 2.0 * M_PI)) { startangle = 0.0; endangle = 2.0 * M_PI; complete = true; } bool parity = false; if (startangle > endangle) { m_gaps.insert(IsoSeg(0.0,endangle)); m_gaps.insert(IsoSeg(startangle,2.0*M_PI)); } else { parity = true; m_gaps.insert(IsoSeg(startangle,endangle)); } make(root); // now it is constructed, make the isovist polygon: m_poly.clear(); m_perimeter = 0.0; m_occluded_perimeter = 0.0; m_occlusion_points.clear(); bool markedcentre = false; auto prev = m_blocks.begin(); auto curr = m_blocks.begin(); for (;curr != m_blocks.end(); ++curr){ if (!complete && !markedcentre && !parity && curr->startangle == startangle) { // centre m_poly.push_back(p); // perimeter! occlusivity! markedcentre = true; } if (curr != m_blocks.begin() && !approxeq(prev->endpoint, curr->startpoint, tolerance)) { m_poly.push_back(curr->startpoint); // record perimeter information: double occluded = dist(prev->endpoint,curr->startpoint); m_perimeter += occluded; m_occluded_perimeter += occluded; // record the near *point* for use in agent analysis // (as the point will not move between isovists, so can record *which* occlusion this is, and spot novel ones) if (dist(prev->endpoint,m_centre) < dist(curr->startpoint,m_centre)) { m_occlusion_points.push_back(PointDist(prev->endpoint,occluded)); } else { m_occlusion_points.push_back(PointDist(curr->startpoint,occluded)); } } m_poly.push_back(curr->endpoint); m_perimeter += dist(curr->startpoint,curr->endpoint); prev = curr; } // for some reason to do with ordering, if parity is true, the centre point must be last not first if (!complete && parity) { // centre m_poly.push_back(p); // perimeter! occlusivity! } if (m_blocks.size() && !approxeq(m_blocks.rbegin()->endpoint, m_blocks.begin()->startpoint, tolerance)) { m_poly.push_back(m_blocks.begin()->startpoint); // record perimeter information: double occluded = dist(m_blocks.rbegin()->endpoint,m_blocks.begin()->startpoint); m_perimeter += occluded; m_occluded_perimeter += occluded; // record the near *point* for use in agent analysis // (as the point will not move between isovists, so can record *which* occlusion this is, and spot novel ones) if (occluded > 1.5) { if (dist(m_blocks.rbegin()->endpoint,m_centre) < dist(m_blocks.begin()->startpoint,m_centre)) { m_occlusion_points.push_back(PointDist(m_blocks.rbegin()->endpoint,occluded)); } else { m_occlusion_points.push_back(PointDist(m_blocks.begin()->startpoint,occluded)); } } } } int Isovist::getClosestLine(BSPNode *root, const Point2f& p) { m_centre = p; m_blocks.clear(); m_gaps.clear(); m_gaps.insert(IsoSeg(0.0,2.0*M_PI)); make(root); int mintag = -1; double mindist = 0.0; for (auto& block: m_blocks) { Line l(block.startpoint, block.endpoint); if (mintag == -1 || dist(p,l) < mindist) { mindist = dist(p,l); mintag = block.tag; } } return mintag; } void Isovist::make(BSPNode *here) { if (m_gaps.size()) { int which = here->classify(m_centre); if (which == BSPNode::BSPLEFT) { if (here->m_left.get()) make(here->m_left.get()); drawnode(here->getLine(),here->getTag()); if (here->m_right) make(here->m_right.get()); } else { if (here->m_right.get()) make(here->m_right.get()); drawnode(here->getLine(),here->getTag()); if (here->m_left) make(here->m_left.get()); } } } void Isovist::drawnode(const Line& li, int tag) { Point2f p1 = li.start() - m_centre; p1.normalise(); double angle1 = p1.angle(); Point2f p2 = li.end() - m_centre; p2.normalise(); double angle2 = p2.angle(); if (angle2 > angle1) { if (angle2 - angle1 >= M_PI) { // 0 to angle1 and angle2 to 2 pi addBlock(li,tag,0.0,angle1); addBlock(li,tag,angle2,2.0*M_PI); } else { // angle1 to angle2 addBlock(li,tag,angle1,angle2); } } else { if (angle1 - angle2 >= M_PI) { // 0 to angle2 and angle1 to 2 pi addBlock(li,tag,0.0,angle2); addBlock(li,tag,angle1,2.0*M_PI); } else { // angle2 to angle1 addBlock(li,tag,angle2,angle1); } } // for (auto it = m_gaps.begin(); it != m_gaps.end(); ) { if (it->tagdelete) { it = m_gaps.erase(it); } else { ++it; } } } void Isovist::addBlock(const Line& li, int tag, double startangle, double endangle) { auto gap = m_gaps.begin(); bool finished = false; while (!finished) { while (gap != m_gaps.end() && gap->endangle < startangle) { gap++; } if (gap != m_gaps.end() && gap->startangle < endangle + 1e-9) { double a,b; if (gap->startangle > startangle - 1e-9) { a = gap->startangle; if (gap->endangle < endangle + 1e-9) { b = gap->endangle; gap->tagdelete = true; } else { b = endangle; IsoSeg isoseg = *gap; isoseg.startangle = endangle; auto hint = gap; hint++; m_gaps.erase(gap); gap = m_gaps.insert(hint, isoseg); } } else { a = startangle; if (gap->endangle < endangle + 1e-9) { b = gap->endangle; IsoSeg isoseg = *gap; isoseg.endangle = startangle; auto hint = gap; hint++; m_gaps.erase(gap); gap = m_gaps.insert(hint, isoseg); } else { b = endangle; m_gaps.insert(IsoSeg(endangle, gap->endangle, gap->quadrant)); IsoSeg isoseg = *gap; isoseg.endangle = startangle; auto hint = gap; hint++; m_gaps.erase(gap); gap = m_gaps.insert(hint, isoseg); gap++; // advance past gap just added } } Point2f pa = intersection_point(li,Line(m_centre,m_centre+pointfromangle(a))); Point2f pb = intersection_point(li,Line(m_centre,m_centre+pointfromangle(b))); m_blocks.insert(IsoSeg(a,b,pa,pb,tag)); } else { finished = true; } if(gap == m_gaps.end()) break; gap++; } } void Isovist::setData(AttributeTable& table, AttributeRow& row, bool simple_version) { // the area / centre of gravity calculation is a duplicate of the SalaPolygon version, // included here for general information about the isovist double area = 0.0; Point2f centroid = Point2f(0,0); for (size_t i = 0; i < m_poly.size(); i++) { Point2f& p1 = m_poly.at(i); Point2f& p2 = m_poly.at((i+1)%m_poly.size()); double a_i = (p1.x * p2.y - p2.x * p1.y) / 2.0; area += a_i ; a_i /= 6.0; centroid.x += (p1.x+p2.x) * a_i; centroid.y += (p1.y+p2.y) * a_i; double dpoint = dist(m_centre,p1); double dline = dist(m_centre,Line(p1,p2)); if (i != 0) { // This is not minimum radial -- it's the distance to the closest corner! if (dline < m_min_radial) { m_min_radial = dline; dist(m_centre,Line(p1,p2)); } if (dpoint > m_max_radial) { m_max_radial = dpoint; } } else { m_max_radial = dpoint; m_min_radial = dline; } } centroid.scale(2.0/fabs(area)); Point2f driftvec = centroid - m_centre; double driftmag = driftvec.length(); driftvec.normalise(); double driftang = driftvec.angle(); // int col = table.getOrInsertColumn("Isovist Area"); row.setValue(col, float(area)); if(!simple_version) { col = table.getOrInsertColumn("Isovist Compactness"); row.setValue(col, float(4.0 * M_PI * area / (m_perimeter*m_perimeter))); col = table.getOrInsertColumn("Isovist Drift Angle"); row.setValue(col, float(180.0*driftang/M_PI)); col = table.getOrInsertColumn("Isovist Drift Magnitude"); row.setValue(col, float(driftmag)); col = table.getOrInsertColumn("Isovist Min Radial"); row.setValue(col, float(m_min_radial)); col = table.getOrInsertColumn("Isovist Max Radial"); row.setValue(col, float(m_max_radial)); col = table.getOrInsertColumn("Isovist Occlusivity"); row.setValue(col, float(m_occluded_perimeter)); col = table.getOrInsertColumn("Isovist Perimeter"); row.setValue(col, float(m_perimeter)); } } ================================================ FILE: salalib/isovist.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // isovist.h #pragma once #include "salalib/attributetable.h" #include "genlib/bsptree.h" #include // this is very much like sparksieve: struct IsoSeg { mutable bool tagdelete; double startangle; double endangle; Point2f startpoint; Point2f endpoint; char quadrant; int tag; IsoSeg(double start = 0.0, double end = 0.0, char q = 0, int t = -1) { startangle = start; endangle = end; tagdelete = false; quadrant = q; tag = t; } IsoSeg(double start, double end, const Point2f& pstart, Point2f& pend, int t = -1) { startangle = start; endangle = end; startpoint = pstart; endpoint = pend; tagdelete = false; tag = t; } friend bool operator == (const IsoSeg& b1, const IsoSeg& b2); friend bool operator > (const IsoSeg& b1, const IsoSeg& b2); friend bool operator < (const IsoSeg& b1, const IsoSeg& b2); }; inline bool operator == (const IsoSeg& b1, const IsoSeg& b2) { return (b1.startangle == b2.startangle && b1.endangle == b2.endangle); } inline bool operator > (const IsoSeg& b1, const IsoSeg& b2) { return b1.startangle == b2.startangle ? b1.endangle > b2.endangle : b1.startangle > b2.startangle; } inline bool operator < (const IsoSeg& b1, const IsoSeg& b2) { return b1.startangle == b2.startangle ? b1.endangle < b2.endangle : b1.startangle < b2.startangle; } class AttributeTable; struct PointDist { Point2f m_point; double m_dist; PointDist(const Point2f& p = Point2f(), double d = 0.0) { m_point = p; m_dist = d; } }; class Isovist { protected: Point2f m_centre; std::set m_blocks; std::set m_gaps; std::vector m_poly; std::vector m_occlusion_points; double m_perimeter; double m_occluded_perimeter; double m_max_radial; double m_min_radial; public: Isovist() {;} const std::vector& getPolygon() const { return m_poly; } const std::vector& getOcclusionPoints() const { return m_occlusion_points; } const Point2f& getCentre() const { return m_centre; } // void makeit(BSPNode *root, const Point2f& p, const QtRegion& region, double startangle = 0.0, double endangle = 0.0); void make(BSPNode *here); void drawnode(const Line& li, int tag); void addBlock(const Line& li, int tag, double startangle, double endangle); void setData(AttributeTable &table, AttributeRow &row, bool simple_version); // int getClosestLine(BSPNode *root, const Point2f& p); }; ================================================ FILE: salalib/isovistdef.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" class IsovistDefinition { public: IsovistDefinition( double x, double y, double angle, double viewAngle ) : mLocation(x, y), mAngle(angle), mViewAngle(viewAngle) { if ( viewAngle >= 2 * M_PI) { mAngle = 0.0; mViewAngle = 0.0; } } IsovistDefinition(double x, double y) : mLocation(x,y), mAngle(0), mViewAngle(0) {} const Point2f &getLocation() const { return mLocation;} double getAngle() const { return mAngle; } double getViewAngle() const { return mViewAngle; } double getLeftAngle() const { double leftAngle = mAngle - 0.5 * mViewAngle; if (leftAngle < 0 ) { leftAngle += 2 * M_PI; } return leftAngle; } double getRightAngle() const{ double rightAngle = mAngle + 0.5 * mViewAngle; if (rightAngle > 2 * M_PI) { rightAngle -= 2 * M_PI; } return rightAngle; } private: Point2f mLocation; double mAngle; double mViewAngle; }; ================================================ FILE: salalib/ivga.h ================================================ // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Interface to handle different kinds of VGA analysis #include "salalib/mgraph.h" #include "salalib/pointdata.h" #include "genlib/comm.h" #include class IVGA { public: virtual std::string getAnalysisName() const = 0; virtual bool run(Communicator *comm, PointMap &map, bool simple_version) = 0; virtual ~IVGA() {} }; ================================================ FILE: salalib/layermanager.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include #include class LayerManager { public: typedef int64_t KeyType; virtual size_t addLayer(const std::string &layerName) = 0; virtual const std::string& getLayerName(size_t index) const = 0; virtual size_t getLayerIndex(const std::string &layerName) const = 0; virtual void setLayerVisible( size_t layerIndex, bool visible = true ) = 0; virtual bool isLayerVisible( size_t layerIndex ) const = 0; virtual size_t getNumLayers() const = 0; virtual KeyType getKey(size_t layerIndex) const = 0; virtual bool isVisible( const KeyType &key ) const = 0; virtual void read(std::istream& stream) = 0; virtual void write(std::ostream& stream) const = 0; virtual ~LayerManager(){} public: class OutOfLayersException : depthmapX::BaseException { public: OutOfLayersException() {} OutOfLayersException(const std::string &message) : depthmapX::BaseException(message.c_str()) { } }; class DuplicateKeyException : depthmapX::BaseException { public: DuplicateKeyException() {} DuplicateKeyException(const std::string &message) : depthmapX::BaseException(message.c_str()) { } }; }; class LayerAware { public: virtual void setLayerKey( const LayerManager::KeyType & key) { m_layerKey = key; } virtual const LayerManager::KeyType& getLayerKey() const { return m_layerKey; } virtual ~LayerAware(){} protected: LayerManager::KeyType m_layerKey; }; inline bool isObjectVisible(const LayerManager& manager, const LayerAware& object ) { return manager.isVisible(object.getLayerKey()); } inline void addLayerToObject(LayerAware& object, const LayerManager::KeyType& layerKey) { object.setLayerKey(object.getLayerKey() | layerKey); } ================================================ FILE: salalib/layermanagerimpl.cpp ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "layermanagerimpl.h" #include LayerManagerImpl::LayerManagerImpl() : m_visibleLayers(1) { m_layers.push_back("Everything"); m_layerLookup["Everything"] = 0; } size_t LayerManagerImpl::addLayer(const std::string &layerName) { size_t newLayerIndex = m_layers.size(); if (newLayerIndex > 63) { throw OutOfLayersException(); } auto result = m_layerLookup.insert(std::make_pair(layerName, newLayerIndex)); if (!result.second) { throw DuplicateKeyException(std::string("Trying to insert duplicate key: ") + layerName); } m_layers.push_back(layerName); return newLayerIndex; } const std::string& LayerManagerImpl::getLayerName(size_t index) const { checkIndex(index); return m_layers[index]; } size_t LayerManagerImpl::getLayerIndex(const std::string &layerName) const { auto iter = m_layerLookup.find(layerName); if ( iter == m_layerLookup.end()) { throw std::out_of_range("Unknown layer name"); } return iter->second; } void LayerManagerImpl::setLayerVisible(size_t layerIndex, bool visible) { checkIndex(layerIndex); if (layerIndex == 0) { // this it the everything layer - if switching on just show everything, else switch everything off m_visibleLayers = visible ? 1 : 0; return; } int64_t layerValue = ((KeyType)1) << layerIndex; // if visible, switch on this layer and switch everything layer off, else just switch off this layer if (visible) { m_visibleLayers = (m_visibleLayers | layerValue) & (~0x1); } else { m_visibleLayers &= (~layerValue); } } bool LayerManagerImpl::isLayerVisible(size_t layerIndex) const { checkIndex(layerIndex); return isVisible(getKey(layerIndex)); } bool LayerManagerImpl::isVisible(const KeyType &key) const { return (m_visibleLayers & key) != 0; } void LayerManagerImpl::read(std::istream &stream) { m_layerLookup.clear(); m_layers.clear(); KeyType dummy; stream.read((char *)&dummy, sizeof(dummy)); stream.read((char *)&m_visibleLayers, sizeof(m_visibleLayers)); int count; stream.read((char *)&count, sizeof(int)); for( int i = 0; i < count; ++i) { stream.read((char *)&dummy, sizeof(dummy)); m_layers.push_back(dXstring::readString(stream)); m_layerLookup[m_layers.back()] = i; } } void LayerManagerImpl::write(std::ostream &stream) const { // KeyType availableLayers = 0; // for (size_t i = m_layers.size(); i < 64; ++i) // { // availableLayers |= ((KeyType)1) << i; // } // TODO: (PK) While the above seems to me like the sane solution and potentially // what the intention was in the original implementation, the one in the old // attributes table seems to be messed up because of its starting value. // Therefore, for temporary binary compatibility at least until the new // attributes table is in place the original solution is used here as found // in AttributeTable::selectionToLayer(): int64_t availableLayers = 0xffffffff << (32 + 0xfffffffe); // should have been: // int64_t availableLayers = (int64_t(0xffffffff) << 32) + 0xfffffffe; for (size_t i = 1; i < 64 & i < m_layers.size(); ++i) { int loc = 1; while (loc < 64 && ((availableLayers>>loc) & 0x1) == 0) { loc++; } if (loc == 64) { // too many layers -- maximum 64 throw OutOfLayersException(); } int64_t newlayer = 0x1 << loc; // now layer has been found, eliminate from available layers // and add a lookup for the name availableLayers = (availableLayers & (~newlayer)); } stream.write((const char *)&availableLayers, sizeof(KeyType)); stream.write((const char *)&m_visibleLayers, sizeof(KeyType)); int size_as_int = (int)m_layers.size(); stream.write((const char *)&size_as_int, sizeof(int)); availableLayers = 0xffffffff << (32 + 0xfffffffe); int64_t newlayer = 0x1; stream.write((const char *)&newlayer, sizeof(KeyType)); dXstring::writeString(stream, m_layers[0]); for ( size_t i = 1; i < m_layers.size(); ++i) { // again keeping binary comatibility // KeyType key = ((KeyType)1) << i; // stream.write((const char *)&key, sizeof(KeyType)); // dXstring::writeString(stream,m_layers[i]); int loc = 1; while (loc < 64 && ((availableLayers>>loc) & 0x1) == 0) { loc++; } if (loc == 64) { // too many layers -- maximum 64 throw OutOfLayersException(); } newlayer = 0x1 << loc; stream.write((const char *)&newlayer, sizeof(KeyType)); dXstring::writeString(stream, m_layers[i]); } } LayerManager::KeyType LayerManagerImpl::getKey(size_t layerIndex) const { return ((int64_t)1) << layerIndex; } void LayerManagerImpl::checkIndex(size_t index) const { if(index >= m_layers.size()) { throw std::out_of_range("Invalid layer index"); } } ================================================ FILE: salalib/layermanagerimpl.h ================================================ // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "layermanager.h" #include #include class LayerManagerImpl : public LayerManager { // LayerManager interface public: LayerManagerImpl(); virtual size_t addLayer(const std::string &layerName); virtual const std::string& getLayerName(size_t index) const; virtual size_t getLayerIndex(const std::string &layerName) const; virtual void setLayerVisible(size_t layerIndex, bool visible); virtual bool isLayerVisible(size_t layerIndex) const; virtual size_t getNumLayers() const {return m_layers.size();} virtual KeyType getKey(size_t layerIndex) const; virtual bool isVisible(const KeyType &key) const; virtual void read(std::istream& stream); virtual void write(std::ostream& stream ) const; private: void checkIndex(size_t index) const; private: int64_t m_visibleLayers; std::vector m_layers; std::map m_layerLookup; }; ================================================ FILE: salalib/linkutils.cpp ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "linkutils.h" #include namespace depthmapX { std::vector pixelateMergeLines(const std::vector& mergeLines, PointMap& currentMap) { std::vector mergePixelPairs; std::vector::const_iterator iter = mergeLines.begin(), end = mergeLines.end(); for ( ; iter != end; ++iter ) { const Line & mergeLine = *iter; const PixelRef & a = currentMap.pixelate(mergeLine.start(), false); const PixelRef & b = currentMap.pixelate(mergeLine.end(), false); mergePixelPairs.push_back(PixelRefPair(a, b)); } return mergePixelPairs; } void mergePixelPairs(const std::vector& links, PointMap& currentMap) { // check if any link pixel already exists on the map std::vector::const_iterator iter = links.begin(), end = links.end(); for ( ; iter != end; ++iter ) { const PixelRefPair link = *iter; // check in limits: if (!currentMap.includes(link.a) || !currentMap.getPoint(link.a).filled() || !currentMap.includes(link.b) || !currentMap.getPoint(link.b).filled()) { std::stringstream message; message << "Line ends not both on painted analysis space (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } // check if we were given coordinates that fall on a previously // merged cell, in which case the newest given will replace the // oldest and effectively delete the whole link if(currentMap.isPixelMerged(link.a) || currentMap.isPixelMerged(link.b)) { // one of the cells is already on the map std::stringstream message; message << "Link pixel found that is already linked on the map (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } // also check if given links have overlapping pixels: std::vector::const_iterator prevIter = links.begin(); for ( ; prevIter != iter; ++prevIter ) { const PixelRefPair prevLink = *prevIter; // PixelRefPair internal == operator only checks a with a and b with b // but we also need to check the inverse if(link.a == prevLink.a || link.b == prevLink.b || link.a == prevLink.b || link.b == prevLink.a) { // one of the cells has already been seen. std::stringstream message; message << "Overlapping link found (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } } } std::for_each(links.begin(), links.end(), [&](const PixelRefPair &pair)->void{ currentMap.mergePixels(pair.a,pair.b); }); } void unmergePixelPairs(const std::vector& links, PointMap& currentMap) { // check if any link pixel exists on the map std::vector::const_iterator iter = links.begin(), end = links.end(); for ( ; iter != end; ++iter ) { const PixelRefPair link = *iter; // check in limits: if (!currentMap.includes(link.a) || !currentMap.getPoint(link.a).filled() || !currentMap.includes(link.b) || !currentMap.getPoint(link.b).filled()) { std::stringstream message; message << "Line ends not both on painted analysis space (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } // check if we were given coordinates that fall on a previously // merged cell, in which case the newest given will replace the // oldest and effectively delete the whole link // check if the two pixels are actually merged to each other if(!currentMap.isPixelMerged(link.a) || !currentMap.isPixelMerged(link.b)) { // one of the cells is already on the map std::stringstream message; message << "Link pixel pair found that is not linked on the map (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } // also check if given links have overlapping pixels: std::vector::const_iterator prevIter = links.begin(); for ( ; prevIter != iter; ++prevIter ) { const PixelRefPair prevLink = *prevIter; // PixelRefPair internal == operator only checks a with a and b with b // but we also need to check the inverse if(link.a == prevLink.a || link.b == prevLink.b || link.a == prevLink.b || link.b == prevLink.a) { // one of the cells has already been seen. std::stringstream message; message << "Overlapping link found (index: " << (iter - links.begin() + 1) << ")" << std::flush; throw depthmapX::InvalidLinkException(message.str().c_str()); } } } std::for_each(links.begin(), links.end(), [&](const PixelRefPair &pair)->void{ currentMap.unmergePixel(pair.a); }); } std::vector getMergedPixelsAsLines(PointMap& currentMap) { std::vector mergedPixelsAsLines; std::vector> mergedPixelPairs = currentMap.getMergedPixelPairs(); std::vector>::const_iterator iter = mergedPixelPairs.begin(), end = mergedPixelPairs.end(); for ( ; iter != end; ++iter ) { std::pair pixelPair = *iter; mergedPixelsAsLines.push_back(SimpleLine( currentMap.depixelate(pixelPair.first), currentMap.depixelate(pixelPair.second) )); } return mergedPixelsAsLines; } } ================================================ FILE: salalib/linkutils.h ================================================ // Copyright (C) 2017 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "mgraph.h" #include "genlib/exceptions.h" #include namespace depthmapX { class InvalidLinkException : public depthmapX::BaseException { public: InvalidLinkException(std::string message) : depthmapX::BaseException(message) {} }; std::vector pixelateMergeLines(const std::vector& mergeLines, PointMap& currentMap); void mergePixelPairs(const std::vector &links, PointMap& currentMap); void unmergePixelPairs(const std::vector &links, PointMap& currentMap); std::vector getMergedPixelsAsLines(PointMap& currentMap); } ================================================ FILE: salalib/mapconverter.cpp ================================================ #include "salalib/mapconverter.h" #include "salalib/tidylines.h" #include "genlib/exceptions.h" #include // convert line layers to an axial map std::unique_ptr MapConverter::convertDrawingToAxial(Communicator *comm, const std::string& name, const std::vector &drawingFiles) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 2 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } QtRegion region; std::map> lines; // map required for tidy lines, otherwise acts like vector // this is used to say which layer it originated from bool recordlayer = false; // add all visible layers to the set of polygon lines... int count = 0; for (const auto& pixelGroup: drawingFiles) { int j = 0; for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { if (region.atZero()) { region = pixel.getRegion(); } else { region = runion(region, pixel.getRegion()); } std::vector newLines = pixel.getAllShapesAsLines(); for (const auto& line: newLines) { lines.insert(std::make_pair(count, std::make_pair(Line(line.start(), line.end()), j))); count ++; } pixel.setShow(false); } if (j > 0) { recordlayer = true; } j++; } } if (count == 0) { // TODO: write a better error message throw depthmapX::RuntimeException("Failed to convert lines"); } // quick tidy removes very short and duplicate lines, but does not merge overlapping lines TidyLines tidier; tidier.quicktidy(lines, region); if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found after removing short and duplicates"); } if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); } // create map layer... // we can stop here for all line axial map! std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::AXIALMAP)); usermap->init(int(lines.size()),region); // used to be double density std::map layerAttributes; usermap->initialiseAttributesAxial(); int layerCol = -1; if (recordlayer) { layerCol = usermap->getAttributeTable().getOrInsertColumn("Drawing Layer"); } for (auto & line: lines) { if (recordlayer) { layerAttributes[layerCol] = float(line.second.second); } usermap->makeLineShape(line.second.first, false, false, layerAttributes ); } usermap->makeConnections(); return usermap; } // create axial map directly from data maps // note that actually should be able to merge this code with the line layers, now both use similar code std::unique_ptr MapConverter::convertDataToAxial(Communicator *comm, const std::string& name, ShapeMap& shapemap, bool copydata) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 2 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } // add all visible layers to the set of polygon lines... std::map> lines; //m_region = shapemap.getRegion(); QtRegion region = shapemap.getRegion(); // add all visible layers to the set of polygon lines... int count = 0; for (auto shape: shapemap.getAllShapes()) { int key = shape.first; std::vector shapeLines = shape.second.getAsLines(); for(Line line: shapeLines) { lines.insert(std::make_pair(count, std::make_pair(line, key))); count++; } } if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found in data map"); } // quick tidy removes very short and duplicate lines, but does not merge overlapping lines TidyLines tidier; tidier.quicktidy(lines, region); if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found after removing short and duplicates"); } if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); } // create map layer... // we can stop here for all line axial map! std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::AXIALMAP)); usermap->init(int(lines.size()),region); // used to be double density usermap->initialiseAttributesAxial(); usermap->getAttributeTable().insertOrResetColumn("Data Map Ref"); std::map extraAttr; std::map inOutColumns; if (copydata) { AttributeTable& input = shapemap.getAttributeTable(); AttributeTable& output = usermap->getAttributeTable(); // TODO: Compatibility. The columns are sorted in the old implementation so // they are also passed sorted in the conversion: std::vector indices(input.getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return input.getColumnName(a) < input.getColumnName(b); }); std::vector newColumns; for (size_t i = 0; i < indices.size(); i++) { int idx = indices[i]; std::string colname = input.getColumnName(idx); for (size_t k = 1; output.hasColumn(colname); k++){ colname = dXstring::formatString(int(k), input.getColumnName(idx) + " %d"); } newColumns.push_back(colname); output.insertOrResetColumn(colname); } for (size_t i = 0; i < indices.size(); i++) { inOutColumns[indices[i]] = output.getOrInsertColumn(newColumns[i]); } } int dataMapShapeRefCol = usermap->getAttributeTable().getOrInsertColumn("Data Map Ref"); AttributeTable& input = shapemap.getAttributeTable(); for (auto& line: lines) { if (copydata){ auto& row = input.getRow(AttributeKey(line.second.second)); for (auto inOutColumn: inOutColumns){ extraAttr[inOutColumn.second] = row.getValue(inOutColumn.first); } } extraAttr[dataMapShapeRefCol] = line.second.second; usermap->makeLineShape(line.second.first, false, false, extraAttr); } // n.b. make connections also initialises attributes usermap->makeConnections(); // if we are inheriting from a mapinfo map, pass on the coordsys and bounds: if (shapemap.hasMapInfoData()) { usermap->copyMapInfoBaseData(shapemap); } return usermap; } ///////////////////////////////////////////////////////////////////////////////////////////////// // yet more conversions, this time polygons to shape elements std::unique_ptr MapConverter::convertDrawingToConvex(Communicator *, const std::string& name, const std::vector &drawingFiles) { std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::CONVEXMAP)); int conn_col = usermap->getAttributeTable().insertOrResetLockedColumn("Connectivity"); size_t count = 0; for (const auto& pixelGroup: drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { auto refShapes = pixel.getAllShapes(); for (const auto& refShape: refShapes) { const SalaShape& shape = refShape.second; if (shape.isPolygon()) { int newShapeRef = usermap->makeShape(shape); usermap->getConnections().push_back( Connector() ); usermap->getAttributeTable().getRow(AttributeKey(newShapeRef)).setValue(conn_col,0); count++; } } } } } if (count == 0) { throw depthmapX::RuntimeException("No polygons found in drawing"); } for (const auto& pixelGroup: drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { pixel.setShow(false); } } return usermap; } std::unique_ptr MapConverter::convertDataToConvex(Communicator *, const std::string& name, ShapeMap& shapemap, bool copydata) { std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::CONVEXMAP)); int conn_col = usermap->getAttributeTable().insertOrResetLockedColumn("Connectivity"); std::vector lookup; auto refShapes = shapemap.getAllShapes(); std::map extraAttr; std::vector attrCols; AttributeTable& input = shapemap.getAttributeTable(); if (copydata) { AttributeTable& output = usermap->getAttributeTable(); for (size_t i = 0; i < input.getNumColumns(); i++) { std::string colname = input.getColumnName(i); for (int k = 1; static_cast(output.getColumnIndex(colname)) != -1; k++){ colname = dXstring::formatString(k,input.getColumnName(i) + " %d"); } attrCols.push_back(output.insertOrResetColumn(colname)); } } for (auto refShape: refShapes) { if ( copydata ){ for ( size_t i = 0; i < input.getNumColumns(); ++i ){ extraAttr[attrCols[size_t(i)]] = input.getRow(AttributeKey(refShape.first)).getValue(i); } } SalaShape& shape = refShape.second; if (shape.isPolygon()) { int n = usermap->makeShape(shape, -1, extraAttr); usermap->getConnections().push_back( Connector() ); usermap->getAttributeTable().getRow(AttributeKey(n)).setValue(conn_col,0); } } if (usermap->getShapeCount() == 0) { throw depthmapX::RuntimeException("No polygons found in data map"); } return usermap; } ///////////////////////////////////////////////////////////////////////////////////////////////// // create segment map directly from line layers std::unique_ptr MapConverter::convertDrawingToSegment(Communicator *comm, const std::string& name, const std::vector &drawingFiles) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 2 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } // second number in internal pair is used to say which layer it originated from std::map> lines; bool recordlayer = false; QtRegion region; // add all visible layers to the set of polygon lines... int count = 0; for (const auto& pixelGroup: drawingFiles) { int j = 0; for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { if (region.atZero()) { region = pixel.getRegion(); } else { region = runion(region, pixel.getRegion()); } std::vector newLines = pixel.getAllShapesAsLines(); for (const auto& line: newLines) { lines.insert(std::make_pair(count, std::make_pair(Line(line.start(), line.end()), j))); count++; } pixel.setShow(false); } if (j > 0) { recordlayer = true; } j++; } } if (count == 0) { throw depthmapX::RuntimeException("No lines found in drawing"); } // quick tidy removes very short and duplicate lines, but does not merge overlapping lines TidyLines tidier; tidier.quicktidy(lines, region); if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found after removing short and duplicates"); } if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); } // create map layer... // we can stop here for all line axial map! std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::SEGMENTMAP)); usermap->init(int(lines.size()),region); std::map layerAttributes; usermap->initialiseAttributesSegment(); int layerCol = -1; if (recordlayer) { layerCol = usermap->getAttributeTable().insertOrResetColumn("Drawing Layer"); } for (auto & line: lines) { if (recordlayer) { layerAttributes[layerCol] = float(line.second.second); } usermap->makeLineShape(line.second.first, false, false, layerAttributes); } // make it! usermap->makeNewSegMap(comm); return usermap; } // create segment map directly from data maps (ultimately, this will replace the line layers version) std::unique_ptr MapConverter::convertDataToSegment(Communicator *comm, const std::string& name, ShapeMap& shapemap, bool copydata) { if (comm) { comm->CommPostMessage( Communicator::NUM_STEPS, 2 ); comm->CommPostMessage( Communicator::CURRENT_STEP, 1 ); } std::map> lines; // no longer requires m_region //m_region = shapemap.getRegion(); QtRegion region = shapemap.getRegion(); // add all visible layers to the set of polygon lines... int count = 0; for (auto shape: shapemap.getAllShapes()) { int key = shape.first; std::vector shapeLines = shape.second.getAsLines(); for(Line line: shapeLines) { lines.insert(std::make_pair(count, std::make_pair(line, key))); count++; } } if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found in data map"); } // quick tidy removes very short and duplicate lines, but does not merge overlapping lines TidyLines tidier; tidier.quicktidy(lines, region); if (lines.size() == 0) { throw depthmapX::RuntimeException("No lines found after removing short and duplicates"); } if (comm) { comm->CommPostMessage( Communicator::CURRENT_STEP, 2 ); } // create map layer... // note, I may need to reuse this: std::unique_ptr usermap(new ShapeGraph(name,ShapeMap::SEGMENTMAP)); // if we are inheriting from a mapinfo map, pass on the coordsys and bounds: if (shapemap.hasMapInfoData()) { usermap->copyMapInfoBaseData(shapemap); } usermap->init(int(lines.size()),region); usermap->initialiseAttributesSegment(); usermap->getAttributeTable().insertOrResetColumn("Data Map Ref"); std::map extraAttr; std::map inOutColumns; if (copydata) { AttributeTable& input = shapemap.getAttributeTable(); AttributeTable& output = usermap->getAttributeTable(); // TODO: Compatibility. The columns are sorted in the old implementation so // they are also passed sorted in the conversion: std::vector indices(input.getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return input.getColumnName(a) < input.getColumnName(b); }); std::vector newColumns; for (size_t i = 0; i < indices.size(); i++) { int idx = indices[i]; std::string colname = input.getColumnName(idx); for (size_t k = 1; output.hasColumn(colname); k++){ colname = dXstring::formatString(int(k), input.getColumnName(idx) + " %d"); } newColumns.push_back(colname); output.insertOrResetColumn(colname); } for (size_t i = 0; i < indices.size(); i++) { inOutColumns[indices[i]] = output.getOrInsertColumn(newColumns[i]); } } int dataMapShapeRefCol = usermap->getAttributeTable().getOrInsertColumn("Data Map Ref"); AttributeTable& input = shapemap.getAttributeTable(); for (auto& line: lines) { if (copydata){ auto& row = input.getRow(AttributeKey(line.second.second)); for (auto inOutColumn: inOutColumns){ extraAttr[inOutColumn.second] = row.getValue(inOutColumn.first); } } extraAttr[dataMapShapeRefCol] = line.second.second; usermap->makeLineShape(line.second.first, false, false, extraAttr); } // start to be a little bit more efficient about memory now we are hitting the limits // from time to time: if (!copydata) { lines.clear(); } // make it! usermap->makeNewSegMap(comm); return usermap; } // stubremoval is fraction of overhanging line length before axial "stub" is removed std::unique_ptr MapConverter::convertAxialToSegment(Communicator *, ShapeGraph& axialMap, const std::string& name, bool keeporiginal, bool copydata, double stubremoval) { std::vector lines; std::vector connectionset; axialMap.makeSegmentMap(lines, connectionset, stubremoval); // destroy unnecessary parts of axial map as quickly as possible in order not to overload memory if (!keeporiginal) { axialMap.getAllShapes().clear(); axialMap.getConnections().clear(); } // create map layer... std::unique_ptr segmap(new ShapeGraph(name,ShapeMap::SEGMENTMAP)); segmap->init(int(lines.size()),axialMap.getRegion()); segmap->initialiseAttributesSegment(); for (size_t k = 0; k < lines.size(); k++) { segmap->makeLineShape(lines[k]); } // clear data as soon as we do not need it: lines.clear(); // if we are inheriting from a mapinfo map, pass on the coordsys and bounds: if (axialMap.hasMapInfoData()) { segmap->copyMapInfoBaseData(axialMap); } segmap->makeSegmentConnections(connectionset); if (copydata) { segmap->pushAxialValues(axialMap); } // destroy unnecessary parts of axial map as quickly as possible in order not to overload memory if (!keeporiginal) { axialMap.getAttributeTable().clear(); } return segmap; } ================================================ FILE: salalib/mapconverter.h ================================================ #pragma once #include "salalib/axialmap.h" #include "salalib/shapemap.h" #include "salalib/spacepixfile.h" #include "genlib/comm.h" namespace MapConverter { std::unique_ptr convertDrawingToAxial(Communicator *comm, const std::string& name, const std::vector &drawingFiles); std::unique_ptr convertDataToAxial(Communicator *comm, const std::string& name, ShapeMap& shapemap, bool copydata = false); std::unique_ptr convertDrawingToConvex(Communicator *, const std::string& name, const std::vector &drawingFiles); std::unique_ptr convertDataToConvex(Communicator *, const std::string& name, ShapeMap& shapemap, bool copydata = false); std::unique_ptr convertDrawingToSegment(Communicator *comm, const std::string& name, const std::vector &drawingFiles); std::unique_ptr convertDataToSegment(Communicator *comm, const std::string& name, ShapeMap& shapemap, bool copydata = false); std::unique_ptr convertAxialToSegment(Communicator *, ShapeGraph& axialMap, const std::string& name, bool keeporiginal = true, bool pushvalues = false, double stubremoval = 0.0); } ================================================ FILE: salalib/mgraph.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // The meta graph #include "salalib/alllinemap.h" #include "salalib/mapconverter.h" #include "salalib/isovist.h" #include "salalib/mgraph.h" #include "salalib/importutils.h" #include "salalib/parsers/ntfp.h" #include "salalib/parsers/tigerp.h" #include "salalib/parsers/dxfp.h" #include "salalib/segmmodules/segmangular.h" #include "salalib/segmmodules/segmtulip.h" #include "salalib/segmmodules/segmtulipdepth.h" #include "salalib/segmmodules/segmmetric.h" #include "salalib/segmmodules/segmmetricpd.h" #include "salalib/segmmodules/segmtopological.h" #include "salalib/segmmodules/segmtopologicalpd.h" #include "salalib/axialmodules/axialintegration.h" #include "salalib/axialmodules/axialstepdepth.h" #include "salalib/vgamodules/vgaisovist.h" #include "salalib/vgamodules/vgavisualglobal.h" #include "salalib/vgamodules/vgavisualglobaldepth.h" #include "salalib/vgamodules/vgavisuallocal.h" #include "salalib/vgamodules/vgametric.h" #include "salalib/vgamodules/vgametricdepth.h" #include "salalib/vgamodules/vgaangular.h" #include "salalib/vgamodules/vgaangulardepth.h" #include "salalib/vgamodules/vgathroughvision.h" #include "salalib/agents/agenthelpers.h" #include "mgraph440/mgraph.h" #include "genlib/pafmath.h" #include "genlib/p2dpoly.h" #include "genlib/comm.h" #include "math.h" #include "time.h" #include #include MetaGraph::MetaGraph(std::string name) { m_name = name; m_state = 0; m_view_class = VIEWNONE; m_file_version = -1; // <- if unsaved, file version is -1 // whether or not showing text / grid saved with file: m_showtext = false; m_showgrid = false; // bsp tree for making isovists: m_bsp_tree = false; m_bsp_root = NULL; } MetaGraph::~MetaGraph() { if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_bsp_tree = false; } QtRegion MetaGraph::getBoundingBox() const { QtRegion bounds = m_region; if (bounds.atZero() && ((getState() & MetaGraph::SHAPEGRAPHS) == MetaGraph::SHAPEGRAPHS)) { bounds = getDisplayedShapeGraph().getRegion(); } if (bounds.atZero() && ((getState() & MetaGraph::DATAMAPS) == MetaGraph::DATAMAPS)) { bounds = getDisplayedDataMap().getRegion(); } return bounds; } bool MetaGraph::setViewClass(int command) { if (command < 0x10) { throw ("Use with a show command, not a view class type"); } if ((command & (SHOWHIDEVGA | SHOWVGATOP)) && (~m_state & POINTMAPS)) return false; if ((command & (SHOWHIDEAXIAL | SHOWAXIALTOP)) && (~m_state & SHAPEGRAPHS)) return false; if ((command & (SHOWHIDESHAPE | SHOWSHAPETOP)) && (~m_state & DATAMAPS)) return false; switch (command) { case SHOWHIDEVGA: if (m_view_class & (VIEWVGA | VIEWBACKVGA)) { m_view_class &= ~(VIEWVGA | VIEWBACKVGA); if (m_view_class & VIEWBACKAXIAL) { m_view_class ^= (VIEWAXIAL | VIEWBACKAXIAL); } else if (m_view_class & VIEWBACKDATA) { m_view_class ^= (VIEWDATA | VIEWBACKDATA); } } else if (m_view_class & (VIEWAXIAL | VIEWDATA)) { m_view_class &= ~(VIEWBACKAXIAL | VIEWBACKDATA); m_view_class |= VIEWBACKVGA; } else { m_view_class |= VIEWVGA; } break; case SHOWHIDEAXIAL: if (m_view_class & (VIEWAXIAL | VIEWBACKAXIAL)) { m_view_class &= ~(VIEWAXIAL | VIEWBACKAXIAL); if (m_view_class & VIEWBACKVGA) { m_view_class ^= (VIEWVGA | VIEWBACKVGA); } else if (m_view_class & VIEWBACKDATA) { m_view_class ^= (VIEWDATA | VIEWBACKDATA); } } else if (m_view_class & (VIEWVGA | VIEWDATA)) { m_view_class &= ~(VIEWBACKVGA | VIEWBACKDATA); m_view_class |= VIEWBACKAXIAL; } else { m_view_class |= VIEWAXIAL; } break; case SHOWHIDESHAPE: if (m_view_class & (VIEWDATA | VIEWBACKDATA)) { m_view_class &= ~(VIEWDATA | VIEWBACKDATA); if (m_view_class & VIEWBACKVGA) { m_view_class ^= (VIEWVGA | VIEWBACKVGA); } else if (m_view_class & VIEWBACKAXIAL) { m_view_class ^= (VIEWAXIAL | VIEWBACKAXIAL); } } else if (m_view_class & (VIEWVGA | VIEWAXIAL)) { m_view_class &= ~(VIEWBACKVGA | VIEWBACKAXIAL); m_view_class |= VIEWBACKDATA; } else { m_view_class |= VIEWDATA; } break; case SHOWVGATOP: if (m_view_class & VIEWAXIAL) { m_view_class = VIEWBACKAXIAL | VIEWVGA; } else if (m_view_class & VIEWDATA) { m_view_class = VIEWBACKDATA | VIEWVGA; } else { m_view_class = VIEWVGA | (m_view_class & (VIEWBACKAXIAL | VIEWBACKDATA)); } break; case SHOWAXIALTOP: if (m_view_class & VIEWVGA) { m_view_class = VIEWBACKVGA | VIEWAXIAL; } else if (m_view_class & VIEWDATA) { m_view_class = VIEWBACKDATA | VIEWAXIAL; } else { m_view_class = VIEWAXIAL | (m_view_class & (VIEWBACKVGA | VIEWBACKDATA)); } break; case SHOWSHAPETOP: if (m_view_class & VIEWVGA) { m_view_class = VIEWBACKVGA | VIEWDATA; } else if (m_view_class & VIEWAXIAL) { m_view_class = VIEWBACKAXIAL | VIEWDATA; } else { m_view_class = VIEWDATA | (m_view_class & (VIEWBACKVGA | VIEWBACKAXIAL)); } break; } return true; } double MetaGraph::getLocationValue(const Point2f& point) { // this varies according to whether axial or vga information is displayed on top double val = -2; if (viewingProcessedPoints()) { val = getDisplayedPointMap().getLocationValue(point); } else if (viewingProcessedLines()) { val = getDisplayedShapeGraph().getLocationValue(point); } else if (viewingProcessedShapes()) { val = getDisplayedDataMap().getLocationValue(point); } return val; } bool MetaGraph::setGrid( double spacing, const Point2f& offset ) { m_state &= ~POINTMAPS; getDisplayedPointMap().setGrid( spacing, offset ); m_state |= POINTMAPS; // just reassert that we should be viewing this (since set grid is essentially a "new point map") setViewClass(SHOWVGATOP); return true; } // AV TV // semifilled bool MetaGraph::makePoints( const Point2f& p, int fill_type , Communicator *communicator ) { // m_state &= ~POINTS; try { getDisplayedPointMap().makePoints( p, fill_type, communicator ); } catch (Communicator::CancelledException) { // By this stage points almost certainly exist, // To avoid problems, just say points exist: m_state |= POINTMAPS; return false; } // m_state |= POINTS; return true; } bool MetaGraph::clearPoints() { bool b_return = getDisplayedPointMap().clearPoints(); return b_return; } bool MetaGraph::makeGraph( Communicator *communicator, int algorithm, double maxdist ) { // this is essentially a version tag, and remains for historical reasons: m_state |= ANGULARGRAPH; bool graphMade = false; try { // algorithm is now used for boundary graph option (as a simple boolean) graphMade = getDisplayedPointMap().sparkGraph2(communicator, (algorithm != 0), maxdist); } catch (Communicator::CancelledException) { graphMade = false; } if (graphMade) { setViewClass(SHOWVGATOP); } return graphMade; } bool MetaGraph::unmakeGraph(bool removeLinks) { bool graphUnmade = getDisplayedPointMap().unmake(removeLinks); if (graphUnmade) { setViewClass(SHOWVGATOP); } return graphUnmade; } bool MetaGraph::analyseGraph( Communicator *communicator, Options options , bool simple_version ) // <- options copied to keep thread safe { bool analysisCompleted = false; if (options.point_depth_selection) { if (m_view_class & VIEWVGA && !getDisplayedPointMap().isSelected()) { return false; } else if (m_view_class & VIEWAXIAL && !getDisplayedShapeGraph().hasSelectedElements()) { return false; } } try { analysisCompleted = true; if (options.point_depth_selection == 1) { if (m_view_class & VIEWVGA) { analysisCompleted = VGAVisualGlobalDepth().run(communicator, getDisplayedPointMap(), false); } else if (m_view_class & VIEWAXIAL) { if (!getDisplayedShapeGraph().isSegmentMap()) { analysisCompleted = AxialStepDepth().run(communicator, getDisplayedShapeGraph(), false); } else { analysisCompleted = SegmentTulipDepth().run(communicator, getDisplayedShapeGraph(), false); } } // REPLACES: // Graph::calculate_point_depth_matrix( communicator ); } else if (options.point_depth_selection == 2) { if (m_view_class & VIEWVGA) { analysisCompleted = VGAMetricDepth().run(communicator, getDisplayedPointMap(), false); } else if (m_view_class & VIEWAXIAL && getDisplayedShapeGraph().isSegmentMap()) { analysisCompleted = SegmentMetricPD().run(communicator, getDisplayedShapeGraph(), false); } } else if (options.point_depth_selection == 3) { analysisCompleted = VGAAngularDepth().run(communicator, getDisplayedPointMap(), false); } else if (options.point_depth_selection == 4) { if (m_view_class & VIEWVGA) { getDisplayedPointMap().binDisplay( communicator ); } else if (m_view_class & VIEWAXIAL && getDisplayedShapeGraph().isSegmentMap()) { analysisCompleted = SegmentTopologicalPD().run(communicator, getDisplayedShapeGraph(), false); } } else if (options.output_type == Options::OUTPUT_ISOVIST) { analysisCompleted = VGAIsovist().run(communicator, getDisplayedPointMap(), simple_version); } else if (options.output_type == Options::OUTPUT_VISUAL) { bool localResult = true; bool globalResult = true; if (options.local) { localResult = VGAVisualLocal(options.gates_only).run(communicator, getDisplayedPointMap(), simple_version); } if (options.global) { globalResult = VGAVisualGlobal(options.radius, options.gates_only).run(communicator, getDisplayedPointMap(), simple_version); } analysisCompleted = globalResult & localResult; } else if (options.output_type == Options::OUTPUT_METRIC) { analysisCompleted = VGAMetric(options.radius, options.gates_only).run(communicator, getDisplayedPointMap(), simple_version); } else if (options.output_type == Options::OUTPUT_ANGULAR) { analysisCompleted = VGAAngular(options.radius, options.gates_only).run(communicator, getDisplayedPointMap(), simple_version); } else if (options.output_type == Options::OUTPUT_THRU_VISION) { analysisCompleted = VGAThroughVision().run(communicator, getDisplayedPointMap(), simple_version); } } catch (Communicator::CancelledException) { analysisCompleted = false; } return analysisCompleted; } ////////////////////////////////////////////////////////////////// bool MetaGraph::isEditableMap() { if (m_view_class & VIEWAXIAL) { return getDisplayedShapeGraph().isEditable(); } else if (m_view_class & VIEWDATA) { return getDisplayedDataMap().isEditable(); } // still to do: allow editing of drawing layers return false; } ShapeMap& MetaGraph::getEditableMap() { ShapeMap *map = NULL; if (m_view_class & VIEWAXIAL) { map = &(getDisplayedShapeGraph()); } else if (m_view_class & VIEWDATA) { map = &(getDisplayedDataMap()); } else { // still to do: allow editing of drawing layers } if (map == NULL || !map->isEditable()) { throw 0; } return *map; } bool MetaGraph::makeShape(const Line& line) { if (!isEditableMap()) { return false; } ShapeMap& map = getEditableMap(); return (map.makeLineShape(line,true) != -1); } int MetaGraph::polyBegin(const Line& line) { if (!isEditableMap()) { return -1; } ShapeMap& map = getEditableMap(); return map.polyBegin(line); } bool MetaGraph::polyAppend(int shape_ref, const Point2f& point) { if (!isEditableMap()) { return false; } ShapeMap& map = getEditableMap(); return map.polyAppend(shape_ref, point); } bool MetaGraph::polyClose(int shape_ref) { if (!isEditableMap()) { return false; } ShapeMap& map = getEditableMap(); return map.polyClose(shape_ref); } bool MetaGraph::polyCancel(int shape_ref) { if (!isEditableMap()) { return false; } ShapeMap& map = getEditableMap(); return map.polyCancel(shape_ref); } bool MetaGraph::moveSelShape(const Line& line) { bool shapeMoved = false; if (m_view_class & VIEWAXIAL) { ShapeGraph& map = getDisplayedShapeGraph(); if (!map.isEditable()) { return false; } if (map.getSelCount() > 1) { return false; } int rowid = *map.getSelSet().begin(); shapeMoved = map.moveShape(rowid,line); if (shapeMoved) { map.clearSel(); } } else if (m_view_class & VIEWDATA) { ShapeMap& map = getDisplayedDataMap(); if (!map.isEditable()) { return false; } if (map.getSelCount() > 1) { return false; } int rowid = *map.getSelSet().begin(); shapeMoved = map.moveShape(rowid, line); if (shapeMoved) { map.clearSel(); } } return shapeMoved; } ////////////////////////////////////////////////////////////////// // returns 0: fail, 1: made isovist, 2: made isovist and added new shapemap layer int MetaGraph::makeIsovist(Communicator *communicator, const Point2f& p, double startangle, double endangle, bool simple_version) { int isovistMade = 0; // first make isovist Isovist iso; if (makeBSPtree(communicator)) { m_view_class &= ~VIEWDATA; isovistMade = 1; iso.makeit(m_bsp_root, p, m_region, startangle, endangle); int shapelayer = getMapRef(m_dataMaps, "Isovists"); if (shapelayer == -1) { m_dataMaps.emplace_back("Isovists",ShapeMap::DATAMAP); setDisplayedDataMapRef(m_dataMaps.size() - 1); shapelayer = m_dataMaps.size() - 1; m_state |= DATAMAPS; isovistMade = 2; } ShapeMap& map = m_dataMaps[shapelayer]; // false: closed polygon, true: isovist int polyref = map.makePolyShape(iso.getPolygon(),false); map.getAllShapes()[polyref].setCentroid(p); map.overrideDisplayedAttribute(-2); map.setDisplayedAttribute(-1); setViewClass(SHOWSHAPETOP); AttributeTable& table = map.getAttributeTable(); AttributeRow& row = table.getRow(AttributeKey(polyref)); iso.setData(table,row, simple_version); } return isovistMade; } static std::pair startendangle( Point2f vec, double fov) { std::pair angles; // n.b. you must normalise this before getting the angle! vec.normalise(); angles.first = vec.angle() - fov / 2.0; angles.second = vec.angle() + fov / 2.0; if (angles.first < 0.0) angles.first += 2.0 * M_PI; if (angles.second > 2.0 * M_PI) angles.second -= 2.0 * M_PI; return angles; } // returns 0: fail, 1: made isovist, 2: made isovist and added new shapemap layer int MetaGraph::makeIsovistPath(Communicator *communicator, double fov, bool simple_version) { int pathMade = 0; // must be showing a suitable map -- that is, one which may have polylines or lines ShapeMap *map = NULL, *isovists = NULL; int isovistmapref = -1; int viewclass = getViewClass() & VIEWFRONT; if (viewclass == VIEWAXIAL) { map = &getDisplayedShapeGraph(); } else if (viewclass == VIEWDATA) { map = &getDisplayedDataMap(); } else { return 0; } // must have a selection: the selected shapes will form the set from which to create the isovist paths if (!map->hasSelectedElements()) { return 0; } bool first = true; if (makeBSPtree(communicator)) { std::set selset = map->getSelSet(); std::map& shapes = map->getAllShapes(); for (auto& shapeRef: selset) { const SalaShape& path = shapes.at(shapeRef); if (path.isLine() || path.isPolyLine()) { if (first) { pathMade = 1; isovistmapref = getMapRef(m_dataMaps, "Isovists"); if (isovistmapref == -1) { m_dataMaps.emplace_back("Isovists",ShapeMap::DATAMAP); isovistmapref = m_dataMaps.size() - 1; setDisplayedDataMapRef(isovistmapref); pathMade = 2; } isovists = &(m_dataMaps[isovistmapref]); first = false; } // now make an isovist: Isovist iso; // std::pair angles; angles.first = 0.0; angles.second = 0.0; // if (path.isLine()) { Point2f start = path.getLine().t_start(); Point2f vec = path.getLine().vector(); if (fov < 2.0 * M_PI) { angles = startendangle(vec, fov); } iso.makeit(m_bsp_root, start, m_region, angles.first, angles.second); int polyref = isovists->makePolyShape(iso.getPolygon(),false); isovists->getAllShapes()[polyref].setCentroid(start); AttributeTable& table = isovists->getAttributeTable(); AttributeRow& row = table.getRow(AttributeKey(polyref)); iso.setData(table,row, simple_version); } else { for (size_t i = 0; i < path.m_points.size() - 1; i++) { Line li = Line(path.m_points[i],path.m_points[i+1]); Point2f start = li.t_start(); Point2f vec = li.vector(); if (fov < 2.0 * M_PI) { angles = startendangle(vec, fov); } iso.makeit(m_bsp_root, start, m_region, angles.first, angles.second); int polyref = isovists->makePolyShape(iso.getPolygon(),false); isovists->getAllShapes().find(polyref)->second.setCentroid(start); AttributeTable& table = isovists->getAttributeTable(); AttributeRow& row = table.getRow(AttributeKey(polyref)); iso.setData(table,row, simple_version); } } } } if (isovists) { isovists->overrideDisplayedAttribute(-2); isovists->setDisplayedAttribute(-1); setDisplayedDataMapRef(isovistmapref); } } return pathMade; } // this version uses your own isovist (and assumes no communicator required for BSP tree bool MetaGraph::makeIsovist(const Point2f& p, Isovist& iso) { if (makeBSPtree()) { iso.makeit(m_bsp_root, p, m_region); return true; } return false; } bool MetaGraph::makeBSPtree(Communicator *communicator) { if (m_bsp_tree) { return true; } std::vector partitionlines; for (const auto& pixelGroup: m_drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { // chooses the first editable layer it can find: if (pixel.isShown()) { auto refShapes = pixel.getAllShapes(); int k = -1; for (const auto& refShape: refShapes) { k++; std::vector newLines = refShape.second.getAsLines(); // I'm not sure what the tagging was meant for any more, // tagging at the moment tags the *polygon* it was original attached to // must check it is not a zero length line: for(const Line& line: newLines) { if(line.length() > 0.0) { partitionlines.push_back(TaggedLine(line,k)); } } } } } } if (partitionlines.size()) { // // Now we'll try the BSP tree: // if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_bsp_root = new BSPNode(); time_t atime = 0; if (communicator) { communicator->CommPostMessage( Communicator::NUM_RECORDS, partitionlines.size() ); qtimer( atime, 0 ); } try { BSPTree::make(communicator,atime,partitionlines,m_bsp_root); m_bsp_tree = true; } catch (Communicator::CancelledException) { m_bsp_tree = false; // probably best to delete the half made bastard of a tree: delete m_bsp_root; m_bsp_root = NULL; } } partitionlines.clear(); return m_bsp_tree; } ////////////////////////////////////////////////////////////////// int MetaGraph::addShapeGraph(std::unique_ptr& shapeGraph) { m_shapeGraphs.push_back(std::move(shapeGraph)); int mapref= int(m_shapeGraphs.size() - 1); setDisplayedShapeGraphRef(mapref); m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); return mapref; } int MetaGraph::addShapeGraph(const std::string& name, int type) { std::unique_ptr shapeGraph(new ShapeGraph(name, type)); int mapref = addShapeGraph(shapeGraph); // add a couple of default columns: AttributeTable& table = m_shapeGraphs[size_t(mapref)]->getAttributeTable(); int connIdx = table.insertOrResetLockedColumn("Connectivity"); if ((type & ShapeMap::LINEMAP) != 0) { table.insertOrResetLockedColumn("Line Length"); } m_shapeGraphs[mapref]->setDisplayedAttribute(connIdx); return mapref; } int MetaGraph::addShapeMap(const std::string& name) { m_dataMaps.emplace_back(name,ShapeMap::DATAMAP); m_state |= DATAMAPS; setViewClass(SHOWSHAPETOP); return m_dataMaps.size() - 1; } void MetaGraph::removeDisplayedMap() { int ref = getDisplayedMapRef(); switch (m_view_class & VIEWFRONT) { case VIEWVGA: removePointMap(ref); if (m_pointMaps.empty()) { setViewClass(SHOWHIDEVGA); m_state &= ~POINTMAPS; } break; case VIEWAXIAL: removeShapeGraph(ref); if (m_shapeGraphs.empty()) { setViewClass(SHOWHIDEAXIAL); m_state &= ~SHAPEGRAPHS; } break; case VIEWDATA: removeDataMap(ref); if (m_dataMaps.empty()) { setViewClass(SHOWHIDESHAPE); m_state &= ~DATAMAPS; } break; } } ////////////////////////////////////////////////////////////////// bool MetaGraph::convertDrawingToAxial(Communicator *comm, std::string layer_name) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; bool converted = true; try { auto shapeGraph = MapConverter::convertDrawingToAxial( comm, layer_name, m_drawingFiles ); int mapref = addShapeGraph(shapeGraph); setDisplayedShapeGraphRef(mapref); } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } bool MetaGraph::convertDataToAxial(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; bool converted = true; try { auto shapeGraph = MapConverter::convertDataToAxial( comm, layer_name, getDisplayedDataMap(), pushvalues ); addShapeGraph(shapeGraph); m_shapeGraphs.back()->overrideDisplayedAttribute(-2); // <- override if it's already showing m_shapeGraphs.back()->setDisplayedAttribute( m_shapeGraphs.back()->getAttributeTable().getColumnIndex("Connectivity") ); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 1)); } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { if (!keeporiginal) { removeDataMap( getDisplayedDataMapRef() ); if (m_dataMaps.empty()) { setViewClass(SHOWHIDESHAPE); m_state &= ~DATAMAPS; } } m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } // typeflag: -1 convert drawing to convex, 0 or 1, convert data to convex (1 is pushvalues) bool MetaGraph::convertToConvex(Communicator *comm, std::string layer_name, bool keeporiginal, int shapeMapType, bool copydata) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; // and convex maps... bool converted = false; try { int mapref = -1; if (shapeMapType == ShapeMap::DRAWINGMAP) { auto shapeGraph = MapConverter::convertDrawingToConvex( comm, layer_name, m_drawingFiles ); mapref = addShapeGraph(shapeGraph); } else if (shapeMapType == ShapeMap::DATAMAP) { auto shapeGraph = MapConverter::convertDataToConvex( comm, layer_name, getDisplayedDataMap(), copydata ); mapref = addShapeGraph(shapeGraph); } m_shapeGraphs.back()->overrideDisplayedAttribute( -2 ); // <- override if it's already showing m_shapeGraphs.back()->setDisplayedAttribute( -1 ); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 1)); if (mapref != -1) { converted = true; } } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { if (shapeMapType != ShapeMap::DRAWINGMAP && !keeporiginal) { removeDataMap( getDisplayedDataMapRef() ); if (m_dataMaps.empty()) { setViewClass(SHOWHIDESHAPE); m_state &= ~DATAMAPS; } } m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } bool MetaGraph::convertDrawingToSegment(Communicator *comm, std::string layer_name) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; bool converted = true; try { auto shapeGraph = MapConverter::convertDrawingToSegment( comm, layer_name, m_drawingFiles ); addShapeGraph(shapeGraph); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 1)); } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } bool MetaGraph::convertDataToSegment(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; bool converted = true; try { auto shapeGraph = MapConverter::convertDataToSegment( comm, layer_name, getDisplayedDataMap(), pushvalues ); addShapeGraph(shapeGraph); m_shapeGraphs.back()->overrideDisplayedAttribute( -2 ); // <- override if it's already showing m_shapeGraphs.back()->setDisplayedAttribute( -1 ); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 1)); } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { if (!keeporiginal) { removeDataMap( getDisplayedDataMapRef() ); if (m_dataMaps.empty()) { setViewClass(SHOWHIDESHAPE); m_state &= ~DATAMAPS; } } m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } // note: type flag says whether this is graph to data map or drawing to data map bool MetaGraph::convertToData(Communicator *, std::string layer_name, bool keeporiginal, int shapeMapType, bool copydata) { int oldstate = m_state; m_state &= ~DATAMAPS; bool converted = false; try { // This should be much easier than before, // simply move the shapes from the drawing layer // note however that more than one layer might be combined: // create map layer... m_dataMaps.emplace_back(layer_name,ShapeMap::DATAMAP); int destmapref = m_dataMaps.size() - 1; ShapeMap& destmap = m_dataMaps.back(); AttributeTable& table = destmap.getAttributeTable(); int count = 0; // // drawing to data if (shapeMapType == ShapeMap::DRAWINGMAP) { int layercol = destmap.addAttribute("Drawing Layer"); // add all visible layers to the set of map: for (const auto& pixelGroup: m_drawingFiles) { int j = 0; for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { auto refShapes = pixel.getAllShapes(); for (const auto& refShape: refShapes) { int key = destmap.makeShape(refShape.second); table.getRow(AttributeKey(key)).setValue(layercol,float(j+1)); count++; } pixel.setShow(false); } j++; } } } // convex, axial or segment graph to data (similar) else { ShapeGraph& sourcemap = getDisplayedShapeGraph(); count = sourcemap.getShapeCount(); // take viewed graph and push all geometry to it (since it is *all* geometry, pushing is easy) int copyflag = copydata ? (ShapeMap::COPY_GEOMETRY | ShapeMap::COPY_ATTRIBUTES) : (ShapeMap::COPY_GEOMETRY); destmap.copy(sourcemap, copyflag); } // if (count == 0) { // if no objects converted then a crash is caused, so remove it: removeDataMap(destmapref); converted = false; } else { // we can stop here! -- remember to set up display: setDisplayedDataMapRef(destmapref); destmap.invalidateDisplayedAttribute(); destmap.setDisplayedAttribute(-1); converted = true; } } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { if (shapeMapType != ShapeMap::DRAWINGMAP && !keeporiginal) { removeShapeGraph( getDisplayedShapeGraphRef() ); if (m_shapeGraphs.empty()) { setViewClass(SHOWHIDEAXIAL); m_state &= ~SHAPEGRAPHS; } } m_state |= DATAMAPS; setViewClass(SHOWSHAPETOP); } return converted; } bool MetaGraph::convertToDrawing(Communicator *, std::string layer_name, bool fromDisplayedDataMap) { bool converted = false; int oldstate = m_state; m_state &= ~LINEDATA; try { const ShapeMap *sourcemap; if (fromDisplayedDataMap) { sourcemap = &(getDisplayedDataMap()); } else { sourcemap = &(getDisplayedShapeGraph()); } // if (sourcemap->getShapeCount() != 0) { // this is very simple: create a new drawing layer, and add the data... auto group = m_drawingFiles.begin(); for (; group != m_drawingFiles.end(); ++group) { if (group->getName() == "Converted Maps") { break; } } if (group == m_drawingFiles.end()) { m_drawingFiles.emplace_back(std::string("Converted Maps")); group = std::prev(m_drawingFiles.end()); } group->m_spacePixels.emplace_back(layer_name); group->m_spacePixels.back().copy(*sourcemap, ShapeMap::COPY_GEOMETRY); // // dummy set still required: group->m_spacePixels.back().invalidateDisplayedAttribute(); group->m_spacePixels.back().setDisplayedAttribute(-1); // // three levels of merge region: if (group->m_spacePixels.size() == 1) { group->m_region = group->m_spacePixels.back().getRegion(); } else { group->m_region = runion(group->m_region, group->m_spacePixels.back().getRegion()); } if (m_drawingFiles.size() == 1) { m_region = group->m_region; } else { m_region = runion(m_region, group->m_region); } // converted = true; } converted = true; } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { m_state |= LINEDATA; } return converted; } bool MetaGraph::convertAxialToSegment(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues, double stubremoval) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; bool converted = true; int orig_ref = getDisplayedShapeGraphRef(); try { if (orig_ref == -1) { return false; } auto shapeGraph = MapConverter::convertAxialToSegment(comm, getDisplayedShapeGraph(), layer_name, keeporiginal, pushvalues, stubremoval); addShapeGraph(shapeGraph); m_shapeGraphs.back()->overrideDisplayedAttribute(-2); // <- override if it's already showing m_shapeGraphs.back()->setDisplayedAttribute( m_shapeGraphs.back()->getAttributeTable().getColumnIndex("Connectivity") ); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 1)); } catch (Communicator::CancelledException) { converted = false; } m_state |= oldstate; if (converted) { if (!keeporiginal) { removeShapeGraph(orig_ref); } m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return converted; } int MetaGraph::loadMifMap(Communicator *comm, std::istream& miffile, std::istream& midfile) { int oldstate = m_state; m_state &= ~DATAMAPS; int mapLoaded = -1; try { // create map layer... m_dataMaps.emplace_back(comm->GetMBInfileName(),ShapeMap::DATAMAP); int mifmapref = m_dataMaps.size() - 1; ShapeMap& mifmap = m_dataMaps.back(); mapLoaded = mifmap.loadMifMap(miffile, midfile); if (mapLoaded == MINFO_OK || mapLoaded == MINFO_MULTIPLE) { // multiple is just a warning // display an attribute: mifmap.overrideDisplayedAttribute(-2); mifmap.setDisplayedAttribute(-1); setDisplayedDataMapRef(mifmapref); } else { // error: undo! removeDataMap(mifmapref); } } catch (Communicator::CancelledException) { mapLoaded = -1; } m_state = oldstate; if (mapLoaded == MINFO_OK || mapLoaded == MINFO_MULTIPLE) { // MINFO_MULTIPLE is simply a warning m_state |= DATAMAPS; setViewClass(SHOWSHAPETOP); } return mapLoaded; } bool MetaGraph::makeAllLineMap( Communicator *communicator, const Point2f& seed ) { int oldstate = m_state; m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) m_view_class &= ~VIEWAXIAL; // Also clear the view_class flag bool mapMade = true; try { // this is an index to look up the all line map, used by UI to determine if can make fewest line map // note: it is not saved for historical reasons if (m_all_line_map != -1) { removeShapeGraph(m_all_line_map); m_all_line_map = -1; } m_shapeGraphs.push_back(std::unique_ptr(new AllLineMap(communicator, m_drawingFiles, seed))); m_all_line_map = int(m_shapeGraphs.size() - 1); setDisplayedShapeGraphRef(m_all_line_map); } catch (Communicator::CancelledException) { mapMade = false; } m_state = oldstate; if (mapMade) { m_state |= SHAPEGRAPHS; setViewClass(SHOWAXIALTOP); } return mapMade; } bool MetaGraph::makeFewestLineMap( Communicator *communicator, int replace ) { int oldstate= m_state; m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool mapMade = true; try { // no all line map if (m_all_line_map == -1) { return false; } AllLineMap* alllinemap = dynamic_cast(m_shapeGraphs[size_t(m_all_line_map)].get()); if(alllinemap == nullptr) { throw depthmapX::RuntimeException("Failed to cast from ShapeGraph to AllLineMap"); } // waiting for C++17... std::unique_ptr fewestlinemap_subsets, fewestlinemap_minimal; std::tie(fewestlinemap_subsets, fewestlinemap_minimal) = alllinemap->extractFewestLineMaps(communicator); if (replace != 0) { int index = -1; for(size_t i = 0; i < m_shapeGraphs.size(); i++) { if(m_shapeGraphs[i]->getName() == "Fewest-Line Map (Subsets)" || m_shapeGraphs[i]->getName() == "Fewest Line Map (Subsets)") { index = int(i); } } if(index != -1) { removeShapeGraph(index); } for(size_t i = 0; i < m_shapeGraphs.size(); i++) { if(m_shapeGraphs[i]->getName() == "Fewest-Line Map (Subsets)" || m_shapeGraphs[i]->getName() == "Fewest Line Map (Subsets)") { index = int(i); } } if(index != -1) { removeShapeGraph(index); } } addShapeGraph(fewestlinemap_subsets); addShapeGraph(fewestlinemap_minimal); setDisplayedShapeGraphRef(int(m_shapeGraphs.size() - 2)); } catch (Communicator::CancelledException) { mapMade = false; } m_state = oldstate; if (mapMade) { m_state |= SHAPEGRAPHS; // note: should originally have at least one axial map setViewClass(SHOWAXIALTOP); } return mapMade; } bool MetaGraph::analyseAxial( Communicator *communicator, Options options, bool ) // options copied to keep thread safe { m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool analysisCompleted = false; try { analysisCompleted = AxialIntegration(options.radius_set, options.weighted_measure_col, options.choice, options.fulloutput, options.local) .run(communicator, getDisplayedShapeGraph(), false); } catch (Communicator::CancelledException) { analysisCompleted = false; } m_state |= SHAPEGRAPHS; return analysisCompleted; } bool MetaGraph::analyseSegmentsTulip( Communicator *communicator, Options options ) // <- options copied to keep thread safe { m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool analysisCompleted = false; try { analysisCompleted = SegmentTulip(options.radius_set, options.sel_only, options.tulip_bins, options.weighted_measure_col, options.radius_type, options.choice) .run(communicator, getDisplayedShapeGraph(), false); } catch (Communicator::CancelledException) { analysisCompleted = false; } m_state |= SHAPEGRAPHS; return analysisCompleted; } bool MetaGraph::analyseSegmentsAngular( Communicator *communicator, Options options ) // <- options copied to keep thread safe { m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool analysisCompleted = false; try { analysisCompleted = SegmentAngular(options.radius_set).run(communicator, getDisplayedShapeGraph(), false); } catch (Communicator::CancelledException) { analysisCompleted = false; } m_state |= SHAPEGRAPHS; return analysisCompleted; } bool MetaGraph::analyseTopoMetMultipleRadii( Communicator *communicator, Options options ) // <- options copied to keep thread safe { m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool analysisCompleted = true; try { // note: "output_type" reused for analysis type (either 0 = topological or 1 = metric) for(size_t r = 0; r < options.radius_set.size(); r++) { if(options.output_type == 0) { if(!SegmentTopological(options.radius, options.sel_only).run(communicator, getDisplayedShapeGraph(), false)) analysisCompleted = false; } else { if(!SegmentMetric(options.radius, options.sel_only).run(communicator, getDisplayedShapeGraph(), false)) analysisCompleted = false; } } } catch (Communicator::CancelledException) { analysisCompleted = false; } m_state |= SHAPEGRAPHS; return analysisCompleted; } bool MetaGraph::analyseTopoMet( Communicator *communicator, Options options ) // <- options copied to keep thread safe { m_state &= ~SHAPEGRAPHS; // Clear axial map data flag (stops accidental redraw during reload) bool analysisCompleted = false; try { // note: "output_type" reused for analysis type (either 0 = topological or 1 = metric) if(options.output_type == 0) { analysisCompleted = SegmentTopological(options.radius, options.sel_only).run(communicator, getDisplayedShapeGraph(), false); } else { analysisCompleted = SegmentMetric(options.radius, options.sel_only).run(communicator, getDisplayedShapeGraph(), false); } } catch (Communicator::CancelledException) { analysisCompleted = false; } m_state |= SHAPEGRAPHS; return analysisCompleted; } int MetaGraph::loadLineData( Communicator *communicator, int load_type ) { if (load_type & DXF) { // separate the stream and the communicator, allowing non-file streams read return depthmapX::importFile(*this, communicator->getInFileStream(), communicator, communicator->GetMBInfileName(), depthmapX::ImportType::DRAWINGMAP, depthmapX::ImportFileType::DXF); } m_state &= ~LINEDATA; // Clear line data flag (stops accidental redraw during reload) // if bsp tree exists if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_bsp_tree = false; if (load_type & REPLACE) { m_drawingFiles.clear(); } m_drawingFiles.emplace_back(communicator->GetMBInfileName()); if (load_type & CAT) { // separate the stream and the communicator, allowing non-file streams read int error = loadCat(communicator->getInFileStream(), communicator); if (error != 1) { return error; } } else if (load_type & RT1) { // separate the stream and the communicator, allowing non-file streams read int error = loadRT1(communicator->GetFileSet(), communicator); if (error != 1) { return error; } } else if (load_type & NTF) { NtfMap map; try { map.open(communicator->GetFileSet(), communicator); } catch (Communicator::CancelledException) { m_drawingFiles.pop_back(); return 0; } catch (std::invalid_argument&) { m_drawingFiles.pop_back(); return -1; } catch (std::out_of_range&) { m_drawingFiles.pop_back(); return -1; } if (communicator->IsCancelled()) { m_drawingFiles.pop_back(); return 0; } m_drawingFiles.back().m_region = map.getRegion();; for (auto layer: map.layers) { m_drawingFiles.back().m_spacePixels.emplace_back(layer.getName()); m_drawingFiles.back().m_spacePixels.back().init(layer.getLineCount(), map.getRegion()); for (auto geometry: layer.geometries) { for (auto& line: geometry.lines) { m_drawingFiles.back().m_spacePixels.back().makeLineShape( line ); } } // TODO: Investigate why setDisplayedAttribute needs to be set to -2 first m_drawingFiles.back().m_spacePixels.back().setDisplayedAttribute(-2); m_drawingFiles.back().m_spacePixels.back().setDisplayedAttribute(-1); } } if (m_drawingFiles.size() == 1) { m_region = m_drawingFiles.back().m_region; } else { m_region = runion(m_region, m_drawingFiles.back().m_region); } m_state |= LINEDATA; return 1; } // From: Alasdair Turner (2004) - Depthmap 4: a researcher's handbook (p. 6): // [..] CAT, which stands for Chiron and Alasdair Transfer Format [..] void MetaGraph::writeMapShapesAsCat(ShapeMap& map, std::ostream &stream) { stream << "CAT" << std::endl; for (auto refShape: map.getAllShapes()) { SalaShape& shape = refShape.second; if(shape.isPolyLine() || shape.isPolygon()) { stream << "Begin " << (shape.isPolyLine() ? "Polyline" : "Polygon") << std::endl; for (Point2f p: shape.m_points) { stream << p.x << " " << p.y << std::endl; } stream << "End " << (shape.isPolyLine() ? "Polyline" : "Polygon") << std::endl; } else if(shape.isLine()) { stream << "Begin Polyline" << std::endl; stream << shape.getLine().ax() << " " << shape.getLine().ay() << std::endl; stream << shape.getLine().bx() << " " << shape.getLine().by() << std::endl; stream << "End Polyline" << std::endl; } } } int MetaGraph::loadCat( std::istream& stream, Communicator *communicator ) { if (communicator) { long size = communicator->GetInfileSize(); communicator->CommPostMessage( Communicator::NUM_RECORDS, size ); } time_t atime = 0; qtimer( atime, 0 ); long size = 0; int numlines = 0; int parsing = 0; bool first = true; Point2f current_point, min_point, max_point; while (!stream.eof()) { std::string inputline; stream >> inputline; if (inputline.length() > 1 && inputline[0] != '#') { if (!parsing) { if (dXstring::toLower(inputline) == "begin polygon") { parsing = 1; } else if (dXstring::toLower(inputline) == "begin polyline") { parsing = 2; } } else if (dXstring::toLower(inputline).substr(0,3) == "end") { parsing = 0; } else { auto tokens = dXstring::split(inputline, ' ', true); current_point.x = stod(tokens[0]); current_point.y = stod(tokens[1]); numlines++; if (first) { min_point = current_point; max_point = current_point; first = false; } else { if (current_point.x < min_point.x) { min_point.x = current_point.x; } if (current_point.y < min_point.y) { min_point.y = current_point.y; } if (current_point.x > max_point.x) { max_point.x = current_point.x; } if (current_point.y > max_point.y) { max_point.y = current_point.y; } } } } } m_drawingFiles.back().m_region = QtRegion(min_point, max_point); m_drawingFiles.back().m_spacePixels.emplace_back(); m_drawingFiles.back().m_spacePixels.back().init( numlines, QtRegion(min_point, max_point) ); // in MSVC 6, ios::eof remains set and it needs to be cleared. // in MSVC 8 it's even worse: it won't even seekg until eof flag has been cleared stream.clear(); stream.seekg(0, std::ios::beg); parsing = 0; first = true; std::vector points; while (!stream.eof()) { std::string inputline; stream >> inputline; if (inputline.length() > 1 && inputline[0] != '#') { if (!parsing) { if (dXstring::toLower(inputline) == "begin polygon") { parsing = 1; first = true; } else if (dXstring::toLower(inputline) == "begin polyline") { parsing = 2; first = true; } } else if (dXstring::toLower(inputline).substr(0,3) == "end") { if (points.size() > 2) { if (parsing == 1) { // polygon m_drawingFiles.back().m_spacePixels.back().makePolyShape(points, false); } else { // polyline m_drawingFiles.back().m_spacePixels.back().makePolyShape(points, true); } } else if (points.size() == 2) { m_drawingFiles.back().m_spacePixels.back().makeLineShape(Line(points[0],points[1])); } points.clear(); parsing = 0; } else { auto tokens = dXstring::split(inputline, ' ', true); current_point.x = stod(tokens[0]); current_point.y = stod(tokens[1]); points.push_back(current_point); } } size += inputline.length() + 1; if (communicator) { if (qtimer( atime, 500 )) { if (communicator->IsCancelled()) { throw Communicator::CancelledException(); } communicator->CommPostMessage( Communicator::CURRENT_RECORD, size ); } } } m_drawingFiles.back().m_spacePixels.back().setDisplayedAttribute(-2); m_drawingFiles.back().m_spacePixels.back().setDisplayedAttribute(-1); return 1; } int MetaGraph::loadRT1(const std::vector& fileset, Communicator *communicator) { TigerMap map; try { map.parse( fileset, communicator ); } catch (Communicator::CancelledException) { m_drawingFiles.pop_back(); return 0; } catch (std::invalid_argument&) { m_drawingFiles.pop_back(); return -1; } catch (std::out_of_range&) { m_drawingFiles.pop_back(); return -1; } if (communicator->IsCancelled()) { m_drawingFiles.pop_back(); return 0; } m_drawingFiles.back().m_region = QtRegion(map.getBottomLeft(), map.getTopRight()); // for each category for (auto val: map.m_categories) { ShapeMap shapeMap = ShapeMap(val.first); shapeMap.init(val.second.chains.size(), map.getRegion() ); // for each chains in category: for (size_t j = 0; j < val.second.chains.size(); j++) { // for each node pair in each category for (size_t k = 0; k < val.second.chains[j].lines.size(); k++) { shapeMap.makeLineShape( val.second.chains[j].lines[k] ); } } shapeMap.setDisplayedAttribute(-2); shapeMap.setDisplayedAttribute(-1); m_drawingFiles.back().m_spacePixels.emplace_back(std::move(shapeMap)); } return 1; } ShapeMap &MetaGraph::createNewShapeMap(depthmapX::ImportType mapType, std::string name) { if (mapType == depthmapX::ImportType::DATAMAP) { m_dataMaps.emplace_back(name, ShapeMap::DATAMAP); m_dataMaps.back().setDisplayedAttribute(0); return m_dataMaps.back(); } // depthmapX::ImportType::DRAWINGMAP m_drawingFiles.back().m_spacePixels.emplace_back(name); return m_drawingFiles.back().m_spacePixels.back(); } void MetaGraph::deleteShapeMap(depthmapX::ImportType mapType, ShapeMap &shapeMap) { switch(mapType) { case depthmapX::ImportType::DRAWINGMAP: { // go through the files to find if the layer is in one of them // if it is, remove it and if the remaining file is empty then // remove that too auto pixelGroup = m_drawingFiles.begin(); for (; pixelGroup != m_drawingFiles.begin(); ++pixelGroup) { auto mapToRemove = pixelGroup->m_spacePixels.end(); auto pixel = pixelGroup->m_spacePixels.begin(); for (; pixel != pixelGroup->m_spacePixels.end(); ++pixel) { if(&(*pixel) == &shapeMap) { mapToRemove = pixel; break; } } if(mapToRemove != pixelGroup->m_spacePixels.end()) { pixelGroup->m_spacePixels.erase(mapToRemove); if(pixelGroup->m_spacePixels.size() == 0) { m_drawingFiles.erase(pixelGroup); } break; } } } case depthmapX::ImportType::DATAMAP: { for(size_t i = 0; i < m_dataMaps.size(); i++) { if(&m_dataMaps[i] == &shapeMap) { m_dataMaps.erase(m_dataMaps.begin() + i); break; } } } } } void MetaGraph::updateParentRegions(ShapeMap &shapeMap) { if(m_drawingFiles.back().m_region.atZero()) { m_drawingFiles.back().m_region = shapeMap.getRegion(); } else { m_drawingFiles.back().m_region = runion(m_drawingFiles.back().m_region, shapeMap.getRegion()); } if(m_region.atZero()) { m_region = m_drawingFiles.back().m_region; } else { m_region = runion(m_region, m_drawingFiles.back().m_region); } } // the tidy(ish) version: still needs to be at top level and switch between layers bool MetaGraph::pushValuesToLayer(int desttype, int destlayer, int push_func, bool count_col) { int sourcetype = m_view_class; int sourcelayer = getDisplayedMapRef(); int col_in = getDisplayedAttribute(); // no col_out specified int col_out = -2; // temporarily turn off everything to prevent redraw during sensitive time: int oldstate = m_state; m_state &= ~(DATAMAPS | AXIALLINES | POINTMAPS); bool valuesPushed = pushValuesToLayer(sourcetype, sourcelayer, desttype, destlayer, col_in, col_out, push_func, count_col); m_state = oldstate; return valuesPushed; } // helper void pushValue(double& val, int& count, double thisval, int push_func) { if (thisval != -1) { switch (push_func) { case MetaGraph::PUSH_FUNC_MAX: if (val == -1 || thisval > val) val = thisval; break; case MetaGraph::PUSH_FUNC_MIN: if (val == -1 || thisval < val) val = thisval; break; case MetaGraph::PUSH_FUNC_AVG: case MetaGraph::PUSH_FUNC_TOT: if (val == -1.0) val = thisval; else val += thisval; break; } count++; } } // the full ubercontrol version: bool MetaGraph::pushValuesToLayer(int sourcetype, int sourcelayer, int desttype, int destlayer, int col_in, int col_out, int push_func, bool count_col) { AttributeTable& table_in = getAttributeTable(sourcetype, sourcelayer); AttributeTable& table_out = getAttributeTable(desttype, destlayer); if (col_out == -2) { std::string name = table_in.getColumnName(col_in); if ((table_out.hasColumn(name) && table_out.getColumn(table_out.getColumnIndex(name)).isLocked()) || name == "Object Count") { name = std::string("Copied ") + name; } col_out = table_out.insertOrResetColumn(name); } int col_count = -1; if (count_col) { col_count = table_out.insertOrResetColumn("Object Count"); if (col_count <= col_out) { col_out++; } } if (desttype == VIEWVGA && ((sourcetype & VIEWDATA) || (sourcetype & VIEWAXIAL))) { // pushing from a shapemap (data/axial/segment/convex) requires a combination of // finding points (VGA) in polygons (convex and data maps with polygons) and points // that are on lines (axial, segment and data maps with lines). Thus, in this case // a composite approach is implemented, which takes both options from the other parts // of this conditional. struct ValueCountRow { double m_value = -1; int m_count = 0; AttributeRow &m_row; ValueCountRow(AttributeRow &row) : m_row(row) {} }; // prepare a temporary value table to store counts and values std::map valCounts; for (auto &row : table_out) { valCounts.insert(std::make_pair(row.getKey(), ValueCountRow(row.getRow()))); // count set to zero for all } ShapeMap &sourceMap = sourcetype & VIEWDATA ? m_dataMaps[sourcelayer] : *m_shapeGraphs[sourcelayer].get(); PointMap &vgaMap = m_pointMaps[destlayer]; // first collect the lines by pixelating them using the vga map std::map &shapeMap = sourceMap.getAllShapes(); for (auto &shape : shapeMap) { float thisval = table_in.getRow(AttributeKey(shape.first)).getValue(col_in); if (shape.second.isLine()) { PixelRefVector linePixels = vgaMap.pixelateLine(shape.second.getLine()); for (const PixelRef &pix : linePixels) { if (!vgaMap.getPoint(pix).filled()) continue; auto valCount = valCounts.find(AttributeKey(pix)); if(valCount != valCounts.end()) { pushValue(valCount->second.m_value, valCount->second.m_count, thisval, push_func); } } } else if (shape.second.isPolyLine()) { std::set polylinePixels; for (size_t i = 1; i < shape.second.m_points.size(); i++) { Line li(shape.second.m_points[i - 1], shape.second.m_points[i]); PixelRefVector linePixels = vgaMap.pixelateLine(li); polylinePixels.insert(linePixels.begin(), linePixels.end()); } for (const PixelRef &pix : polylinePixels) { if (!vgaMap.getPoint(pix).filled()) continue; auto valCount = valCounts.find(AttributeKey(pix)); if(valCount != valCounts.end()) { pushValue(valCount->second.m_value, valCount->second.m_count, thisval, push_func); } } } } // then collect the polygons and push to vga map for (auto &valCount : valCounts) { int key_out = valCount.first.value; double &val = valCount.second.m_value; int &count = valCount.second.m_count; AttributeRow &row = valCount.second.m_row; std::vector gatelist; if (!isObjectVisible(vgaMap.m_layers, row)) { continue; } gatelist = sourceMap.pointInPolyList(vgaMap.getPoint(key_out).m_location); for (int gate : gatelist) { AttributeRow &row_in = sourceMap.getAttributeRowFromShapeIndex(gate); if (isObjectVisible(sourceMap.getLayers(), row_in)) { double thisval = row_in.getValue(col_in); pushValue(val, count, thisval, push_func); } } if (push_func == PUSH_FUNC_AVG && val != -1.0) { val /= double(count); } row.setValue(col_out, float(val)); if (count_col) { row.setValue(col_count, float(count)); } } } else if (sourcetype & VIEWDATA) { for (auto iter_out = table_out.begin(); iter_out != table_out.end(); iter_out++) { int key_out = iter_out->getKey().value; std::vector gatelist; if (desttype == VIEWAXIAL) { if (!isObjectVisible(m_shapeGraphs[destlayer]->getLayers(), iter_out->getRow())) { continue; } auto shapeMap = m_shapeGraphs[destlayer]->getAllShapes(); gatelist = m_dataMaps[sourcelayer].shapeInPolyList(shapeMap[key_out]); } else if (desttype == VIEWDATA) { if (sourcelayer == destlayer) { // error: pushing to same map return false; } if (!isObjectVisible(m_dataMaps[destlayer].getLayers(), iter_out->getRow())) { continue; } auto dataMap = m_dataMaps[destlayer].getAllShapes(); gatelist = m_dataMaps[sourcelayer].shapeInPolyList(dataMap[key_out]); } double val = -1.0; int count = 0; for (int gate: gatelist) { AttributeRow &row_in = m_dataMaps[sourcelayer].getAttributeRowFromShapeIndex(gate); if (isObjectVisible(m_dataMaps[sourcelayer].getLayers(), row_in)) { double thisval = gate; if(col_in != -1) thisval = row_in.getValue(col_in); pushValue(val,count,thisval,push_func); } } if (push_func == PUSH_FUNC_AVG && val != -1.0) { val /= double(count); } iter_out->getRow().setValue(col_out,float(val)); if (count_col) { iter_out->getRow().setValue(col_count,float(count)); } } } else { // prepare a temporary value table to store counts and values std::vector vals(table_out.getNumRows()); std::vector counts(table_out.getNumRows()); for (size_t i = 0; i < table_out.getNumRows(); i++) { counts[i] = 0; // count set to zero for all vals[i] = -1; } if (sourcetype & VIEWVGA) { for (auto iter_in = table_in.begin(); iter_in != table_in.end(); iter_in++) { int pix_in = iter_in->getKey().value; if (!isObjectVisible(m_pointMaps[sourcelayer].getLayers(), iter_in->getRow())) { continue; } std::vector gatelist; if (desttype == VIEWDATA) { gatelist = m_dataMaps[size_t(destlayer)].pointInPolyList(m_pointMaps[size_t(sourcelayer)].getPoint(pix_in).m_location); double thisval = iter_in->getKey().value; if(col_in != -1) thisval = iter_in->getRow().getValue(col_in); for (int gate: gatelist) { AttributeRow &row_out = m_dataMaps[destlayer].getAttributeRowFromShapeIndex(gate); if (isObjectVisible(m_dataMaps[destlayer].getLayers(), row_out)) { double& val = vals[gate]; int& count = counts[gate]; pushValue(val,count,thisval,push_func); } } } else if (desttype == VIEWAXIAL) { // note, "axial" could be convex map, and hence this would be a valid operation gatelist = m_shapeGraphs[size_t(destlayer)]->pointInPolyList(m_pointMaps[size_t(sourcelayer)].getPoint(pix_in).m_location); double thisval = iter_in->getKey().value; if(col_in != -1) thisval = iter_in->getRow().getValue(col_in); for (int gate: gatelist) { int key_out = m_shapeGraphs[destlayer]->getShapeRefFromIndex(gate)->first; AttributeRow &row_out = table_out.getRow(AttributeKey(key_out)); if (isObjectVisible(m_shapeGraphs[destlayer]->getLayers(), row_out)) { double& val = vals[gate]; int& count = counts[gate]; pushValue(val,count,thisval,push_func); } } } } } else if (sourcetype & VIEWAXIAL) { // note, in the spirit of mapping fewer objects in the gate list, it is *usually* best to // perform axial -> gate map in this direction for (auto iter_in = table_in.begin(); iter_in != table_in.end(); iter_in++) { int key_in = iter_in->getKey().value; if (!isObjectVisible(m_shapeGraphs[size_t(sourcelayer)]->getLayers(),iter_in->getRow())) { continue; } std::vector gatelist; if (desttype == VIEWDATA) { auto dataMap = m_shapeGraphs[size_t(sourcelayer)]->getAllShapes(); gatelist = m_dataMaps[size_t(destlayer)].shapeInPolyList(dataMap[key_in]); double thisval = iter_in->getKey().value; if(col_in != -1) thisval = iter_in->getRow().getValue(col_in); for (int gate: gatelist) { int key_out = m_dataMaps[destlayer].getShapeRefFromIndex(gate)->first; AttributeRow &row_out = table_out.getRow(AttributeKey(key_out)); if (isObjectVisible(m_dataMaps[size_t(destlayer)].getLayers(), row_out)) { double& val = vals[gate]; int& count = counts[gate]; pushValue(val,count,thisval,push_func); } } } else if (desttype == VIEWAXIAL) { auto shapeMap = m_shapeGraphs[size_t(sourcelayer)]->getAllShapes(); gatelist = m_shapeGraphs[size_t(destlayer)]->shapeInPolyList(shapeMap[key_in]); double thisval = iter_in->getKey().value; if(col_in != -1) thisval = iter_in->getRow().getValue(col_in); for (int gate: gatelist) { int key_out = m_shapeGraphs[destlayer]->getShapeRefFromIndex(gate)->first; AttributeRow &row_out = table_out.getRow(AttributeKey(key_out)); if (isObjectVisible(m_shapeGraphs[destlayer]->getLayers(), row_out)) { double& val = vals[gate]; int& count = counts[gate]; pushValue(val,count,thisval,push_func); } } } } } int i = -1; for (auto iter = table_out.begin(); iter != table_out.end(); iter++) { i++; if (!isObjectVisible(m_shapeGraphs[destlayer]->getLayers(), iter->getRow())) { continue; } if (push_func == PUSH_FUNC_AVG && vals[i] != -1.0) { vals[i] /= double(counts[i]); } iter->getRow().setValue(col_out,float(vals[i])); if (count_col) { iter->getRow().setValue(col_count,float(counts[i])); } } } // display new data in the relevant layer if (desttype == VIEWVGA) { m_pointMaps[destlayer].overrideDisplayedAttribute(-2); m_pointMaps[destlayer].setDisplayedAttribute(col_out); } else if (desttype == VIEWAXIAL) { m_shapeGraphs[destlayer]->overrideDisplayedAttribute(-2); m_shapeGraphs[destlayer]->setDisplayedAttribute(col_out); } else if (desttype == VIEWDATA) { m_dataMaps[destlayer].overrideDisplayedAttribute(-2); m_dataMaps[destlayer].setDisplayedAttribute(col_out); } return true; } // Agent functionality: some of it still kept here with the metagraph // (to allow push value to layer and back again) void MetaGraph::runAgentEngine(Communicator *comm) { AttributeTable& table = getDisplayedPointMap().getAttributeTable(); if (m_agent_engine.m_gatelayer != -1) { // switch the reference numbers from the gates layer to the vga layer int colgates = table.insertOrResetColumn(g_col_gate); pushValuesToLayer(VIEWDATA,m_agent_engine.m_gatelayer, VIEWVGA,getDisplayedPointMapRef(), -1,colgates,PUSH_FUNC_TOT); table.insertOrResetColumn(g_col_gate_counts); } m_agent_engine.run(comm, &(getDisplayedPointMap()) ); if(m_agent_engine.m_record_trails) { std::string mapName = "Agent Trails"; int count = 1; while(std::find_if(std::begin(m_dataMaps), std::end(m_dataMaps), [&] (ShapeMap const& m) {return m.getName() == mapName; }) != m_dataMaps.end()) { mapName = "Agent Trails " + std::to_string(count); count++; } m_dataMaps.emplace_back(mapName); m_agent_engine.insertTrailsInMap(m_dataMaps.back()); m_state |= DATAMAPS; } if (m_agent_engine.m_gatelayer != -1) { // switch column counts from vga layer to gates layer... int colcounts = table.getColumnIndex(g_col_gate_counts); AttributeTable& tableout = m_dataMaps[m_agent_engine.m_gatelayer].getAttributeTable(); int targetcol = tableout.insertOrResetColumn("Agent Counts"); pushValuesToLayer(VIEWVGA,getDisplayedPointMapRef(), VIEWDATA,m_agent_engine.m_gatelayer, colcounts,targetcol,PUSH_FUNC_TOT); // and delete the temporary columns: table.removeColumn(colcounts); int colgates = table.getColumnIndex(g_col_gate); table.removeColumn(colgates); } } // Thru vision // TODO: Undocumented functionality bool MetaGraph::analyseThruVision(Communicator *comm, int gatelayer) { bool analysisCompleted = false; AttributeTable& table = getDisplayedPointMap().getAttributeTable(); // always have temporary gate counting layers -- makes it easier to code int colgates = table.insertOrResetColumn(g_col_gate); int colcounts = table.insertOrResetColumn(g_col_gate_counts); if (gatelayer != -1) { // switch the reference numbers from the gates layer to the vga layer pushValuesToLayer(VIEWDATA,gatelayer, VIEWVGA,getDisplayedPointMapRef(), -1,colgates,PUSH_FUNC_TOT); } try { analysisCompleted = VGAThroughVision().run(comm, getDisplayedPointMap(), false); } catch (Communicator::CancelledException) { analysisCompleted = false; } // note after the analysis, the column order might have changed... retrieve: colgates = table.getColumnIndex(g_col_gate); colcounts = table.getColumnIndex(g_col_gate_counts); if (analysisCompleted && gatelayer != -1) { AttributeTable& tableout = m_dataMaps[gatelayer].getAttributeTable(); int targetcol = tableout.insertOrResetColumn("Thru Vision Counts"); pushValuesToLayer(VIEWVGA,getDisplayedPointMapRef(), VIEWDATA,gatelayer, colcounts,targetcol,PUSH_FUNC_TOT); } // and always delete the temporary columns: table.removeColumn(colcounts); table.removeColumn(colgates); return analysisCompleted; } /////////////////////////////////////////////////////////////////////////////////// int MetaGraph::getDisplayedMapRef() const { int ref = -1; switch (m_view_class & VIEWFRONT) { case VIEWVGA: ref = getDisplayedPointMapRef(); break; case VIEWAXIAL: ref = getDisplayedShapeGraphRef(); break; case VIEWDATA: ref = getDisplayedDataMapRef(); break; } return ref; } // I'd like to use this more often so that several classes other than data maps and shape graphs // can be used in the future int MetaGraph::getDisplayedMapType() { switch (m_view_class & VIEWFRONT) { case VIEWVGA: return ShapeMap::POINTMAP; case VIEWAXIAL: return getDisplayedShapeGraph().getMapType(); case VIEWDATA: return getDisplayedDataMap().getMapType(); } return ShapeMap::EMPTYMAP; } AttributeTable& MetaGraph::getDisplayedMapAttributes() { switch (m_view_class & VIEWFRONT) { case VIEWVGA: return getDisplayedPointMap().getAttributeTable(); case VIEWAXIAL: return getDisplayedShapeGraph().getAttributeTable(); case VIEWDATA: return getDisplayedDataMap().getAttributeTable(); } throw depthmapX::RuntimeException("No map displayed to get attribute table from"); } bool MetaGraph::hasVisibleDrawingLayers() { if(!m_drawingFiles.empty()) { for (const auto& pixelGroup: m_drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) return true; } } } return false; } // note: 0 is not at all editable, 1 is editable off and 2 is editable on int MetaGraph::isEditable() const { int editable = 0; switch (m_view_class & VIEWFRONT) { case VIEWVGA: if (getDisplayedPointMap().isProcessed()) { editable = NOT_EDITABLE; } else { editable = EDITABLE_ON; } break; case VIEWAXIAL: { int type = getDisplayedShapeGraph().getMapType(); if (type != ShapeMap::SEGMENTMAP && type != ShapeMap::ALLLINEMAP) { editable = getDisplayedShapeGraph().isEditable() ? EDITABLE_ON : EDITABLE_OFF; } else { editable = NOT_EDITABLE; } } break; case VIEWDATA: editable = getDisplayedDataMap().isEditable() ? EDITABLE_ON : EDITABLE_OFF; break; } return editable; } bool MetaGraph::canUndo() const { bool canundo = false; switch (m_view_class & VIEWFRONT) { case VIEWVGA: canundo = getDisplayedPointMap().canUndo(); break; case VIEWAXIAL: canundo = getDisplayedShapeGraph().canUndo(); break; case VIEWDATA: canundo = getDisplayedDataMap().canUndo(); break; } return canundo; } void MetaGraph::undo() { switch (m_view_class & VIEWFRONT) { case VIEWVGA: getDisplayedPointMap().undoPoints(); break; case VIEWAXIAL: getDisplayedShapeGraph().undo(); break; case VIEWDATA: getDisplayedDataMap().undo(); break; } } // Moving to global ways of doing things: int MetaGraph::addAttribute(const std::string& name) { int col; switch (m_view_class & VIEWFRONT) { case VIEWVGA: col = getDisplayedPointMap().addAttribute(name); break; case VIEWAXIAL: col = getDisplayedShapeGraph().addAttribute(name); break; case VIEWDATA: col = getDisplayedDataMap().addAttribute(name); break; } return col; } void MetaGraph::removeAttribute(int col) { switch (m_view_class & VIEWFRONT) { case VIEWVGA: getDisplayedPointMap().removeAttribute(col); break; case VIEWAXIAL: getDisplayedShapeGraph().removeAttribute(col); break; case VIEWDATA: getDisplayedDataMap().removeAttribute(col); break; } } bool MetaGraph::isAttributeLocked(int col) { return getAttributeTable(m_view_class).getColumn(col).isLocked(); } int MetaGraph::getDisplayedAttribute() const { int col = -1; switch (m_view_class & VIEWFRONT) { case VIEWVGA: col = getDisplayedPointMap().getDisplayedAttribute(); break; case VIEWAXIAL: col = getDisplayedShapeGraph().getDisplayedAttribute(); break; case VIEWDATA: col = getDisplayedDataMap().getDisplayedAttribute(); break; } return col; } // this is coming from the front end, so force override: void MetaGraph::setDisplayedAttribute(int col) { switch (m_view_class & VIEWFRONT) { case VIEWVGA: getDisplayedPointMap().overrideDisplayedAttribute(-2); getDisplayedPointMap().setDisplayedAttribute(col); break; case VIEWAXIAL: getDisplayedShapeGraph().overrideDisplayedAttribute(-2); getDisplayedShapeGraph().setDisplayedAttribute(col); break; case VIEWDATA: getDisplayedDataMap().overrideDisplayedAttribute(-2); getDisplayedDataMap().setDisplayedAttribute(col); break; } } // const and non-const versions: AttributeTable& MetaGraph::getAttributeTable(int type, int layer) { AttributeTable *tab = NULL; if (type == -1) { type = m_view_class; } switch (type & VIEWFRONT) { case VIEWVGA: tab = (layer == -1) ? &(getDisplayedPointMap().getAttributeTable()) : &(m_pointMaps[layer].getAttributeTable()); break; case VIEWAXIAL: tab = (layer == -1) ? &(getDisplayedShapeGraph().getAttributeTable()) : &(m_shapeGraphs[layer]->getAttributeTable()); break; case VIEWDATA: tab = (layer == -1) ? &(getDisplayedDataMap().getAttributeTable()) : &(m_dataMaps[layer].getAttributeTable()); break; } return *tab; } const AttributeTable& MetaGraph::getAttributeTable(int type, int layer) const { const AttributeTable *tab = NULL; if (type == -1) { type = m_view_class & VIEWFRONT; } switch (type) { case VIEWVGA: tab = layer == -1 ? &(getDisplayedPointMap().getAttributeTable()) : &(m_pointMaps[layer].getAttributeTable()); break; case VIEWAXIAL: tab = layer == -1 ? &(getDisplayedShapeGraph().getAttributeTable()) : &(m_shapeGraphs[layer]->getAttributeTable()); break; case VIEWDATA: tab = layer == -1 ? &(getDisplayedDataMap().getAttributeTable()) : &(m_dataMaps[layer].getAttributeTable()); break; } return *tab; } LayerManagerImpl &MetaGraph::getLayers(int type, int layer) { LayerManagerImpl *tab = NULL; if (type == -1) { type = m_view_class; } switch (type & VIEWFRONT) { case VIEWVGA: tab = (layer == -1) ? &(getDisplayedPointMap().getLayers()) : &(m_pointMaps[layer].getLayers()); break; case VIEWAXIAL: tab = (layer == -1) ? &(getDisplayedShapeGraph().getLayers()) : &(m_shapeGraphs[layer]->getLayers()); break; case VIEWDATA: tab = (layer == -1) ? &(getDisplayedDataMap().getLayers()) : &(m_dataMaps[layer].getLayers()); break; } return *tab; } const LayerManagerImpl &MetaGraph::getLayers(int type, int layer) const { const LayerManagerImpl *tab = NULL; if (type == -1) { type = m_view_class & VIEWFRONT; } switch (type) { case VIEWVGA: tab = layer == -1 ? &(getDisplayedPointMap().getLayers()) : &(m_pointMaps[layer].getLayers()); break; case VIEWAXIAL: tab = layer == -1 ? &(getDisplayedShapeGraph().getLayers()) : &(m_shapeGraphs[layer]->getLayers()); break; case VIEWDATA: tab = layer == -1 ? &(getDisplayedDataMap().getLayers()) : &(m_dataMaps[layer].getLayers()); break; } return *tab; } AttributeTableHandle& MetaGraph::getAttributeTableHandle(int type, int layer) { AttributeTableHandle *tab = NULL; if (type == -1) { type = m_view_class; } switch (type & VIEWFRONT) { case VIEWVGA: tab = (layer == -1) ? &(getDisplayedPointMap().getAttributeTableHandle()) : &(m_pointMaps[layer].getAttributeTableHandle()); break; case VIEWAXIAL: tab = (layer == -1) ? &(getDisplayedShapeGraph().getAttributeTableHandle()) : &(m_shapeGraphs[layer]->getAttributeTableHandle()); break; case VIEWDATA: tab = (layer == -1) ? &(getDisplayedDataMap().getAttributeTableHandle()) : &(m_dataMaps[layer].getAttributeTableHandle()); break; } return *tab; } const AttributeTableHandle& MetaGraph::getAttributeTableHandle(int type, int layer) const { const AttributeTableHandle *tab = NULL; if (type == -1) { type = m_view_class & VIEWFRONT; } switch (type) { case VIEWVGA: tab = layer == -1 ? &(getDisplayedPointMap().getAttributeTableHandle()) : &(m_pointMaps[layer].getAttributeTableHandle()); break; case VIEWAXIAL: tab = layer == -1 ? &(getDisplayedShapeGraph().getAttributeTableHandle()) : &(m_shapeGraphs[layer]->getAttributeTableHandle()); break; case VIEWDATA: tab = layer == -1 ? &(getDisplayedDataMap().getAttributeTableHandle()) : &(m_dataMaps[layer].getAttributeTableHandle()); break; } return *tab; } int MetaGraph::readFromFile( const std::string& filename ) { if (filename.empty()) { return NOT_A_GRAPH; } #ifdef _WIN32 std::ifstream stream( filename.c_str(), std::ios::binary | std::ios::in ); #else std::ifstream stream( filename.c_str(), std::ios::in ); #endif int result = readFromStream(stream, filename); stream.close(); return result; } int MetaGraph::readFromStream( std::istream &stream, const std::string& filename ) { m_state = 0; // <- clear the state out // clear BSP tree if it exists: if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_bsp_tree = false; char header[3]; stream.read( header, 3 ); if (stream.fail() || header[0] != 'g' || header[1] != 'r' || header[2] != 'f') { return NOT_A_GRAPH; } int version; stream.read( (char *) &version, sizeof( version ) ); m_file_version = version; // <- recorded for easy debugging if (version > METAGRAPH_VERSION) { return NEWER_VERSION; } if (version < METAGRAPH_VERSION) { std::unique_ptr mgraph(new mgraph440::MetaGraph); auto result = mgraph->read(filename); if ( result != mgraph440::MetaGraph::OK) { return DAMAGED_FILE; } std::stringstream tempstream; mgraph->writeToStream(tempstream, METAGRAPH_VERSION, 0); return readFromStream(tempstream, filename); } // have to use temporary state here as redraw attempt may come too early: int temp_state = 0; int temp_view_class = 0; stream.read( (char *) &temp_state, sizeof( temp_state ) ); stream.read( (char *) &temp_view_class, sizeof(temp_view_class) ); stream.read( (char *) &m_showgrid, sizeof(m_showgrid) ); stream.read( (char *) &m_showtext, sizeof(m_showtext) ); // type codes: x --- properties // v --- virtual graph (from versions below 70) // n --- ngraph format // l --- layer data // p --- point data // d --- data summary layers char type; stream.read( &type, 1 ); if (type == 'd') { // contains deprecated datalayers. Read through mgraph440 which will // convert them into shapemaps std::unique_ptr mgraph(new mgraph440::MetaGraph); auto result = mgraph->read(filename); if ( result != mgraph440::MetaGraph::OK) { return DAMAGED_FILE; } std::stringstream tempstream; mgraph->writeToStream(tempstream, METAGRAPH_VERSION, 0); return readFromStream(tempstream, filename); } if (type == 'x') { FileProperties::read(stream); if (stream.eof()) { // erk... this shouldn't happen return DAMAGED_FILE; } else if (!stream.eof()) { stream.read( &type, 1 ); } } else { FileProperties::setProperties("","","",""); } if (stream.eof()) { // file is still ok, just empty return OK; } if (type == 'v') { skipVirtualMem(stream); // and set our filename: // Graph::m_nodes.setFilename( filename ); // and tell everyone it's been archived // temp_state |= GRAPHARCHIVED; if (stream.eof()) { // erk... this shouldn't happen return DAMAGED_FILE; } else if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'l') { m_name = dXstring::readString(stream); stream.read( (char *) &m_region, sizeof(m_region) ); int count; stream.read( (char *) &count, sizeof(count) ); for (int i = 0; i < count; i++) { m_drawingFiles.emplace_back(); m_drawingFiles.back().read(stream); } if (m_name.empty()) { m_name = ""; } temp_state |= LINEDATA; if (!stream.eof()) { stream.read( &type, 1 ); } if (!stream.eof() && !stream.good()) { // erk... this shouldn't happen return DAMAGED_FILE; } } if (type == 'p') { readPointMaps( stream ); temp_state |= POINTMAPS; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'g') { // record on state of actual point map: m_pointMaps.back().m_processed = true; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'a') { temp_state |= ANGULARGRAPH; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 'x') { readShapeGraphs(stream); temp_state |= SHAPEGRAPHS; if (!stream.eof()) { stream.read( &type, 1 ); } } if (type == 's') { readDataMaps(stream); temp_state |= DATAMAPS; if (!stream.eof()) { stream.read( &type, 1 ); } } m_state = temp_state; m_view_class = temp_view_class; return OK; } int MetaGraph::write( const std::string& filename, int version, bool currentlayer ) { std::ofstream stream; int oldstate = m_state; m_state = 0; // <- temporarily clear out state, avoids any potential read / write errors char type; // As of MetaGraph version 70 the disk caching has been removed stream.open( filename.c_str(), std::ios::binary | std::ios::out | std::ios::trunc ); if (stream.fail()) { if (stream.rdbuf()->is_open()) { stream.close(); } m_state = oldstate; return DISK_ERROR; } stream.write("grf", 3); m_file_version = version; // <- note, the file may now have an updated file version stream.write( (char *) &version, sizeof(version) ); if (currentlayer) { int tempstate, tempclass; if (m_view_class & VIEWVGA) { tempstate = POINTMAPS; tempclass = VIEWVGA; } else if (m_view_class & MetaGraph::VIEWAXIAL) { tempstate = SHAPEGRAPHS; tempclass = VIEWAXIAL; } else if (m_view_class & MetaGraph::VIEWDATA) { tempstate = DATAMAPS; tempclass = VIEWDATA; } stream.write( (char *) &tempstate, sizeof(tempstate) ); stream.write( (char *) &tempclass, sizeof(tempclass) ); } else { stream.write( (char *) &oldstate, sizeof(oldstate) ); stream.write( (char *) &m_view_class, sizeof(m_view_class) ); } stream.write( (char *) &m_showgrid, sizeof(m_showgrid) ); stream.write( (char *) &m_showtext, sizeof(m_showtext) ); type = 'x'; stream.write(&type, 1); FileProperties::write(stream); if (currentlayer) { if (m_view_class & MetaGraph::VIEWVGA) { type = 'p'; stream.write(&type, 1); writePointMaps( stream, true ); } else if (m_view_class & MetaGraph::VIEWAXIAL) { type = 'x'; stream.write(&type, 1); writeShapeGraphs( stream, true ); } else if (m_view_class & MetaGraph::VIEWDATA) { type = 's'; stream.write(&type, 1); writeDataMaps( stream, true ); } } else { if (oldstate & LINEDATA) { type = 'l'; stream.write(&type, 1); dXstring::writeString(stream, m_name); stream.write( (char *) &m_region, sizeof(m_region) ); // Quick mod - TV int count = m_drawingFiles.size(); stream.write( (char *) &count, sizeof(count) ); for (auto& spacePixel: m_drawingFiles) { spacePixel.write(stream); } } if (oldstate & POINTMAPS) { type = 'p'; stream.write(&type, 1); writePointMaps( stream ); } if (oldstate & SHAPEGRAPHS) { type = 'x'; stream.write(&type, 1); writeShapeGraphs( stream ); } if (oldstate & DATAMAPS) { type = 's'; stream.write(&type, 1); writeDataMaps( stream ); } } stream.close(); m_state = oldstate; return OK; } std::streampos MetaGraph::skipVirtualMem(std::istream& stream) { // it's graph virtual memory: skip it int nodes = -1; stream.read( (char *) &nodes, sizeof(nodes) ); nodes *= 2; for (int i = 0; i < nodes; i++) { int connections; stream.read( (char *) &connections, sizeof(connections) ); stream.seekg( stream.tellg() + std::streamoff(connections * sizeof(connections)) ); } return (stream.tellg()); } std::vector MetaGraph::getVisibleDrawingLines() { std::vector lines; for (const auto& pixelGroup: m_drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { if (pixel.isShown()) { const std::vector &newLines = pixel.getAllShapesAsLines(); lines.insert(std::end(lines), std::begin(newLines), std::end(newLines)); } } } return lines; } int MetaGraph::addNewPointMap(const std::string& name) { std::string myname = name; int counter = 1; bool duplicate = true; while (duplicate) { duplicate = false; for (auto& pointMap: m_pointMaps) { if (pointMap.getName() == myname) { duplicate = true; myname = dXstring::formatString(counter++,name + " %d"); break; } } } m_pointMaps.push_back(PointMap(m_region, m_drawingFiles, myname)); m_displayed_pointmap = m_pointMaps.size() - 1; return m_pointMaps.size() - 1; } bool MetaGraph::readPointMaps(std::istream& stream) { stream.read((char *) &m_displayed_pointmap, sizeof(m_displayed_pointmap)); int count; stream.read((char *) &count, sizeof(count)); for (int i = 0; i < count; i++) { m_pointMaps.push_back(PointMap(m_region, m_drawingFiles)); m_pointMaps.back().read( stream ); } return true; } bool MetaGraph::writePointMaps(std::ofstream& stream, bool displayedmaponly) { if (!displayedmaponly) { stream.write((char *) &m_displayed_pointmap, sizeof(m_displayed_pointmap)); int count = m_pointMaps.size(); stream.write((char *) &count, sizeof(count)); for (auto& pointmap: m_pointMaps) { pointmap.write( stream ); } } else { int dummy; // displayed map is 0: dummy = 0; stream.write((char *) &dummy, sizeof(dummy)); // count is 1 dummy = 1; stream.write((char *) &dummy, sizeof(dummy)); // m_pointMaps[m_displayed_pointmap].write(stream); } return true; } bool MetaGraph::readDataMaps(std::istream& stream ) { m_dataMaps.clear(); // empty existing data // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map; stream.read((char *)&displayed_map,sizeof(displayed_map)); m_displayed_datamap = size_t(displayed_map); // read maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = 0; stream.read((char *) &count, sizeof(count)); for (size_t j = 0; j < size_t(count); j++) { m_dataMaps.emplace_back(); m_dataMaps.back().read(stream); } return true; } bool MetaGraph::writeDataMaps( std::ofstream& stream, bool displayedmaponly ) { if (!displayedmaponly) { // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map = (unsigned int)(m_displayed_datamap); stream.write((char *)&displayed_map,sizeof(displayed_map)); // write maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = (unsigned int) m_dataMaps.size(); stream.write((char *) &count, sizeof(count)); for (size_t j = 0; j < count; j++) { m_dataMaps[j].write(stream); } } else { unsigned int dummy; // displayed map is 0 dummy = 0; stream.write((char *)&dummy,sizeof(dummy)); // count is 1 dummy = 1; stream.write((char *)&dummy,sizeof(dummy)); // write map: m_dataMaps[m_displayed_datamap].write(stream); } return true; } bool MetaGraph::readShapeGraphs(std::istream& stream) { m_shapeGraphs.clear(); // empty existing data // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map; stream.read((char *)&displayed_map,sizeof(displayed_map)); setDisplayedShapeGraphRef(int(displayed_map)); // read maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = 0; stream.read((char *) &count, sizeof(count)); for (size_t j = 0; j < size_t(count); j++) { m_shapeGraphs.push_back(std::unique_ptr(new ShapeGraph())); // P.K. Hairy solution given that we don't know the type/name of the shapegraph // before we actually read it: mark the beginning of the shapegraph in the stream // and if it's found to be an AllLineMap then just roll the stream back and read // from the mark again long mark = stream.tellg(); m_shapeGraphs.back()->read(stream); std::string name = m_shapeGraphs.back()->getName(); if(name == "All-Line Map" || name == "All Line Map") { m_shapeGraphs.pop_back(); m_shapeGraphs.push_back(std::unique_ptr(new AllLineMap())); stream.seekg(mark); m_shapeGraphs.back()->read(stream); } } // P.K: ideally this should be read together with the // all-line map, but the way the graph file is structured // this is not possible // TODO: Fix on next graph file update bool foundAllLineMap = false; for(size_t i = 0; i < m_shapeGraphs.size(); i++) { ShapeGraph* shapeGraph = m_shapeGraphs[i].get(); if(shapeGraph->getName() == "All-Line Map" || shapeGraph->getName() == "All Line Map") { foundAllLineMap = true; AllLineMap* alllinemap = dynamic_cast(shapeGraph); if(alllinemap == nullptr) { throw depthmapX::RuntimeException("Failed to cast from ShapeGraph to AllLineMap"); } // these are additional essentially for all line axial maps // should probably be kept *with* the all line axial map... alllinemap->m_poly_connections.clear(); dXreadwrite::readIntoVector(stream, alllinemap->m_poly_connections); alllinemap->m_radial_lines.clear(); dXreadwrite::readIntoVector(stream, alllinemap->m_radial_lines); // this is an index to look up the all line map, used by UI to determine if can make fewest line map // note: it is not saved for historical reasons // will get confused by more than one all line map m_all_line_map = int(i); // there is currently only one: break; } } if(!foundAllLineMap) { // P.K. This is just a dummy read to cover cases where there is no All-Line Map // The below is taken from pmemvec::read // READ / WRITE USES 32-bit LENGTHS (number of elements) // n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems unsigned int length; stream.read( (char *) &length, sizeof(unsigned int) ); stream.read( (char *) &length, sizeof(unsigned int) ); } return true; } bool MetaGraph::writeShapeGraphs( std::ofstream& stream, bool displayedmaponly ) { if (!displayedmaponly) { // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int displayed_map = (unsigned int)(getDisplayedShapeGraphRef()); stream.write((char *)&displayed_map,sizeof(displayed_map)); // write maps // n.b. -- do not change to size_t as will cause 32-bit to 64-bit conversion problems unsigned int count = (unsigned int) m_shapeGraphs.size(); stream.write((char *) &count, sizeof(count)); for (size_t j = 0; j < count; j++) { m_shapeGraphs[j]->write(stream); } } else { unsigned int dummy; // displayed map is 0 dummy = 0; stream.write((char *)&dummy,sizeof(dummy)); // count is 1 dummy = 1; stream.write((char *)&dummy,sizeof(dummy)); // write map: m_shapeGraphs[getDisplayedShapeGraphRef()]->write(stream); } if(m_all_line_map == -1) { std::vector temp_poly_connections; std::vector temp_radial_lines; dXreadwrite::writeVector(stream, temp_poly_connections); dXreadwrite::writeVector(stream, temp_radial_lines); } else { AllLineMap* alllinemap = dynamic_cast(m_shapeGraphs[size_t(m_all_line_map)].get()); if(alllinemap == nullptr) { throw depthmapX::RuntimeException("Failed to cast from ShapeGraph to AllLineMap"); } dXreadwrite::writeVector(stream, alllinemap->m_poly_connections); dXreadwrite::writeVector(stream, alllinemap->m_radial_lines); } return true; } void MetaGraph::makeViewportShapes( const QtRegion& viewport ) const { m_current_layer = -1; size_t i = m_drawingFiles.size() - 1; for (auto iter = m_drawingFiles.rbegin(); iter != m_drawingFiles.rend(); iter++) { if (iter->isShown()) { m_current_layer = (int) i; iter->makeViewportShapes( (viewport.atZero() ? m_region : viewport) ); } i--; } } bool MetaGraph::findNextShape(bool& nextlayer) const { if (m_current_layer == -1) return false; while (!m_drawingFiles[m_current_layer].findNextShape(nextlayer)) { while (++m_current_layer < (int)m_drawingFiles.size() && !m_drawingFiles[m_current_layer].isShown()); if (m_current_layer == static_cast(m_drawingFiles.size())) { m_current_layer = -1; return false; } } return true; } ================================================ FILE: salalib/mgraph.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Interface: the meta graph loads and holds all sorts of arbitrary data... #include "salalib/mgraph_consts.h" #include "salalib/displayparams.h" #include "salalib/fileproperties.h" #include "salalib/importtypedefs.h" // still call paftl: #include "salalib/connector.h" #include "salalib/spacepix.h" #include "salalib/agents/agentengine.h" // for agent engine interface // still need paftl: #include "salalib/shapemap.h" #include "salalib/pointdata.h" #include "salalib/axialmap.h" #include "genlib/p2dpoly.h" #include #include #include /////////////////////////////////////////////////////////////////////////////////// class Communicator; // A meta graph is precisely what it says it is class MetaGraph : public FileProperties { private: QtRegion m_region; // easier public for now std::string m_name; public: std::vector m_drawingFiles; const QtRegion& getRegion() { return m_region; } void setRegion(Point2f& bottomLeft, Point2f& topRight) { m_region.bottom_left = bottomLeft; m_region.top_right = topRight; } bool isShown() const { for (size_t i = 0; i < m_drawingFiles.size(); i++) if (m_drawingFiles[i].isShown()) return true; return false; } // TODO: drawing state functions/fields that should be eventually removed void makeViewportShapes( const QtRegion& viewport ) const; bool findNextShape(bool& nextlayer) const; const SalaShape& getNextShape() const { return m_drawingFiles[m_current_layer].getNextShape(); } mutable int m_current_layer; enum { ADD = 0x0001, REPLACE = 0x0002, CAT = 0x0010, DXF = 0x0020, NTF = 0x0040, RT1 = 0x0080, GML = 0x0100 }; enum { NONE = 0x0000, POINTMAPS = 0x0002, LINEDATA = 0x0004, ANGULARGRAPH = 0x0010, DATAMAPS = 0x0020, AXIALLINES = 0x0040, SHAPEGRAPHS = 0x0100, BUGGY = 0x8000 }; enum { NOT_EDITABLE = 0, EDITABLE_OFF = 1, EDITABLE_ON = 2 }; protected: int m_file_version; int m_state; public: // some display options now set at file level bool m_showgrid; bool m_showtext; // public: std::vector m_dataMaps; std::vector> m_shapeGraphs; int m_displayed_shapegraph = -1; public: MetaGraph(std::string name = ""); ~MetaGraph(); // int getVersion() { // note, if unsaved, m_file_version is -1 return m_file_version; } std::vector& getPointMaps() { return m_pointMaps; } PointMap& getDisplayedPointMap() { return m_pointMaps[m_displayed_pointmap]; } const PointMap& getDisplayedPointMap() const { return m_pointMaps[m_displayed_pointmap]; } void setDisplayedPointMapRef(int i) { m_displayed_pointmap = i; } int getDisplayedPointMapRef() const { return m_displayed_pointmap; } void redoPointMapBlockLines() // (flags blockedlines, but also flags that you need to rebuild a bsp tree if you have one) { for (auto& pointMap: m_pointMaps) { pointMap.m_blockedlines = false; } } int addNewPointMap(const std::string& name = std::string("VGA Map")); private: std::vector m_pointMaps; int m_displayed_pointmap = -1; // helpful to know this for creating fewest line maps, although has to be reread at input int m_all_line_map = -1; void removePointMap(int i) { if (m_displayed_pointmap >= i) m_displayed_pointmap--; if(m_displayed_pointmap < 0) m_displayed_pointmap = 0; m_pointMaps.erase(m_pointMaps.begin() + i); } bool readPointMaps(std::istream &stream); bool writePointMaps(std::ofstream& stream, bool displayedmaponly = false ); std::recursive_mutex mLock; public: std::unique_lock getLock(){ return std::unique_lock(mLock); } std::unique_lock getLockDeferred(){ return std::unique_lock(mLock, std::defer_lock_t()); } int getState() const { return m_state; } // use with caution: only very rarely needed outside MetaGraph itself void setState(int state) { m_state = state; } int loadLineData( Communicator *communicator, int load_type ); void writeMapShapesAsCat(ShapeMap& map, std::ostream &stream); int loadCat( std::istream& stream, Communicator *communicator ); int loadRT1(const std::vector& fileset, Communicator *communicator); ShapeMap &createNewShapeMap(depthmapX::ImportType mapType, std::string name); void deleteShapeMap(depthmapX::ImportType mapType, ShapeMap &shapeMap); void updateParentRegions(ShapeMap &shapeMap); bool clearPoints(); bool setGrid( double spacing, const Point2f& offset = Point2f() ); // override of PointMap bool makePoints( const Point2f& p, int semifilled, Communicator *communicator = NULL); // override of PointMap bool makeGraph( Communicator *communicator, int algorithm, double maxdist ); bool unmakeGraph(bool removeLinks); bool analyseGraph(Communicator *communicator, Options options , bool simple_version); // <- options copied to keep thread safe // // helpers for editing maps bool isEditableMap(); ShapeMap& getEditableMap(); // currently only making / moving lines, but should be able to extend this to polys fairly easily: bool makeShape(const Line& line); bool moveSelShape(const Line& line); // onto polys as well: int polyBegin(const Line& line); bool polyAppend(int shape_ref, const Point2f& point); bool polyClose(int shape_ref); bool polyCancel(int shape_ref); // int addShapeGraph(std::unique_ptr& shapeGraph); int addShapeGraph(const std::string& name, int type); int addShapeMap(const std::string& name); void removeDisplayedMap(); // // various map conversions bool convertDrawingToAxial(Communicator *comm, std::string layer_name); // n.b., name copied for thread safety bool convertDataToAxial(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues); bool convertDrawingToSegment(Communicator *comm, std::string layer_name); bool convertDataToSegment(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues); bool convertToData(Communicator *, std::string layer_name, bool keeporiginal, int shapeMapType, bool copydata); bool convertToDrawing(Communicator *, std::string layer_name, bool fromDisplayedDataMap); bool convertToConvex(Communicator *comm, std::string layer_name, bool keeporiginal, int shapeMapType, bool copydata); bool convertAxialToSegment(Communicator *comm, std::string layer_name, bool keeporiginal, bool pushvalues, double stubremoval); int loadMifMap(Communicator *comm, std::istream& miffile, std::istream& midfile); bool makeAllLineMap( Communicator *communicator, const Point2f& seed ); bool makeFewestLineMap( Communicator *communicator, int replace ); bool analyseAxial(Communicator *communicator, Options options, bool); // <- options copied to keep thread safe bool analyseSegmentsTulip( Communicator *communicator, Options options ); // <- options copied to keep thread safe bool analyseSegmentsAngular( Communicator *communicator, Options options ); // <- options copied to keep thread safe bool analyseTopoMetMultipleRadii( Communicator *communicator, Options options ); // <- options copied to keep thread safe bool analyseTopoMet( Communicator *communicator, Options options ); // <- options copied to keep thread safe // bool hasAllLineMap() { return m_all_line_map != -1; } bool hasFewestLineMaps() { for(const auto& shapeGraph: m_shapeGraphs) { if(shapeGraph->getName() == "Fewest-Line Map (Subsets)" || shapeGraph->getName() == "Fewest Line Map (Subsets)" || shapeGraph->getName() == "Fewest-Line Map (Minimal)" || shapeGraph->getName() == "Fewest Line Map (Minimal)") { return true; } } return false; } enum { PUSH_FUNC_MAX = 0, PUSH_FUNC_MIN = 1, PUSH_FUNC_AVG = 2, PUSH_FUNC_TOT = 3}; bool pushValuesToLayer(int desttype, int destlayer, int push_func, bool count_col = false); bool pushValuesToLayer(int sourcetype, int sourcelayer, int desttype, int destlayer, int col_in, int col_out, int push_func, bool count_col = false); // int getDisplayedMapRef() const; // // NB -- returns 0 (not editable), 1 (editable off) or 2 (editable on) int isEditable() const; bool canUndo() const; void undo(); size_t m_displayed_datamap = -1; ShapeMap& getDisplayedDataMap() { return m_dataMaps[m_displayed_datamap]; } const ShapeMap& getDisplayedDataMap() const { return m_dataMaps[m_displayed_datamap]; } size_t getDisplayedDataMapRef() const { return m_displayed_datamap; } void removeDataMap(size_t i) { if (m_displayed_datamap >= i && i > 0) m_displayed_datamap--; m_dataMaps.erase(m_dataMaps.begin() + i); } void setDisplayedDataMapRef(size_t map) { if (static_cast(m_displayed_datamap) != -1 && m_displayed_datamap != map) m_dataMaps[m_displayed_datamap].clearSel(); m_displayed_datamap = map; } template size_t getMapRef(std::vector& maps, const std::string& name) const { // note, only finds first map with this name for (size_t i = 0; i < maps.size(); i++) { if (maps[i].getName() == name) return i; } return -1; } std::vector >& getShapeGraphs() { return m_shapeGraphs; } ShapeGraph& getDisplayedShapeGraph() { return *m_shapeGraphs[m_displayed_shapegraph].get(); } const ShapeGraph& getDisplayedShapeGraph() const { return *m_shapeGraphs[m_displayed_shapegraph].get(); } void setDisplayedShapeGraphRef(int map) { if (m_displayed_shapegraph != -1 && m_displayed_shapegraph != map) m_shapeGraphs[size_t(m_displayed_shapegraph)]->clearSel(); m_displayed_shapegraph = map; } int getDisplayedShapeGraphRef() const { return m_displayed_shapegraph; } void removeShapeGraph(int i) { if (m_displayed_shapegraph >= i) m_displayed_shapegraph--; if(m_displayed_shapegraph < 0) m_displayed_shapegraph = 0; m_shapeGraphs.erase(m_shapeGraphs.begin() + i); } bool readShapeGraphs(std::istream &stream); bool writeShapeGraphs(std::ofstream& stream, bool displayedmaponly = false ); std::vector& getDataMaps() { return m_dataMaps; } bool readDataMaps(std::istream &stream); bool writeDataMaps(std::ofstream& stream, bool displayedmaponly = false ); // int getDisplayedMapType(); AttributeTable& getDisplayedMapAttributes(); bool hasVisibleDrawingLayers(); QtRegion getBoundingBox() const; // int getDisplayedAttribute() const; void setDisplayedAttribute(int col); int addAttribute(const std::string& name); void removeAttribute(int col); bool isAttributeLocked(int col); AttributeTable& getAttributeTable(int type = -1, int layer = -1); const AttributeTable& getAttributeTable(int type = -1, int layer = -1) const; LayerManagerImpl& getLayers(int type = -1, int layer = -1); const LayerManagerImpl& getLayers(int type = -1, int layer = -1) const; AttributeTableHandle& getAttributeTableHandle(int type = -1, int layer = -1); const AttributeTableHandle& getAttributeTableHandle(int type = -1, int layer = -1) const; int getLineFileCount() const { return (int) m_drawingFiles.size(); } // Quick mod - TV const std::string& getLineFileName(int file) const { return m_drawingFiles[file].getName(); } int getLineLayerCount(int file) const { return (int) m_drawingFiles[file].m_spacePixels.size(); } ShapeMap& getLineLayer(int file, int layer) { return m_drawingFiles[file].m_spacePixels[layer]; } const ShapeMap& getLineLayer(int file, int layer) const { return m_drawingFiles[file].m_spacePixels[layer]; } // // Some error handling -- the idea is that you catch the error in MetaGraph, // return a generic error code and then get your front end to interrogate the // last error (pretty much as per standard Unix etc). // May have problems with multithreading. public: class Error { protected: std::string error; public: Error(const std::string& err = std::string()) { error = err; } }; protected: Error m_last_error; public: Error& getLastError() { return m_last_error; } // for drawing either axial analysis or VGA protected: int m_view_class; public: enum { SHOWHIDEVGA = 0x0100, SHOWVGATOP = 0x0200, SHOWHIDEAXIAL = 0x0400, SHOWAXIALTOP = 0x0800, SHOWHIDESHAPE = 0x1000, SHOWSHAPETOP = 0x2000 }; enum { VIEWNONE = 0x00, VIEWVGA = 0x01, VIEWBACKVGA = 0x02, VIEWAXIAL = 0x04, VIEWBACKAXIAL = 0x08, VIEWDATA = 0x20, VIEWBACKDATA = 0x40, VIEWFRONT = 0x25 }; // int getViewClass() { return m_view_class; } // These functions make specifying conditions to do things much easier: bool viewingNone() { return (m_view_class == VIEWNONE); } bool viewingProcessed() { return ((m_view_class & (VIEWAXIAL | VIEWDATA)) || (m_view_class & VIEWVGA && getDisplayedPointMap().isProcessed())); } bool viewingShapes() { return (m_view_class & (VIEWAXIAL | VIEWDATA)) != 0; } bool viewingProcessedLines() { return ((m_view_class & VIEWAXIAL) == VIEWAXIAL); } bool viewingProcessedShapes() { return ((m_view_class & VIEWDATA) == VIEWDATA); } bool viewingProcessedPoints() { return ((m_view_class & VIEWVGA) && getDisplayedPointMap().isProcessed()); } bool viewingUnprocessedPoints() { return ((m_view_class & VIEWVGA) && !getDisplayedPointMap().isProcessed()); } // bool setViewClass(int command); // double getLocationValue(const Point2f& point); // public: // these are dependent on what the view class is: bool isSelected() // does a selection exist { if (m_view_class & VIEWVGA) return getDisplayedPointMap().isSelected(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().hasSelectedElements(); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().hasSelectedElements(); else return false; } bool setCurSel( QtRegion& r, bool add = false ) // set current selection { if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().setCurSel(r, add); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().setCurSel( r, add ); else if (m_view_class & VIEWVGA) return getDisplayedPointMap().setCurSel( r, add ); else if (m_state & POINTMAPS && !getDisplayedPointMap().isProcessed()) // this is a default select application return getDisplayedPointMap().setCurSel( r, add ); else if (m_state & DATAMAPS) // I'm not sure why this is a possibility, but it appears you might have state & DATAMAPS without VIEWDATA... return getDisplayedDataMap().setCurSel( r, add ); else return false; } bool clearSel() { // really needs a separate clearSel for the datalayers... at the moment this is handled in PointMap if (m_view_class & VIEWVGA) return getDisplayedPointMap().clearSel(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().clearSel(); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().clearSel(); else return false; } int getSelCount() { if (m_view_class & VIEWVGA) return getDisplayedPointMap().getSelCount(); else if (m_view_class & VIEWAXIAL) return (int) getDisplayedShapeGraph().getSelCount(); else if (m_view_class & VIEWDATA) return (int) getDisplayedDataMap().getSelCount(); else return 0; } float getSelAvg() { if (m_view_class & VIEWVGA) return (float)getDisplayedPointMap().getDisplayedSelectedAvg(); else if (m_view_class & VIEWAXIAL) return (float)getDisplayedShapeGraph().getDisplayedSelectedAvg(); else if (m_view_class & VIEWDATA) return (float)getDisplayedDataMap().getDisplayedSelectedAvg(); else return -1.0f; } QtRegion getSelBounds() { if (m_view_class & VIEWVGA) return getDisplayedPointMap().getSelBounds(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelBounds(); else if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelBounds(); else return QtRegion(); } // setSelSet expects a set of ref ids: void setSelSet(const std::vector& selset, bool add = false) { if (m_view_class & VIEWVGA && m_state & POINTMAPS) getDisplayedPointMap().setCurSel(selset,add); else if (m_view_class & VIEWAXIAL) getDisplayedShapeGraph().setCurSel(selset,add); else // if (m_view_class & VIEWDATA) getDisplayedDataMap().setCurSel(selset,add); } std::set& getSelSet() { if (m_view_class & VIEWVGA && m_state & POINTMAPS) return getDisplayedPointMap().getSelSet(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelSet(); else // if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelSet(); } const std::set& getSelSet() const { if (m_view_class & VIEWVGA && m_state & POINTMAPS) return getDisplayedPointMap().getSelSet(); else if (m_view_class & VIEWAXIAL) return getDisplayedShapeGraph().getSelSet(); else // if (m_view_class & VIEWDATA) return getDisplayedDataMap().getSelSet(); } // public: // no longer supported //int addLineDynamic(const Line& l); //bool removeLineDynamic(LineKey linekey); // // Agent engine interface: protected: AgentEngine m_agent_engine; public: AgentEngine& getAgentEngine() { return m_agent_engine; } void runAgentEngine(Communicator *comm); // public: // thru vision bool analyseThruVision(Communicator *comm = NULL, int gatelayer = -1); // BSP tree for making isovists protected: BSPNode *m_bsp_root; bool m_bsp_tree; public: bool makeBSPtree(Communicator *communicator = NULL); void resetBSPtree() { m_bsp_tree = false; } // returns 0: fail, 1: made isovist, 2: made isovist and added new shapemap layer int makeIsovist(Communicator *communicator, const Point2f& p, double startangle = 0, double endangle = 0, bool simple_version = true); // returns 0: fail, 1: made isovist, 2: made isovist and added new shapemap layer int makeIsovistPath(Communicator *communicator, double fov_angle = 2.0 * M_PI, bool simple_version = true); bool makeIsovist(const Point2f& p, Isovist& iso); protected: // properties public: // a few read-write returns: enum { OK, WARN_BUGGY_VERSION, WARN_CONVERTED, NOT_A_GRAPH, DAMAGED_FILE, DISK_ERROR, NEWER_VERSION, DEPRECATED_VERSION }; // likely to use communicator if too slow... int readFromFile( const std::string& filename ); int readFromStream( std::istream &stream, const std::string& filename ); int write( const std::string& filename, int version, bool currentlayer = false); // std::vector getVisibleDrawingLines(); protected: std::streampos skipVirtualMem(std::istream &stream); }; ================================================ FILE: salalib/mgraph_consts.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once // Human readable(ish) metagraph version changes const int VERSION_ALWAYS_RECORD_BINDISTANCES = 440; // Current metagraph version const int METAGRAPH_VERSION = VERSION_ALWAYS_RECORD_BINDISTANCES; /////////////////////////////////////////////////////////////////////////////// const unsigned int SALA_SELECTED_COLOR = 0x00FFFF77; const unsigned int SALA_HIGHLIGHTED_COLOR = 0x0077FFFF; /////////////////////////////////////////////////////////////////////////////// // Parse errors for MapInfo: enum { MINFO_OK, MINFO_HEADER, MINFO_TABLE, MINFO_MIFPARSE, MINFO_OBJROWS, MINFO_MULTIPLE }; /////////////////////////////////////////////////////////////////////////////// ================================================ FILE: salalib/ngraph.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ngraph.cpp #include #include #include #include #include "genlib/containerutils.h" void Node::make(const PixelRef pix, PixelRefVector *bins, float *bin_far_dists, int q_octants) { m_pixel = pix; for (int i = 0; i < 32; i++) { if (q_octants != 0x00FF) { // now, an octant filter has been used... note that the exact q-octants that // will have been processed rely on adjacenies in the q_octants... if (!(q_octants & processoctant(i))) { continue; } } m_bins[i].m_distance = bin_far_dists[i]; if (i == 4 || i == 20) { m_bins[i].make(bins[i], PixelRef::POSDIAGONAL); } else if (i == 12 || i == 28) { m_bins[i].make(bins[i], PixelRef::NEGDIAGONAL); } else if ((i > 4 && i < 12) || (i > 20 && i < 28)) { m_bins[i].make(bins[i], PixelRef::VERTICAL); } else { m_bins[i].make(bins[i], PixelRef::HORIZONTAL); } // Now clear the bin! bins[i].clear(); } } void Node::extractUnseen(PixelRefVector& pixels, PointMap *pointdata) { for (int i = 0; i < 32; i++) { m_bins[i].extractUnseen(pixels, pointdata, (1 << i)); } } void Node::extractMetric(std::set& pixels, PointMap *pointdata, const MetricTriple& curs) { //if (dist == 0.0f || concaveConnected()) { // increases effiency but is too inaccurate //if (dist == 0.0f || !fullyConnected()) { // increases effiency but can miss lines if (curs.dist == 0.0f || pointdata->getPoint(curs.pixel).blocked() || pointdata->blockedAdjacent(curs.pixel)) { for (int i = 0; i < 32; i++) { m_bins[i].extractMetric(pixels, pointdata, curs); } } } // based on extract metric void Node::extractAngular(std::set& pixels, PointMap *pointdata, const AngularTriple& curs) { if (curs.angle == 0.0f || pointdata->getPoint(curs.pixel).blocked() || pointdata->blockedAdjacent(curs.pixel)) { for (int i = 0; i < 32; i++) { m_bins[i].extractAngular(pixels, pointdata, curs); } } } bool Node::concaveConnected() { // not quite correct -- sometimes at corners you 'see through' the very first connection // but a useful approximation: to be concave connected, you need less than 3 in a row somewhere: unsigned int test = 0; // note wraps around test |= (m_bins[0].count()) ? 0 : 0x101; test |= (m_bins[4].count()) ? 0 : 0x202; test |= (m_bins[8].count()) ? 0 : 0x404; test |= (m_bins[12].count()) ? 0 : 0x808; test |= (m_bins[16].count()) ? 0 : 0x010; test |= (m_bins[20].count()) ? 0 : 0x020; test |= (m_bins[24].count()) ? 0 : 0x040; test |= (m_bins[28].count()) ? 0 : 0x080; if (test != 0) { for (int i = 0; i < 8; i++) { if (((~test) & 1) && (test & 4) && ((~test) & 12)) { // less than 3 in a row test return true; } test >>= 1; } } return false; } bool Node::fullyConnected() { // not quite correct -- sometimes at corners you 'see through' the very first connection return (m_bins[0].count() && m_bins[4].count() && m_bins[8].count() && m_bins[12].count() && m_bins[16].count() && m_bins[20].count() && m_bins[24].count() && m_bins[28].count()); } ////////////////////////////////////////////////////////////////////////////////// bool Node::containsPoint(const PixelRef pixel) const { bool found = false; int start, end; // This should really calculate which bin it ought to be in, but for now, // we'll reduce by quadrant: if (pixel.x > m_pixel.x) { if (pixel.y >= m_pixel.y) { start = 0; end = 7; } else { start = 25; end = 31; } } else { if (pixel.y > m_pixel.y) { start = 8; end = 15; } else { start = 16; end = 24; } } for (int i = start; i <= end; i++) { if (m_bins[i].containsPoint(pixel)) { found = true; break; } } return found; } ////////////////////////////////////////////////////////////////////////////////// void Node::first() const { m_curbin = 0; do { m_bins[m_curbin].first(); } while (m_bins[m_curbin].is_tail() && ++m_curbin < 32); } void Node::next() const { m_bins[m_curbin].next(); while (m_bins[m_curbin].is_tail() && ++m_curbin < 32) { m_bins[m_curbin].first(); } } bool Node::is_tail() const { return m_curbin == 32; } PixelRef Node::cursor() const { return m_bins[m_curbin].cursor(); } void Node::contents(PixelRefVector& hood) const { first(); while (!is_tail()) { depthmapX::addIfNotExists(hood, cursor()); next(); } } ////////////////////////////////////////////////////////////////////////////////// std::istream& Node::read(std::istream& stream) { int i; for (i = 0; i < 32; i++) { m_bins[i].read(stream); } for (i = 0; i < 32; i++) { dXreadwrite::readIntoVector(stream, m_occlusion_bins[i]); } return stream; } std::ostream& Node::write(std::ostream& stream) { int i; for (i = 0; i < 32; i++) { m_bins[i].write(stream); } for (i = 0; i < 32; i++) { dXreadwrite::writeVector(stream, m_occlusion_bins[i]); } return stream; } std::ostream& operator << (std::ostream& stream, const Node& node) { for (int i = 0; i < 32; i++) { if (node.m_bins[i].count()) { stream << " " << node.m_bins[i] << std::endl; } } return stream; } /////////////////////////////////////////////////////////////////////////////////////// void Bin::make(const PixelRefVector& pixels, char dir) { m_pixel_vecs.clear(); m_node_count = 0; if (pixels.size()) { m_dir = dir; if (m_dir & PixelRef::DIAGONAL) { PixelVec cur( pixels[0], pixels[0] ); // Special, the diagonal should be pixels directly along the diagonal // Both posdiagonal and negdiagonal are positive in the x direction // Note that it is ordered anyway, so no need for anything too fancy: if (pixels.back().x < cur.start().x) { cur.m_start = pixels.back(); } if (pixels.back().x > cur.end().x) { cur.m_end = pixels.back(); } m_pixel_vecs.push_back(cur); m_node_count = pixels.size(); } else { // Reorder the pixels: if (m_dir == PixelRef::HORIZONTAL) { std::set pixels_h; for (size_t i = 0; i < pixels.size(); i++) { pixels_h.insert(PixelRefH(pixels[i])); } // this looks like a simple bubble sort auto curr = pixels_h.begin(); m_pixel_vecs.push_back(PixelVec(*curr, *curr)); ++curr; auto prev = pixels_h.begin(); for (;curr != pixels_h.end(); ++curr) { if (prev->y != curr->y || prev->x + 1 != curr->x) { m_pixel_vecs.back().m_end = *prev; m_pixel_vecs.push_back(PixelVec(*curr, *curr)); } prev = curr; } m_pixel_vecs.back().m_end = *pixels_h.rbegin(); } if (m_dir == PixelRef::VERTICAL) { std::set pixels_v; for (size_t i = 0; i < pixels.size(); i++) { pixels_v.insert(PixelRefV(pixels[i])); } // this looks like a simple bubble sort auto curr = pixels_v.begin(); m_pixel_vecs.push_back(PixelVec(*curr, *curr)); ++curr; auto prev = pixels_v.begin(); for (;curr != pixels_v.end(); ++curr) { if (prev->x != curr->x || prev->y + 1 != curr->y) { m_pixel_vecs.back().m_end = *prev; m_pixel_vecs.push_back(PixelVec(*curr, *curr)); } prev = curr; } m_pixel_vecs.back().m_end = *pixels_v.rbegin(); } m_node_count = pixels.size(); } } } /////////////////////////////////////////////////////////////////////////////////////// void Bin::extractUnseen(PixelRefVector& pixels, PointMap *pointdata, int binmark) { for (auto pixVec: m_pixel_vecs) { for (PixelRef pix = pixVec.start(); pix.col(m_dir) <= pixVec.end().col(m_dir); ) { Point& pt = pointdata->getPoint(pix); if (pointdata->getPoint(pix).m_misc == 0) { pixels.push_back(pix); pointdata->getPoint(pix).m_misc |= binmark; } // 10.2.02 revised --- diagonal was breaking this as it was extent in diagonal or horizontal if (!(m_dir & PixelRef::DIAGONAL)) { if (pt.m_extent.col(m_dir) >= pixVec.end().col(m_dir)) break; pt.m_extent.col(m_dir) = pixVec.end().col(m_dir); } pix.move(m_dir); } } } /////////////////////////////////////////////////////////////////////////////////////// void Bin::extractMetric(std::set& pixels, PointMap *pointdata, const MetricTriple& curs) { for (auto pixVec: m_pixel_vecs) { for (PixelRef pix = pixVec.start(); pix.col(m_dir) <= pixVec.end().col(m_dir); ) { Point& pt = pointdata->getPoint(pix); if (pt.m_misc == 0 && (pt.m_dist == -1.0 || (curs.dist + dist(pix,curs.pixel) < pt.m_dist))) { pt.m_dist = curs.dist + (float) dist(pix,curs.pixel); // n.b. dmap v4.06r now sets angle in range 0 to 4 (1 = 90 degrees) pt.m_cumangle = pointdata->getPoint(curs.pixel).m_cumangle + (curs.lastpixel == NoPixel ? 0.0f : (float) (angle(pix,curs.pixel,curs.lastpixel) / (M_PI * 0.5))); pixels.insert(MetricTriple(pt.m_dist, pix, curs.pixel)); } pix.move(m_dir); } } } // based on metric void Bin::extractAngular(std::set& pixels, PointMap *pointdata, const AngularTriple& curs) { for (auto pixVec: m_pixel_vecs) { for (PixelRef pix = pixVec.start(); pix.col(m_dir) <= pixVec.end().col(m_dir); ) { Point& pt = pointdata->getPoint(pix); if (pt.m_misc == 0) { // n.b. dmap v4.06r now sets angle in range 0 to 4 (1 = 90 degrees) float ang = (curs.lastpixel == NoPixel) ? 0.0f : (float) (angle(pix,curs.pixel,curs.lastpixel) / (M_PI * 0.5)); if (pt.m_cumangle == -1.0 || curs.angle + ang < pt.m_cumangle) { pt.m_cumangle = pointdata->getPoint(curs.pixel).m_cumangle + ang; pixels.insert(AngularTriple(pt.m_cumangle, pix, curs.pixel)); } } pix.move(m_dir); } } } /////////////////////////////////////////////////////////////////////////////////////// bool Bin::containsPoint(const PixelRef p) const { for (auto pixVec: m_pixel_vecs) { if (m_dir & PixelRef::DIAGONAL) { // note abs is only allowed if you have pre-checked you are in the right quadrant! if (p.x >= pixVec.start().x && p.x <= pixVec.end().x && abs(p.y - pixVec.start().y) == p.x - pixVec.start().x) { return true; } } else { if (p.row(m_dir) == pixVec.start().row(m_dir) && p.col(m_dir) >= pixVec.start().col(m_dir) && p.col(m_dir) <= pixVec.end().col(m_dir)) { return true; } } } return false; } /////////////////////////////////////////////////////////////////////////////////////// void Bin::first() const { m_curvec = 0; if (!m_pixel_vecs.empty()) m_curpix = m_pixel_vecs[m_curvec].m_start; } void Bin::next() const { if (m_curpix.move(m_dir).col(m_dir) > m_pixel_vecs[m_curvec].end().col(m_dir)) { m_curvec++; if (m_curvec < static_cast(m_pixel_vecs.size())) m_curpix = m_pixel_vecs[m_curvec].m_start; } } bool Bin::is_tail() const { return m_curvec >= static_cast(m_pixel_vecs.size()); } PixelRef Bin::cursor() const { return (int) m_curpix; } /////////////////////////////////////////////////////////////////////////////////////// std::istream& Bin::read(std::istream& stream) { stream.read( (char *) &m_dir, sizeof(m_dir) ); stream.read( (char *) &m_node_count, sizeof(m_node_count) ); stream.read( (char *) &m_distance, sizeof(m_distance) ); stream.read( (char *) &m_occ_distance, sizeof(m_occ_distance) ); if (m_node_count) { if (m_dir & PixelRef::DIAGONAL) { m_pixel_vecs = std::vector(1); m_pixel_vecs[0].read(stream, m_dir); } else { unsigned short length; stream.read( (char *) &length, sizeof(length) ); m_pixel_vecs = std::vector(length); m_pixel_vecs[0].read(stream, m_dir); for (int i = 1; i < length; i++) { m_pixel_vecs[i].read(stream, m_dir,m_pixel_vecs[i-1]); } } } return stream; } std::ostream& Bin::write(std::ostream& stream) { stream.write( (char *) &m_dir, sizeof(m_dir) ); stream.write( (char *) &m_node_count, sizeof(m_node_count) ); stream.write( (char *) &m_distance, sizeof(m_distance) ); stream.write( (char *) &m_occ_distance, sizeof(m_occ_distance) ); if (m_node_count) { if (m_dir & PixelRef::DIAGONAL) { m_pixel_vecs[0].write(stream,m_dir); } else { // TODO: Remove this limitation in the next version of the .graph format unsigned short length = m_pixel_vecs.size(); stream.write( (char *) &length, sizeof(length) ); m_pixel_vecs[0].write(stream,m_dir); for (int i = 1; i < length; i++) { m_pixel_vecs[i].write(stream,m_dir,m_pixel_vecs[i-1]); } } } return stream; } std::ostream& operator << (std::ostream& stream, const Bin& bin) { int c = 0; for (auto pixVec: bin.m_pixel_vecs) { for (PixelRef p = pixVec.m_start; p.col(bin.m_dir) <= pixVec.end().col(bin.m_dir); p.move(bin.m_dir)) { if (++c % 10 == 0) { stream << "\n "; } stream << p << ","; } } return stream; } /////////////////////////////////////////////////////////////////////////////////////// std::istream& PixelVec::read(std::istream& stream, const char dir) { unsigned short runlength; stream.read((char *) &m_start, sizeof(m_start)); stream.read((char *) &runlength, sizeof(runlength)); switch (dir) { case PixelRef::POSDIAGONAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y + runlength; break; case PixelRef::NEGDIAGONAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y - runlength; break; case PixelRef::HORIZONTAL: m_end.x = m_start.x + runlength; m_end.y = m_start.y; break; case PixelRef::VERTICAL: m_end.x = m_start.x; m_end.y = m_start.y + runlength; break; } return stream; } std::ostream& PixelVec::write(std::ostream& stream, const char dir) { stream.write((char *) &m_start, sizeof(m_start)); unsigned short runlength; switch (dir) { case PixelRef::HORIZONTAL: case PixelRef::POSDIAGONAL: case PixelRef::NEGDIAGONAL: runlength = m_end.x - m_start.x; break; case PixelRef::VERTICAL: runlength = m_end.y - m_start.y; break; } stream.write((char *) &runlength, sizeof(runlength)); return stream; } struct ShiftLength { unsigned short shift : 4; unsigned short runlength : 12; }; std::istream& PixelVec::read(std::istream& stream, const char dir, const PixelVec& context) { short primary; ShiftLength shiftlength; stream.read((char *) &primary, sizeof(primary)); stream.read((char *) &shiftlength, sizeof(shiftlength)); switch (dir) { case PixelRef::HORIZONTAL: m_start.x = primary; m_start.y = context.m_start.y + shiftlength.shift; m_end.x = m_start.x + shiftlength.runlength; m_end.y = m_start.y; break; case PixelRef::VERTICAL: m_start.x = context.m_start.x + shiftlength.shift; m_start.y = primary; m_end.x = m_start.x; m_end.y = m_start.y + shiftlength.runlength; break; } return stream; } std::ostream& PixelVec::write(std::ostream& stream, const char dir, const PixelVec& context) { ShiftLength shiftlength; switch (dir) { case PixelRef::HORIZONTAL: stream.write((char *) &(m_start.x), sizeof(m_start.x)); shiftlength.runlength = m_end.x - m_start.x; shiftlength.shift = m_start.y - context.m_start.y; break; case PixelRef::VERTICAL: stream.write((char *) &(m_start.y), sizeof(m_start.y)); shiftlength.runlength = m_end.y - m_start.y; shiftlength.shift = m_start.x - context.m_start.x; break; } stream.write((char *) &shiftlength, sizeof(shiftlength)); return stream; } ================================================ FILE: salalib/ngraph.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // ngraph.h #pragma once #include "salalib/pixelref.h" #include class PointMap; struct MetricPair; struct MetricTriple; struct AngularTriple; struct PixelVec { PixelRef m_start; PixelRef m_end; PixelVec(const PixelRef start = NoPixel, const PixelRef end = NoPixel) { m_start = (int) start; m_end = (int) end; }; PixelRef start() const { return m_start; } PixelRef end() const { return m_end; } // std::istream &read(std::istream &stream, const char dir); std::istream &read(std::istream &stream, const char dir, const PixelVec& context); std::ostream &write(std::ostream &stream, const char dir); std::ostream &write(std::ostream &stream, const char dir, const PixelVec& context); }; class Bin { friend class Node; protected: unsigned short m_node_count; float m_distance; float m_occ_distance; public: char m_dir; std::vector m_pixel_vecs; Bin() { m_dir = PixelRef::NODIR; m_node_count = 0; m_distance = 0.0f; m_occ_distance = 0.0f; } // void make(const PixelRefVector& pixels, char m_dir); void extractUnseen(PixelRefVector& pixels, PointMap *pointdata, int binmark); void extractMetric(std::set &pixels, PointMap *pointdata, const MetricTriple& curs); void extractAngular(std::set &pixels, PointMap *pointdata, const AngularTriple& curs); // int count() const { return m_node_count; } float distance() const { return m_distance; } float occdistance() const { return m_occ_distance; } // void setOccDistance(float d) { m_occ_distance = d; } // bool containsPoint(const PixelRef p) const; // // Iterator protected: // Conversion back to old fashioned schema: mutable int m_curvec; mutable PixelRef m_curpix; public: void first() const; void next() const; bool is_tail() const; PixelRef cursor() const; // std::istream &read(std::istream &stream); std::ostream &write(std::ostream &stream); // friend std::ostream& operator << (std::ostream& stream, const Bin& bin); }; class Node { protected: PixelRef m_pixel; Bin m_bins[32]; public: // testing some agent stuff: std::vector m_occlusion_bins[32]; public: // Note: this function clears the bins as it goes void make(const PixelRef pix, PixelRefVector *bins, float *bin_far_dists, int q_octants); void extractUnseen(PixelRefVector& pixels, PointMap *pointdata); void extractMetric(std::set &pixels, PointMap *pointdata, const MetricTriple& curs); void extractAngular(std::set &pixels, PointMap *pointdata, const AngularTriple& curs); bool concaveConnected(); bool fullyConnected(); // void setPixel(const PixelRef& pixel) { m_pixel = pixel; } // const Bin& bin(int i) const { return m_bins[i]; } Bin& bin(int i) { return m_bins[i]; } // int count() { int c = 0; for (int i = 0; i < 32; i++) c += m_bins[i].count(); return c; } int bincount(int i) { return m_bins[i].count(); } float bindistance(int i) { return m_bins[i].distance(); } void setbindistances(float bin_dists[32]) { for (int i = 0; i < 32; i++) m_bins[i].m_distance = bin_dists[i]; } float occdistance(int i) { return m_bins[i].occdistance(); } // bool containsPoint(const PixelRef p) const; // // // Iterator: protected: // Conversion back to old fashioned schema: mutable int m_curbin; public: void contents(PixelRefVector& hood) const; void first() const; void next() const; bool is_tail() const; PixelRef cursor() const; // std::istream &read(std::istream &stream); std::ostream &write(std::ostream &stream); // friend std::ostream& operator << (std::ostream& stream, const Node& node); }; // Two little helpers: class PixelRefH : public PixelRef { public: PixelRefH() : PixelRef() {;} PixelRefH(const PixelRef& p) : PixelRef(p) {;} friend bool operator > (const PixelRefH& a, const PixelRefH& b); friend bool operator < (const PixelRefH& a, const PixelRefH& b); }; inline bool operator > (const PixelRefH& a, const PixelRefH& b) { return (a.y > b.y || (a.y == b.y && a.x > b.x)); } inline bool operator < (const PixelRefH& a, const PixelRefH& b) { return (a.y < b.y || (a.y == b.y && a.x < b.x)); } class PixelRefV : public PixelRef { public: PixelRefV() : PixelRef() {;} PixelRefV(const PixelRef& p) : PixelRef(p) {;} friend bool operator > (const PixelRefV& a, const PixelRefV& b); friend bool operator < (const PixelRefV& a, const PixelRefV& b); }; inline bool operator > (const PixelRefV& a, const PixelRefV& b) { return (a.x > b.x || (a.x == b.x && a.y > b.y)); } inline bool operator < (const PixelRefV& a, const PixelRefV& b) { return (a.x < b.x || (a.x == b.x && a.y < b.y)); } ================================================ FILE: salalib/options.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include #include // Options for mean depth calculations struct Options { enum output_t { OUTPUT_ISOVIST, OUTPUT_VISUAL, OUTPUT_METRIC, OUTPUT_ANGULAR, OUTPUT_THRU_VISION, OUTPUT_CLIQUE_GRAPH, OUTPUT_KERNEL_GRAPH, OUTPUT_MATRIX_REDUCTION }; // Output type, see above int output_type; // Options for the summary type: int local; int global; int cliques; // bool choice; // include measures that can be derived: RA, RRA and total depth bool fulloutput; // enum { RADIUS_STEPS, RADIUS_METRIC, RADIUS_ANGULAR }; int radius_type; double radius; // <- n.b. for metric integ radius is floating point // radius has to go up to a list (phase out radius as is) std::set radius_set; // int point_depth_selection; int tulip_bins; bool process_in_memory; bool sel_only; bool gates_only; // for pushing to a gates layer int gatelayer; // a column to weight measures by: int weighted_measure_col; int weighted_measure_col2; //EFEF int routeweight_col; //EFEF std::string output_file; // To save an output graph (for example) // default values Options() { local = 0; global = 1; cliques = 0; choice = false; fulloutput = false; point_depth_selection = 0; tulip_bins = 1024; radius = -1; radius_type = 0; output_type = OUTPUT_ISOVIST; process_in_memory = false; gates_only = false; sel_only = false; gatelayer = -1; weighted_measure_col = -1;} }; ================================================ FILE: salalib/pafcolor.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include // _finite support #include // <- sala actually includes vertex.h for us static unsigned int g_nicecolor[] = { 0x003333DD, // 0 blue 0x003388DD, // 1 0x0022CCDD, // 2 0x0022CCBB, // 3 0x0022DD88, // 4 0x0088DD22, // 5 0x00BBCC22, // 6 0x00DDCC22, // 7 0x00DD8833, // 8 0x00DD3333, // 9 red }; // Test a range designed to try to keep consistent saturation and brightness of g_nicecolor, and only move hue static unsigned int g_nicecolorhsb[] = { 0x003333DD, // 0 blue 0x003377DD, // 1 0x0033BBDD, // 2 0x0033DDBB, // 3 0x0033DD55, // 4 0x0055DD33, // 5 0x00BBDD33, // 6 0x00DDBB33, // 7 0x00DD7733, // 8 0x00DD3333, // 9 red }; static unsigned int g_greyscale[] = { 0x00000000, // 0 black 0x00444444, // 1 0x00777777, // 2 0x00AAAAAA, // 3 0x00CCCCCC, // 4 0x00EEEEEE, // 5 0x00FFFFFF, // 6 white }; static unsigned int g_bluered[] = { 0x004575B4, // 0 blue 0x0091BFDB, 0x00E0F3F8, 0x00FFFFBF, 0x00FEE090, 0x00FC8D59, 0x00D73027 // 6 red }; static unsigned int g_purpleorange[] = { 0x00542788, // 0 purple 0x00998EC3, // 1 0x00D8DAEB, // 2 0x00F7F7F7, // 3 0x00FEE0B6, // 4 0x00F1A340, // 5 0x00B35806 // 6 orange }; // htmlByte converts a normalised number to an HTML safe byte unsigned char htmlByte(double colorByte) { // Quick mod - TV #if defined(_MSC_VER) return (unsigned char((colorByte + 0.0333) * 15.0) * 0x11); #else return ((unsigned char)((colorByte + 0.0333) * 15.0) * 0x11); #endif } PafColor& PafColor::makeColor(double field, DisplayParams dp) { // Quick mod - TV if (field == -1.0 || std::isnan(field)) { // -1.0 is (currently) a nan value, set alpha channel to 0 (transparent) switch (dp.colorscale) { case DisplayParams::MONOCHROME: case DisplayParams::GREYSCALE: m_color = 0x00000000; // <- monochrome and greyscale, simply hide break; default: // if in colour, then show greyed out: m_color = 0x007f7f7f; // <- grey retained for visibility on certain values break; } return *this; } if (dp.blue > dp.red) { field = 1.0 - field; dp.blue = 1.0f - dp.blue; dp.red = 1.0f - dp.red; } if (dp.colorscale == DisplayParams::DEPTHMAPCLASSIC) { makeDepthmapClassic(field, dp.blue, dp.red); } else { field = (field - dp.blue) / (dp.red - dp.blue); // Quick mod - TV if (std::isnan(field)) { field = 0.5; } if (field > 1.0) { field = 1.0; } else if (field < 0.0) { field = 0.0; } switch(dp.colorscale) { case DisplayParams::AXMANESQUE: makeAxmanesque(field); break; case DisplayParams::HUEONLYAXMANESQUE: makeHueOnlyAxmanesque(field); break; case DisplayParams::PURPLEORANGE: makePurpleOrange(field); break; case DisplayParams::BLUERED: makeBlueRed(field); break; case DisplayParams::GREYSCALE: case DisplayParams::MONOCHROME: makeGreyScale(field); break; } } return *this; } // this makes an Axman-like colour range PafColor& PafColor::makeAxmanesque( double field ) { m_color = 0xff000000 | g_nicecolor[int((field - 1e-9) * 10.0)]; return *this; } PafColor& PafColor::makeHueOnlyAxmanesque( double field ) { m_color = 0xff000000 | g_nicecolorhsb[int((field - 1e-9) * 10.0)]; return *this; } // this makes a purple-orange scheme that is red-green colour-blind safe PafColor& PafColor::makePurpleOrange( double field ) { m_color = 0xff000000 | g_purpleorange[int((field - 1e-9) * 7.0)]; return *this; } // this makes a blue-red scheme that is red-green colour-blind safe PafColor& PafColor::makeBlueRed( double field ) { m_color = 0xff000000 | g_bluered[int((field - 1e-9) * 7.0)]; return *this; } // this makes a greyscale colour range PafColor& PafColor::makeGreyScale( double field ) { m_color = 0xff000000 | g_greyscale[int((field - 1e-9) * 7.0)]; return *this; } // note, makeDepthmapClassic converts to a safe HTML colour PafColor& PafColor::makeDepthmapClassic( double field, double blue, double red ) { m_color = 0xff000000; // set alpha to 255, solid colour double green = blue + (red-blue) / 10.0; // NB previously included colour muting: the 1.0 was originally 0.9 to mute the colours slightly if (field >= 0.0 && field < blue) { setr(htmlByte(0.5 * (blue - field)/blue * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setb(unsigned char(0xFF)); #else setb((unsigned char)(0xFF)); #endif } else if (field >= blue && field < (green+blue)/2.0) { // Quick mod - TV #if defined(_MSC_VER) setb(unsigned char(0xFF)); #else setb((unsigned char)(0xFF)); #endif setg(htmlByte((2.0*(field - blue)/(green-blue)) * 1.0)); } else if (field >= (green+blue)/2.0 && field < green) { setb(htmlByte((2.0*(green - field)/(green-blue)) * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setg(unsigned char(0xFF)); #else setg((unsigned char)(0xFF)); #endif } else if (field >= green && field < (green+red)/2.0 ) { // Quick mod - TV #if defined(_MSC_VER) setg(unsigned char(0xFF)); #else setg((unsigned char)(0xFF)); #endif setr(htmlByte((2.0*(field - green)/(red-green)) * 1.0)); } else if (field >= (green+red)/2.0 && field < red) { setg(htmlByte((2.0*(red - field)/(red-green)) * 1.0)); // Quick mod - TV #if defined(_MSC_VER) setr(unsigned char(0xFF)); #else setr((unsigned char)(0xFF)); #endif } else if (field >= red) { // Quick mod - TV #if defined(_MSC_VER) setr(unsigned char(0xFF)); #else setr((unsigned char)(0xFF)); #endif setb(htmlByte(0.5 * (field - red)/(1.0 - red) * 1.0)); } return *this; } ================================================ FILE: salalib/pafcolor.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/displayparams.h" #include "genlib/p2dpoly.h" // For my colour scheme... some parameters to pass, and my own colour class // Converts everything to safe HTML colours struct PafColor { unsigned int m_color; unsigned char redb() const { return (unsigned char) (m_color >> 16); } unsigned char greenb() const { return (unsigned char) (m_color >> 8); } unsigned char blueb() const { return (unsigned char) (m_color); } unsigned char alphab() const { return (unsigned char) (m_color >> 24); } // Quick mod - TV void setr(unsigned char r) { m_color &= 0xff00ffff; m_color |= (((unsigned int)r) << 16);} // Quick mod - TV void setg(unsigned char g) { m_color &= 0xffff00ff; m_color |= (((unsigned int)g) << 8);} // Quick mod - TV void setb(unsigned char b) { m_color &= 0xffffff00; m_color |= ((unsigned int)b);} float redf() const { return float(redb()) / 255.0f; } float greenf() const { return float(greenb()) / 255.0f; } float bluef() const { return float(blueb()) / 255.0f; } PafColor() { m_color = 0x00000000; } PafColor(unsigned int rgb) // color in 0x00rrggbb format { m_color = 0xff000000 | rgb; } PafColor( double r, double g, double b, double a = 1.0 ) { m_color = 0x00000000 | (((unsigned char) (a * 255.0)) << 24) | (((unsigned char) (r * 255.0)) << 16) | (((unsigned char) (g * 255.0)) << 8) | (((unsigned char) (b * 255.0))); } PafColor( const Point2f& vec, double a = 1.0 ) { m_color = 0x00000000 | (((unsigned char) (a * 255.0)) << 24) | (((unsigned char) (dot(vec,Point2f(1.0, 0.0)) * 255.0)) << 16) | (((unsigned char) (dot(vec,Point2f(-0.5,0.86602540378443864676372317075294)) * 255.0)) << 8) | (((unsigned char) (dot(vec,Point2f(-0.5,-0.86602540378443864676372317075294)) * 255.0))); } operator unsigned int () { return m_color & 0x00ffffff; } friend bool operator == (const PafColor& a, const PafColor& b); friend bool operator != (const PafColor& a, const PafColor& b); PafColor& makeAxmanesque( double field); PafColor& makeHueOnlyAxmanesque( double field); PafColor& makePurpleOrange( double field ); PafColor& makeBlueRed( double field ); PafColor& makeGreyScale( double field ); PafColor& makeMonochrome( double field ); PafColor& makeDepthmapClassic( double field, double blue, double red ); PafColor& makeColor(double field, DisplayParams dp); // <- note, make copy to play around with }; inline bool operator == (const PafColor& a, const PafColor& b) { return (a.m_color == b.m_color); } inline bool operator != (const PafColor& a, const PafColor& b) { return (a.m_color != b.m_color); } ================================================ FILE: salalib/parsers/CMakeLists.txt ================================================ target_sources(salalib PRIVATE ntfp.cpp dxfp.cpp mapinfodata.cpp tigerp.cpp PUBLIC dxfp.h ntfp.h mapinfodata.h tigerp.h) ================================================ FILE: salalib/parsers/dxfp.cpp ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // parser class #include "dxfp.h" #include "genlib/comm.h" // for communicator #include "genlib/stringutils.h" #include #include #include #include static int counter = 0; /////////////////////////////////////////////////////////////////////////////// bool operator > (const DxfTableRow& a, const DxfTableRow& b) // for hash table { return a.m_name > b.m_name; } bool operator < (const DxfTableRow& a, const DxfTableRow& b) // for hash table { return a.m_name < b.m_name; } bool operator == (const DxfTableRow& a, const DxfTableRow& b) // for hash table { return a.m_name == b.m_name; } /////////////////////////////////////////////////////////////////////////////// DxfParser::DxfParser(Communicator *comm /* = NULL */) { m_communicator = comm; m_size = 0; m_time = 0; } const DxfVertex& DxfParser::getExtMin() const { return m_region.getExtMin(); } const DxfVertex& DxfParser::getExtMax() const { return m_region.getExtMax(); } DxfLayer *DxfParser::getLayer( const std::string& layer_name ) // const <- removed as m_layers may be changed if DXF is poor { std::map::iterator layerIter = m_layers.find(layer_name); if (layerIter == m_layers.end()) { m_layers.insert( std::pair (layer_name, DxfLayer(layer_name))); return &(m_layers.find(layer_name)->second); } return &(layerIter->second); } DxfLineType *DxfParser::getLineType( const std::string& line_type_name ) // const <- removed as m_layers may be changed if DXF is poor { static DxfLineType line_type; line_type.m_name = line_type_name; std::map::iterator lineTypeIter = m_line_types.find(line_type_name); if (lineTypeIter == m_line_types.end()) { m_line_types.insert( std::pair (line_type_name, line_type)); return &(m_line_types.find(line_type_name)->second); } return &(lineTypeIter->second); } size_t DxfParser::numLayers() const { return m_layers.size(); } size_t DxfParser::numLineTypes() const { return m_line_types.size(); } /////////////////////////////////////////////////////////////////////////////// std::istream& operator >> (std::istream& stream, DxfParser& dxfp) { if (dxfp.m_communicator) { long size = static_cast(dxfp.m_communicator->GetInfileSize()); dxfp.m_communicator->CommPostMessage( Communicator::NUM_RECORDS, size ); qtimer( dxfp.m_time, 0 ); } return dxfp.open( stream ); } std::istream& DxfParser::open( std::istream& stream ) { DxfToken token; int section = UNIDENTIFIED; while (!stream.eof() && section != _EOF) { switch (section) { case ZEROTOKEN: if (token.data == "SECTION") { // find out the section stream >> token; m_size += token.size; // if (token.code != 2) { // oops... section = UNIDENTIFIED; } else if (token.data == "HEADER") { section = HEADER; } else if (token.data == "TABLES") { section = TABLES; } else if (token.data == "BLOCKS") { section = BLOCKS; } else if (token.data == "ENTITIES") { section = ENTITIES; } else { section = UNIDENTIFIED; } } else if (token.data == "EOF") { section = _EOF; } else { section = UNIDENTIFIED; } break; case HEADER: openHeader( stream ); section = UNIDENTIFIED; break; case TABLES: openTables( stream ); section = UNIDENTIFIED; break; case BLOCKS: openBlocks( stream ); section = UNIDENTIFIED; break; case ENTITIES: openEntities( stream, token ); // I'm adding the token here as before the function was unsafe, but I'm not sure reuse of this token is a good idea AT 29-APR-11 section = UNIDENTIFIED; break; default: stream >> token; m_size += token.size; if (token.code == 0) { section = ZEROTOKEN; } break; } if (m_communicator) { counter++; if (qtimer( m_time, 500 )) { if (m_communicator->IsCancelled()) { throw Communicator::CancelledException(); } m_communicator->CommPostMessage( Communicator::CURRENT_RECORD, static_cast(m_size) ); } } } // Get overall bounding box from layers: for ( const auto& layer : m_layers ) { if (!layer.second.empty()) { m_region.merge( layer.second ); } } return stream; } /////////////////////////////////////////////////////////////////////////////// void DxfParser::openHeader( std::istream& stream ) { DxfToken token; int subsection = UNIDENTIFIED; DxfVertex vertex; while (!stream.eof() && subsection != ENDSEC) { switch (subsection) { case ZEROTOKEN: if (token.data == "ENDSEC") { subsection = ENDSEC; } /* // EXTMIN and EXTMAX are deprecated: Now calculate ourselves instead... // although now my blocks reading is done properly, should be okay! else if (token.data == "$EXTMIN") { subsection = EXTMIN; } else if (token.data == "$EXTMAX") { subsection = EXTMAX; } */ else { subsection = UNIDENTIFIED; } break; /* // EXTMIN and EXTMAX are deprecated: Now calculate ourselves instead... // although now my blocks reading is done properly, should be okay! case EXTMIN: stream >> token; m_size += token.size; if ( vertex.parse(token, this) ) { m_extmin = vertex; vertex.clear(); // reuse subsection = ZEROTOKEN; } break; case EXTMAX: stream >> token; m_size += token.size; if ( vertex.parse(token, this) ) { m_extmax = vertex; vertex.clear(); // reuse subsection = ZEROTOKEN; } break; */ default: stream >> token; m_size += token.size; if (token.code == 0 || token.code == 9 ) { // 9 is used as a '0' in the header subsection = ZEROTOKEN; } break; } } } /////////////////////////////////////////////////////////////////////////////// void DxfParser::openTables( std::istream& stream ) { DxfToken token; int subsection = UNIDENTIFIED; DxfLayer layer; DxfLineType line_type; while (!stream.eof() && subsection != ENDSEC) { switch (subsection) { case ZEROTOKEN: if (token.data == "TABLE") { // find out the table type stream >> token; m_size += token.size; // if (token.code != 2) { // oops... subsection = UNIDENTIFIED; } else if (token.data == "LTYPE") { subsection = LTYPE_TABLE; } else if (token.data == "LAYER") { subsection = LAYER_TABLE; } else { subsection = UNIDENTIFIED; } } else if (token.data == "ENDSEC") { subsection = ENDSEC; } else { subsection = UNIDENTIFIED; } break; case LTYPE_TABLE: stream >> token; m_size += token.size; if (token.code == 0) { if (token.data == "LTYPE") { subsection = LTYPE_ROW; } else if (token.data == "ENDTAB") { subsection = ZEROTOKEN; } } break; case LTYPE_ROW: stream >> token; m_size += token.size; if ( line_type.parse( token, this ) ) { m_line_types.insert( std::pair(line_type.m_name, line_type) ); if (token.data == "ENDTAB") { subsection = ZEROTOKEN; } } break; case LAYER_TABLE: stream >> token; m_size += token.size; if (token.code == 0) { if (token.data == "LAYER") { subsection = LAYER_ROW; } else if (token.data == "ENDTAB") { subsection = ZEROTOKEN; } } break; case LAYER_ROW: stream >> token; m_size += token.size; if ( layer.parse( token, this ) ) { // m_layers.add( layer ); if (token.data == "ENDTAB") { subsection = ZEROTOKEN; } } break; default: stream >> token; m_size += token.size; if (token.code == 0 ) { subsection = ZEROTOKEN; } break; } } } /////////////////////////////////////////////////////////////////////////////// void DxfParser::openBlocks( std::istream& stream ) { DxfToken token; int subsection = UNIDENTIFIED; DxfBlock block; while (!stream.eof() && subsection != ENDSEC) { switch (subsection) { case ZEROTOKEN: if (token.data == "BLOCK") { subsection = BLOCK; } else if (token.data == "ENDSEC") { subsection = ENDSEC; } else { subsection = UNIDENTIFIED; } break; case BLOCK: stream >> token; m_size += token.size; if ( block.parse( token, this ) ) { m_blocks.insert( std::pair (block.m_name, block) ); if (token.data == "ENDBLK") { subsection = ZEROTOKEN; } else { // this drills down to the data for the block: openEntities(stream, token, &(m_blocks[block.m_name]) ); // only if the block ends should we move up: if (token.data == "ENDBLK") { subsection = ZEROTOKEN; } } } break; default: stream >> token; m_size += token.size; if (token.code == 0 ) { subsection = ZEROTOKEN; } break; } if (m_communicator) { counter++; if (qtimer( m_time, 500 )) { if (m_communicator->IsCancelled()) { throw Communicator::CancelledException(); } m_communicator->CommPostMessage( Communicator::CURRENT_RECORD, static_cast(m_size) ); } } } } /////////////////////////////////////////////////////////////////////////////// void DxfParser::openEntities( std::istream& stream, DxfToken& token, DxfBlock *block ) { int subsection = UNIDENTIFIED; if (token.code == 0) { // a block must always pass it's first token: subsection = ZEROTOKEN; } DxfVertex point; DxfLine line; DxfPolyLine poly_line; DxfLwPolyLine lw_poly_line; DxfArc arc; DxfEllipse ellipse; DxfCircle circle; DxfSpline spline; DxfInsert insert; std::string layer_name; std::string line_type_name; while (!stream.eof() && subsection != ENDSEC) { switch (subsection) { case ZEROTOKEN: if (token.data == "POINT") { subsection = POINT; } else if (token.data == "LINE") { subsection = LINE; } else if (token.data == "POLYLINE") { subsection = POLYLINE; } else if (token.data == "LWPOLYLINE") { subsection = LWPOLYLINE; } else if (token.data == "ARC") { subsection = ARC; } else if (token.data == "ELLIPSE") { subsection = ELLIPSE; } else if (token.data == "CIRCLE") { subsection = CIRCLE; } else if (token.data == "SPLINE") { subsection = SPLINE; } else if (token.data == "INSERT") { subsection = INSERT; } else if (token.data == "ENDSEC" || token.data == "ENDBLK") { subsection = ENDSEC; } else { subsection = UNIDENTIFIED; } break; case POINT: stream >> token; m_size += token.size; if ( point.parse( token, this ) ) { DxfLayer *layer = block; if (layer == NULL) { layer = point.m_p_layer; } layer->m_points.push_back( point ); layer->merge(point); // <- merge bounding box layer->m_total_point_count += 1; point.clear(); subsection = ZEROTOKEN; } break; case LINE: stream >> token; m_size += token.size; if ( line.parse( token, this ) ) { if (line.m_start != line.m_end) { DxfLayer *layer = block; if (layer == NULL) { layer = line.m_p_layer; } layer->m_lines.push_back( line ); layer->merge(line); // <- merge bounding box layer->m_total_line_count += 1; } line.clear(); subsection = ZEROTOKEN; } break; case POLYLINE: stream >> token; m_size += token.size; if ( poly_line.parse( token, this ) ) { if (poly_line.m_vertex_count > 0) { DxfLayer *layer = block; if (layer == NULL) { layer = poly_line.m_p_layer; } layer->m_poly_lines.push_back( poly_line ); size_t line_count = (poly_line.getAttributes() & DxfPolyLine::CLOSED) ? poly_line.numVertices() - 2 : poly_line.numVertices() - 1; layer->merge(poly_line); // <- merge bounding box layer->m_total_line_count += line_count; poly_line.clear(); // (Now reuse) } poly_line.clear(); // (Now reuse) subsection = ZEROTOKEN; } break; case LWPOLYLINE: stream >> token; m_size += token.size; if ( lw_poly_line.parse( token, this ) ) { if (lw_poly_line.m_vertex_count > 0) { DxfLayer *layer = block; if (layer == NULL) { layer = lw_poly_line.m_p_layer; } layer->m_poly_lines.push_back( lw_poly_line ); size_t line_count = (lw_poly_line.getAttributes() & DxfPolyLine::CLOSED) ? lw_poly_line.numVertices() - 2 : lw_poly_line.numVertices() - 1; layer->merge(lw_poly_line); // <- merge bounding box layer->m_total_line_count += line_count; } lw_poly_line.clear(); // (Now reuse) subsection = ZEROTOKEN; } break; case ARC: stream >> token; m_size += token.size; if ( arc.parse( token, this ) ) { DxfLayer *layer = block; if (layer == NULL) { layer = arc.m_p_layer; } layer->m_arcs.push_back( arc ); layer->merge(arc); arc.clear(); // (Now reuse) subsection = ZEROTOKEN; } break; case ELLIPSE: stream >> token; m_size += token.size; if ( ellipse.parse( token, this ) ) { DxfLayer *layer = block; if (layer == NULL) { layer = ellipse.m_p_layer; } layer->m_ellipses.push_back( ellipse ); layer->merge(ellipse); ellipse.clear(); // (Now reuse) subsection = ZEROTOKEN; } break; case CIRCLE: stream >> token; m_size += token.size; if ( circle.parse( token, this ) ) { DxfLayer *layer = block; if (layer == NULL) { layer = circle.m_p_layer; } layer->m_circles.push_back( circle ); layer->merge(circle); circle.clear(); // (Now reuse) subsection = ZEROTOKEN; } break; case SPLINE: stream >> token; m_size += token.size; if ( spline.parse( token, this ) ) { if (spline.numVertices() > 0) { DxfLayer *layer = block; if (layer == NULL) { layer = spline.m_p_layer; } layer->m_splines.push_back( spline ); size_t line_count = (spline.getAttributes() & DxfSpline::CLOSED) ? spline.numVertices() - 2 : spline.numVertices() - 1; layer->merge(spline); layer->m_total_line_count += line_count; spline.clear(); // (Now reuse) } subsection = ZEROTOKEN; } break; case INSERT: stream >> token; m_size += token.size; if ( insert.parse( token, this ) ) { if ( insert.m_blockName.length() ) { DxfLayer *layer = block; if (layer == NULL) { layer = insert.m_p_layer; // we are in the entities section, unwind all the blocks layer->insert( insert, this ); } else { // we are within a block, hold on until we load all of them // before we can unwind them into the entities section layer->m_inserts.push_back( insert ); } } insert.clear(); subsection = ZEROTOKEN; } break; default: stream >> token; m_size += token.size; if (token.code == 0 ) { subsection = ZEROTOKEN; } break; } if (m_communicator) { counter++; if (qtimer( m_time, 500 )) { if (m_communicator->IsCancelled()) { throw Communicator::CancelledException(); } m_communicator->CommPostMessage( Communicator::CURRENT_RECORD, static_cast(m_size) ); } } } } /////////////////////////////////////////////////////////////////////////////// // Individual parsing of the types DxfTableRow::DxfTableRow(const std::string& name) { m_name = name; } bool DxfTableRow::parse( const DxfToken& token, DxfParser * ) { bool parsed = false; switch (token.code) { case 2: m_name = token.data; break; case 0: parsed = true; break; default: break; } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfEntity::DxfEntity(int tag) { m_tag = tag; } void DxfEntity::clear() { m_tag = -1; } bool DxfEntity::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 5: m_tag = std::stoi(std::string("0x") + token.data); // tag is in hex break; case 6: m_p_line_type = parser->getLineType( token.data ); break; case 8: m_p_layer = parser->getLayer( token.data ); break; case 0: parsed = true; break; default: break; } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfVertex::DxfVertex(int tag) : DxfEntity( tag ) { x = 0.0; y = 0.0; z = 0.0; } void DxfVertex::clear() { x = 0.0; y = 0.0; z = 0.0; DxfEntity::clear(); } bool operator == (const DxfVertex& a, const DxfVertex& b) { return (a.x == b.x && a.y == b.y && a.z == b.z); } bool operator != (const DxfVertex& a, const DxfVertex& b) { return (a.x != b.x || a.y != b.y || a.z != b.z); } bool DxfVertex::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 10: x = std::stod(token.data); break; case 20: y = std::stod(token.data); break; case 30: z = std::stod(token.data); break; case 0: case 9: // 0 is standard vertex, 9 is for header section variables parsed = true; break; default: parsed = DxfEntity::parse( token, parser ); // base class parse } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfLine::DxfLine(int tag) : DxfEntity( tag ) { } void DxfLine::clear() { DxfRegion::clear(); DxfEntity::clear(); } bool DxfLine::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 10: m_start.x = std::stod(token.data); break; case 20: m_start.y = std::stod(token.data); break; case 30: m_start.z = std::stod(token.data); break; case 11: m_end.x = std::stod(token.data); break; case 21: m_end.y = std::stod(token.data); break; case 31: m_end.z = std::stod(token.data); break; case 0: add(m_start); // <- add to region add(m_end); // <- add to region parsed = true; break; default: parsed = DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfPolyLine::DxfPolyLine(int tag) : DxfEntity( tag ) { clear(); } void DxfPolyLine::clear() { m_vertex_count = 0; m_vertices.clear(); m_attributes = 0; DxfRegion::clear(); DxfEntity::clear(); } bool DxfPolyLine::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; static DxfVertex vertex; if (m_vertex_count) { if ( vertex.parse( token, parser ) ) { add(vertex); // <- add to region if (m_min.x == 0) { std::cerr << "problem" << std::endl; } m_vertices.push_back( vertex ); if ( token.data == "VERTEX" ) { // Another vertex... m_vertex_count++; } else { // Should be a SEQEND parsed = true; } } } else { // parse the polyline header... switch (token.code) { case 0: if (token.data == "VERTEX") { m_vertex_count++; } else { parsed = true; } break; case 70: m_attributes = std::stoi(token.data); default: DxfEntity::parse( token, parser ); // base class parse break; } } return parsed; } size_t DxfPolyLine::numVertices() const { return m_vertices.size(); } const DxfVertex& DxfPolyLine::getVertex(int i) const { return m_vertices[i]; } int DxfPolyLine::getAttributes() const { return m_attributes; } /////////////////////////////////////////////////////////////////////////////// DxfLwPolyLine::DxfLwPolyLine(int tag) : DxfPolyLine( tag ) { clear(); } void DxfLwPolyLine::clear() { m_expected_vertex_count = 0; DxfPolyLine::clear(); } bool DxfLwPolyLine::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; static DxfVertex vertex; switch (token.code) { case 0: // push final vertex if (m_vertex_count) { add(vertex); // <- add vertex to region m_vertices.push_back( vertex ); } parsed = true; break; case 10: if (m_vertex_count) { // push last vertex add(vertex); // <- add vertex to region m_vertices.push_back( vertex ); } m_vertex_count++; vertex.clear(); vertex.parse( token, parser ); break; case 20: case 30: // continue last vertex: vertex.parse( token, parser ); break; case 70: m_attributes = std::stoi(token.data); case 90: m_expected_vertex_count = std::stoi(token.data); default: DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfArc::DxfArc(int tag) : DxfEntity( tag ) { } void DxfArc::clear() { m_start = 0.0; m_end = 0.0; DxfRegion::clear(); DxfEntity::clear(); } bool DxfArc::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 10: m_centre.x = std::stod(token.data); break; case 20: m_centre.y = std::stod(token.data); break; case 30: m_centre.z = std::stod(token.data); break; case 40: m_radius = std::stod(token.data); break; case 50: m_start = std::stod(token.data); break; case 51: m_end = std::stod(token.data); break; case 0: { // just loop round if m_start is bigger than m_end if (m_start > m_end) { m_end += 360; } // technically should check for arc limits for tighter bounding box, // but easier to give circular bounding box DxfVertex bounds; bounds.x = m_centre.x - m_radius; bounds.y = m_centre.y - m_radius; bounds.z = m_centre.z; add(bounds); // <- add to region bounds.x = m_centre.x + m_radius; bounds.y = m_centre.y + m_radius; bounds.z = m_centre.z; add(bounds); // <- add to region parsed = true; } break; default: parsed = DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } int DxfArc::numSegments(int segments) const { return ((m_start == m_end) ? segments : (int(m_end - m_start) * segments / 360)); } DxfVertex DxfArc::getVertex(int i, int segments) const { DxfVertex v = m_centre; double range = 2.0 * DXF_PI; if(m_start != m_end) range = (m_end - m_start) * DXF_PI / 180.0; double ang = range * double(i)/double(segments); if (m_start != m_end) { ang += 2.0 * DXF_PI * (m_start / 360.0); } // ARCS go anticlockwise from (1 0) v.x = m_centre.x + m_radius * cos(ang); v.y = m_centre.y + m_radius * sin(ang); v.z = m_centre.z; return v; } void DxfArc::reflect(double x, double y) { if (x < 0) { m_start = 180 - m_start; m_end = 180 - m_end; } if (y < 0) { m_start = 360 - m_start; m_end = 360 - m_end; } while (m_start < 0) { m_start += 360; } while (m_end < 0) { m_end += 360; } if (x * y < 0) { double temp; temp = m_start; m_start = m_end; m_end = temp; } } DxfEllipse::DxfEllipse(int tag) : DxfEntity( tag ) { } void DxfEllipse::clear() { m_start = 0.0; m_end = 0.0; DxfRegion::clear(); DxfEntity::clear(); } bool DxfEllipse::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 10: m_centre.x = std::stod(token.data); break; case 20: m_centre.y = std::stod(token.data); break; case 30: m_centre.z = std::stod(token.data); break; case 11: m_majorAxisEndPoint.x = std::stod(token.data); break; case 21: m_majorAxisEndPoint.y = std::stod(token.data); break; case 31: m_majorAxisEndPoint.z = std::stod(token.data); break; case 210: m_extrusionDirection.x = std::stod(token.data); break; case 220: m_extrusionDirection.y = std::stod(token.data); break; case 230: m_extrusionDirection.z = std::stod(token.data); break; case 40: m_minorMajorAxisRatio = std::stod(token.data); break; case 41: m_start = std::stod(token.data); break; case 42: m_end = std::stod(token.data); break; case 0: { // just loop round if m_start is bigger than m_end if (m_start > m_end) { m_end += 360; } // technically should check for ellipse limits for tighter bounding box, // but easier to give circular bounding box DxfVertex bounds; double xdiff = fabs(m_majorAxisEndPoint.x); double ydiff = fabs(m_majorAxisEndPoint.y); bounds.x = m_centre.x - xdiff; bounds.y = m_centre.y - ydiff; bounds.z = m_centre.z; add(bounds); // <- add to region bounds.x = m_centre.x + xdiff; bounds.y = m_centre.y + ydiff; bounds.z = m_centre.z; add(bounds); // <- add to region parsed = true; } break; default: parsed = DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } int DxfEllipse::numSegments(int segments) const { return ((m_start == m_end) ? segments : (int(m_end - m_start) * segments / (2 * DXF_PI))); } DxfVertex DxfEllipse::getVertex(int i, int segments) const { DxfVertex v = m_centre; double range = 2.0 * DXF_PI; if(m_start != m_end) range = (m_end - m_start); double ang = m_start + range * double(i)/double(segments); double c = cos(ang); double s = sin(ang); double reverse = 1; if(m_extrusionDirection.z < 0) reverse = -1; double xnew = c * m_majorAxisEndPoint.x - m_minorMajorAxisRatio * s * m_majorAxisEndPoint.y; double ynew = c * m_majorAxisEndPoint.y + reverse * m_minorMajorAxisRatio * s * m_majorAxisEndPoint.x; v.x = m_centre.x + xnew; v.y = m_centre.y + ynew; v.z = m_centre.z; return v; } void DxfEllipse::reflect(double x, double y) { if (x < 0) { m_start = 180 - m_start; m_end = 180 - m_end; } if (y < 0) { m_start = 360 - m_start; m_end = 360 - m_end; } while (m_start < 0) { m_start += 360; } while (m_end < 0) { m_end += 360; } if (x * y < 0) { double temp; temp = m_start; m_start = m_end; m_end = temp; } } /////////////////////////////////////////////////////////////////////////// DxfCircle::DxfCircle(int tag) : DxfEntity( tag ) { } void DxfCircle::clear() { DxfRegion::clear(); DxfEntity::clear(); } bool DxfCircle::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 10: m_centre.x = std::stod(token.data); break; case 20: m_centre.y = std::stod(token.data); break; case 30: m_centre.z = std::stod(token.data); break; case 40: m_radius = std::stod(token.data); break; case 0: { DxfVertex bounds; bounds.x = m_centre.x - m_radius; bounds.y = m_centre.y - m_radius; bounds.z = m_centre.z; add(bounds); // <- add to region bounds.x = m_centre.x + m_radius; bounds.y = m_centre.y + m_radius; bounds.z = m_centre.z; add(bounds); // <- add to region parsed = true; } break; default: parsed = DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } DxfVertex DxfCircle::getVertex(int i, int segments) const { DxfVertex v = m_centre; double ang = 2.0 * DXF_PI * double(i)/double(segments); // CIRCLES go anticlockwise from (1 0) v.x = m_centre.x + m_radius * cos(ang); v.y = m_centre.y + m_radius * sin(ang); v.z = m_centre.z; return v; } void DxfCircle::reflect(double , double ) { // reflect has no effect on a circle } /////////////////////////////////////////////////////////////////////////// // Spline // n.b. currently just linear interpolation between control points - // not good, but whatever method will have to make some sort of approximation at some point /////////////////////////////////////////////////////////////////////////////// DxfSpline::DxfSpline(int tag) : DxfEntity( tag ) { clear(); } void DxfSpline::clear() { m_xyz = 0; m_ctrl_pt_count = 0; m_knot_count = 0; m_ctrl_pts.clear(); m_knots.clear(); m_attributes = 0; DxfRegion::clear(); DxfEntity::clear(); } bool DxfSpline::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; static DxfVertex vertex; switch (token.code) { case 0: parsed = true; break; case 70: m_attributes = std::stoi(token.data); break; case 72: m_knot_count = std::stoi(token.data); break; case 73: m_ctrl_pt_count = std::stoi(token.data); break; case 40: m_knots.push_back( std::stod(token.data) ); case 10: vertex.x = std::stod(token.data); m_xyz |= 0x0001; break; case 20: vertex.y = std::stod(token.data); m_xyz |= 0x0010; break; case 30: vertex.z = std::stod(token.data); m_xyz |= 0x0100; break; default: DxfEntity::parse( token, parser ); // base class parse break; } if (m_xyz == 0x0111) { add(vertex); // <- add vertex to region m_ctrl_pts.push_back( vertex ); m_xyz = 0; } return parsed; } // Note: return control points not actual points! size_t DxfSpline::numVertices() const { return m_ctrl_pts.size(); } const DxfVertex& DxfSpline::getVertex(size_t i) const { return m_ctrl_pts[i]; } int DxfSpline::getAttributes() const { return m_attributes; } /////////////////////////////////////////////////////////////////////////////// // note: inserts are flattened on way through DxfInsert::DxfInsert(int tag) : DxfEntity( tag ) { clear(); } void DxfInsert::clear() { m_blockName = ""; m_translation.clear(); m_scale.clear(); // actually default scale is 1,1,1 m_scale.x = 1.0; m_scale.y = 1.0; m_scale.z = 1.0; m_rotation = 0.0; DxfRegion::clear(); DxfEntity::clear(); } bool DxfInsert::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 0: parsed = true; break; case 2: m_blockName = token.data; break; case 10: m_translation.x = std::stod(token.data); break; case 20: m_translation.y = std::stod(token.data); break; case 30: m_translation.z = std::stod(token.data); break; case 41: m_scale.x = std::stod(token.data); break; case 42: m_scale.y = std::stod(token.data); break; case 43: m_scale.z = std::stod(token.data); break; case 50: m_rotation = std::stod(token.data); break; default: DxfEntity::parse( token, parser ); // base class parse break; } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfLineType::DxfLineType(const std::string& name) : DxfTableRow( name ) { } bool DxfLineType::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 0: parsed = true; break; default: parsed = DxfTableRow::parse( token, parser ); // base class parse } return parsed; } DxfVertex& DxfLine::getStart() const { return (DxfVertex&) m_start; } DxfVertex& DxfLine::getEnd() const { return (DxfVertex&) m_end; } /////////////////////////////////////////////////////////////////////////////// DxfLayer::DxfLayer(const std::string& name) : DxfTableRow( name ) { m_total_line_count = 0; } bool DxfLayer::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 0: parsed = true; break; default: parsed = DxfTableRow::parse( token, parser ); // base class parse } return parsed; } const DxfVertex& DxfLayer::getPoint( int i ) const { return m_points[i]; } const DxfLine& DxfLayer::getLine( int i ) const { return m_lines[i]; } const DxfPolyLine& DxfLayer::getPolyLine( int i ) const { return m_poly_lines[i]; } const DxfArc& DxfLayer::getArc( int i ) const { return m_arcs[i]; } const DxfEllipse& DxfLayer::getEllipse( int i ) const { return m_ellipses[i]; } const DxfCircle& DxfLayer::getCircle( int i ) const { return m_circles[i]; } const DxfSpline& DxfLayer::getSpline( int i ) const { return m_splines[i]; } size_t DxfLayer::numPoints() const { return m_points.size(); } size_t DxfLayer::numLines() const { return m_lines.size(); } size_t DxfLayer::numPolyLines() const { return m_poly_lines.size(); } size_t DxfLayer::numArcs() const { return m_arcs.size(); } size_t DxfLayer::numEllipses() const { return m_ellipses.size(); } size_t DxfLayer::numCircles() const { return m_circles.size(); } size_t DxfLayer::numSplines() const { return m_splines.size(); } void DxfLayer::insert(DxfInsert& insert, DxfParser *parser) { size_t i; // munge in insert... bool scale = (insert.m_scale.x != 1.0 || insert.m_scale.y != 1.0 || insert.m_scale.z != 1.0); bool rotate = (insert.m_rotation != 0.0 && insert.m_rotation < 359.9999999); if (insert.m_rotation < 0) { insert.m_rotation += 360; } // lookup in blocks table if (!parser->m_blocks.count(insert.m_blockName)) { // throw exception } DxfBlock &block = parser->m_blocks[insert.m_blockName]; // unwind deeper inserts for(i = 0; i < block.m_inserts.size(); i++) { block.insert( block.m_inserts[i], parser); } // delete inserts at this level to avoid re-inserting them // if the block is re-inserted block.m_inserts.clear(); for (i = 0; i < block.m_lines.size(); i++) { m_lines.push_back(block.m_lines[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_lines.back().scale(block.m_base_point,insert.m_scale); if (rotate) m_lines.back().rotate(block.m_base_point,insert.m_rotation); m_lines.back().translate(insert.m_translation); merge(m_lines.back()); // <- merge bounding box } for (i = 0; i < block.m_poly_lines.size(); i++) { m_poly_lines.push_back(block.m_poly_lines[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_poly_lines.back().scale(block.m_base_point,insert.m_scale); if (rotate) m_poly_lines.back().rotate(block.m_base_point,insert.m_rotation); m_poly_lines.back().translate(insert.m_translation); merge(m_poly_lines.back()); // <- merge bounding box } for (i = 0; i < block.m_arcs.size(); i++) { m_arcs.push_back(block.m_arcs[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_arcs.back().scale(block.m_base_point,insert.m_scale); if (rotate) m_arcs.back().rotate(block.m_base_point,insert.m_rotation); m_arcs.back().translate(insert.m_translation); merge(m_arcs.back()); // <- merge bounding box } for (i = 0; i < block.m_ellipses.size(); i++) { m_ellipses.push_back(block.m_ellipses[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_ellipses.back().scale(block.m_base_point,insert.m_scale); if (rotate) m_ellipses.back().rotate(block.m_base_point,insert.m_rotation); m_ellipses.back().translate(insert.m_translation); merge(m_ellipses.back()); // <- merge bounding box } for (i = 0; i < block.m_circles.size(); i++) { m_circles.push_back(block.m_circles[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_circles.back().scale(block.m_base_point,insert.m_scale); // n.b., rotate does nothing with circles if (rotate) m_circles.back().rotate(block.m_base_point,insert.m_rotation); m_circles.back().translate(insert.m_translation); merge(m_circles.back()); // <- merge bounding box } for (i = 0; i < block.m_splines.size(); i++) { m_splines.push_back(block.m_splines[i]); // rotate, translate, scale each line as specified in the insert if (scale) m_splines.back().scale(block.m_base_point,insert.m_scale); if (rotate) m_splines.back().rotate(block.m_base_point,insert.m_rotation); m_splines.back().translate(insert.m_translation); merge(m_splines.back()); // <- merge bounding box } m_total_line_count += block.m_total_line_count; } /////////////////////////////////////////////////////////////////////////////// DxfBlock::DxfBlock(const std::string& name) : DxfLayer( name ) { } bool DxfBlock::parse( const DxfToken& token, DxfParser *parser ) { bool parsed = false; switch (token.code) { case 0: parsed = true; break; default: parsed = DxfLayer::parse( token, parser ); // base class parse } return parsed; } /////////////////////////////////////////////////////////////////////////////// DxfToken::DxfToken() { size = 0; code = -1; } std::istream& operator >> (std::istream& stream, DxfToken& token) { std::string codeInputLine; std::getline(stream,codeInputLine); token.code = std::stoi(codeInputLine); std::string dataInputLine; std::getline(stream,dataInputLine); dXstring::ltrim(dataInputLine,'\r'); dXstring::ltrim(dataInputLine,'\n'); dXstring::rtrim(dataInputLine,'\r'); dXstring::rtrim(dataInputLine,'\n'); token.data = dataInputLine; token.size = codeInputLine.length() + token.data.length() + 2; // might be missing a few end line characters --- never mind return stream; } /////////////////////////////////////////////////////////////////////////////// ================================================ FILE: salalib/parsers/dxfp.h ================================================ // genlib - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // DXF parser header file #pragma once /////////////////////////////////////////////////////////////////////////////// // DXF parser reads in DXF files // So far very simple: // The parser reads in vertices, lines and polylines, and stores them in the // defined layers. It also reads in any line types defined. #include #include #include class DxfToken; class DxfTableRow; class DxfEntity; class DxfVertex; class DxfLine; class DxfPolyLine; class DxfArc; class DxfCircle; class DxfSpline; class DxfInsert; class DxfLineType; class DxfLayer; class DxfBlock; class DxfParser; #include const double DXF_PI = 3.1415926535897932384626433832795; /////////////////////////////////////////////////////////////////////////////// // Tokens read from file class DxfToken { public: int code; size_t size; std::string data; // DxfToken(); friend std::istream& operator >> (std::istream& stream, DxfToken& token); }; /////////////////////////////////////////////////////////////////////////////// // Table (row) base classes class DxfTableRow { friend class DxfParser; protected: std::string m_name; public: DxfTableRow( const std::string& name = "" ); const std::string& getName() const { return m_name; } virtual ~DxfTableRow(){} protected: virtual bool parse( const DxfToken& token, DxfParser *Parser ); public: // for hash table storage friend bool operator > (const DxfTableRow&, const DxfTableRow& ); friend bool operator < (const DxfTableRow&, const DxfTableRow& ); friend bool operator == (const DxfTableRow&, const DxfTableRow& ); }; // Entity base class class DxfEntity { friend class DxfParser; protected: // Reference data int m_tag; DxfLineType *m_p_line_type; DxfLayer *m_p_layer; public: DxfEntity( int tag = -1 ); void clear(); // for reuse when parsing virtual ~DxfEntity(){} protected: virtual bool parse( const DxfToken& token, DxfParser *parser ); }; // Three very simple 'entities'... // Vertex class DxfVertex : public DxfEntity { friend class DxfParser; friend class DxfLine; friend class DxfPolyLine; friend class DxfLwPolyLine; public: double x; double y; double z; public: DxfVertex( int tag = -1 ); void clear(); // for reuse when parsing // some simple manipulation // note, all ops are 2d... void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { x = (x - base_vertex.x) * scale.x + base_vertex.x; y = (y - base_vertex.y) * scale.y + base_vertex.y; } // note, rotation is 2d op, angle in degrees, ccw void rotate(const DxfVertex& base_vertex, double angle) { DxfVertex reg; double ang = (2.0 * DXF_PI * angle / 360.0); reg.x = (x - base_vertex.x) * cos(ang) - (y - base_vertex.y) * sin(ang); reg.y = (y - base_vertex.y) * cos(ang) + (x - base_vertex.x) * sin(ang); x = reg.x + base_vertex.x; y = reg.y + base_vertex.y; } void translate(const DxfVertex& translation) { x += translation.x; y += translation.y; } // friend bool operator == (const DxfVertex& a, const DxfVertex& b); friend bool operator != (const DxfVertex& a, const DxfVertex& b); protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// // Helper: a bounding box region (only 2D at present) class DxfRegion { protected: bool m_first; DxfVertex m_min; DxfVertex m_max; public: DxfRegion() { m_first = true; } void add(const DxfVertex& v) { if (m_first) { m_min = v; m_max = v; m_first = false; } if (v.x < m_min.x) m_min.x = v.x; if (v.x > m_max.x) m_max.x = v.x; if (v.y < m_min.y) m_min.y = v.y; if (v.y > m_max.y) m_max.y = v.y; } void merge(const DxfVertex& point) { add(point); } void merge(const DxfRegion& region) { add(region.m_min); add(region.m_max); } const DxfVertex& getExtMin() const { return m_min; } const DxfVertex& getExtMax() const { return m_max; } void clear() { m_first = true; } bool empty() const { return m_first; } // // some simple manipulations void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { m_min.scale(base_vertex, scale); m_max.scale(base_vertex, scale); } // rotate tricky... void rotate(const DxfVertex&, double) { ; } void translate(const DxfVertex& translation) { m_min.translate(translation); m_max.translate(translation); } }; /////////////////////////////////////////////////////////////////////////////// // Line class DxfLine : public DxfEntity, public DxfRegion { friend class DxfParser; protected: DxfVertex m_start; DxfVertex m_end; public: DxfLine( int tag = -1 ); void clear(); // for reuse when parsing // DxfVertex& getStart() const; DxfVertex& getEnd() const; // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { m_start.scale(base_vertex, scale); m_end.scale(base_vertex, scale); DxfRegion::scale(base_vertex, scale); } void rotate(const DxfVertex& base_vertex, double angle) { m_start.rotate(base_vertex, angle); m_end.rotate(base_vertex, angle); DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { m_start.translate(translation); m_end.translate(translation); DxfRegion::translate(translation); } // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; // PolyLine class DxfPolyLine : public DxfEntity, public DxfRegion { friend class DxfParser; public: enum { CLOSED = 1 }; // CLOSED = closed polygon protected: int m_attributes; int m_vertex_count; std::vector m_vertices; public: DxfPolyLine( int tag = -1 ); void clear(); // for reuse when parsing // size_t numVertices() const; const DxfVertex& getVertex(int i) const; int getAttributes() const; const DxfRegion& getBoundingBox(); // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { for (int i = 0; i < m_vertex_count; i++) m_vertices[i].scale(base_vertex, scale); DxfRegion::scale(base_vertex, scale); } void rotate(const DxfVertex& base_vertex, double angle) { for (int i = 0; i < m_vertex_count; i++) m_vertices[i].rotate(base_vertex, angle); DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { for (int i = 0; i < m_vertex_count; i++) m_vertices[i].translate(translation); DxfRegion::translate(translation); } // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; // LwPolyLine --- just inherit from DxfPolyLine class DxfLwPolyLine : public DxfPolyLine { friend class DxfParser; // protected: int m_expected_vertex_count; public: DxfLwPolyLine( int tag = -1 ); void clear(); // for reuse when parsing // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// // Arcs and Cicles class DxfArc : public DxfEntity, public DxfRegion { friend class DxfParser; DxfVertex m_centre; double m_radius; mutable double m_start; double m_end; public: DxfArc( int tag = -1 ); void clear(); // for reuse when parsing // getVertex splits into number of segments int numSegments(int segments) const; DxfVertex getVertex(int i, int segments) const; const DxfVertex& getCentre() const { return m_centre; } const double& getRadius() const { return m_radius; } int getAttributes() const; const DxfRegion& getBoundingBox(); // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { m_centre.scale(base_vertex, scale); m_radius *= (fabs(scale.x) + fabs(scale.y)) / 2.0; // this is rather tricky to do, need to think more than just reflect around 0,0,0 if (m_start != m_end && (scale.x < 0 || scale.y < 0)) { reflect(scale.x, scale.y); } DxfRegion::scale(base_vertex, scale); } void reflect(double x, double y); void rotate(const DxfVertex& base_vertex, double angle) { m_centre.rotate(base_vertex, angle); // this is rather tricky to do, need to think more than just rotate around 0,0,0 if (m_start != m_end) { m_start += angle; m_end += angle; } DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { m_centre.translate(translation); DxfRegion::translate(translation); } // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; class DxfEllipse : public DxfEntity, public DxfRegion { friend class DxfParser; DxfVertex m_centre; DxfVertex m_majorAxisEndPoint; DxfVertex m_extrusionDirection; double m_minorMajorAxisRatio; mutable double m_start; double m_end; public: DxfEllipse( int tag = -1 ); void clear(); // for reuse when parsing // getVertex splits into number of segments int numSegments(int segments) const; DxfVertex getVertex(int i, int segments) const; const DxfVertex& getCentre() const { return m_centre; } const double& getMinorMajorAxisRatio() const { return m_minorMajorAxisRatio; } int getAttributes() const; const DxfRegion& getBoundingBox(); // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { m_centre.scale(base_vertex, scale); m_majorAxisEndPoint.x *= scale.x; m_majorAxisEndPoint.y *= scale.y; // this is rather tricky to do, need to think more than just reflect around 0,0,0 if (m_start != m_end && (scale.x < 0 || scale.y < 0)) { reflect(scale.x, scale.y); } DxfRegion::scale(base_vertex, scale); } void reflect(double x, double y); void rotate(const DxfVertex& base_vertex, double angle) { m_centre.rotate(base_vertex, angle); // this is rather tricky to do, need to think more than just rotate around 0,0,0 if (m_start != m_end) { m_start += angle; m_end += angle; } DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { m_centre.translate(translation); DxfRegion::translate(translation); } // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; class DxfCircle : public DxfEntity, public DxfRegion { friend class DxfParser; DxfVertex m_centre; double m_radius; public: DxfCircle( int tag = -1 ); void clear(); // for reuse when parsing DxfVertex getVertex(int i, int segments) const; const DxfVertex& getCentre() const { return m_centre; } const double& getRadius() const { return m_radius; } int getAttributes() const; const DxfRegion& getBoundingBox(); // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { m_centre.scale(base_vertex, scale); m_radius *= (fabs(scale.x) + fabs(scale.y)) / 2.0; DxfRegion::scale(base_vertex, scale); } void reflect(double x, double y); void rotate(const DxfVertex& base_vertex, double angle) { DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { m_centre.translate(translation); DxfRegion::translate(translation); } // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// // Spline // n.b. currently just linear interpolation between control points - // not good, but whatever method will have to make some sort of approximation at some point class DxfSpline : public DxfEntity, public DxfRegion { friend class DxfParser; public: enum { CLOSED = 1 }; // CLOSED = closed spline protected: int m_xyz; int m_attributes; int m_ctrl_pt_count; int m_knot_count; std::vector m_ctrl_pts; std::vector m_knots; public: DxfSpline( int tag = -1 ); void clear(); // for reuse when parsing // size_t numVertices() const; const DxfVertex& getVertex(size_t i) const; int getAttributes() const; // // some basic manipulation void scale(const DxfVertex& base_vertex, const DxfVertex& scale) { for (int i = 0; i < m_ctrl_pt_count; i++) m_ctrl_pts[i].scale(base_vertex, scale); DxfRegion::scale(base_vertex, scale); } void rotate(const DxfVertex& base_vertex, double angle) { for (int i = 0; i < m_ctrl_pt_count; i++) m_ctrl_pts[i].rotate(base_vertex, angle); DxfRegion::rotate(base_vertex, angle); } void translate(const DxfVertex& translation) { for (int i = 0; i < m_ctrl_pt_count; i++) m_ctrl_pts[i].translate(translation); DxfRegion::translate(translation); } protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// // Inserts... these are flattened at parse-time and not retained in layers class DxfInsert : public DxfEntity, public DxfRegion { friend class DxfParser; friend class DxfLayer; protected: std::string m_blockName; DxfVertex m_translation; DxfVertex m_scale; double m_rotation; public: DxfInsert( int tag = -1 ); void clear(); // for reuse when parsing // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// // Two very simple 'table' entries: // Line types class DxfLineType : public DxfTableRow { friend class DxfParser; public: DxfLineType( const std::string& name = "" ); protected: bool parse( const DxfToken& token, DxfParser *parser ); }; // Layers class DxfLayer : public DxfTableRow, public DxfRegion { friend class DxfParser; protected: // Originally was going to be clever, but it's far easier to have a list for each type: std::vector m_points; std::vector m_lines; std::vector m_poly_lines; std::vector m_arcs; std::vector m_ellipses; std::vector m_circles; std::vector m_splines; std::vector m_inserts; size_t m_total_point_count = 0; size_t m_total_line_count = 0; public: DxfLayer( const std::string& name = "" ); // const DxfVertex& getPoint( int i ) const; const DxfLine& getLine( int i ) const; const DxfPolyLine& getPolyLine( int i ) const; const DxfArc& getArc( int i ) const; const DxfEllipse& getEllipse( int i ) const; const DxfCircle& getCircle( int i ) const; const DxfSpline& getSpline( int i ) const; // size_t numPoints() const; size_t numLines() const; size_t numPolyLines() const; size_t numArcs() const; size_t numEllipses() const; size_t numCircles() const; size_t numSplines() const; // size_t numTotalPoints() const { return m_total_point_count; } size_t numTotalLines() const { return m_total_line_count; } // // this merges an insert (so the insert remains flattened) void insert(DxfInsert& insert, DxfParser *parser); protected: bool parse( const DxfToken& token, DxfParser *parser ); }; class DxfBlock : public DxfLayer { friend class DxfParser; friend class DxfLayer; protected: DxfVertex m_base_point; public: DxfBlock( const std::string& name = "" ); // protected: bool parse( const DxfToken& token, DxfParser *parser ); }; /////////////////////////////////////////////////////////////////////////////// class Communicator; class DxfParser { friend class DxfInsert; friend class DxfLayer; public: enum token_t { UNIDENTIFIED = -2, ZEROTOKEN = -1 }; enum section_t { HEADER, CLASSES, TABLES, BLOCKS, ENTITIES, OBJECTS, _EOF }; enum subsection_t { EXTMIN, EXTMAX, LTYPE_TABLE, LTYPE_ROW, LAYER_TABLE, LAYER_ROW, BLOCK, POINT, LINE, POLYLINE, LWPOLYLINE, ARC, ELLIPSE, CIRCLE, SPLINE, INSERT, VERTEX, ENDSEC }; protected: time_t m_time; protected: DxfRegion m_region; std::map m_layers; std::map m_blocks; std::map m_line_types; // size_t m_size; Communicator *m_communicator; public: DxfParser(Communicator *comm = NULL); // std::istream& open( std::istream& stream ); // void openHeader( std::istream& stream ); void openTables( std::istream& stream ); void openBlocks( std::istream& stream ); void openEntities( std::istream& stream, DxfToken& token, DxfBlock *block = NULL ); // cannot have a default token: it's a reference. Removed default to DxfToken() AT 29.04.11 // const DxfVertex& getExtMin() const; const DxfVertex& getExtMax() const; DxfLayer *getLayer( const std::string& layer_name ); // const; <- removed as will have to add layer when DXF hasn't declared one DxfLineType *getLineType( const std::string& line_type_name ); // const; // size_t numLayers() const; size_t numLineTypes() const; // friend std::istream& operator >> (std::istream& stream, DxfParser& dxfp); std::map getLayers() { return m_layers; } }; /////////////////////////////////////////////////////////////////////////////// ================================================ FILE: salalib/parsers/mapinfodata.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "mapinfodata.h" #include "salalib/mgraph.h" #include "salalib/shapemap.h" #include "salalib/axialmap.h" #include int MapInfoData::import(std::istream& miffile, std::istream& midfile, ShapeMap& map) { int mapLoaded = MINFO_OK; // read the header... if (!readheader(miffile)) { return MINFO_HEADER; } std::vector columnheads; AttributeTable& attributes = map.getAttributeTable(); // read mif table if (!readcolumnheaders(miffile, columnheads)) { return MINFO_TABLE; } // set up a list of readable columns from the headers: // std::vector colnames; std::vector readable, colindexes; for (size_t i = 0; i < columnheads.size(); i++) { dXstring::ltrim(columnheads[i]); auto tokens = dXstring::split(columnheads[i], ' ',true); if (dXstring::beginsWith(tokens[1],"Integer") || dXstring::beginsWith(tokens[1],"Smallint") || dXstring::beginsWith(tokens[1],"Decimal") || dXstring::beginsWith(tokens[1],"Float")) { colnames.push_back(tokens[0]); attributes.insertOrResetColumn(colnames.back()); readable.push_back(i); } } for (std::string colname: colnames) { colindexes.push_back(attributes.getColumnIndex(colname)); } std::string textline; std::vector> pointsets; std::vector duplicates; std::vector types; try { // now read line data into the axial map while (!miffile.eof()) { dXstring::safeGetline(miffile, textline); dXstring::ltrim(textline); dXstring::toLower(textline); if (textline.empty()) { continue; } if (dXstring::beginsWith(textline,"point")) { auto tokens = dXstring::split(textline,' ',true); pointsets.push_back(std::vector()); types.push_back(SalaShape::SHAPE_POINT); pointsets.back().push_back(Point2f(stod(tokens[1]),stod(tokens[2]))); } if (dXstring::beginsWith(textline,"line")) { auto tokens = dXstring::split(textline,' ',true); pointsets.push_back(std::vector()); types.push_back(SalaShape::SHAPE_LINE); pointsets.back().push_back(Point2f(stod(tokens[1]),stod(tokens[2]))); pointsets.back().push_back(Point2f(stod(tokens[3]),stod(tokens[4]))); } else if (dXstring::beginsWith(textline,"pline") || dXstring::beginsWith(textline,"region")) { int type = dXstring::beginsWith(textline,"pline") ? SalaShape::SHAPE_POLY : (SalaShape::SHAPE_POLY | SalaShape::SHAPE_CLOSED); // note: polylines, even multiple lines, are condensed into a single line auto tokens = dXstring::split(textline,' ',true); int multiple = 1; if (tokens.size() > 1) { if (tokens[1] == "multiple") { multiple = stoi(tokens[2]); } else if (type & SalaShape::SHAPE_CLOSED) { multiple = stoi(tokens[1]); } // if for some reason c_int fails: if (multiple == 0) { multiple = 1; } } for (int i = 0; i < multiple; i++) { int count = -1; if ((type & SalaShape::SHAPE_CLOSED) != SalaShape::SHAPE_CLOSED && tokens.size() == 2) { // token 2 can apparently be used for count in pline rather than a newline being used... count = stoi(tokens[1]); } else { dXstring::safeGetline(miffile, textline); dXstring::ltrim(textline); count = stoi(textline); } pointsets.push_back(std::vector()); types.push_back(type); for (int j = 0; j < count; j++) { dXstring::safeGetline(miffile, textline); dXstring::ltrim(textline); auto tokens = dXstring::split(textline,' ',true); pointsets.back().push_back(Point2f(stod(tokens[0]),stod(tokens[1]))); } if (i != 0) { // warn about extraneous pline data mapLoaded = MINFO_MULTIPLE; duplicates.push_back(pointsets.size() - 1); } } } } } // TODO: Use the proper exception catch (std::exception) { // unhandled parsing exceptions return read error: return MINFO_MIFPARSE; } size_t nextduplicate = 0; AttributeRow *lastrow; QtRegion region(pointsets[0][0],pointsets[0][0]); for (size_t i = 0; i < pointsets.size(); i++) { for (size_t j = 0; j < pointsets[i].size(); j++) { region.encompass(pointsets[i][j]); } } try { // switch lines into our format map.init(pointsets.size(),region); for (size_t i = 0; i < pointsets.size(); i++) { bool open = false; if ((types[i] & SalaShape::SHAPE_CLOSED) == 0) { open = true; } map.makePolyShape(pointsets[i],open); AttributeRow &row = *attributes.back().second; // // table data entries: if (nextduplicate < duplicates.size() && duplicates[nextduplicate] == i) { // duplicate last row: for (int colindex: colindexes) { row.setValue(colindex, lastrow->getValue(colindex)); } nextduplicate++; } else { // read next row: std::string line; while (!midfile.eof() && line.empty()) { dXstring::safeGetline(midfile, line); } if (line.empty()) { return MINFO_OBJROWS; } bool instring = false; size_t here = 0, first = 0, reading = 0, nextreadable = 0; while (nextreadable < readable.size()) { char next = line[here]; if (next == '\"') { instring = !instring; } here++; if ((!instring && next == m_delimiter) || here >= line.length()) { int length = (here < line.length()) ? here-first-1 : here-first; std::string field = line.substr(first,length); first = here; if (length == 1 && field[0] == m_delimiter) { // field is empty row.setValue(colindexes[nextreadable], -1); nextreadable++; // go to next column } else if (reading == readable[nextreadable]) { float val = -1; if(!field.empty()) { val = stof(field); } row.setValue(colindexes[nextreadable],val); nextreadable++; // go to next column } reading++; } } } lastrow = &row; } } // TODO: use a proper exception catch (std::exception) { // unhandled parsing exceptions return read error: return MINFO_TABLE; } return mapLoaded; } /* bool MapInfoData::exportFile(std::ostream& miffile, std::ostream& midfile, const ShapeGraph& map) { // if bounds has not been filled in, fill it in if (m_bounds.empty()) { char bounds[256]; sprintf(bounds,"Bounds (%10f, %10f) (%10f, %10f)", map.m_region.bottom_left.x, map.m_region.bottom_left.y, map.m_region.top_right.x, map.m_region.top_right.y); m_bounds = bounds; } // write the header... writeheader(miffile); // write the mif table writetable(miffile,midfile,map.m_attributes); miffile.precision(16); for (int i = 0; i < map.m_lines.size(); i++) { miffile << "Line " << map.m_lines[i].line.start().x << " " << map.m_lines[i].line.start().y << " " << map.m_lines[i].line.end().x << " " << map.m_lines[i].line.end().y << std::endl; miffile << " Pen (1,2,0)" << std::endl; } return true; } */ bool MapInfoData::exportFile(std::ostream& miffile, std::ostream& midfile, const PointMap& points) { // if bounds has not been filled in, fill it in if (m_bounds.empty()) { char bounds[256]; sprintf(bounds,"Bounds (%10f, %10f) (%10f, %10f)", points.m_region.bottom_left.x, points.m_region.bottom_left.y, points.m_region.top_right.x, points.m_region.top_right.y); m_bounds = bounds; } // write the header... writeheader(miffile); // write the mif table writetable(miffile, midfile, points.getAttributeTable(), points.m_layers); miffile.precision(16); for (auto iter = points.getAttributeTable().begin(); iter != points.getAttributeTable().end(); iter++) { PixelRef pix = iter->getKey().value; Point2f p = points.depixelate(pix); miffile << "Point " << p.x << " " << p.y << std::endl; miffile << " Symbol (32,0,10)" << std::endl; } return true; } bool MapInfoData::exportFile(std::ostream& miffile, std::ostream& midfile, const ShapeMap& map) { // if bounds has not been filled in, fill it in if (m_bounds.empty()) { char bounds[256]; sprintf(bounds,"Bounds (%10f, %10f) (%10f, %10f)", map.getRegion().bottom_left.x, map.getRegion().bottom_left.y, map.getRegion().top_right.x, map.getRegion().top_right.y); m_bounds = bounds; } miffile.precision(8); midfile.precision(8); // write the header... writeheader(miffile); // write the mid table writetable(miffile, midfile, *map.m_attributes, map.m_layers); miffile.precision(16); midfile.precision(16); for (auto shape: map.m_shapes) { // note, attributes must align for this: if (isObjectVisible(map.m_layers, map.getAttributeTable().getRow(AttributeKey(shape.first)))) { const SalaShape& poly = shape.second; if (poly.isPoint()) { miffile << "POINT " << poly.getPoint().x << " " << poly.getPoint().y << std::endl; miffile << " SYMBOL (32,0,10)" << std::endl; } else if (poly.isLine()) { miffile << "LINE " << poly.getLine().start().x << " " << poly.getLine().start().y << " " << poly.getLine().end().x << " " << poly.getLine().end().y << std::endl; miffile << " PEN (1,2,0)" << std::endl; } else if (poly.isPolyLine()) { miffile << "PLINE" << std::endl; miffile << " " << poly.m_points.size() << std::endl; for (auto& point: poly.m_points) { miffile << point.x << " " << point.y << std::endl; } miffile << " PEN (1,2,0)" << std::endl; } else if (poly.isPolygon()) { miffile << "REGION 1" << std::endl; miffile << " " << poly.m_points.size() + 1 << std::endl; for (auto& point: poly.m_points) { miffile << point.x << " " << point.y << std::endl; } miffile << poly.m_points[0].x << " " << poly.m_points[0].y << std::endl; miffile << " PEN (1,2,0)" << std::endl; miffile << " BRUSH (2,16777215,16777215)" << std::endl; miffile << " CENTER " << poly.getCentroid().x << " " << poly.getCentroid().y << std::endl; } } } return true; } bool MapInfoData::exportPolygons(std::ostream& miffile, std::ostream& midfile, const std::vector>& polygons, const QtRegion& region) { // if bounds has not been filled in, fill it in if (m_bounds.empty()) { char bounds[256]; sprintf(bounds,"Bounds (%10f, %10f) (%10f, %10f)", region.bottom_left.x, region.bottom_left.y, region.top_right.x, region.top_right.y); m_bounds = bounds; } // write the header... writeheader(miffile); // dummy attributes table: AttributeTable attributes; for (size_t i = 0; i < polygons.size(); i++) { attributes.addRow(AttributeKey(i)); } // dummy layers: LayerManagerImpl layers; // write the mid table writetable(miffile, midfile, attributes, layers); miffile.precision(16); for (auto& polygon: polygons) { Point2f centre; miffile << "QtRegion 1" << std::endl; miffile << " " << polygon.size() + 1 << std::endl; for (auto& point: polygon) { centre += point; miffile << point.x << " " << point.y << std::endl; } miffile << polygon[0].x << " " << polygon[0].y << std::endl; miffile << " Pen (1,2,0)" << std::endl; miffile << " Brush (2,16777215,16777215)" << std::endl; centre /= polygon.size(); miffile << " Center " << centre.x << " " << centre.y << std::endl; } return true; } /////////////////////////////////////////////////////////////////////// MapInfoData::MapInfoData() { m_version = "Version 300"; m_charset = "Charset \"WindowsLatin1\""; m_delimiter = ','; m_index = "Index 1"; m_coordsys = "CoordSys NonEarth Units \"m\" "; // note: m_bounds is filled in later } bool MapInfoData::readheader(std::istream& miffile) { std::string line; dXstring::safeGetline(miffile, m_version); dXstring::safeGetline(miffile, m_charset); dXstring::makeInitCaps(m_charset); // this should read "Charset..." but some files have delimiter straight away... if (dXstring::beginsWith(m_charset,"Delimiter")) { line = m_charset; m_charset = "Charset \"WindowsLatin1\""; } else { dXstring::safeGetline(miffile, line); } size_t index = line.find_first_of("\""); if (index == std::string::npos) { return false; } m_delimiter = line[index+1]; dXstring::safeGetline(miffile, line); dXstring::makeInitCaps(line); while (dXstring::beginsWith(line,"Index") || dXstring::beginsWith(line,"Unique")) { m_index = line; dXstring::safeGetline(miffile, line); } dXstring::ltrim(line); dXstring::makeInitCaps(line); if (dXstring::beginsWith(line,"Coordsys")) { line[5] = 'S'; // set back to CoordSys // coordsys and bounds together in one line auto boundIndex = line.find("Bounds"); if(boundIndex != std::string::npos) { m_coordsys = line.substr(0,boundIndex); m_bounds = line.substr(boundIndex); } else { m_coordsys = line; m_bounds = ""; } } else { return false; } return true; } bool MapInfoData::readcolumnheaders(std::istream& miffile, std::vector& columnheads) { std::string line; dXstring::safeGetline(miffile, line); dXstring::makeInitCaps(line); auto bits = dXstring::split(line, ' '); if (line.find("Columns") == std::string::npos || bits.size() < 2 ) { return false; } int cols = stoi(bits[1]); for (int i = 0; i < cols; i++) { dXstring::safeGetline(miffile, line); dXstring::makeInitCaps(line); columnheads.push_back(line); } dXstring::safeGetline(miffile, line); dXstring::makeInitCaps(line); if (line != "Data") { return false; } return true; } void MapInfoData::writeheader(std::ostream& miffile) { miffile << m_version << std::endl; miffile << m_charset << std::endl; miffile << "Delimiter \"" << m_delimiter << "\"" << std::endl; miffile << m_index << std::endl; miffile << m_coordsys; miffile << m_bounds << std::endl; } // note: stopped using m_table and m_columnheads as of VERSION_MAPINFO_SHAPES // simply hack up the table now for own purposes void MapInfoData::writetable(std::ostream& miffile, std::ostream& midfile, const AttributeTable& attributes, const LayerManagerImpl layers) { miffile << "Columns " << attributes.getNumColumns() + 1 << std::endl; /* miffile << "Columns " << m_columnheads.size() + 1 + attributes.getColumnCount() << std::endl; for (int i = 0; i < m_columnheads.size(); i++) { miffile << m_columnheads[i] << std::endl; } */ miffile << " Depthmap_Ref Integer" << std::endl; // TODO: For compatibility write the columns in alphabetical order // but the physical columns in the order inserted std::vector indices(attributes.getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return attributes.getColumnName(a) < attributes.getColumnName(b); }); for (int idx: indices) { std::string colname = attributes.getColumnName(idx); miffile << " "; bool lastalpha = false; for (size_t i = 0; i < colname.length(); i++) { // get rid of any character that's not alphanumeric: if (isalnum(colname[i])) { miffile << colname[i]; lastalpha = true; } else if (lastalpha) { miffile << "_"; lastalpha = false; } } miffile << " Float" << std::endl; } miffile << "Data" << std::endl << std::endl; for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { int rowKey = iter->getKey().value; /* if (k < m_table.size()) { midfile << m_table[k] << m_delimiter; } */ if (isObjectVisible(layers, iter->getRow())) { midfile << rowKey; for (int idx: indices) { midfile << m_delimiter << iter->getRow().getValue(idx); } midfile << std::endl; } } } //////////////////////////////////////////////////////////////////////////////// std::istream& MapInfoData::read(std::istream& stream) { m_version = dXstring::readString(stream); m_charset = dXstring::readString(stream); m_delimiter = stream.get(); m_index = dXstring::readString(stream); m_coordsys = dXstring::readString(stream); m_bounds = dXstring::readString(stream); return stream; } std::ostream& MapInfoData::write(std::ostream& stream) { dXstring::writeString(stream, m_version); dXstring::writeString(stream, m_charset); stream.put(m_delimiter); dXstring::writeString(stream, m_index); dXstring::writeString(stream, m_coordsys); dXstring::writeString(stream, m_bounds); /* // No longer used as of VERSION_MAPINFO_SHAPES int columns = m_columnheads.size(); int rows = m_table.size(); stream.write((char *)&columns, sizeof(columns)); for (int i = 0; i < m_columnheads.size(); i++) { m_columnheads[i].write(stream); } stream.write((char *)&rows, sizeof(rows)); for (int j = 0; j < m_table.size(); j++) { m_table[j].write(stream); } */ return stream; } ================================================ FILE: salalib/parsers/mapinfodata.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/attributetable.h" #include "salalib/layermanagerimpl.h" #include "genlib/p2dpoly.h" #include #include #include // imported and exported data // note: this is very basic and designed for axial line import / export only // MapInfoData is stored with axial map data class ShapeMap; class PointMap; class AttributeTable; class MapInfoData { friend class ShapeGraph; friend class ShapeGraphs; friend class ShapeMap; // protected: std::string m_version; std::string m_charset; char m_delimiter; std::string m_index; std::string m_coordsys; std::string m_bounds; // // no longer use columnheads and table // -- where possible, added directly to the data // pvecstring m_columnheads; // <- original mapinfo column headers // pvecstring m_table; // <- original mapinfo table (stored as a flat text file!) // public: MapInfoData(); // int import(std::istream& miffile, std::istream& midfile, ShapeMap& map); //bool exportFile(ostream& miffile, ostream& midfile, const ShapeGraph& map); // n.b., deprecated: use shapemap instead bool exportFile(std::ostream& miffile, std::ostream& midfile, const PointMap& points); bool exportFile(std::ostream& miffile, std::ostream& midfile, const ShapeMap& map); bool exportPolygons(std::ostream& miffile, std::ostream& midfile, const std::vector > &polygons, const QtRegion& region); // bool readheader(std::istream& miffile); bool readcolumnheaders(std::istream& miffile, std::vector& columnheads); void writeheader(std::ostream& miffile); void writetable(std::ostream& miffile, std::ostream& midfile, const AttributeTable& attributes, const LayerManagerImpl layers); // std::istream& read(std::istream& stream); std::ostream& write(std::ostream& stream); }; ================================================ FILE: salalib/parsers/ntfp.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Quick OS land-line NTF parser #include "ntfp.h" #include "genlib/p2dpoly.h" #include "genlib/comm.h" // for communicator #include "genlib/stringutils.h" #include "genlib/containerutils.h" #include #include #include /////////////////////////////////////////////////////////////////////////////// int NtfPoint::parse(const std::string& token, bool secondhalf /* = false */) { if (secondhalf) { std::string second = token.substr(0,m_chars); b = stoi(second); if (m_chars == 5) { b *= 100; } return 2; } else if ((int)token.length() < m_chars * 2) { if ((int)token.length() < m_chars) { return 0; } std::string first = token.substr(0,m_chars); a = stoi(first); if (m_chars == 5) { a *= 100; } return 1; } else { std::string first = token.substr(0,m_chars); std::string second = token.substr(m_chars,m_chars); a = stoi(first); b = stoi(second); if (m_chars == 5) { a *= 100; b *= 100; } } return 2; } void NtfMap::fitBounds(const Line& li) { if (m_region.atZero()) { m_region = li; } else { m_region = runion(m_region,li); } } void NtfMap::addGeom(size_t layerIdx, NtfGeometry& geom) { m_line_count += geom.lines.size(); layers[layerIdx].m_line_count += geom.lines.size(); layers[layerIdx].geometries.push_back( geom ); for (size_t i = 0; i < geom.lines.size(); i++) { fitBounds(geom.lines[i]); } geom.lines.clear(); } /////////////////////////////////////////////////////////////////////////////// Line NtfMap::makeLine(const NtfPoint& a, const NtfPoint& b) { // In future requires offset return Line( Point2f(double(m_offset.a)+double(a.a)/100.0,double(m_offset.b)+double(a.b)/100.0), Point2f(double(m_offset.a)+double(b.a)/100.0,double(m_offset.b)+double(b.b)/100.0) ); } void NtfMap::open(const std::vector& fileset, Communicator *comm) { time_t time = 0; qtimer( time, 0 ); std::vector featcodes; /* m_bottom_left.a = 2147483647; // 2^31 - 1 m_bottom_left.b = 2147483647; m_top_right.a = -2147483647; m_top_right.b = -2147483647; */ m_line_count = 0; layers.clear(); for (size_t i = 0; i < fileset.size(); i++) { std::ifstream stream(fileset[i].c_str()); int filetype = NTF_UNKNOWN; while (!stream.eof() && filetype == NTF_UNKNOWN) { std::string line; dXstring::safeGetline(stream, line); if (line.length() > 2) { if (dXstring::beginsWith(line, "02")) { std::transform(line.begin(), line.end(), line.begin(), ::tolower); if (dXstring::beginsWith(line, "02land-line")) { filetype = NTF_LANDLINE; } else if (dXstring::beginsWith(line, "02meridian")) { filetype = NTF_MERIDIAN; } } } } int precision = 10; if (filetype == NTF_UNKNOWN) { // not recognised -- really ought to throw error stream.close(); continue; } else if (filetype == NTF_LANDLINE) { precision = 6; } else if (filetype == NTF_MERIDIAN) { precision = 5; } NtfGeometry geom; NtfPoint lastpoint(precision), currpoint(precision); int parsing = 0; std::vector::iterator currpos; int currtoken = 0; std::vector tokens; while (!stream.eof()) { std::string line; dXstring::safeGetline(stream, line); if (line.length()) { if (parsing == 0 && dXstring::beginsWith(line, "07")) { // Grab the easting and northing offset std::string easting = line.substr(46,10); std::string northing =line.substr(56,10); m_offset.a = stoi(easting); m_offset.b = stoi(northing); } if (parsing == 0 && dXstring::beginsWith(line, "05")) { // Grab the feature codes // Example without continuation: // 050001 Building outline\0% // Example with continuation: // 050001 Building ou1% // tline\0% std::stringstream fullLine; fullLine << line; while(line.substr(line.length()-2,2) == "1%") { // the last line had 1% so remove it fullLine.seekp(-2, std::ios_base::end); dXstring::safeGetline(stream, line); fullLine << line; } line = fullLine.str(); line = line.substr(0, line.length()-3); std::string code = line.substr(2,4); std::string name = line.substr(36); if (depthmapX::addIfNotExists(featcodes, stoi(code))) layers.push_back( NtfLayer(name) ); } if (parsing == 0 && dXstring::beginsWith(line, "23")) { geom.lines.clear(); // In Landline, check to see if it's a code we recognise: if (filetype == NTF_LANDLINE) { std::string featcodestr = line.substr(16,4); auto pos = std::find(featcodes.begin(), featcodes.end(), stoi(featcodestr) ); if (pos != featcodes.end()) { layers[size_t(std::distance(featcodes.begin(), pos))].geometries.push_back( NtfGeometry() ); parsing = 1; currpos = pos; } } else if (filetype == NTF_MERIDIAN) { // In Meridian, irritatingly the feature code *follows* the geometry, // just have to read in parsing = 1; } } else if (parsing == 1) { if (dXstring::beginsWith(line, "21")) { tokens.clear(); // Some line data: // read to end, and possibly leave hanging: tokens = dXstring::split(line, ' ',true); tokens[0] = tokens[0].substr(13); lastpoint.parse(tokens[0]); currtoken = 1; parsing = 3; } } else if (parsing > 1) { if (dXstring::beginsWith(line, "00")) { tokens = dXstring::split(line, ' ',true); tokens[0] = tokens[0].substr(2); currtoken = 0; } else if (dXstring::beginsWith(line, "14") && filetype == NTF_MERIDIAN) { // Meridian record for this line: // finish up and add if featcode is recognised // (goodness knows how we are supposed to know in advance what sort of feature we are given) if (line.length() > 25 && line.substr(23,2) == "FC") { std::string featcodestr = line.substr(25,4); auto pos = std::find(featcodes.begin(), featcodes.end(), stoi(featcodestr) ); if (pos != featcodes.end()) { addGeom(static_cast(std::distance(featcodes.begin(), pos)), geom); } } parsing = 0; } } if (parsing > 1) { if (parsing == 2) { // hanging half point: currpoint.parse(tokens[0], true); Line li = makeLine(lastpoint, currpoint); geom.lines.push_back(li); lastpoint = currpoint; currtoken = 1; } for (size_t i = currtoken; i < tokens.size(); i++) { int numbersparsed = currpoint.parse(tokens[i]); if (numbersparsed == 2) { Line li = makeLine(lastpoint, currpoint); geom.lines.push_back(li); lastpoint = currpoint; } else if (numbersparsed == 1) { parsing = 2; // hanging half point } else { parsing = 3; } } if (tokens.back()[tokens.back().length()-2] == '0') { // 0 here indicates no continuation if (filetype == NTF_LANDLINE) { addGeom(static_cast(std::distance(featcodes.begin(), currpos)),geom); parsing = 0; } } } } if (comm) { if (qtimer( time, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } } } } } } ================================================ FILE: salalib/parsers/ntfp.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" struct NtfPoint { int m_chars; int a; int b; NtfPoint(int chars = 10) // apparently 10 is NTF default { m_chars = chars; } int parse(const std::string& token, bool secondhalf = false); }; class NtfGeometry { public: std::vector lines; NtfGeometry() {;} }; class NtfLayer { friend class NtfMap; protected: std::string m_name; int m_line_count; public: int pad1 : 32; std::vector geometries; NtfLayer(const std::string& name = std::string()) { m_name = name; m_line_count = 0; } int getLineCount() { return m_line_count; } std::string getName() { return m_name; } }; class NtfMap { public: std::vector layers; enum {NTF_UNKNOWN, NTF_LANDLINE, NTF_MERIDIAN}; protected: NtfPoint m_offset; // note: in metres QtRegion m_region; // made in metres, although points are in cm int m_line_count; public: NtfMap() {;} Line makeLine(const NtfPoint& a, const NtfPoint& b); void open(const std::vector &fileset, Communicator *comm); const QtRegion& getRegion() const { return m_region; } int getLineCount() const { return m_line_count; } protected: void fitBounds(const Line& li); void addGeom(size_t layerIdx, NtfGeometry& geom); }; ================================================ FILE: salalib/parsers/tigerp.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines // Quick Tiger line parser (type 1 records) #include "salalib/parsers/tigerp.h" #include "genlib/comm.h" #include #include // at some point will need to extend to parsing record type 2 (chains) as well as record type 1 (node to node) // Thank you US Census Bureau -- this is a great easy flat file format: void TigerMap::parse(const std::vector& fileset, Communicator *comm) { time_t atime = 0; qtimer( atime, 0 ); for (size_t i = 0; i < fileset.size(); i++) { std::ifstream stream(fileset[i].c_str()); while (!stream.eof()) { std::string line; std::getline(stream, line); if (line.length()) { // grab major code: std::string code = line.substr(55,2); if (code[0] == 'A' || code[0] == 'B') { auto iter = m_categories.insert(std::make_pair(code,TigerCategory())).first; int long1 = stoi(line.substr(190,10)); int lat1 = stoi(line.substr(200,9)); int long2 = stoi(line.substr(209,10)); int lat2 = stoi(line.substr(219,9)); Point2f p1(double(long1)/1e6,double(lat1)/1e6); Point2f p2(double(long2)/1e6,double(lat2)/1e6); Line li(p1,p2); iter->second.chains.push_back(TigerChain()); iter->second.chains.back().lines.push_back(li); if (!m_init) { m_region = li; m_init = true; } else { m_region = runion(m_region,li); } } } if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } } } } } } ================================================ FILE: salalib/parsers/tigerp.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include #include // look up is the tiger (major) line category: // string is A1, A2, A3 (road types) or B1, B2 (railroad types) // C,D etc are not currently parsed, but given the nice file format // (thank you US Census Bureau!) they can easily be added class TigerChain { public: std::vector lines; TigerChain() {;} }; class TigerCategory { public: std::vector chains; TigerCategory() {;} }; class TigerMap { protected: QtRegion m_region; bool m_init; public: std::map m_categories; TigerMap() { m_init = false;} void parse(const std::vector &fileset, Communicator *communicator); Point2f getBottomLeft() { return m_region.bottom_left; } Point2f getTopRight() { return m_region.top_right; } QtRegion getRegion() { return m_region; } }; ================================================ FILE: salalib/pixelref.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include class PixelRef { public: short x; short y; PixelRef( short ax = -1, short ay = -1 ) { x = ax; y = ay; } PixelRef( int i ) { x = short(i >> 16); y = short(i & 0xffff); } bool empty() { return x == -1 && y == -1; } PixelRef up() const { return PixelRef(x, y + 1); } PixelRef left() const { return PixelRef(x - 1, y); } PixelRef right() const { return PixelRef(x + 1, y); } PixelRef down() const { return PixelRef(x, y - 1); } short& operator [] (int i) { return (i == XAXIS) ? x : y; } bool within( const PixelRef bl, const PixelRef tr ) const { return (x >= bl.x && x <= tr.x && y >= bl.y && y <= tr.y); } bool encloses( PixelRef testpoint ) const { return (testpoint.x >= 0 && testpoint.x < x && testpoint.y >= 0 && testpoint.y < y);} // directions for the ngraph: enum {NODIR = 0x00, HORIZONTAL = 0x01, VERTICAL = 0x02, POSDIAGONAL = 0x04, NEGDIAGONAL = 0x08, DIAGONAL = 0x0c, NEGHORIZONTAL = 0x10, NEGVERTICAL = 0x20}; short& row(char dir) { return (dir & VERTICAL) ? x : y; } short& col(char dir) { return (dir & VERTICAL) ? y : x; } const short& row(char dir) const { return (dir & VERTICAL) ? x : y; } const short& col(char dir) const { return (dir & VERTICAL) ? y : x; } PixelRef& move(char dir) { switch (dir) { case POSDIAGONAL: x++; y++; break; case NEGDIAGONAL: x++; y--; break; case HORIZONTAL: x++; break; case VERTICAL: y++; break; case NEGHORIZONTAL: x--; break; case NEGVERTICAL: y--; break; } return *this; } bool isodd() const { return x % 2 == 1 && y % 2 == 1; } bool iseven() const { return x % 2 == 0 && y % 2 == 0; } friend bool operator == (const PixelRef a, const PixelRef b); friend bool operator != (const PixelRef a, const PixelRef b); friend bool operator < (const PixelRef a, const PixelRef b); friend bool operator > (const PixelRef a, const PixelRef b); friend PixelRef operator + (const PixelRef a, const PixelRef b); friend PixelRef operator - (const PixelRef a, const PixelRef b); friend PixelRef operator / (const PixelRef a, const int factor); friend double dist(const PixelRef a, const PixelRef b); friend double angle(const PixelRef a, const PixelRef b, const PixelRef c); operator int() const { return ((int(x) << 16) + (int(y) & 0xffff)); } }; const PixelRef NoPixel( -1, -1 ); inline bool operator == (const PixelRef a, const PixelRef b) { return (a.x == b.x) && (a.y == b.y); } inline bool operator != (const PixelRef a, const PixelRef b) { return (a.x != b.x) || (a.y != b.y); } inline bool operator < (const PixelRef a, const PixelRef b) { return (a.x < b.x) || (a.x == b.x && a.y < b.y); } inline bool operator > (const PixelRef a, const PixelRef b) { return (a.x > b.x) || (a.x == b.x && a.y > b.y); } inline PixelRef operator + (const PixelRef a, const PixelRef b) { return PixelRef(a.x + b.x, a.y + b.y); } inline PixelRef operator - (const PixelRef a, const PixelRef b) { return PixelRef(a.x - b.x, a.y - b.y); } inline PixelRef operator / (const PixelRef a, const int factor) { return PixelRef(a.x / factor, a.y / factor); } inline double dist(const PixelRef a, const PixelRef b) { return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)); } inline double angle(const PixelRef a, const PixelRef b, const PixelRef c) { if (c == NoPixel) { return 0.0; } else { // n.b. 1e-12 required for floating point error return acos( double((a.x - b.x) * (b.x - c.x) + (a.y - b.y) * (b.y - c.y)) / (sqrt(sqr(a.x - b.x) + sqr(a.y - b.y)) * sqrt(sqr(b.x - c.x) + sqr(b.y - c.y)) + 1e-12) ); } } // Now sizeof(PixelRef) == sizeof(int) better stored directly: typedef std::vector PixelRefVector; ///////////////////////////////////////////////////////////////////////////////////////////////// struct PixelRefPair { PixelRef a; PixelRef b; PixelRefPair(const PixelRef x = NoPixel, const PixelRef y = NoPixel) { a = x < y ? x : y; b = x < y ? y : x; } friend bool operator == (const PixelRefPair& x, const PixelRefPair& y); friend bool operator != (const PixelRefPair& x, const PixelRefPair& y); friend bool operator < (const PixelRefPair& x, const PixelRefPair& y); friend bool operator > (const PixelRefPair& x, const PixelRefPair& y); }; // note: these are made with a is always less than b inline bool operator == (const PixelRefPair& x, const PixelRefPair& y) { return (x.a == y.a && x.b == y.b); } inline bool operator != (const PixelRefPair& x, const PixelRefPair& y) { return (x.a != y.a || x.b != y.b); } inline bool operator < (const PixelRefPair& x, const PixelRefPair& y) { return ( (x.a == y.a) ? x.b < y.b : x.a < y.a ); } inline bool operator > (const PixelRefPair& x, const PixelRefPair& y) { return ( (x.a == y.a) ? x.b > y.b : x.a > y.a ); } struct hashPixelRef { size_t operator()(const PixelRef &pixelRef) const{ return std::hash()(int(pixelRef)); } }; ================================================ FILE: salalib/point.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/point.h" #include "salalib/ngraph.h" float Point::getBinDistance(int i) { return m_node->bindistance(i); } std::istream& Point::read(std::istream& stream) { stream.read( (char *) &m_state, sizeof(m_state) ); // block is the same size as m_noderef used to be for ease of replacement: // (note block NO LONGER used!) stream.read( (char *) &m_block, sizeof(m_block) ); int dummy = 0; stream.read( reinterpret_cast(&dummy), sizeof(dummy) ); stream.read( (char *) &m_grid_connections, sizeof(m_grid_connections) ); stream.read( (char *) &m_merge, sizeof(m_merge) ); bool ngraph; stream.read( (char *) &ngraph, sizeof(ngraph) ); if (ngraph) { m_node = std::unique_ptr(new Node()); m_node->read(stream); } stream.read((char *) &m_location, sizeof(m_location)); return stream; } std::ostream &Point::write(std::ostream& stream) { stream.write( (char *) &m_state, sizeof(m_state) ); // block is the same size as m_noderef used to be for ease of replacement: // note block is no longer used at all stream.write( (char *) &m_block, sizeof(m_block) ); int dummy = 0; stream.write( (char *) &dummy, sizeof(dummy) ); stream.write( (char *) &m_grid_connections, sizeof(m_grid_connections) ); stream.write( (char *) &m_merge, sizeof(m_merge) ); bool ngraph; if (m_node) { ngraph = true; stream.write( (char *) &ngraph, sizeof(ngraph) ); m_node->write(stream); } else { ngraph = false; stream.write( (char *) &ngraph, sizeof(ngraph) ); } stream.write((char *) &m_location, sizeof(m_location)); return stream; } ================================================ FILE: salalib/point.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "genlib/p2dpoly.h" #include "salalib/pixelref.h" #include "salalib/ngraph.h" #include #include class Point { friend class Bin; friend class PointMap; friend class MetaGraph; // <- for file conversion routines friend class PafAgent; friend class PafWalker; public: enum { EMPTY = 0x0001, FILLED = 0x0002, BLOCKED = 0x0004, CONTEXTFILLED = 0x0008, // PARTBLOCKED = 0x0008 deprecated SELECTED = 0x0010, EDGE = 0x0020, MERGED = 0x0040, // PINNED = 0x0020 deprecated AGENTFILLED = 0x0080, AGENTFADE = 0x0100, AGENTA = 0x0200, AGENTB = 0x0400, AGENTC = 0x0800, UPDATELINEADDED = 0x1000, UPDATELINEREMOVED = 0x2000, HIGHLIGHT = 0x4000, AUGMENTED = 0x8000 // AV TV }; // note the order of these connections is important and used elsewhere: enum { CONNECT_E = 0x01, CONNECT_NE = 0x02, CONNECT_N = 0x04, CONNECT_NW = 0x08, CONNECT_W = 0x10, CONNECT_SW = 0x20, CONNECT_S = 0x40, CONNECT_SE = 0x80 }; // TODO: These intermediary variables are only used for storing arbitrary data during the // analysis. They should be made into local variables and removed from this class int m_misc; // <- undocounter / point seen register / agent reference number, etc float m_dist; // used to speed up metric analysis float m_cumangle; // cummulative angle -- used in metric analysis and angular analysis PixelRef m_extent; // used to speed up graph analysis (not sure whether or not it breaks it!) protected: int m_block; // not used, unlikely to be used, but kept for time being int m_state; char m_grid_connections; // this is a standard set of grid connections, with bits set for E,NE,N,NW,W,SW,S,SE std::unique_ptr m_node; // graph links Point2f m_location; // note: this is large, but it helps allow loading of non-standard grid points, // whilst allowing them to be displayed as a visibility graph, also speeds up time to // display float m_color; // although display color for the point now introduced PixelRef m_merge; // to merge with another point // hmm... this is for my 3rd attempt at a quick line intersect algo: // every line that goes through the gridsquare -- memory intensive I know, but what can you do: // accuracy is imperative here! Calculated pre-fillpoints / pre-makegraph, and (importantly) it works. std::vector m_lines; int m_processflag; public: Point() { m_state = EMPTY; m_block = 0; m_misc = 0; m_grid_connections = 0; m_node = nullptr; m_processflag = 0; m_merge = NoPixel; m_user_data = NULL; } Point& operator = (const Point& p) { m_block = p.m_block; m_state = p.m_state; m_misc = p.m_misc; m_grid_connections = p.m_grid_connections; m_node = p.m_node ? std::unique_ptr(new Node(*p.m_node)) : nullptr; m_location = p.m_location; m_color = p.m_color; m_merge = p.m_merge; m_color = p.m_color; m_extent = p.m_extent; m_dist = p.m_dist; m_cumangle = p.m_cumangle; m_lines = p.m_lines; m_processflag = p.m_processflag; return *this; } Point(const Point& p) { m_block = p.m_block; m_state = p.m_state; m_misc = p.m_misc; m_grid_connections = p.m_grid_connections; m_node = p.m_node ? std::unique_ptr(new Node(*p.m_node)) : nullptr; m_location = p.m_location; m_color = p.m_color; m_merge = p.m_merge; m_color = p.m_color; m_extent = p.m_extent; m_dist = p.m_dist; m_cumangle = p.m_cumangle; m_lines = p.m_lines; m_processflag = p.m_processflag; } // bool empty() const { return (m_state & EMPTY) == EMPTY; } bool filled() const { return (m_state & FILLED) == FILLED; } bool blocked() const { return (m_state & BLOCKED) == BLOCKED; } bool contextfilled() const { return (m_state & CONTEXTFILLED) == CONTEXTFILLED; } bool edge() const { return (m_state & EDGE) == EDGE; } bool selected() const { return (m_state & SELECTED) == SELECTED; } // // Augmented Vis bool augmented() const { return (m_state & AUGMENTED) == AUGMENTED; } // void set( int state, int undocounter = 0) { m_state = state | (m_state & Point::BLOCKED); // careful not to clear the blocked flag m_misc = undocounter; } void setBlock(bool blocked = true) { if (blocked) m_state |= Point::BLOCKED; else m_state &= ~Point::BLOCKED; } void setEdge() { m_state |= Point::EDGE; } // old blocking code //void addBlock( int block ) // { m_block |= block; } //void setBlock( int block ) // { m_block = block; } //int getBlock() const // { return m_block & 0x0000FFFF; } //void addPartBlock( int block ) // { m_block |= (block << 16); } //int getPartBlock() const // { return (m_block & 0xFFFF0000) >> 16; } //int getAllBlock() const // { return m_block | (m_block >> 16); } //int fillBlocked() const // { return m_block & 0x06600660; } int getState() { return m_state; } int getMisc() // used as: undocounter, in graph construction, and an agent reference, as well as for making axial maps { return m_misc; } void setMisc(int misc) { m_misc = misc; } // note -- set merge pixel should be done only through merge pixels PixelRef getMergePixel() { return m_merge; } Node& getNode() { return *m_node; } bool hasNode() { return m_node != nullptr; } char getGridConnections() const { return m_grid_connections; } float getBinDistance(int i); const Point2f &getLocation() const { return m_location; } public: std::istream &read(std::istream &stream); std::ostream& write(std::ostream &stream); // protected: // for user processing, set their own data on the point: void *m_user_data; public: void *getUserData() { return m_user_data; } void setUserData(void *user_data) { m_user_data = user_data; } }; ================================================ FILE: salalib/pointdata.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // Point data #include "salalib/pointdata.h" #include "salalib/parsers/mapinfodata.h" // for mapinfo interface #include "salalib/vgamodules/vgavisuallocal.h" #include "salalib/vgamodules/vgavisualglobal.h" #include "salalib/isovist.h" #include "salalib/mgraph.h" // Metagraphs are used... #include "salalib/ngraph.h" #include "salalib/attributetable.h" #include "salalib/attributetablehelpers.h" #include "genlib/comm.h" // for communicator #include "genlib/stringutils.h" #include "genlib/containerutils.h" #include #include #include ///////////////////////////////////////////////////////////////////////////////// PointMap::PointMap(const QtRegion& parentRegion, const std::vector& drawingFiles, const std::string& name): m_parentRegion(&parentRegion), m_drawingFiles(&drawingFiles), m_points(0,0), m_attributes(new AttributeTable()), m_attribHandle(new AttributeTableHandle(*m_attributes)) { m_name = name; m_cols = 0; m_rows = 0; m_filled_point_count = 0; m_spacing = 0.0; m_initialised = false; m_blockedlines = false; m_processed = false; m_boundarygraph = false; m_selection = NO_SELECTION; m_pinned_selection = false; m_undocounter = 0; // screen m_viewing_deprecated = -1; m_draw_step = 1; s_bl = NoPixel; s_tr = NoPixel; curmergeline = -1; // -2 follows axial map convention, where -1 is the reference number m_displayed_attribute = -2; } void PointMap::copy(const PointMap& other) { m_name = other.getName(); m_region = other.getRegion(); m_cols = other.getCols(); m_rows = other.getRows(); m_filled_point_count = other.getFilledPointCount(); m_spacing = other.getSpacing(); m_initialised = other.m_initialised; m_blockedlines = other.m_blockedlines; m_processed = other.m_processed; m_boundarygraph = other.m_boundarygraph; m_selection = other.m_selection; m_pinned_selection = other.m_pinned_selection; m_undocounter = other.m_undocounter; // screen m_viewing_deprecated = other.m_viewing_deprecated; m_draw_step = other.m_draw_step; s_bl = other.s_bl; s_tr = other.s_tr; curmergeline = other.curmergeline; m_offset = other.m_offset; m_bottom_left = other.m_bottom_left; // -2 follows axial map convention, where -1 is the reference number m_displayed_attribute = other.m_displayed_attribute; } void PointMap::communicate( time_t& atime, Communicator *comm, int record ) { if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage( Communicator::CURRENT_RECORD, record); } } } bool PointMap::setGrid(double spacing, const Point2f& offset) { m_spacing = spacing; // note, the internal offset is the offset from the bottom left double xoffset = fmod(m_parentRegion->bottom_left.x + offset.x,m_spacing); double yoffset = fmod(m_parentRegion->bottom_left.y + offset.y,m_spacing); if (xoffset < m_spacing / 2.0) xoffset += m_spacing; if (xoffset > m_spacing / 2.0) xoffset -= m_spacing; if (yoffset < m_spacing / 2.0) yoffset += m_spacing; if (yoffset > m_spacing / 2.0) yoffset -= m_spacing; m_offset = Point2f(-xoffset, -yoffset); if (m_points.size() != 0) { m_filled_point_count = 0; } m_undocounter = 0; // <- reset the undo counter... sorry... once you've done this you can't undo // A grid at the required spacing: m_cols = (int) floor((xoffset + m_parentRegion->width()) / m_spacing + 0.5) + 1; m_rows = (int) floor((yoffset + m_parentRegion->height()) / m_spacing + 0.5) + 1; m_bottom_left = Point2f(m_parentRegion->bottom_left.x + m_offset.x, m_parentRegion->bottom_left.y + m_offset.y); m_region = QtRegion( Point2f(m_bottom_left.x-m_spacing/2.0, m_bottom_left.y-m_spacing/2.0), Point2f(m_bottom_left.x+double(m_cols-1)*m_spacing + m_spacing/2.0, m_bottom_left.y+double(m_rows-1)*m_spacing + m_spacing/2.0) ); m_points = depthmapX::ColumnMatrix(m_rows, m_cols); for (size_t j = 0; j < m_cols; j++) { for (size_t k = 0; k < m_rows; k++) { m_points(k,j).m_location = depixelate(PixelRef(static_cast(j),static_cast(k))); } } m_initialised = true; m_blockedlines = false; m_processed = false; m_boundarygraph = false; m_merge_lines.clear(); return true; } bool PointMap::clearPoints() { if (!m_filled_point_count) { return false; } // This function is a bit messy... // each is a slight variation (saves a little time when there's a single selection as opposed to a compound selection // someday clean up m_undocounter++; if (m_selection == NO_SELECTION) { for(auto& point: m_points) { if(point.filled()) { point.set( Point::EMPTY, m_undocounter ); } } m_filled_point_count = 0; m_merge_lines.clear(); } else if (m_selection & SINGLE_SELECTION) { m_undocounter++; for (int i = s_bl.x; i <= s_tr.x; i++) { for (int j = s_bl.y; j <= s_tr.y; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.m_state & (Point::SELECTED | Point::FILLED)) { pnt.set( Point::EMPTY, m_undocounter ); if (!pnt.m_merge.empty()) { PixelRef p = pnt.m_merge; depthmapX::findAndErase(m_merge_lines, PixelRefPair(PixelRef(i,j),p)); getPoint(p).m_merge = NoPixel; getPoint(p).m_state &= ~Point::MERGED; } m_filled_point_count--; } } } } else { // COMPOUND_SELECTION (note, need to test bitwise now) for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.m_state & (Point::SELECTED | Point::FILLED)) { pnt.set( Point::EMPTY, m_undocounter ); if (!pnt.m_merge.empty()) { PixelRef p = pnt.m_merge; depthmapX::findAndErase(m_merge_lines, PixelRefPair(PixelRef(i,j),p)); getPoint(p).m_merge = NoPixel; getPoint(p).m_state &= ~Point::MERGED; } m_filled_point_count--; } } } } m_selection_set.clear(); m_selection = NO_SELECTION; return true; } bool PointMap::undoPoints() { if (!m_undocounter) { return false; } for (auto& p: m_points) { if ( p.m_misc == m_undocounter) { if (p.m_state & Point::FILLED) { p.m_state &= ~Point::FILLED; p.m_state |= Point::EMPTY; p.m_misc = 0; // probably shouldn't set to 0 (can't undo) Eventually will implement 'redo' counter as well m_filled_point_count--; } else if (p.m_state & Point::EMPTY) { p.m_state |= Point::FILLED; p.m_state &= ~Point::EMPTY; p.m_misc = 0; // probably shouldn't set to 0 (can't undo) Eventually will implement 'redo' counter as well m_filled_point_count++; } } } m_undocounter--; // reduce undo counter return true; } // constrain is used to constrain to existing rows / cols // (not quite the same as constraining to bounding box due to spacing offsets) PixelRef PointMap::pixelate( const Point2f& p, bool constrain, int scalefactor ) const { PixelRef ref; double spacing = m_spacing / double(scalefactor); ref.x = int(floor( (p.x - m_bottom_left.x + (m_spacing / 2.0)) / spacing )); ref.y = int(floor( (p.y - m_bottom_left.y + (m_spacing / 2.0)) / spacing )); if (constrain) { if (ref.x < 0) ref.x = 0; else if (ref.x >= static_cast(m_cols * scalefactor)) ref.x = (m_cols * scalefactor) - 1; if (ref.y < 0) ref.y = 0; else if (ref.y >= static_cast(m_rows * scalefactor)) ref.y = (m_rows * scalefactor) - 1; } return ref; } void PointMap::fillLine(const Line& li) { PixelRefVector pixels = pixelateLine( li, 1 ); for (size_t j = 0; j < pixels.size(); j++) { if (getPoint(pixels[j]).empty()) { getPoint(pixels[j]).set( Point::FILLED, m_undocounter ); m_filled_point_count++; } } } bool PointMap::blockLines() { if (!m_initialised || m_points.size() == 0) { return false; } if (m_blockedlines) { return true; } // just ensure lines don't exist to start off with (e.g., if someone's been playing with the visible layers) unblockLines(); // This used to use a packed Linekey (file, layer, line), but // would require a key with (file, layer, shaperef, seg) when used with shaperef, // so just switched to an integer key: for (const auto& pixelGroup: *m_drawingFiles) { for (const auto& pixel: pixelGroup.m_spacePixels) { // chooses the first editable layer it can find: if (pixel.isShown()) { std::vector newLines = pixel.getAllShapesAsLines(); for (const auto& line: newLines) { blockLine(Line(line.start(), line.end())); } } } } for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef( i, j ); Point& pt = getPoint( curs ); QtRegion viewport = regionate( curs, 1e-10 ); std::vector::iterator iter = pt.m_lines.begin(), end = pt.m_lines.end(); for(; iter != end; ) { if (!iter->crop( viewport )) { // the pixelation is fairly rough to make sure that no point is missed: this just // clears up if any point has been added in error: iter = pt.m_lines.erase(iter); end = pt.m_lines.end(); } else { ++iter; } } } } m_blockedlines = true; return true; } void PointMap::blockLine(const Line& li) { std::vector pixels = pixelateLineTouching(li,1e-10); // touching is generally better for ensuring lines pixelated completely, // although it may catch extra points... for (size_t n = 0; n < pixels.size(); n++) { getPoint(pixels[n]).m_lines.push_back(li); getPoint(pixels[n]).setBlock(true); } } void PointMap::unblockLines(bool clearblockedflag) { // just ensure lines don't exist to start off with (e.g., if someone's been playing with the visible layers) for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef(i,j); getPoint(curs).m_lines.clear(); if (clearblockedflag) { getPoint(curs).setBlock(false); } } } } // still used through pencil tool bool PointMap::fillPoint(const Point2f& p, bool add) { // "false" is do not constrain to bounding box, includes() must be used before getPoint PixelRef pix = pixelate(p,false); if (!includes(pix)) { return false; } Point& pt = getPoint(pix); if (add && !pt.filled()) { m_filled_point_count++; pt.set( Point::FILLED, ++m_undocounter ); } else if (!add && (pt.m_state & Point::FILLED)) { m_filled_point_count--; pt.set( Point::EMPTY, ++m_undocounter ); if (pt.m_merge != NoPixel) { unmergePixel(pix); } } return true; } ///////////////////////////////////////////////////////////////////////////////// // NB --- I've returned to original //AV TV // semifilled bool PointMap::makePoints(const Point2f& seed, int fill_type, Communicator *comm) { if (!m_initialised || m_points.size() == 0) { return false; } if (comm) { comm->CommPostMessage( Communicator::NUM_RECORDS, (m_rows * m_cols)); } // Snap to existing grid // "false" is does not constrain: must use includes() before getPoint PixelRef seedref = pixelate( seed, false ); if (!includes(seedref) || getPoint(seedref).filled()) { return false; } // check if seed point is actually visible from the centre of the cell std::vector& linesTouching = getPoint(seedref).m_lines; for(auto line: linesTouching) { if(intersect_line_no_touch(line, Line(seed, getPoint(seedref).m_location))) { return false; } } if (!m_blockedlines) { blockLines(); } m_undocounter++; // undo counter increased ready for fill... // AV TV //int filltype = fill_type ? Point::FILLED | Point::CONTEXTFILLED : Point::FILLED; int filltype; if( fill_type == 0 ) // FULLFILL filltype = Point::FILLED; else if( fill_type == 1 ) // SEMIFILL filltype = Point::FILLED | Point::CONTEXTFILLED; else // AUGMENT filltype = Point::AUGMENTED; getPoint(seedref).set( filltype, m_undocounter ); m_filled_point_count++; // Now... start making lines: pflipper surface; surface.a().push_back( seedref ); int added = 0; time_t atime = 0; qtimer( atime, 0 ); while (surface.a().size() > 0) { PixelRef& currpix = surface.a().back(); int result = 0; result |= expand( currpix, currpix.up(), surface.b(), filltype ); result |= expand( currpix, currpix.down(), surface.b(), filltype ); result |= expand( currpix, currpix.left(), surface.b(), filltype ); result |= expand( currpix, currpix.right(), surface.b(), filltype ); result |= expand( currpix, currpix.up().left(), surface.b(), filltype ); result |= expand( currpix, currpix.up().right(), surface.b(), filltype ); result |= expand( currpix, currpix.down().left(), surface.b(), filltype ); result |= expand( currpix, currpix.down().right(), surface.b(), filltype ); // if there is a block, mark the currpix as an edge if ((result & 4) || getPoint(currpix).blocked()) { getPoint(currpix).setEdge(); } // surface.a().pop_back(); if (surface.a().size() == 0) { surface.flip(); } added++; communicate( atime, comm, added ); } return true; } int PointMap::expand( const PixelRef p1, const PixelRef p2, PixelRefVector& list, int filltype) { if (p2.x < 0 || p2.x >= static_cast(m_cols) || p2.y < 0 || p2.y >= static_cast(m_rows)) { // 1 = off edge return 1; } if (getPoint(p2).getState() & Point::FILLED) { // 2 = already filled return 2; } Line l(depixelate(p1),depixelate(p2)); for (auto& line: getPoint(p1).m_lines) { if (intersect_region(l, line, m_spacing * 1e-10) && intersect_line(l, line, m_spacing * 1e-10)) { // 4 = blocked return 4; } } for (auto& line: getPoint(p2).m_lines) { if (intersect_region(l, line, m_spacing * 1e-10) && intersect_line(l, line, m_spacing * 1e-10)) { // 4 = blocked return 4; } } getPoint(p2).set( filltype, m_undocounter ); m_filled_point_count++; list.push_back( p2 ); // 8 = success return 8; } void PointMap::outputPoints(std::ostream& stream, char delim) { stream << "Ref" << delim << "x" << delim << "y" << std::endl; stream.precision(12); int count = 0; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef( i, j ); if ( getPoint(curs).filled() ) { Point2f p = depixelate(curs); stream << curs << delim << p.x << delim << p.y << std::endl; count++; } } } } void PointMap::outputMergeLines(std::ostream& stream, char delim) { stream << "x1" << delim << "y1" << delim << "x2" << delim << "y2" << std::endl; stream.precision(12); for (size_t i = 0; i < m_merge_lines.size(); i++) { Line li(depixelate(m_merge_lines[i].a),depixelate(m_merge_lines[i].b)); stream << li.start().x << delim << li.start().y << delim << li.end().x << delim << li.end().y << std::endl; } } ///////////////////////////////////////////////////////////////////////////////// void PointMap::outputSummary(std::ostream& myout, char delimiter) { myout << "Ref" << delimiter << "x" << delimiter << "y"; // TODO: For compatibility write the columns in alphabetical order // but the physical columns in the order inserted std::vector indices(m_attributes->getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return m_attributes->getColumnName(a) < m_attributes->getColumnName(b); }); for (int idx: indices) { myout << delimiter << m_attributes->getColumnName(idx); } myout << std::endl; myout.precision(8); for (auto iter = m_attributes->begin(); iter != m_attributes->end(); iter++) { PixelRef pix = iter->getKey().value; if (isObjectVisible(m_layers, iter->getRow())) { myout << pix << delimiter; Point2f p = depixelate(pix); myout << p.x << delimiter << p.y; for (int idx: indices) { myout << delimiter << iter->getRow().getValue(idx); } myout << std::endl; } } } void PointMap::outputMif( std::ostream& miffile, std::ostream& midfile ) { MapInfoData mapinfodata; mapinfodata.exportFile(miffile, midfile, *this); } void PointMap::outputNet(std::ostream& netfile) { // this is a bid of a faff, as we first have to get the point locations, // then the connections from a lookup table... ickity ick ick... std::map graph; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.filled() && pnt.m_node) { PixelRef pix(i,j); PixelRefVector connections; pnt.m_node->contents(connections); graph.insert(std::make_pair(pix,connections)); } } } netfile << "*Vertices " << graph.size() << std::endl; double maxdim = __max(m_region.width(),m_region.height()); Point2f offset = Point2f((maxdim - m_region.width())/(2.0*maxdim),(maxdim - m_region.height())/(2.0*maxdim)); size_t j = 0; for (auto& iter: graph) { auto graphKey = iter.first; Point2f p = depixelate(graphKey); p.x = offset.x + (p.x - m_region.bottom_left.x) / maxdim; p.y = 1.0 - (offset.y + (p.y - m_region.bottom_left.y) / maxdim); netfile << (j+1) << " \"" << graphKey << "\" " << p.x << " " << p.y << std::endl; j++; } netfile << "*Edges" << std::endl; size_t k = 0; for (auto& iter: graph) { PixelRefVector& list = iter.second; for (size_t m = 0; m < list.size(); m++) { size_t n = depthmapX::findIndexFromKey(graph, list[m]); if (static_cast(n) != -1 && k < n) { netfile << (k+1) << " " << (n+1) << " 1" << std::endl; } } } } void PointMap::outputConnections(std::ostream& myout) { myout << "#graph v1.0" << std::endl; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.filled() && pnt.m_node) { PixelRef pix(i,j); Point2f p = depixelate(pix); myout << "node {\n" << " ref " << pix << "\n" << " origin " << p.x << " " << p.y << " " << 0.0 << "\n" << " connections [" << std::endl; myout << *(pnt.m_node); myout << " ]\n}" << std::endl; } } } } void PointMap::outputConnectionsAsCSV(std::ostream& myout, std::string delim) { myout << "RefFrom" << delim << "RefTo"; std::unordered_set seenPix; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.filled() && pnt.m_node) { PixelRef pix(i,j); seenPix.insert(pix); PixelRefVector hood; pnt.m_node->contents(hood); for(PixelRef &p: hood) { if(!(std::find(seenPix.begin(), seenPix.end(), p) != seenPix.end()) && getPoint(p).filled()) { myout << std::endl << pix << delim << p; } } } } } } void PointMap::outputLinksAsCSV(std::ostream& myout, std::string delim) { myout << "RefFrom" << delim << "RefTo"; std::unordered_set seenPix; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if (pnt.filled() && pnt.m_node) { PixelRef mergePixelRef = pnt.getMergePixel(); if(mergePixelRef != NoPixel) { PixelRef pix(i,j); if(seenPix.insert(pix).second) { seenPix.insert(mergePixelRef); myout << std::endl << pix << delim << mergePixelRef; } } } } } } void PointMap::outputBinSummaries(std::ostream& myout) { myout << "cols " << m_cols << " rows " << m_rows << std::endl; myout << "x\ty"; for (int i = 0; i < 32; i++) { myout << "\tbin" << i; } myout << std::endl; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { Point p = getPoint(PixelRef(i, j)); myout << i << "\t" << j; if (!p.filled()) { for (int k = 0; k < 32; k++) { myout << "\t" << 0; } } else { for (int k = 0; k < 32; k++) { myout << "\t" << p.m_node->bin(k).count(); } } myout << std::endl; } } } ///////////////////////////////////////////////////////////////////////////////// // Attribute Stuff void PointMap::setDisplayedAttribute(int col) { if (m_displayed_attribute == col) { return; } else { m_displayed_attribute = col; } m_attribHandle->setDisplayColIndex(m_displayed_attribute); } ///////////////////////////////////////////////////////////////////////////////// // Screen stuff void PointMap::setScreenPixel( double unit ) { if (unit / m_spacing > 1) { m_draw_step = int(unit / m_spacing); } else { m_draw_step = 1; } } void PointMap::makeViewportPoints( const QtRegion& viewport ) const { // n.b., relies on "constrain" being set to true bl = pixelate( viewport.bottom_left, true ); cur = bl; // cursor for points cur.x -= 1; // findNext expects to find cur.x in the -1 position rc = bl; // cursor for grid lines prc = bl; // cursor for point centre grid lines prc.x -= 1; prc.y -= 1; // n.b., relies on "constrain" being set to true tr = pixelate( viewport.top_right, true ); curmergeline = -1; m_finished = false; } bool PointMap::findNextPoint() const { if (m_finished) { return false; } do { cur.x += m_draw_step; if (cur.x > tr.x) { cur.x = bl.x; cur.y += m_draw_step; if (cur.y > tr.y) { cur = tr; // safety first --- this will at least return something m_finished = true; return false; } } } while ( !getPoint(cur).filled() && !getPoint(cur).blocked() ); return true; } bool PointMap::findNextRow() const { rc.y += 1; if (rc.y > tr.y) return false; return true; } Line PointMap::getNextRow() const { Point2f offset( m_spacing / 2.0, m_spacing / 2.0 ); return Line( depixelate( PixelRef(bl.x, rc.y)) - offset, depixelate( PixelRef(tr.x+1, rc.y)) - offset ); } bool PointMap::findNextPointRow() const { prc.y += 1; if (prc.y > tr.y) return false; return true; } Line PointMap::getNextPointRow() const { Point2f offset( m_spacing / 2.0, 0 ); return Line( depixelate( PixelRef(bl.x, prc.y)) - offset, depixelate( PixelRef(tr.x+1, prc.y)) - offset ); } bool PointMap::findNextCol() const { rc.x += 1; if (rc.x > tr.x) return false; return true; } Line PointMap::getNextCol() const { Point2f offset( m_spacing / 2.0, m_spacing / 2.0 ); return Line( depixelate( PixelRef(rc.x, bl.y) ) - offset, depixelate( PixelRef(rc.x, tr.y+1) ) - offset ); } bool PointMap::findNextPointCol() const { prc.x += 1; if (prc.x > tr.x) return false; return true; } Line PointMap::getNextPointCol() const { Point2f offset( 0.0, m_spacing / 2.0 ); return Line( depixelate( PixelRef(prc.x, bl.y) ) - offset, depixelate( PixelRef(prc.x, tr.y+1) ) - offset ); } bool PointMap::findNextMergeLine() const { if (curmergeline < (int)m_merge_lines.size()) { curmergeline++; } return (curmergeline < (int)m_merge_lines.size()); } Line PointMap::getNextMergeLine() const { if (curmergeline < (int)m_merge_lines.size()) { return Line(depixelate(m_merge_lines[curmergeline].a), depixelate(m_merge_lines[curmergeline].b)); } return Line(); } bool PointMap::getPointSelected() const { int state = pointState( cur ); if (state & Point::SELECTED) { return true; } return false; } PafColor PointMap::getPointColor(PixelRef pixelRef) const { PafColor color; int state = pointState( pixelRef ); if (state & Point::HIGHLIGHT) { return PafColor( SALA_HIGHLIGHTED_COLOR ); } else if (state & Point::SELECTED) { return PafColor( SALA_SELECTED_COLOR ); } else { if (state & Point::FILLED) { if (m_processed) { return dXreimpl::getDisplayColor(AttributeKey(pixelRef), m_attributes->getRow(AttributeKey(pixelRef)), *m_attribHandle.get(), true); } else if (state & Point::EDGE) { return PafColor( 0x0077BB77 ); } else if (state & Point::CONTEXTFILLED) { return PafColor( 0x007777BB ); } else { return PafColor( 0x00777777 ); } } else { return PafColor(); } } return PafColor(); // <- note alpha channel set to transparent - will not be drawn } PafColor PointMap::getCurrentPointColor() const { return getPointColor( cur ); } ///////////////////////////////////////////////////////////////////////////////// // Selection stuff // eventually we will use returned info to draw the selected point quickly bool PointMap::clearSel() { if (m_selection == NO_SELECTION) { return false; } for (auto& sel: m_selection_set) { getPoint(sel).m_state &= ~Point::SELECTED; } m_selection_set.clear(); m_selection = NO_SELECTION; m_attributes->deselectAllRows(); return true; } bool PointMap::setCurSel(QtRegion &r, bool add ) { if (m_selection == NO_SELECTION) { add = false; } else if (!add) { // Since we started using point locations in the sel set this is a lot easier! clearSel(); } // n.b., assumes constrain set to true (for if you start the selection off the grid) s_bl = pixelate(r.bottom_left, true); s_tr = pixelate(r.top_right, true); if (!add) { m_sel_bounds = r; } else { m_sel_bounds = runion(m_sel_bounds, r); } int mask = 0; mask |= Point::FILLED; for (int i = s_bl.x; i <= s_tr.x; i++) { for (int j = s_bl.y; j <= s_tr.y; j++) { Point& pnt = m_points(static_cast(j), static_cast(i)); if ((pnt.m_state & mask) && (~pnt.m_state & Point::SELECTED)) { pnt.m_state |= Point::SELECTED; m_selection_set.insert( PixelRef(i,j) ); if (add) { m_selection &= ~SINGLE_SELECTION; m_selection |= COMPOUND_SELECTION; } else { m_selection |= SINGLE_SELECTION; } if (pnt.m_node) { m_attributes->getRow(AttributeKey(PixelRef(i,j))).setSelection(true); } } } } // Set the region to our actual region: r = QtRegion( depixelate(s_bl), depixelate(s_tr) ); return true; } bool PointMap::setCurSel(const std::vector& selset, bool add) { // note: override cursel, can only be used with analysed pointdata: if (!add) { clearSel(); } m_selection = COMPOUND_SELECTION; // not sure what to do with m_sel_bounds (is it necessary?) for (size_t i = 0; i < selset.size(); i++) { PixelRef pix = selset[i]; if (includes(pix)) { m_points(static_cast(pix.y), static_cast(pix.x)).m_state |= Point::SELECTED; AttributeRow& row = m_attributes->getRow(AttributeKey(pix)); if (!row.isSelected()) { row.setSelection(true); m_selection_set.insert(pix); } } } return true; } // Helper function: is there a blocked point next to you? // ...rather scruffily goes round the eight adjacent points... // This is being phased out, with the new "edge" points (which are the filled edges of the graph) bool PointMap::blockedAdjacent( const PixelRef p ) const { bool ba = false; PixelRef temp = p.right(); PixelRef bounds(m_cols, m_rows); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Right ba = true; } else { temp = temp.up(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Top right ba = true; } else { temp = temp.left(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Top ba = true; } else { temp = temp.left(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Top Left ba = true; } else { temp = temp.down(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Left ba = true; } else { temp = temp.down(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Bottom Left ba = true; } else { temp = temp.right(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Bottom ba = true; } else { temp = temp.right(); if (bounds.encloses(temp) && getPoint(temp).blocked()) { // Bottom right ba = true; } } } } } } } } return ba; } //////////////////////////////////////////////////////////////////////////////// bool PointMap::read(std::istream& stream ) { m_name = dXstring::readString(stream); // NOTE: You MUST set m_spacepix manually! m_displayed_attribute = -1; stream.read( (char *) &m_spacing, sizeof(m_spacing) ); int rows, cols; stream.read( reinterpret_cast(&rows), sizeof(rows) ); stream.read( reinterpret_cast(&cols), sizeof(cols) ); m_rows = static_cast(rows); m_cols = static_cast(cols); stream.read( (char *) &m_filled_point_count, sizeof(m_filled_point_count) ); stream.read( (char *) &m_bottom_left, sizeof(m_bottom_left) ); m_region = QtRegion( Point2f(m_bottom_left.x-m_spacing/2.0, m_bottom_left.y-m_spacing/2.0), Point2f(m_bottom_left.x+double(m_cols-1)*m_spacing + m_spacing/2.0, m_bottom_left.y+double(m_rows-1)*m_spacing + m_spacing/2.0) ); int displayed_attribute; // n.b., temp variable necessary to force recalc below // our data read stream.read((char *)&displayed_attribute,sizeof(displayed_attribute)); m_attributes->read( stream, m_layers ); m_points = depthmapX::ColumnMatrix(m_rows, m_cols); for (size_t j = 0; j < m_cols; j++) { for (size_t k = 0; k < m_rows; k++) { m_points(k, j).read(stream); // check if occdistance of any pixel's bin is set, meaning that // the isovist analysis was done if(!m_hasIsovistAnalysis) { for(int b = 0; b < 32; b++) { if(m_points(k, j).m_node && m_points(k, j).m_node->occdistance(b) > 0) { m_hasIsovistAnalysis = true; break; } } } } for (size_t k = 0; k < m_rows; k++) { Point& pnt = m_points(k, j); // Old style point node reffing and also unselects selected nodes which would otherwise be difficult // would soon be better simply to turn off the select flag.... pnt.m_state &= ( Point::EMPTY | Point::FILLED | Point::MERGED | Point::BLOCKED | Point::CONTEXTFILLED | Point::EDGE); // Set the node pixel if it exists: if (pnt.m_node) { pnt.m_node->setPixel(PixelRef(j,k)); } // Add merge line if merged: if (!pnt.m_merge.empty()) { depthmapX::addIfNotExists(m_merge_lines, PixelRefPair(PixelRef(j,k),pnt.m_merge)); } } } m_selection = NO_SELECTION; m_pinned_selection = false; m_initialised = true; m_blockedlines = false; stream.read((char *) &m_processed, sizeof(m_processed)); stream.read((char *) &m_boundarygraph, sizeof(m_boundarygraph)); // now, as soon as loaded, must recalculate our screen display: // note m_displayed_attribute should be -2 in order to force recalc... m_displayed_attribute = -2; setDisplayedAttribute(displayed_attribute); return true; } bool PointMap::write( std::ostream& stream ) { dXstring::writeString(stream, m_name); stream.write( (char *) &m_spacing, sizeof(m_spacing) ); int rows = static_cast(m_rows); int cols = static_cast(m_cols); stream.write( reinterpret_cast(&rows), sizeof(rows) ); stream.write( reinterpret_cast(&cols), sizeof(cols) ); stream.write( (char *) &m_filled_point_count, sizeof(m_filled_point_count) ); stream.write( (char *) &m_bottom_left, sizeof(m_bottom_left) ); // TODO: Compatibility. The attribute columns will be stored sorted alphabetically // so the displayed attribute needs to match that int sortedDisplayedAttribute = m_attributes->getColumnSortedIndex(m_displayed_attribute); stream.write( (char *) &sortedDisplayedAttribute, sizeof(sortedDisplayedAttribute) ); m_attributes->write( stream, m_layers ); for (auto& point: m_points) { point.write( stream ); } stream.write((char *) &m_processed, sizeof(m_processed)); stream.write((char *) &m_boundarygraph, sizeof(m_boundarygraph)); return false; } //////////////////////////////////////////////////////////////////////////////// // Now what this class is actually for: making a visibility graph! // Visibility graph construction constants int PointMap::tagState(bool settag) { m_selection_set.clear(); m_selection = NO_SELECTION; int count = 0; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef( i, j ); // First ensure only one of filled/empty/blocked is on: Point& pt = getPoint(curs); if (pt.filled() ) { if (settag) { pt.m_misc = count; pt.m_processflag = 0x00FF; // process all quadrants } else { pt.m_misc = 0; pt.m_processflag = 0x0000; // reset process flag } count++; } } } return count; } //////////////////////////////////////////////////////////////////////////////////////////////// #include "sparksieve2.h" // The fast way to generate graphs... attempt 2 // This uses the new points line segments to allow quick overlap comparisons // The spark method uses a 1024 long bit string to check against // writing the algo has thrown up something: it would be more appropriate to // have lines between the grid points, rather than centred on the grid square, // i.e.: // // .-. --- // |X| not |.| (dots are the grid points) // .-. --- // // Then wouldn't have to 'test twice' for the grid point being blocked... // ...perhaps a tweak for a later date! bool PointMap::sparkGraph2( Communicator *comm, bool boundarygraph, double maxdist ) { // Note, graph must be fixed (i.e., having blocking pixels filled in) if (!m_blockedlines) { blockLines(); } if (boundarygraph) { for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef( static_cast(i), static_cast(j) ); if ( getPoint( curs ).filled() && !getPoint( curs ).edge()) { m_points(j, i).m_state &= ~Point::FILLED; m_filled_point_count--; } } } } // attributes table set up // n.b. these must be entered in alphabetical order to preserve col indexing: int connectivity_col = m_attributes->insertOrResetLockedColumn("Connectivity"); m_attributes->insertOrResetColumn("Point First Moment"); m_attributes->insertOrResetColumn("Point Second Moment"); // pre-label --- allows faster node access later on int count = tagState( true ); // start the timer when you know the true count including fixed points time_t atime = 0; if (comm) { qtimer( atime, 0 ); comm->CommPostMessage( Communicator::NUM_RECORDS, count ); } count = 0; for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef( i, j ); if ( getPoint( curs ).getState() & Point::FILLED ) { getPoint( curs ).m_node = std::unique_ptr(new Node()); m_attributes->addRow( AttributeKey(curs) ); sparkPixel2(curs,1,maxdist); // make flag of 1 suggests make this node, don't set reciprocral process flags on those you can see // maxdist controls how far to see out to count++; // <- increment count if (comm) { if (qtimer( atime, 500 )) { if (comm->IsCancelled()) { tagState( false ); // <- the state field has been used for tagging visited nodes... set back to a state variable // (well, actually, no it hasn't!) // Should clear all nodes and attributes here: // Clear nodes // Clear attributes m_attributes->clear(); m_displayed_attribute = -2; // throw Communicator::CancelledException(); } comm->CommPostMessage( Communicator::CURRENT_RECORD, count ); } } // if (comm) } // if ( getPoint( curs ).getState() & Point::FILLED ) } // rows } // cols tagState( false ); // <- the state field has been used for tagging visited nodes... set back to a state variable // keeping lines blocked now is wasteful of memory... free the memory involved unblockLines(false); // and add grid connections // (this is easier than trying to work it out per pixel as we calculate visibility) addGridConnections(); // the graph is processed: m_processed = true; if (boundarygraph) { m_boundarygraph = true; } // override and reset: m_displayed_attribute = -2; setDisplayedAttribute(connectivity_col); return true; } bool PointMap::unmake(bool removeLinks) { for (size_t i = 0; i < m_cols; i++) { for (size_t j = 0; j < m_rows; j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); Point &pnt = getPoint(curs); if (pnt.filled()) { if(removeLinks) { pnt.m_merge = NoPixel; } pnt.m_grid_connections = 0; pnt.m_node = nullptr; pnt.m_lines.clear(); pnt.setBlock(false); } } } m_blockedlines = false; if(removeLinks) { m_merge_lines.clear(); } m_attributes->clear(); m_processed = false; m_boundarygraph = false; m_displayed_attribute = -2; return true; } // 'make' construct types are: // 1 -- build this node // 2 -- register the reciprocal q octant in nodes you can see as requiring processing bool PointMap::sparkPixel2(PixelRef curs, int make, double maxdist) { static std::vector bins_b[32]; static float far_bin_dists[32]; for (int i = 0; i < 32; i++) { far_bin_dists[i] = 0.0f; } int neighbourhood_size = 0; double total_dist = 0.0; double total_dist_sqr = 0.0; Point2f centre0 = depixelate(curs); for (int q = 0; q < 8; q++) { if (!((getPoint(curs).m_processflag) & (1 << q)) ) { continue; } sparkSieve2 sieve(centre0, maxdist); int depth = 0; // attempt 0 depth line tests by taken appropriate quadrant // from immediately around centre // note regionate border must be greater than tolerance squared used in interection testing later double border = m_spacing * 1e-10; QtRegion viewport0 = regionate(curs, 1e-10); switch (q) { case 0: viewport0.top_right.x = centre0.x; viewport0.bottom_left.y = centre0.y - border; break; case 6: viewport0.top_right.x = centre0.x + border; viewport0.bottom_left.y = centre0.y; break; case 1: viewport0.bottom_left.x = centre0.x; viewport0.bottom_left.y = centre0.y - border; break; case 7: viewport0.bottom_left.x = centre0.x - border; viewport0.bottom_left.y = centre0.y; break; case 2: viewport0.top_right.x = centre0.x; viewport0.top_right.y = centre0.y + border; break; case 4: viewport0.top_right.x = centre0.x + border; viewport0.top_right.y = centre0.y; break; case 3: viewport0.bottom_left.x = centre0.x; viewport0.top_right.y = centre0.y + border; break; case 5: viewport0.bottom_left.x = centre0.x - border; viewport0.top_right.y = centre0.y; break; } std::vector lines0; for (const Line& line: getPoint(curs).m_lines) { Line l = line; if (l.crop(viewport0)) { lines0.push_back(l); } } sieve.block(lines0, q); sieve.collectgarbage(); std::vector addlist; for (depth = 1; sieve.hasGaps(); depth++) { addlist.clear(); if (!sieve2(sieve, addlist, q, depth, curs)) { break; } for (size_t n = 0; n < addlist.size(); n++) { if (getPoint(addlist[n]).getState() & Point::FILLED) { int bin = whichbin(depixelate(addlist[n])-centre0); if (make & 1) { // the blocked cells shouldn't contribute to point stats // note m_spacing is used to scale the moment of inertia appropriately double this_dist = dist(addlist[n],curs) * m_spacing; if (this_dist > far_bin_dists[bin]) { far_bin_dists[bin] = (float) this_dist; } total_dist += this_dist; total_dist_sqr += this_dist * this_dist; neighbourhood_size++; bins_b[bin].push_back( addlist[n] ); } if (make & 2) { getPoint(addlist[n]).m_processflag |= q_opposite(bin); } } } } // <- for (depth = 1; sieve.hasgaps(); depth++) } // <- for (int q = 0; q < 8; q++) if (make & 1) { // The bins are cleared in the make function! Point& pt = getPoint( curs ); pt.m_node->make(curs, bins_b, far_bin_dists, pt.m_processflag); // note: make clears bins! AttributeRow& row = m_attributes->getRow( AttributeKey(curs) ); row.setValue( "Connectivity", float(neighbourhood_size) ); row.setValue( "Point First Moment", float(total_dist) ); row.setValue( "Point Second Moment", float(total_dist_sqr) ); } else { // Clear bins by hand if not using them to make for (int i = 0; i < 32; i++) { bins_b[i].clear(); } } // reset process flag getPoint(curs).m_processflag = 0; return true; } bool PointMap::sieve2(sparkSieve2& sieve, std::vector& addlist, int q, int depth, PixelRef curs) { bool hasgaps = false; int firstind = 0; for (auto iter = sieve.m_gaps.begin(); iter != sieve.m_gaps.end(); ++iter) { // this goes through all open points if (iter->remove) { continue; } for (int ind = (int)ceil(iter->start * (depth - 0.5) - 0.5); ind <= (int) floor(iter->end * (depth + 0.5) + 0.5); ind++) { if (ind < firstind) { continue; } if (ind > depth) { break; } // this did say first = ind + 1, but I needed to change it to cope with vertical lines // I have a feeling the ind + 1 was there for a reason! // (if there to cope with boundary graph, could easily simply use ind + 1 in the specific check) firstind = ind; // x and y are calculated using Grad's whichbin q quadrants int x = (q >= 4 ? ind : depth); int y = (q >= 4 ? depth : ind); PixelRef here = PixelRef( curs.x + (q % 2 ? x : -x), curs.y + (q <= 1 || q >= 6 ? y : -y) ); if (includes(here)) { hasgaps = true; // centre gap checks to see if the point is blocked itself bool centregap = (double(ind) >= (iter->start * depth) && double(ind) <= (iter->end * depth)); if (centregap && (getPoint(here).m_state & Point::FILLED)) { // don't repeat axes / diagonals if ((ind != 0 || q == 0 || q == 1 || q == 5 || q == 6) && (ind != depth || q < 4)) { // block test as usual [tested 31.10.04 -- MUST use 1e-10 for Gassin at 10 grid spacing] if (!sieve.testblock(depixelate(here), getPoint(here).m_lines, m_spacing * 1e-10)) { addlist.push_back(here); } } } sieve.block( getPoint(here).m_lines, q ); } } } sieve.collectgarbage(); return hasgaps; } //////////////////////////////////////////////////////////////////////////////////////////////// bool PointMap::binDisplay(Communicator *) { int bindisplay_col = m_attributes->insertOrResetColumn("Node Bins"); for (auto& sel: m_selection_set) { Point& p = getPoint(sel); // Code for colouring pretty bins: for (int i = 0; i < 32; i++) { Bin& b = p.m_node->bin(i); b.first(); while(!b.is_tail()) { //m_attributes->setValue( row, bindisplay_col, float((i % 8) + 1) ); m_attributes->getRow(AttributeKey(b.cursor())).setValue( bindisplay_col, float(b.distance()) ); b.next(); } } } // override and reset: m_displayed_attribute = -2; setDisplayedAttribute(bindisplay_col); return true; } // Merge connections... very fiddly indeed... using a simple method for now... // ...and even that's too complicated... so I'll settle for a very, very simple // merge points (just a reference to another point --- yes, that simple!) // the first point should have been selected, the second is chosen now: bool PointMap::mergePoints(const Point2f& p) { if (!m_selection_set.size()) { return false; } // note that in a multiple selection, the point p is adjusted by the selection bounds PixelRef bl = pixelate(m_sel_bounds.bottom_left); PixelRef tr = pixelate(m_sel_bounds.top_right); // PixelRef offset = pixelate(p) - PixelRef(tr.x,bl.y); // for (auto& sel: m_selection_set) { PixelRef a = sel; PixelRef b = ((PixelRef)sel) + offset; // check in limits: if (includes(b) && getPoint(b).filled()) { mergePixels(a,b); } } clearSel(); return true; } bool PointMap::unmergePoints() { if (!m_selection_set.size()) { return false; } for (auto& sel: m_selection_set) { PixelRef a = sel; Point p = getPoint(a); if(p.getMergePixel() != NoPixel) { unmergePixel(a); } } clearSel(); return true; } // Either of the pixels can be given here and the other will also be unmerged bool PointMap::unmergePixel(PixelRef a) { PixelRef c = getPoint(a).m_merge; depthmapX::findAndErase(m_merge_lines, PixelRefPair(a,c)); getPoint(c).m_merge = NoPixel; getPoint(c).m_state &= ~Point::MERGED; getPoint(a).m_merge = NoPixel; getPoint(a).m_state &= ~Point::MERGED; return true; } bool PointMap::mergePixels(PixelRef a, PixelRef b) { if (a == b && !getPoint(a).m_merge.empty()) { unmergePixel(a); } if (a != b && getPoint(a).m_merge != b) { if (!getPoint(a).m_merge.empty()) { PixelRef c = getPoint(a).m_merge; auto it = std::find(m_merge_lines.begin(), m_merge_lines.end(), PixelRefPair(a,c)); if(it != m_merge_lines.end()) m_merge_lines.erase(it); getPoint(c).m_merge = NoPixel; getPoint(c).m_state &= ~Point::MERGED; } if (!getPoint(b).m_merge.empty()) { PixelRef c = getPoint(b).m_merge; auto it = std::find(m_merge_lines.begin(), m_merge_lines.end(), PixelRefPair(b,c)); if(it != m_merge_lines.end()) m_merge_lines.erase(it); getPoint(c).m_merge = NoPixel; getPoint(c).m_state &= ~Point::MERGED; } getPoint(a).m_merge = b; getPoint(a).m_state |= Point::MERGED; getPoint(b).m_merge = a; getPoint(b).m_state |= Point::MERGED; m_merge_lines.push_back(PixelRefPair(a,b)); } // actually this return now triggers redraw whatever // rather than passing back altered status (as a point must be deselected) return true; } void PointMap::mergeFromShapeMap(const ShapeMap& shapemap) { const std::map& polygons = shapemap.getAllShapes(); for (auto polygon: polygons) { const SalaShape& poly = polygon.second; if (poly.isLine()) { PixelRef a = pixelate(poly.getLine().start()); PixelRef b = pixelate(poly.getLine().end()); if (getPoint(a).filled() && getPoint(b).filled()) { mergePixels(a,b); } } } } bool PointMap::isPixelMerged(const PixelRef& a) { return !getPoint(a).m_merge.empty(); } // -2 for point not in visibility graph, -1 for point has no data double PointMap::getLocationValue(const Point2f& point) { double val = -2; // "false" does not constrain to bounds PixelRef pix = pixelate(point, false); // quick check for outside row / col bounds: if (!includes(pix)) { return val; } if (!getPoint(pix).filled()) { val = -2; } else if (m_displayed_attribute == -1) { val = static_cast(pix); } else { val = m_attributes->getRow(AttributeKey(pix)).getValue(m_displayed_attribute); } return val; } ///////////////////////////////////////////////////////////////////////////////// // Update connections will load an old graph and add char information void PointMap::addGridConnections() { for (auto iter = m_attributes->begin(); iter != m_attributes->end(); iter++) { PixelRef curs = iter->getKey().value; PixelRef node = curs.right(); Point& point = getPoint(curs); point.m_grid_connections = 0; for (int i = 0; i < 32; i += 4) { Bin& bin = point.m_node->bin(i); bin.first(); while (!bin.is_tail()) { if (node == bin.cursor()) { point.m_grid_connections |= (1 << (i / 4)); break; } bin.next(); } char dir = PixelRef::NODIR; if (i == 0) { dir = PixelRef::VERTICAL; } else if (i == 4 || i == 8) { dir = PixelRef::NEGHORIZONTAL; } else if (i == 12 || i == 16) { dir = PixelRef::NEGVERTICAL; } else if (i == 20 || i == 24) { dir = PixelRef::HORIZONTAL; } node.move(dir); } } } // value in range 0 to 1 PixelRef PointMap::pickPixel(double value) const { int which = (int)ceil(value * m_rows * m_cols) - 1; return PixelRef(which % m_cols, which / m_cols); } ================================================ FILE: salalib/pointdata.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef __POINTDATA_H__ #define __POINTDATA_H__ #include "salalib/spacepixfile.h" #include "genlib/exceptions.h" #include "salalib/point.h" #include "salalib/options.h" #include "salalib/attributetable.h" #include #include #include class MetaGraph; class PointMap; class PafAgent; class ShapeMap; class OldPoint1 { friend class PointMap; protected: int m_noderef; int m_state; }; class OldPoint2 { friend class PointMap; protected: int m_noderef; int m_state; int m_misc; }; class Bin; class Isovist; struct PixelVec; class sparkSieve2; namespace depthmapX { enum PointMapExceptionType{NO_ISOVIST_ANALYSIS}; class PointMapException: public depthmapX::RuntimeException { private: PointMapExceptionType m_errorType; public: PointMapException(PointMapExceptionType errorType, std::string message) : depthmapX::RuntimeException(message) { m_errorType = errorType; } PointMapExceptionType getErrorType() const { return m_errorType; } }; } class PointMap : public PixelBase { friend class PointMaps; friend class MapInfoData; // <- for mapinfo export // MetaGraph is a friend for two functions: // convertAttributes: this really should not be at the metagraph level! Fix! // pushValuesToLayer: this swaps values from a PointMap to a DataLayer, and it needs to be changed in the future // (e.g., when making DataLayers into ShapeMaps) friend class MetaGraph; public: bool m_hasIsovistAnalysis = false; const std::vector& getDrawingFiles() { return *m_drawingFiles; } protected: std::string m_name; const QtRegion* m_parentRegion; const std::vector* m_drawingFiles; depthmapX::ColumnMatrix m_points; // will contain the graph reference when created int m_filled_point_count; double m_spacing; Point2f m_offset; Point2f m_bottom_left; bool m_initialised; bool m_blockedlines; bool m_processed; bool m_boundarygraph; int m_undocounter; std::vector m_merge_lines; private: std::unique_ptr m_attributes; std::unique_ptr m_attribHandle; LayerManagerImpl m_layers; public: PointMap(const QtRegion& parentRegion, const std::vector& drawingFiles, const std::string& name = std::string("VGA Map")); virtual ~PointMap() {} void copy(const PointMap& other); const std::string& getName() const { return m_name; } PointMap(PointMap&& other): m_parentRegion(std::move(other.m_parentRegion)), m_drawingFiles(std::move(other.m_drawingFiles)), m_points(std::move(other.m_points)), m_attributes(std::move(other.m_attributes)), m_attribHandle(std::move(other.m_attribHandle)), m_layers(std::move(other.m_layers)) { copy(other); } PointMap& operator =(PointMap&& other) { m_parentRegion = std::move(other.m_parentRegion); m_drawingFiles = std::move(other.m_drawingFiles); m_points = std::move(other.m_points); m_attributes = std::move(other.m_attributes); m_attribHandle = std::move(other.m_attribHandle); m_layers = std::move(other.m_layers); copy(other); return *this; } PointMap(const PointMap& ) = delete; PointMap& operator =(const PointMap&) = delete; void communicate( time_t& atime, Communicator *comm, int record ); // constrain is constrain to existing rows / cols PixelRef pixelate( const Point2f& p, bool constrain = true, int scalefactor = 1 ) const; Point2f depixelate( const PixelRef& p, double scalefactor = 1.0 ) const; // Inlined below QtRegion regionate( const PixelRef& p, double border ) const; // Inlined below bool setGrid(double spacing, const Point2f& offset = Point2f()); std::vector> getMergedPixelPairs() { // unnecessary converter until the m_merge_lines variable is // replaced with a std container std::vector> mergedPixelPairs; for (size_t i = 0; i < m_merge_lines.size(); i++) { mergedPixelPairs.push_back(std::make_pair(m_merge_lines[i].a, m_merge_lines[i].b)); } return mergedPixelPairs; } // bool isProcessed() const { return m_processed; } void fillLine(const Line& li); bool blockLines(); void blockLine(const Line& li); void unblockLines(bool clearblockedflag = true); bool fillPoint(const Point2f& p, bool add = true); // use add = false for remove point //bool blockPoint(const Point2f& p, bool add = true); // no longer used // bool makePoints(const Point2f& seed, int fill_type, Communicator *comm = nullptr); // Point2f non-reference deliberate bool clearPoints(); // Clear *selected* points bool undoPoints(); bool canUndo() const { return !m_processed && m_undocounter != 0; } void outputPoints(std::ostream& stream, char delim ); void outputMergeLines(std::ostream& stream, char delim); int tagState(bool settag); bool sparkGraph2(Communicator *comm, bool boundarygraph, double maxdist ); bool unmake(bool removeLinks); bool sparkPixel2(PixelRef curs, int make, double maxdist = -1.0); bool sieve2(sparkSieve2& sieve, std::vector& addlist, int q, int depth, PixelRef curs); // bool makeGraph( Graph& graph, int optimization_level = 0, Communicator *comm = NULL); // bool binDisplay(Communicator *); bool mergePoints(const Point2f& p); bool unmergePoints(); bool unmergePixel(PixelRef a); bool mergePixels(PixelRef a, PixelRef b); void mergeFromShapeMap(const ShapeMap& shapemap); bool isPixelMerged(const PixelRef &a); void outputSummary(std::ostream& myout, char delimiter = '\t'); void outputMif(std::ostream& miffile, std::ostream& midfile ); void outputNet(std::ostream& netfile ); void outputConnections(std::ostream& myout); void outputBinSummaries(std::ostream& myout); const Point& getPoint(const PixelRef& p) const { return m_points(static_cast(p.y), static_cast(p.x)); } Point& getPoint(const PixelRef& p) { return m_points(static_cast(p.y), static_cast(p.x)); } depthmapX::BaseMatrix& getPoints() { return m_points; } const int& pointState( const PixelRef& p ) const { return m_points(static_cast(p.y), static_cast(p.x)).m_state; } // to be phased out bool blockedAdjacent( const PixelRef p ) const; // int getFilledPointCount() const { return m_filled_point_count; } // void requireIsovistAnalysis() { if(!m_hasIsovistAnalysis) { throw depthmapX::PointMapException(depthmapX::PointMapExceptionType::NO_ISOVIST_ANALYSIS, "Current pointmap does not contain isovist analysis"); } } protected: int expand( const PixelRef p1, const PixelRef p2, PixelRefVector& list, int filltype ); // //void walk( PixelRef& start, int steps, Graph& graph, // int parity, int dominant_axis, const int grad_pair[] ); // Selection functionality protected: enum { NO_SELECTION = 0, SINGLE_SELECTION = 1, COMPOUND_SELECTION = 2, LAYER_SELECTION = 4, OVERRIDE_SELECTION = 8 }; int m_selection; bool m_pinned_selection; std::set m_selection_set; // n.b., m_selection_set stored as int for compatibility with other map layers mutable PixelRef s_bl; mutable PixelRef s_tr; public: bool isSelected() const // does a selection exist { return m_selection != NO_SELECTION; } bool clearSel(); // clear the current selection bool setCurSel( QtRegion& r, bool add = false ); // set current selection bool setCurSel(const std::vector &selset, bool add = false ); // Note: passed by ref, use with care in multi-threaded app std::set& getSelSet() { return m_selection_set; } const std::set& getSelSet() const { return m_selection_set; } // PixelRefVector getLayerPixels(int layer); // Attribute functionality protected: // which attribute is currently displayed: mutable int m_displayed_attribute; public: int addAttribute(const std::string& name) { return m_attributes->insertOrResetColumn(name); } void removeAttribute(int col) { m_attributes->removeColumn(col); } // I don't want to do this, but every so often you will need to update this table // use const version by preference AttributeTable& getAttributeTable() { return *m_attributes.get(); } const AttributeTable& getAttributeTable() const { return *m_attributes.get(); } LayerManagerImpl& getLayers() { return m_layers; } const LayerManagerImpl& getLayers() const { return m_layers; } AttributeTableHandle& getAttributeTableHandle() { return *m_attribHandle.get(); } const AttributeTableHandle& getAttributeTableHandle() const { return *m_attribHandle.get(); } public: double getDisplayMinValue() const { return (m_displayed_attribute != -1) ? m_attributes->getColumn(m_displayed_attribute).getStats().min : 0; } double getDisplayMaxValue() const { return (m_displayed_attribute != -1) ? m_attributes->getColumn(m_displayed_attribute).getStats().max : pixelate(m_region.top_right).x; } const DisplayParams& getDisplayParams() const { return m_attributes->getColumn(m_displayed_attribute).getDisplayParams(); } // make a local copy of the display params for access speed: void setDisplayParams(const DisplayParams& dp, bool apply_to_all = false) { if (apply_to_all) m_attributes->setDisplayParams(dp); else m_attributes->getColumn(m_displayed_attribute).setDisplayParams(dp); } // public: void setDisplayedAttribute( int col ); // use set displayed attribute instead unless you are deliberately changing the column order: void overrideDisplayedAttribute(int attribute) { m_displayed_attribute = attribute; } // now, there is a slightly odd thing here: the displayed attribute can go out of step with the underlying // attribute data if there is a delete of an attribute in idepthmap.h, so it just needs checking before returning! int getDisplayedAttribute() const { if (m_displayed_attribute == m_attribHandle->getDisplayColIndex()) return m_displayed_attribute; if (m_attribHandle->getDisplayColIndex() != -2) { m_displayed_attribute = m_attribHandle->getDisplayColIndex(); } return m_displayed_attribute; } float getDisplayedSelectedAvg() { return(m_attributes->getSelAvg(m_displayed_attribute)); } double getLocationValue(const Point2f& point); // // Screen functionality public: enum {VIEW_ATTRIBUTES, VIEW_MERGED, VIEW_LAYERS, VIEW_AGENTS}; protected: int m_viewing_deprecated; int m_draw_step; mutable bool m_finished; mutable PixelRef bl; mutable PixelRef cur; // cursor for points mutable PixelRef rc; // cursor for grid lines mutable PixelRef prc; // cursor for point lines mutable PixelRef tr; mutable int curmergeline; mutable QtRegion m_sel_bounds; public: void setScreenPixel( double m_unit ); void makeViewportPoints( const QtRegion& viewport ) const; bool findNextPoint() const; Point2f getNextPointLocation() const { return getPoint(cur).m_location; } bool findNextRow() const; Line getNextRow() const; bool findNextPointRow() const; Line getNextPointRow() const; bool findNextCol() const; Line getNextCol() const; bool findNextPointCol() const; Line getNextPointCol() const; bool findNextMergeLine() const; Line getNextMergeLine() const; bool getPointSelected() const; PafColor getPointColor(PixelRef pixelRef) const; PafColor getCurrentPointColor() const; int getSelCount() { return (int) m_selection_set.size(); } const QtRegion& getSelBounds() const { return m_sel_bounds; } // double getSpacing() const { return m_spacing; } // public: // this is an odd helper function, value in range 0 to 1 PixelRef pickPixel(double value) const; public: bool read(std::istream &stream); bool write(std::ostream &stream); void addGridConnections(); // adds grid connections where graph does not include them void outputConnectionsAsCSV(std::ostream &myout, std::string delim = ","); void outputLinksAsCSV(std::ostream &myout, std::string delim = ","); }; // inlined to make thread safe inline Point2f PointMap::depixelate( const PixelRef& p, double scalefactor ) const { return Point2f( m_bottom_left.x + m_spacing * scalefactor * double(p.x), m_bottom_left.y + m_spacing * scalefactor * double(p.y) ); } inline QtRegion PointMap::regionate( const PixelRef& p, double border ) const { return QtRegion( Point2f( m_bottom_left.x + m_spacing * (double(p.x) - 0.5 - border), m_bottom_left.y + m_spacing * (double(p.y) - 0.5 - border)), Point2f( m_bottom_left.x + m_spacing * (double(p.x) + 0.5 + border), m_bottom_left.y + m_spacing * (double(p.y) + 0.5 + border)) ); } ///////////////////////////////////////////////////////////////////////////////////// // A helper class for metric integration // to allow a dist / PixelRef pair for easy sorting // (have to do comparison operation on both dist and PixelRef as // otherwise would have a duplicate key for pqmap / pqvector) struct MetricTriple { float dist; PixelRef pixel; PixelRef lastpixel; MetricTriple(float d = 0.0f, PixelRef p = NoPixel, PixelRef lp = NoPixel) { dist = d; pixel = p; lastpixel = lp; } friend bool operator == (const MetricTriple& mp1, const MetricTriple& mp2); friend bool operator < (const MetricTriple& mp1, const MetricTriple& mp2); friend bool operator > (const MetricTriple& mp1, const MetricTriple& mp2); friend bool operator != (const MetricTriple& mp1, const MetricTriple& mp2); }; inline bool operator == (const MetricTriple& mp1, const MetricTriple& mp2) { return (mp1.dist == mp2.dist && mp1.pixel == mp2.pixel); } inline bool operator < (const MetricTriple& mp1, const MetricTriple& mp2) { return (mp1.dist < mp2.dist) || (mp1.dist == mp2.dist && mp1.pixel < mp2.pixel); } inline bool operator > (const MetricTriple& mp1, const MetricTriple& mp2) { return (mp1.dist > mp2.dist) || (mp1.dist == mp2.dist && mp1.pixel > mp2.pixel); } inline bool operator != (const MetricTriple& mp1, const MetricTriple& mp2) { return (mp1.dist != mp2.dist) || (mp1.pixel != mp2.pixel); } // Note: angular triple simply based on metric triple struct AngularTriple { float angle; PixelRef pixel; PixelRef lastpixel; AngularTriple(float a = 0.0f, PixelRef p = NoPixel, PixelRef lp = NoPixel) { angle = a; pixel = p; lastpixel = lp; } friend bool operator == (const AngularTriple& mp1, const AngularTriple& mp2); friend bool operator < (const AngularTriple& mp1, const AngularTriple& mp2); friend bool operator > (const AngularTriple& mp1, const AngularTriple& mp2); friend bool operator != (const AngularTriple& mp1, const AngularTriple& mp2); }; inline bool operator == (const AngularTriple& mp1, const AngularTriple& mp2) { return (mp1.angle == mp2.angle && mp1.pixel == mp2.pixel); } inline bool operator < (const AngularTriple& mp1, const AngularTriple& mp2) { return (mp1.angle < mp2.angle) || (mp1.angle == mp2.angle && mp1.pixel < mp2.pixel); } inline bool operator > (const AngularTriple& mp1, const AngularTriple& mp2) { return (mp1.angle > mp2.angle) || (mp1.angle == mp2.angle && mp1.pixel > mp2.pixel); } inline bool operator != (const AngularTriple& mp1, const AngularTriple& mp2) { return (mp1.angle != mp2.angle) || (mp1.pixel != mp2.pixel); } // true grads are also similar to generated grads... // this scruffy helper function converts a true grad to a bin: // (now corrected as of 2.1008r!) inline int whichbin( const Point2f& grad ) { int bin = 0; double ratio; // This is only for true gradients... // ...see below for calculated gradients // // Octant: // + - // - \ 8 | 8 / + // 16\ | / 0 // ---- ---- // 16/ | \32 // + /24 | 24\ - // - + if (fabs(grad.y) > fabs(grad.x)) { bin = 1; // temporary: label y priority } if (bin == 0) { ratio = fabs(grad.y) / fabs(grad.x); // now actual bin number if (grad.x > 0.0) { if (grad.y >= 0.0) { bin = 0; } else { bin = -32; } } else { if (grad.y >= 0.0) { bin = -16; } else { bin = 16; } } } else { ratio = fabs(grad.x) / fabs(grad.y); // now actual bin number if (grad.y > 0.0) { if (grad.x >= 0.0) { bin = -8; } else { bin = 8; } } else { if (grad.x >= 0.0) { bin = 24; } else { bin = -24; } } } if (ratio < 1e-12) { // nop } else if (ratio < 0.2679491924311227) { // < 15 degrees bin += 1; } else if (ratio < 0.5773502691896257) { // < 30 degrees bin += 2; } else if (ratio < 1.0 - 1e-12) { // < 45 degrees bin += 3; } else { bin += 4; } if (bin < 0) { bin = -bin; } // this is necessary: bin = bin % 32; return bin; } ///////////////////////////////// // Another helper to write down the q-octant from any bin, in shifted format // note that sieve2 has been used to get the precise required q-octant for the bin inline int processoctant(int bin) { int q = -1; switch (bin) { case 0: case 1: case 2: case 3: case 4: q = 1; break; case 5: case 6: case 7: q = 7; break; case 8: case 9: case 10: case 11: q = 6; break; case 12: case 13: case 14: case 15: case 16: q = 0; break; case 17: case 18: case 19: case 20: q = 2; break; case 21: case 22: case 23: q = 4; break; case 24: case 25: case 26: case 27: q = 5; break; case 28: case 29: case 30: case 31: q = 3; break; } return (1 << q); } // ...but in order to determine what *needs* processing, we need this octant: inline int flagoctant(int bin) { int q = 0; // have to use two q octants if you are on diagonals or axes... switch (bin) { case 0: q |= 1 << 1; q |= 1 << 3; break; case 1: case 2: case 3: q |= 1 << 1; break; case 4: q |= 1 << 1; q |= 1 << 7; break; case 5: case 6: case 7: q |= 1 << 7; break; case 8: q |= 1 << 7; q |= 1 << 6; break; case 9: case 10: case 11: q = 1 << 6; break; case 12: q |= 1 << 6; q |= 1 << 0; break; case 13: case 14: case 15: q |= 1 << 0; break; case 16: q |= 1 << 0; q |= 1 << 2; break; case 17: case 18: case 19: q |= 1 << 2; break; case 20: q |= 1 << 2; q |= 1 << 4; break; case 21: case 22: case 23: q |= 1 << 4; break; case 24: q |= 1 << 4; q |= 1 << 5; break; case 25: case 26: case 27: q |= 1 << 5; break; case 28: q |= 1 << 5; q |= 1 << 3; break; case 29: case 30: case 31: q |= 1 << 3; break; } return q; } // Another helper, this time to write down the q-octant for the bin opposing you inline int q_opposite(int bin) { int opposing_bin = (16 + bin) % 32; /* * \ 6 | 7 / * 0 \ | / 1 * - - - - * 2 / | \ 3 * / 4 | 5 \ */ return flagoctant(opposing_bin); } #endif ================================================ FILE: salalib/salaprogram.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // salaprogram.cpp - a component of the depthmapX - spatial network analysis platform // SalaScripting language ///////////////////////////////////////////////////////////////////////// // SalaScripting language // A "Pythonesque" language, which is pre-interpretted, and thus generally // should run fairly fast // The class implementation is very much hardcoded for built-in classes, // so user defined classes will be difficult to implement // (but would you really want classes in an inbuilt scripting language?! -- I guess some people would) // User defined functions are not included yet, but should be fairly easy using a global function stack // alongside the global variable stack #include "salalib/salaprogram.h" #include "salalib/ngraph.h" #include "salalib/shapemap.h" #include "salalib/pointdata.h" #include "salalib/connector.h" #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////////////////////// // Assign and list access rather incongruently in math ops, but never mind: bool g_sala_loaded = false; std::vector g_sala_math_ops; std::vector g_sala_comp_ops; std::vector g_sala_logical_ops; std::vector g_sala_global_funcs; std::vector g_sala_member_funcs; void loadSalaProgram() { // math ops g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_ADD, "+", "add" ) ); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_SUBTRACT, "-", "subtract" ) ); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MINUS, "-", "negative" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_PLUS, "+", "positive" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MULTIPLY, "*", "multiply" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_DIVIDE, "/", "divide" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_MODULO, "%", "modulo" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_POWER, "^", "power" )); g_sala_math_ops.push_back( SalaFuncLabel( SalaObj::S_ASSIGN, "=", "assignment" )); g_sala_math_ops.push_back(SalaFuncLabel( SalaObj::S_LIST_ACCESS, "[]", "list access" )); // list access included even though not parsed directly like this // comp ops g_sala_comp_ops.push_back( SalaFuncLabel( SalaObj::S_GT, ">", "greater than" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_LT, "<", "less than" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_GEQ, ">=", "greater than or equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_LEQ, "<=", "less than or equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_NEQ, "!=", "not equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_EQ, "==", "equal to" )); g_sala_comp_ops.push_back(SalaFuncLabel( SalaObj::S_IS, "is", "is the same object as" )); // logical ops g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_NOT, "not", "logical not" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_NOT, "!", "logical not" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_AND, "and", "logical and" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_AND, "&&", "logical and" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_OR, "or", "logical or" )); g_sala_logical_ops.push_back(SalaFuncLabel( SalaObj::S_OR, "||", "logical or" )); // global functions g_sala_global_funcs.push_back( SalaFuncLabel( SalaObj::S_SQRT, "sqrt", "square root" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LOG, "log", "log base 10" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LN, "ln", "natural logarithm" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_RAND, "random", "random number (0.0 to 1.0)" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_SIN, "sin", "sine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_COS, "cos", "cosine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_TAN, "tan", "tangent" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ASIN, "asin", "inverse sine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ACOS, "acos", "inverse cosine" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_ATAN, "atan", "inverse tangent" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_LEN, "len", "array or string length" )); g_sala_global_funcs.push_back(SalaFuncLabel( SalaObj::S_RANGE, "range", "set of integers" )); // member functions g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FAPPEND, "append", "append item" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FEXTEND, "extend", "extend by list" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FPOP, "pop", "pop (last) item" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_LIST, SalaObj::S_FCLEAR, "clear", "clear contents" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FVALUE, "value", "get attribute value" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FSETVALUE, "setvalue", "set attribute value" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FMARK, "mark", "get node mark" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FSETMARK, "setmark", "set node mark" )); g_sala_member_funcs.push_back(SalaMemberFuncLabel( SalaObj::S_GRAPHOBJ, SalaObj::S_FCONNECTIONS, "connections", "get list of connections" )); g_sala_loaded = true; } /////////////////////////////////////////////////////////////////////////////////////////////// SalaProgram::SalaProgram(SalaObj context) { if (!g_sala_loaded) { loadSalaProgram(); } // col is used when run in update mode, it does not form part of the program: m_col = -1; m_thisobj = context; } SalaProgram::~SalaProgram() { } // use istrstream to make an istream from a string: // istrstream file(char *); bool SalaProgram::parse(std::istream& program) { m_var_stack.clear(); m_error_stack.clear(); // this ensures wipe of any pre-existing variables in the global context: m_root_command = SalaCommand(this,NULL,-1,SalaCommand::SC_ROOT); int line = 0; SalaCommand *parent = &m_root_command; while (!program.eof()) { // the problem with a language being "Pythonesque" is that the "end" of // any control is implicit through the amount of indentation // Thus, the parser eats the white space, only handing of control // to a function when it is ready to parse, and knows its parent int indent = 0; bool endloop = false; while (!endloop) { char ch = program.peek(); switch (ch) { case ' ': indent++; break; case 13: break; // ignore case '\n': line++; indent = 0; break; case '#': // hit comment, read to end of line: while (ch != EOF && ch != '\n') { program.get(); ch = program.peek(); } line++; break; case '\\': // hit line continuation, ignore everything after it: while (ch != EOF && ch != '\n') { program.get(); ch = program.peek(); } line++; break; case EOF: program.get(); // actually shift onto the eof character endloop = true; break; default: endloop = true; break; } if (!endloop) { program.get(); } } // okay, we now know indent level, and we are ready to parse: if (!program.eof()) { while (indent <= parent->m_indent) { parent = parent->m_parent; } parent->m_children.push_back(SalaCommand(this,parent,indent)); SalaCommand &thiscommand = parent->m_children.back(); try { line = thiscommand.parse(program,line); } catch (SalaError e) { if (e.lineno == -1) e.lineno = line; m_error_stack.push_back(e); return false; } // sort out commands capable of having children: if (thiscommand.m_command == SalaCommand::SC_FOR || thiscommand.m_command == SalaCommand::SC_IF || thiscommand.m_command == SalaCommand::SC_WHILE) { parent = &thiscommand; } else if (thiscommand.m_command == SalaCommand::SC_ELSE) { if (parent->m_children.size() < 2) { m_error_stack.push_back(SalaError("'Else' must be preceded by an 'if','for' or 'while'", thiscommand.m_line)); return false; } int command = parent->m_children[parent->m_children.size()-2].m_command; if (command != SalaCommand::SC_IF && command != SalaCommand::SC_ELIF && command != SalaCommand::SC_FOR && command != SalaCommand::SC_WHILE) { m_error_stack.push_back(SalaError("'Else' must be preceded by an 'if','for' or 'while'", thiscommand.m_line)); return false; } parent = &thiscommand; } else if (thiscommand.m_command == SalaCommand::SC_ELIF) { if (parent->m_children.size() < 2) { m_error_stack.push_back(SalaError("'Elif' must be preceded by an 'if' condition", thiscommand.m_line)); return false; } int command = parent->m_children[parent->m_children.size()-2].m_command; if (command != SalaCommand::SC_IF && command != SalaCommand::SC_ELIF) { m_error_stack.push_back(SalaError("'Elif' must be preceded by an 'if' condition", thiscommand.m_line)); return false; } parent = &thiscommand; } } } // do a quick check that all 'for', 'if' and 'elif' have children: // TO DO! return true; } SalaObj SalaProgram::evaluate() { for (size_t i = 0; i < m_var_stack.size(); i++) { // uninitialise all variables: m_var_stack[i].uninit(); } m_marked = false; // run the program SalaObj obj; bool ret = false, ifhandled = false; m_root_command.evaluate(obj,ret,ifhandled); // clear marks if they've been used: if (m_marked) { marks.clear(); m_marked = false; } return obj; } // this function is called by depthmapX to run a script to update a column // the operation is on a single node / row of the database combination bool SalaProgram::runupdate(int col, const std::set &selset) { AttributeTable *table = m_thisobj.getTable(); // // note: reference, will change object directly, which is important for commands running the program int& row = m_thisobj.data.graph.node; m_col = col; if (selset.size()) { for (auto& sel: selset) { row = sel; try { SalaObj val = evaluate(); float v = (float) val.toDouble(); // note, toDouble will type check and throw if there's a problem if (!std::isfinite(v)) { v = -1.0f; } table->getRow(AttributeKey(sel)).setValue(m_col,v); } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } else { for (auto iter = table->begin(); iter != table->end(); iter++) { row = iter->getKey().value; try { SalaObj val = evaluate(); float v = (float) val.toDouble(); // note, toDouble will type check and throw if there's a problem if (!std::isfinite(v)) { v = -1.0f; } iter->getRow().setValue(m_col,v); } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } return true; } // this function is called by depthmapX to run a script to select values // the operation is on a single node / row of the database combination bool SalaProgram::runselect(std::vector &selsetout, const std::set& selsetin) { AttributeTable *table = m_thisobj.getTable(); if (selsetin.size()) { for (auto& key: selsetin) { try { SalaObj val = evaluate(); bool v = val.toBool(); // note, toBool will type check and throw if there's a problem if (v) { selsetout.push_back(key); } } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } else { for (auto iter = table->begin(); iter != table->end(); iter++) { int key = iter->getKey().value; try { SalaObj val = evaluate(); bool v = val.toBool(); // note, toBool will type check and throw if there's a problem if (v) { selsetout.push_back(key); } } catch (SalaError e) { // error m_error_stack.push_back(e); return false; } } } return true; } std::string SalaProgram::getLastErrorMessage() const { const SalaError& error = m_error_stack.back(); if (error.lineno == -1) { return error.message; } else { return error.message + " on line " + dXstring::formatString(error.lineno+1,"%d"); } } //////////////////////////////////////////////////////////////////////////// SalaCommand::SalaCommand(SalaProgram *program, SalaCommand *parent, int indent, Command command) { m_program = program; m_parent = parent; m_indent = indent; m_command = command; m_line = 0; } int SalaCommand::parse(std::istream& program, int line) { m_func_stack.clear(); m_eval_stack.clear(); m_var_names.clear(); m_command = SC_NONE; // useful to know which line the command starts on for debugging purposes m_line = line; int last = SP_FUNCTION; bool endloop = false; bool overridecache = false; SalaBuffer buffer; char cache = ' '; // while (!endloop && !program.eof()) { char alpha = program.get(); switch (alpha) { // string constant case '\"': case '\'': // variants: either delimit with single or double quotes if (!buffer.empty()) { decode(buffer); buffer.clear(); } { char delim = alpha; char beta = program.peek(); while (beta != EOF && beta != '\n' && (beta != delim || alpha == '\\')) { alpha = program.get(); beta = program.peek(); buffer.add(alpha); } if (beta == EOF || beta == '\n') { throw SalaError("No closing quote",m_line); } else { program.get(); // take off closing quote and discard } // add even if the string constant is empty: m_eval_stack.push_back( std::string(buffer) ); buffer.clear(); last = SP_DATA; } break; // operator stack case '+': case '-': if (!buffer.empty()) { last = decode(buffer); if (last & SP_NUMBER && cache == 'e') { // check for 9.999e+99... // decode will handle later: buffer.add(alpha); break; } // otherwise handled, clear the buffer: buffer.clear(); } if (last == SP_FUNCTION || last == SP_COMMAND) { pushFunc( alpha == '+' ? SalaObj(SalaObj::S_PLUS) : SalaObj(SalaObj::S_MINUS) ); } else { pushFunc( alpha == '+' ? SalaObj(SalaObj::S_ADD) : SalaObj(SalaObj::S_SUBTRACT) ); } last = SP_FUNCTION; break; case '=': if (!buffer.empty()) { // n.b., this will catch '>=', '<=', '==' and '!=' if (strchr("><=!",cache) != NULL) { buffer.add(alpha); last = decode(buffer); buffer.clear(); overridecache = true; // handled next step (see default clause below) break; } else { last = decode(buffer); buffer.clear(); } } buffer.add(alpha); // <- '=' decoded later break; case '!': case '<': case '>': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // note: this looks a little odd, simply adding to the buffer, but these // are handled by the default function next step if still hanging on the buffer buffer.add(alpha); break; case '/': case '*': case '%': case '^': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } last = decode(std::string(1,alpha)); break; case '(': // note: the opening bracket forms a function if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } if (last == SP_DATA) { // whatever that just went onto the eval stack, the user thought it was a function... // alert them: throw SalaError(m_last_string + " is not a known function name", m_line); // (in the future, we may well want to transfer an object hashed function name to the func stack instead) } else if (last == SP_NUMBER) { throw SalaError("Cannot treat a number as if it were a function", m_line); } // check for pair of open / close brackets: () or ( ) -- this is a null value { char beta = program.peek(); while (beta != EOF && beta == ' ') { alpha = program.get(); beta = program.peek(); } if (beta == ')') { alpha = program.get(); m_eval_stack.push_back(SalaObj()); last = SP_DATA; } else { pushFunc( SalaObj::S_OPEN_BRACKET ); last = SP_FUNCTION; } } break; case ')': // note: the closing bracket forms a data packet: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_CLOSE_BRACKET ); last = SP_DATA; break; case '[': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // check for pair of open / close brackets: [] or [ ] -- this is a null value or empty list depending on context { char beta = program.peek(); while (beta != EOF && beta == ' ') { alpha = program.get(); beta = program.peek(); } if (beta == ']') { alpha = program.get(); if (last == SP_DATA) { throw SalaError("Accessor operator ('[]') requires a parameter", m_line); } else { // put an empty list on the stack m_eval_stack.push_back( SalaObj(SalaObj::S_CONST_LIST, 0) ); } last = SP_DATA; } else { if (last == SP_DATA) { // list accessor function pushFunc( SalaObj::S_LIST_ACCESS ); pushFunc( SalaObj::S_OPEN_SQR_BRACKET_ACCESS ); } else { // making an list... pushFunc( SalaObj::S_OPEN_SQR_BRACKET_LIST ); } last = SP_FUNCTION; } } break; case ']': // note: the closing bracket forms a data packet: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_CLOSE_SQR_BRACKET ); last = SP_DATA; break; case ',': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } pushFunc( SalaObj::S_COMMA ); last = SP_FUNCTION; break; case ':': if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } // end of command (def, if, else, elif and for) if (m_command == SC_FOR || m_command == SC_WHILE || m_command == SC_IF || m_command == SC_ELIF || m_command == SC_ELSE) { bool commentfound = false; alpha = program.get(); while (!program.eof() && alpha != '\n') { // continue to end of line, only comments allowed though! if (!commentfound) { if (alpha == '#') { commentfound = true; } else if (alpha != ' ' && alpha != 13) { // 13 ignored, as it appears \n is 10 in this stream... (so 13,10 can be found) throw SalaError("'For', 'if', 'else', etc cannot have execution part on same line; insert a new line after ':'", m_line); } } alpha = program.get(); } line++; endloop = true; } else { throw SalaError("Unexpected colon ':' in expression",m_line); } break; // end of line: case '\\': // hit line continuation, read to end of line: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } while (!program.eof() && program.get() != '\n'); // note, end loop is not set, this is a continuation character line++; // line is incremented, although it this command will still start on the original line break; case '#': // loop through until hit \n or end if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } while (!program.eof() && program.get() != '\n'); line++; // should have hit a line end (or if it's end of file, it doesn't matter) endloop = true; break; case '\n': // force end of command parse: if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } line++; // hit a line end endloop = true; break; case ' ': // white space: read word if (!buffer.empty()) { last = decode(buffer); buffer.clear(); } break; case '.': // currently handled inelegantly through decode for either number (1.002) or member access (blah.x()) buffer.add('.'); break; case '\t': throw SalaError("Tab character found: please use only spaces to indent lines",m_line); break; default: if (strchr("<>=!",cache)) { // >, <, = and ! are held as next step operators last = decode(buffer); buffer.clear(); } if (alpha != EOF && alpha != 13) { // 13 ignored, as it appears \n is 10 in this stream... if (!isalphanum_(alpha) && alpha != '&' && alpha != '|') { // include & and | for and and or throw SalaError("Unrecognised symbol ('" + std::string(1,alpha) + "')",m_line); } buffer.add(alpha); } break; } if (overridecache) { cache = ' '; overridecache = false; } else { cache = alpha; } if (last == SP_COMMAND) { if (m_command == SC_FOR) { // check the name of the for variable: alpha = program.get(); while (alpha == ' ') { alpha = program.get(); } if (!isalpha_(alpha)) { throw SalaError("'For' command expecting variable name",m_line); } while (isalphanum_(alpha)) { buffer.add(alpha); alpha = program.get(); } if (alpha != ' ') { throw SalaError("Command expecting syntax 'for xyz in'...",m_line); } // add the for iterator variable: m_program->m_var_stack.push_back(SalaObj()); int x = m_program->m_var_stack.size() - 1; m_var_names.insert(std::make_pair(buffer,x)); m_for_iter = SalaObj( SalaObj::S_VAR, x); // now check for 'in' while (alpha == ' ') { alpha = program.get(); } if (alpha != 'i' || program.get() != 'n') { throw SalaError("Command expecting syntax 'for xyz in'...",m_line); } } last = SP_FUNCTION; } } if (!buffer.empty()) { decode(buffer); buffer.clear(); last = SP_DATA; } // push remaining functions onto eval stack: while (m_func_stack.size()) { if (m_func_stack.back().type & SalaObj::S_BRACKET) { throw SalaError("Unmatched brackets",m_line); } m_eval_stack.push_back(m_func_stack.back()); m_func_stack.pop_back(); } if (m_eval_stack.size() == 0 && m_command != SC_ELSE) { // note, else is by definition empty throw SalaError("Partial or missing command",m_line); } return line; } int SalaCommand::decode(std::string string) // string copied as makelower applied { // ideally, some form of hashing the string should be performed so that // functions can be found quicker than a long list of "else ifs" int retvar = SP_NONE; dXstring::toLower(string); if (m_command == SC_NONE) { if (string == "return") { m_command = SC_RETURN; retvar = SP_COMMAND; } else if (string == "for") { m_command = SC_FOR; // n.b. will still need a variable name and "in": for x in ... retvar = SP_COMMAND; } else if (string == "while") { m_command = SC_WHILE; retvar = SP_COMMAND; } else if (string == "if") { m_command = SC_IF; retvar = SP_COMMAND; } else if (string == "elif") { m_command = SC_ELIF; retvar = SP_COMMAND; } else if (string == "else") { m_command = SC_ELSE; retvar = SP_COMMAND; } } if (retvar == SP_COMMAND) { // m_last_string = string; // make a copy for debugging purposes return retvar; } // numeric constant if (isdigit(string[0]) || (string.length() > 1 && string[0] == '.' && isdigit(string[1]))) { if (string[string.length()-1] == 'e') { // handle later... at the moment we have hit + or - in 9.999e+99 or 9.999e-99 m_last_string = string; // make a copy for debugging purposes return SP_NUMBER; } if (string.find_first_of('.') != std::string::npos || string.find_first_of('e') != std::string::npos) { m_eval_stack.push_back( atof(string.c_str()) ); } else { m_eval_stack.push_back( atoi(string.c_str()) ); } retvar = SP_NUMBER; } // this is a different 'e' to the 'e' above -> natural logarithm else if (string == "e") { m_eval_stack.push_back( 2.7182818284590452353602874713527 ); retvar = SP_NUMBER; } else if (string == "pi") { m_eval_stack.push_back( 3.1415926535897932384626433832795 ); retvar = SP_NUMBER; } // boolean constants else if (string == "true") { m_eval_stack.push_back( bool(true) ); retvar = SP_NUMBER; } else if (string == "false") { m_eval_stack.push_back( bool(false) ); retvar = SP_NUMBER; } // this else if (string == "this") { m_eval_stack.push_back( SalaObj(SalaObj::S_THIS) ); retvar = SP_DATA; } else if (string == "none") { m_eval_stack.push_back(SalaObj()); retvar = SP_DATA; } else { // everything else should be in one of the operator / func lists: size_t i; if (retvar == SP_NONE) { // note, math ops include assignment for (i = 0 ; i < g_sala_math_ops.size(); i++) { if (string == g_sala_math_ops[i].name) { pushFunc( g_sala_math_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_comp_ops.size(); i++) { if (string == g_sala_comp_ops[i].name) { pushFunc( g_sala_comp_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_logical_ops.size(); i++) { if (string == g_sala_logical_ops[i].name) { pushFunc( g_sala_logical_ops[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_NONE) { for (i = 0 ; i < g_sala_global_funcs.size(); i++) { if (string == g_sala_global_funcs[i].name) { pushFunc( g_sala_global_funcs[i].func ); retvar = SP_FUNCTION; } } } } if (retvar == SP_NONE) { size_t n = string.find_first_of("."); if (n != std::string::npos) { if (n > 0) { decode(string.substr(0,n)); } if (decode_member(string.substr(n+1),false) == SP_NONE) { throw SalaError("There is no known member function called " + string.substr(n+1),m_line); } retvar = SP_FUNCTION; } else { // see if it's a member function of 'this': retvar = decode_member(string,true); if (retvar == SP_NONE) { // see if it exists in the variable stack (walk up scope) SalaCommand *parent = m_parent; auto n = parent->m_var_names.end(); int x = -1; while (parent != NULL) { n = parent->m_var_names.find(string); if (n != parent->m_var_names.end()) { x = n->second; parent = NULL; } else { parent = parent->m_parent; } } if (x != -1) { m_eval_stack.push_back( SalaObj( SalaObj::S_VAR, x) ); retvar = SP_DATA; } else { m_program->m_var_stack.push_back(SalaObj()); x = m_program->m_var_stack.size() - 1; // note: attach simply to your m_parent, not parent variable, which has walked up the stack m_parent->m_var_names.insert(std::make_pair(string,x)); m_eval_stack.push_back( SalaObj( SalaObj::S_VAR, x) ); retvar = SP_DATA; } } } } if (retvar == SP_NONE) { // should never reach this point throw SalaError("There is no known function or variable called " + string,m_line); } if (m_command == SC_NONE) { m_command = SC_EXPR; } m_last_string = string; // make a copy for debugging purposes return retvar; } // note, thisobj not usually known (type S_NALL), // but, depending where SalaScript is called from, it may be: // a graph node / table row (for "select by query" and "edit connections") // a map (not yet implemented, but intended for scripting agents) int SalaCommand::decode_member(const std::string& string, bool apply_to_this) { int retvar = SP_NONE; // note, all hardcoded for built in classes: // string classes: for (size_t i = 0; i < g_sala_member_funcs.size(); i++) { // note '&' in the type -- essentially allows for inheritance between objects (tuple is type of list, etc) if (!apply_to_this || (m_program->m_thisobj.type & g_sala_member_funcs[i].type) != 0) { if (string == g_sala_member_funcs[i].name) { pushFunc( g_sala_member_funcs[i].func ); retvar = SP_FUNCTION; break; } } } if (retvar == SP_FUNCTION && apply_to_this) { m_eval_stack.push_back(SalaObj(SalaObj::S_THIS)); } return retvar; } void SalaCommand::pushFunc(const SalaObj& func) { // note comma is part of the "Bracket" class of things: if (func.type & SalaObj::S_BRACKET) { if (func.type == SalaObj::S_CLOSE_BRACKET) { while (m_func_stack.size() && m_func_stack.back().type != SalaObj::S_OPEN_BRACKET) { m_eval_stack.push_back(m_func_stack.back()); m_func_stack.pop_back(); } if (m_func_stack.size()) { // don't necessarily pop it... if it's a group marker, we want to hang onto it: if (m_func_stack.back().data.count > 1) { m_func_stack.back().type = SalaObj::S_CONST_TUPLE; m_eval_stack.push_back(m_func_stack.back()); } m_func_stack.pop_back(); // remove opening bracket } } else if (func.type == SalaObj::S_CLOSE_SQR_BRACKET) { while (m_func_stack.size() && (m_func_stack.back().type & SalaObj::S_OPEN_SQR_BRACKET) == 0) { m_eval_stack.push_back(m_func_stack.back()); m_func_stack.pop_back(); } if (m_func_stack.size()) { // don't pop it, always make a list from a make list command, even if it's only one item long: if (m_func_stack.back().type == SalaObj::S_OPEN_SQR_BRACKET_LIST || m_func_stack.back().data.count > 1) { m_func_stack.back().type = SalaObj::S_CONST_LIST; m_eval_stack.push_back(m_func_stack.back()); } m_func_stack.pop_back(); } } else if (func.type == SalaObj::S_COMMA) { // go and increment your associated group / list while (m_func_stack.size() && m_func_stack.back().type != SalaObj::S_OPEN_BRACKET && (m_func_stack.back().type & SalaObj::S_OPEN_SQR_BRACKET) == 0) { m_eval_stack.push_back(m_func_stack.back()); m_func_stack.pop_back(); } if (m_func_stack.size()) { m_func_stack.back().data.count++; } } else { m_func_stack.push_back( func ); } } else if (!m_func_stack.size() || func.precedence() > m_func_stack.back().precedence()) { // original: > m_func_stack.push_back(func); } else { while (m_func_stack.size() && func.precedence() <= m_func_stack.back().precedence()) { // original <= m_eval_stack.push_back(m_func_stack.back()); m_func_stack.pop_back(); } m_func_stack.push_back(func); } } void SalaCommand::evaluate(SalaObj& obj, bool& ret, bool& ifhandled) { int begin = m_eval_stack.size()-1; SalaObj *p_obj = NULL; switch (m_command) { case SC_EXPR: obj = evaluate(begin,p_obj); break; case SC_RETURN: ret = true; obj = evaluate(begin,p_obj); break; case SC_ROOT: { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } } break; case SC_IF: { SalaObj test = evaluate(begin,p_obj); if (test.toBool() == true) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } ifhandled = true; } else { ifhandled = false; } } break; case SC_ELIF: if (!ifhandled) { SalaObj test = evaluate(begin,p_obj); if (test.toBool() == true) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } ifhandled = true; } } break; case SC_ELSE: if (!ifhandled) { for (size_t i = 0; i < m_children.size(); i++) { m_children[i].evaluate(obj,ret,ifhandled); if (ret) break; } } break; case SC_FOR: { // eventually I'd like to do this with generators / iterators rather than constructing a list each time SalaObj list = evaluate(begin,p_obj); if (list.type == SalaObj::S_LIST) { int len = list.data.list.list->size(); if (len != 0) { for (int i = 0; i < len; i++) { // reset all my stack (actually, all parent functions should do this!) for (auto varName: m_var_names) { m_program->m_var_stack[varName.second].uninit(); } m_program->m_var_stack[m_for_iter.data.var] = list.data.list.list->at(i); for (size_t k = 0; k < m_children.size(); k++) { m_children[k].evaluate(obj,ret,ifhandled); if (ret) break; } if (ret) break; } ifhandled = true; } else { ifhandled = false; } } else { ifhandled = false; } } break; case SC_WHILE: { int counter = 0; while (evaluate(begin,p_obj).toBool()) { for (size_t k = 0; k < m_children.size(); k++) { m_children[k].evaluate(obj,ret,ifhandled); if (ret) break; } if (ret) break; if (++counter == 0x04000000) { // <- an arbitrary big number throw SalaError("Infinite loop",m_line); } begin = m_eval_stack.size()-1; } if (counter) { ifhandled = true; } else { ifhandled = false; } } break; default: throw SalaError("Unknown command",m_line); break; } } SalaObj SalaCommand::evaluate(int& pointer, SalaObj* &p_obj) { if (pointer < 0) { throw SalaError("Missing argument",m_line); } SalaObj data = m_eval_stack[pointer]; pointer--; if (data.type == SalaObj::S_FUNCTION) { SalaObj::Func func = data.data.func; int group = (func & SalaObj::S_GROUP); if (group == SalaObj::S_MATH_OPS) { try { switch (func) { case SalaObj::S_ADD: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) + evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 + tmp2; } #endif break; case SalaObj::S_SUBTRACT: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) - evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 - tmp2; } #endif break; case SalaObj::S_PLUS: data = evaluate(pointer,p_obj); // just ignore it break; case SalaObj::S_MINUS: // Quick mod - TV #if defined(_MSC_VER) data = -evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = -tmp1; } #endif break; case SalaObj::S_MULTIPLY: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) * evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp1 * tmp2; } #endif break; case SalaObj::S_DIVIDE: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) / evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = tmp2 / tmp1; } #endif break; case SalaObj::S_MODULO: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) % data; // reverse order #else { SalaObj tmp1 = evaluate(pointer, p_obj); data = tmp1 % data; } #endif break; case SalaObj::S_POWER: data = evaluate(pointer,p_obj); // reverse order data = pow(evaluate(pointer,p_obj).toDouble(),data.toDouble()); break; case SalaObj::S_ASSIGN: data = evaluate(pointer,p_obj); // reverse order evaluate(pointer,p_obj); if (p_obj != nullptr) { *p_obj = data; } else { throw SalaError("Cannot assign to constant, function or none",m_line); } data = SalaObj(); // assign returns nil value break; case SalaObj::S_LIST_ACCESS: { int x = evaluate(pointer,p_obj).toInt(); data = evaluate(pointer,p_obj); if (data.type == SalaObj::S_LIST) { // setting p_obj allows things above this in the stack to modify it p_obj = &(data.list_at(x)); return *p_obj; } else if (data.type == SalaObj::S_STRING) { // but n.b., strings cannot be modified, keep p_obj as null p_obj = NULL; return data.char_at(x); } else throw SalaError("Cannot be applied to " + data.getTypeIndefArt() + data.getTypeStr(),m_line); } break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_math_ops.size(); i++) { if (g_sala_math_ops[i].func == func) { e.message = "In '" + g_sala_math_ops[i].name + "' operator: " + e.message; break; } } e.lineno = m_line; throw std::move(e); } } else if (group == SalaObj::S_LOGICAL_OPS) { try { switch (func) { case SalaObj::S_OR: // note: you cannot simply say evaluate(x) || evaluate(y) because if evaluate(x) is true, // the in-built || operator will not evaluate(y) // but... it's on the eval stack... it would be nice simply to pop the eval stack at // this point if the first half evaluates to true, thus emulating C... but it's in reverse order too! data = evaluate(pointer,p_obj); data = evaluate(pointer,p_obj).toBool() || data.toBool(); break; case SalaObj::S_AND: data = evaluate(pointer,p_obj).toBool() && evaluate(pointer,p_obj).toBool(); break; case SalaObj::S_NOT: data = !evaluate(pointer,p_obj).toBool(); break; case SalaObj::S_EQ: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) == evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer, p_obj); SalaObj tmp2 = evaluate(pointer, p_obj); data = (tmp1 == tmp2); } #endif break; case SalaObj::S_IS: // Quick mod - TV #if defined(_MSC_VER) data = op_is(evaluate(pointer,p_obj),evaluate(pointer,p_obj)); #else { SalaObj tmp1 = evaluate(pointer, p_obj); SalaObj tmp2 = evaluate(pointer, p_obj); data = op_is(tmp1, tmp2); } #endif break; case SalaObj::S_NEQ: // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) != evaluate(pointer,p_obj); #else { SalaObj tmp1 = evaluate(pointer,p_obj); SalaObj tmp2 = evaluate(pointer,p_obj); data = (tmp1 != tmp2); } #endif break; case SalaObj::S_GT: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) > data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 > data); } #endif break; case SalaObj::S_LT: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) < data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 < data); } #endif break; case SalaObj::S_GEQ: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) >= data; // revese order #else { SalaObj tmp1 = evaluate(pointer,p_obj); data = (tmp1 >= data); } #endif break; case SalaObj::S_LEQ: data = evaluate(pointer,p_obj); // Quick mod - TV #if defined(_MSC_VER) data = evaluate(pointer,p_obj) <= data; // revese order #else { SalaObj tmp1 = evaluate(pointer, p_obj); data = (tmp1 <= data); } #endif break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_logical_ops.size(); i++) { if (g_sala_logical_ops[i].func == func) { e.message = "In '" + g_sala_logical_ops[i].name + "' operator: " + e.message; break; } } for (size_t j = 0; j < g_sala_comp_ops.size(); j++) { if (g_sala_comp_ops[j].func == func) { e.message = "In '" + g_sala_comp_ops[j].name + "' operator: " + e.message; break; } } e.lineno = m_line; throw std::move(e); } } else if (group == SalaObj::S_GLOBAL_FUNCS) { try { switch (func) { case SalaObj::S_LEN: data = evaluate(pointer,p_obj); data = SalaObj( data.length() ); break; case SalaObj::S_RANGE: data = evaluate(pointer,p_obj); { int len = data.length(); if (len != 2 && len != 3) { throw SalaError("Range takes either 2 or 3 parameters",m_line); } int start = data.data.list.list->at(0).toInt(); int end = data.data.list.list->at(1).toInt(); int step = (len == 3) ? data.data.list.list->at(2).toInt() : 1; if (step == 0) { throw SalaError("Range cannot have a step of 0",m_line); } int listlen = (int) ceil(float(end - start) / float(step)); if (listlen <= 0) { data = SalaObj( SalaObj::S_LIST ); } else { data = SalaObj( SalaObj::S_LIST, listlen ); for (int i = start, j = 0; i < end; i += step, j++) { data.data.list.list->at(j) = i; } } } break; case SalaObj::S_SQRT: data = sqrt(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_LOG: data = log10(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_LN: data = ln(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_RAND: data = evaluate(pointer,p_obj); data.ensureNone(); data = SalaObj(prandom()); break; case SalaObj::S_SIN: data = sin(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_COS: data = cos(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_TAN: data = tan(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ASIN: data = asin(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ACOS: data = acos(evaluate(pointer,p_obj).toDouble()); break; case SalaObj::S_ATAN: data = atan(evaluate(pointer,p_obj).toDouble()); break; default: break; } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_global_funcs.size(); i++) { if (g_sala_global_funcs[i].func == func) { e.message = "In '" + g_sala_global_funcs[i].name + "' function: " + e.message; break; } } e.lineno = m_line; throw std::move(e); } } else if (group == SalaObj::S_MEMBER_FUNCS) { try { SalaObj param = evaluate(pointer,p_obj); SalaObj obj = evaluate(pointer,p_obj); switch (obj.type) { case SalaObj::S_LIST: case SalaObj::S_TUPLE: switch (func) { case SalaObj::S_FAPPEND: obj.data.list.list->push_back(param); data = SalaObj(); // returns none break; case SalaObj::S_FEXTEND: if (param.type & SalaObj::S_LIST) { int count = param.data.list.list->size(); for (int i = 0; i < count; i++) { obj.data.list.list->push_back(param.data.list.list->at(i)); } } else { throw SalaError("Parameter must be a list not " + param.getTypeIndefArt() + param.getTypeStr(),m_line); } data = SalaObj(); // returns none break; case SalaObj::S_FPOP: if (obj.data.list.list->size() == 0) { throw SalaError("List is empty", m_line); } if (param.type == SalaObj::S_NONE) { data = obj.data.list.list->back(); obj.data.list.list->pop_back(); } else { std::vector& list = *(obj.data.list.list); int i = param.toInt(); if (i < 0) i += list.size(); if (i < 0 || i >= (int)list.size()) throw SalaError("Index out of range"); data = list[i]; list.erase(list.begin() + i); } break; case SalaObj::S_FCLEAR: param.ensureNone(); obj.data.list.list->clear(); obj = SalaObj(); break; default: throw SalaError("Not a member function of " + obj.getTypeStr(),m_line); } break; case SalaObj::S_SHAPEMAPOBJ: case SalaObj::S_POINTMAPOBJ: switch (func) { case SalaObj::S_FVALUE: { const std::string& str = param.toStringRef(); AttributeTable *table = obj.getTable(); if (str == "Ref Number") { data = SalaObj(obj.data.graph.node); } else { if (!table->hasColumn(str)) { throw SalaError(str + " is an unknown column",m_line); } data = SalaObj(table->getRow(AttributeKey(obj.data.graph.node)).getValue( table->getColumnIndex(str))); } } break; case SalaObj::S_FSETVALUE: { if (param.length() != 2) { throw SalaError("Function takes 2 parameters"); } const std::string& str = param.list_at(0).toStringRef(); float val = (float) param.list_at(1).toDouble(); AttributeTable *table = obj.getTable(); int col = -1; if (str != "Ref Number") { if (!table->hasColumn(str)) { throw SalaError(str + " is an unknown column",m_line); } col = table->getColumnIndex(str); } else { throw SalaError("The reference number can not be changed",m_line); } table->getRow(AttributeKey(obj.data.graph.node)).setValue(col, val); data = SalaObj(); // returns none } break; case SalaObj::S_FCONNECTIONS: { data = connections(obj, param); } break; case SalaObj::S_FMARK: { param.ensureNone(); data = m_program->marks[obj.data.graph.node]; } break; case SalaObj::S_FSETMARK: { m_program->marks[obj.data.graph.node] = param; m_program->m_marked = true; // <- this tells the program to tidy up marks between executions data = SalaObj(); // returns none } break; default: throw SalaError("Not a member function of " + obj.getTypeStr(),m_line); } break; default: throw SalaError("Not a member function of " + obj.getTypeStr(), m_line); } } catch (SalaError e) { // slow to go through one by one, but this is an exception... for (size_t i = 0; i < g_sala_member_funcs.size(); i++) { if (g_sala_member_funcs[i].func == func) { SalaObj type = SalaObj(g_sala_member_funcs[i].type); e.message = "In " + type.getTypeStr() + " '" + g_sala_member_funcs[i].name + "' function: " + e.message; break; } } e.lineno = m_line; throw std::move(e); } } } else if (data.type == SalaObj::S_THIS) { p_obj = &(m_program->m_thisobj); return *p_obj; } else if (data.type & SalaObj::S_VAR) { // retrieve value from variable stack (keeping in a variable stack means it can be reassigned dynamically) p_obj = &(m_program->m_var_stack[data.data.var]); return *p_obj; } else if (data.type & SalaObj::S_CONST_LIST) { // build an list from either a const tuple or const list: int x = data.data.count; data = SalaObj((data.type == SalaObj::S_CONST_LIST) ? SalaObj::S_LIST : SalaObj::S_TUPLE, x); for (--x; x >= 0; x--) { data.data.list.list->at(x) = evaluate(pointer,p_obj); // n.b., direct access to the list } } p_obj = NULL; return data; } ///////////////////////////////////////////////////////////////////////////////// SalaObj SalaCommand::connections(SalaObj graphobj, SalaObj param) { // now, depending on type of object, it may or may not be allowed parameters: // for point maps it can be none (all connections) or a bin number (0-32) // for segment maps it can be 'all' or 'forward' or 'back' (a string -- no parameters is excluded due to potential for errors) // for axial maps it must be none SalaObj list; if ((graphobj.type & SalaObj::S_MAP) == SalaObj::S_POINTMAP) { // point map version Node& node = graphobj.data.graph.map.point->getPoint(graphobj.data.graph.node).getNode(); if (param.type == SalaObj::S_NONE) { int count = node.count(); list = SalaObj( SalaObj::S_LIST, count); node.first(); for (int i = 0; i < count; i++) { graphobj.data.graph.node = node.cursor(); list.data.list.list->at(i) = graphobj; node.next(); } } else { int b = param.toInt(); // note, will throw if it's not the right type if (b < 0 || b > 31) { throw SalaError("Bin must be in range 0 to 31"); } Bin& bin = node.bin(b); int count = bin.count(); list = SalaObj( SalaObj::S_LIST, count); bin.first(); for (int i = 0; i < count; i++) { graphobj.data.graph.node = bin.cursor(); list.data.list.list->at(i) = graphobj; bin.next(); } } } else { int idx = std::distance(graphobj.data.graph.map.shape->getAllShapes().begin(), graphobj.data.graph.map.shape->getAllShapes().find(graphobj.data.graph.node)); const Connector& connector = graphobj.data.graph.map.shape->getConnections()[idx]; int mode = Connector::CONN_ALL; if (graphobj.data.graph.map.shape->isSegmentMap()) { const std::string& str = param.toStringRef(); if (str == "forward") { mode = Connector::SEG_CONN_FW; } else if (str == "back") { mode = Connector::SEG_CONN_BK; } else if (str == "all") { mode = Connector::SEG_CONN_ALL; } } else { param.ensureNone(); } int count = connector.count(mode); list = SalaObj( SalaObj::S_LIST, count); int cursor = 0; for (int i = 0; i < count; i++) { int connectedIndex = connector.getConnectedRef(cursor, mode); if (connectedIndex == -1) { cursor = -1; graphobj.data.graph.node = -1; } else { graphobj.data.graph.node = graphobj.data.graph.map.shape->getShapeRefFromIndex(connectedIndex)->first; } list.data.list.list->at(i) = graphobj; cursor++; } } return list; } ///////////////////////////////////////////////////////////////////////////////// AttributeTable *SalaObj::getTable() { if ((type & SalaObj::S_MAP) == SalaObj::S_POINTMAP) { return &(data.graph.map.point->getAttributeTable()); } else { return &(data.graph.map.shape->getAttributeTable()); } } int SalaObj::precedence() const { int prec = 0; if ((type & S_BRACKET) == 0) { // preserve bracket on func stack until after close bracket, remember to strip any at end switch (func()) { case S_ASSIGN: prec = 1; // do absolutely last! break; case S_AND: prec = 2; break; case S_OR: prec = 3; break; case S_NOT: prec = 4; break; case S_EQ: case S_IS: case S_LT: case S_GT: case S_LEQ: case S_GEQ: case S_NEQ: prec = 5; break; case S_ADD: case S_SUBTRACT: prec = 6; break; case S_MULTIPLY: case S_DIVIDE: case S_MODULO: prec = 7; break; case S_POWER: prec = 8; break; default: // function -- place straight on eval stack when you meet next operator prec = 9; break; } } return prec; } ================================================ FILE: salalib/salaprogram.h ================================================ // salaprogram.h - a component of the depthmapX - spatial network analysis platform // SalaScripting language // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/attributetable.h" #include "genlib/stringutils.h" #include #include #include #include class AttributeTable; class PointMap; class ShapeMap; inline bool isalphanum_(char c) { if (isalnum(c) || c == '_') return true; else return false; } inline bool isalpha_(char c) { if (isalpha(c) || c == '_') return true; else return false; } struct SalaError { int lineno; std::string message; SalaError(const std::string& m = std::string(), int li = -1) { message = m; lineno = li; } }; ///////////////////////////////////////////////////////////////////////////////////////// // A series of 8-byte types to go in the SalaObj data union // note, they cannot cannot instantiate a copy constructor as it is used as // a member of the union in SalaObj class SalaObj; struct SalaStr { public: int *refcount; std::string *string; public: friend bool operator == (const SalaStr& a, const SalaStr& b); friend bool operator != (const SalaStr& a, const SalaStr& b); friend bool operator < (const SalaStr& a, const SalaStr& b); friend bool operator > (const SalaStr& a, const SalaStr& b); // operator const std::string&() { return *string; } char char_at(size_t i) const { return string->operator[](i); } size_t length() const { return string->length(); } }; inline bool operator == (const SalaStr& a, const SalaStr& b) { return *(a.string) == *(b.string); } inline bool operator != (const SalaStr& a, const SalaStr& b) { return *(a.string) != *(b.string); } inline bool operator < (const SalaStr& a, const SalaStr& b) { return *(a.string) < *(b.string); } inline bool operator > (const SalaStr& a, const SalaStr& b) { return *(a.string) > *(b.string); } struct SalaList { int *refcount; std::vector *list; public: friend bool operator == (const SalaList& a, const SalaList& b); friend bool operator != (const SalaList& a, const SalaList& b); // inlines below }; struct SalaGrf { int node; union Map { PointMap *point; // vga ShapeMap *shape; // everything else }; Map map; }; // SalaObj is 16 bytes, which is larger than I intended, but it appears // when you put both a double (8 bytes) and an int (4 bytes) into a class, it pads // to 16 bytes rather than the 12 you would expect // union members aren't allow copy constructors, so the list functionality // is built directly into the SalaObj, making it no more inefficient than if it // were to reference directly to another object to find, e.g., length or refcount // note lists are stored by reference. I'm not sure if this is a good idea! class SalaObj { friend class SalaProgram; friend class SalaCommand; friend class SalaArray; public: // Object types enum Type { S_BRACKET = 0x0000003f, S_OPEN_SQR_BRACKET = 0x0000000c, S_OPEN_BRACKET = 0x00000001, S_CLOSE_BRACKET = 0x00000002, S_OPEN_SQR_BRACKET_LIST = 0x00000004, S_OPEN_SQR_BRACKET_ACCESS = 0x00000008, S_CLOSE_SQR_BRACKET = 0x00000010, S_COMMA = 0x00000020, // bracket includes comma for checking purposes S_NONE = 0x00000100, S_UNINIT = 0x00000200, S_FUNCTION = 0x00000400, S_BOOL = 0x00001000, S_CHAR = 0x00002000, S_INT = 0x00004000, S_DOUBLE = 0x00008000, S_NUMBER = 0x0000c000, S_STRING = 0x00010000, S_VAR = 0x00020000, S_CONST_LIST = 0x00100000, S_CONST_TUPLE = 0x00300000, // tuple is a type of list S_LIST = 0x00400000, S_TUPLE = 0x00500000, // tuple is a type of list // maps are bitwise 'or'ed to node to make appropriate node type for each map S_GRAPHOBJ = 0x01000000, S_MAP = 0x06000000, S_POINTMAP = 0x02000000, S_SHAPEMAP = 0x04000000, // however, as the variable is uses the typename of the enum, each must be filled in explicitly: S_POINTMAPOBJ = 0x03000000, S_SHAPEMAPOBJ = 0x05000000, S_THIS = 0x10000000 }; // Built-in Functions, note, some of the groupings contain other operations (eg., math ops includes assign, and logical ops includes both comparators and logical ops) enum Func { S_FNULL = 0x00000000, S_GROUP = 0xf0000000, S_MATH_OPS = 0x10000000, S_LOGICAL_OPS = 0x20000000, S_GLOBAL_FUNCS = 0x30000000, S_MEMBER_FUNCS = 0x40000000, S_ADD = 0x10000001, S_SUBTRACT = 0x10000002, S_MINUS = 0x10000003, S_PLUS = 0x10000004, S_MULTIPLY = 0x10000005, S_DIVIDE = 0x10000006, S_MODULO = 0x10000007, S_POWER = 0x10000008, S_ASSIGN = 0x10000009, S_LIST_ACCESS = 0x1000000a, S_LT = 0x20000001, S_GT = 0x20000002, S_LEQ = 0x20000003, S_GEQ = 0x20000004, S_EQ = 0x20000005, S_NEQ = 0x20000006, S_AND = 0x20000007, S_OR = 0x20000008, S_NOT = 0x20000009, S_IS = 0x2000000a, S_LEN = 0x30000001, S_RANGE = 0x30000002, S_SQRT = 0x30000003, S_LOG = 0x30000004, S_LN = 0x30000005, S_RAND = 0x30000006, S_SIN = 0x30000007, S_COS = 0x30000008, S_TAN = 0x30000009, S_ASIN = 0x3000000a, S_ACOS = 0x3000000b, S_ATAN = 0x3000000c, S_FPOP = 0x40000001, S_FAPPEND = 0x40000002, S_FEXTEND = 0x40000003, S_FCLEAR = 0x40000004, S_FVALUE = 0x40000011, S_FSETVALUE = 0x40000012, S_FCONNECTIONS = 0x40000013, S_FMARK = 0x40000014, S_FSETMARK = 0x40000015 }; protected: union Data { bool b; char ch; int i; double f; SalaList list; SalaStr str; SalaGrf graph; Func func; int var; int count; // used by brackets to count how many objects they have }; Data data; Type type; public: SalaObj() { type = S_NONE; } // Two usages: (a) used for brackets (=groups of things, hence the count) and commas // (b) used for lists SalaObj(Type t) { type = t; if (t & S_LIST) { data.list.refcount = new int(1); data.list.list = new std::vector; } else { data.count = 1; } } // Two usages: (a) used to address variable or user function tables // (b) used for lists SalaObj(Type t, int v) { type = t; if (t & S_LIST) { data.list.refcount = new int(1); data.list.list = new std::vector(v); // set blanks } else { data.var = v; } } // other constructors SalaObj(bool a) { type = S_BOOL; data.b = a; } SalaObj(int a) { type = S_INT; data.i = a; } SalaObj(double a) { type = S_DOUBLE; data.f = a; } SalaObj(Func f) { type = S_FUNCTION; data.func = f; } SalaObj(const std::string& a) { type = S_STRING; data.str.refcount = new int(1); data.str.string = new std::string(a); } // note, type required here as sometimes this will be an axial map, sometimes segment map, sometimes point map, // also not fully filled in until runtime, but still required by parse SalaObj(Type t, SalaGrf graph) { type = t; data.graph = graph; } // SalaObj(const SalaObj& obj); SalaObj& operator = (const SalaObj& obj); ~SalaObj(); void reset(); void uninit() { reset(); type = S_UNINIT; } // <- used to uninitialise variables before running program, thus they give nice error messages if used before initialisation int func() const { return data.func; } int precedence() const; bool toBool() const; int toInt() const; double toDouble() const; std::string toString() const; const std::string& toStringRef() const; friend SalaObj op_is(SalaObj& a, SalaObj& b); friend SalaObj operator - (SalaObj& a); friend SalaObj operator + (SalaObj& a, SalaObj& b); friend SalaObj operator - (SalaObj& a, SalaObj& b); friend SalaObj operator / (SalaObj& a, SalaObj& b); friend SalaObj operator * (SalaObj& a, SalaObj& b); friend SalaObj operator % (SalaObj& a, SalaObj& b); friend bool operator || (SalaObj& a, SalaObj& b); friend bool operator && (SalaObj& a, SalaObj& b); friend bool operator ! (SalaObj& a); friend bool operator == (SalaObj& a, SalaObj& b); friend bool operator != (SalaObj& a, SalaObj& b); friend bool operator > (SalaObj& a, SalaObj& b); friend bool operator < (SalaObj& a, SalaObj& b); friend bool operator >= (SalaObj& a, SalaObj& b); friend bool operator <= (SalaObj& a, SalaObj& b); // operations for lists: SalaObj& list_at(int i); SalaObj char_at(int i); // actually returns a string of the char -- note constant int length(); // check for no parameters void ensureNone() { if (type != SalaObj::S_NONE) throw SalaError("Does not take any parameters"); } // // operations for graphs / graph nodes: AttributeTable *getTable(); // const std::string getTypeStr() const; const std::string getTypeIndefArt() const; }; // Quick mod - TV class SalaProgram; class SalaCommand { friend class SalaProgram; // enum Command { SC_NONE, SC_ROOT, SC_EXPR, SC_RETURN, SC_FOR, SC_WHILE, SC_IF, SC_ELIF, SC_ELSE }; enum { SP_NONE, SP_DATA, SP_NUMBER, SP_FUNCTION, SP_COMMAND }; // used while calculating what is on eval stack protected: // SalaProgram *m_program; // information about the running program (in particular, the global variable and error stack) SalaCommand *m_parent; std::vector m_children; // std::map m_var_names; // Command m_command; int m_indent; // vital for program flow due to Pythonesque syntax std::vector m_eval_stack; std::vector m_func_stack; // SalaObj m_for_iter; // object used in a for loop // int m_line; // useful for debugging to know which line this command starts on std::string m_last_string; // occassionally useful in debugging if the user does something unsyntactical // public: SalaCommand() { m_program = NULL; m_parent = NULL; m_indent = 0; m_command = SC_NONE; } SalaCommand(SalaProgram *program, SalaCommand *parent, int indent, Command command = SC_NONE); protected: int parse(std::istream& program, int line); int decode(std::string string); int decode_member(const std::string& string, bool apply_to_this); void pushFunc(const SalaObj& func); // void evaluate(SalaObj& obj, bool& ret, bool& ifhandled); SalaObj evaluate(int& pointer, SalaObj* &p_obj); SalaObj connections(SalaObj graphnode, SalaObj param); }; class SalaProgram { friend class SalaCommand; // SalaCommand m_root_command; std::vector m_var_stack; std::vector m_error_stack; // // column is stored away from the context, as it's not actually passed to the program itself, just used to update a column int m_col; // m_thisobj stores contextual information (which attribute table, node etc) // NB ! -- this can be messed with by SalaCommand! SalaObj m_thisobj; // bool m_marked; // this is used to tell the program that a node has been "marked" -- all marks are cleared at the end of the execution // marks for state management in maps std::map marks; public: SalaProgram(SalaObj context); ~SalaProgram(); bool parse(std::istream& program); SalaObj evaluate(); bool runupdate(int col, const std::set &selset = std::set()); bool runselect(std::vector& selsetout, const std::set &selsetin = std::set()); std::string getLastErrorMessage() const; }; inline SalaObj::SalaObj(const SalaObj& obj) { type = obj.type; switch(obj.type) { case S_FUNCTION: data.func = obj.data.func; break; case S_BOOL: data.b = obj.data.b; break; case S_INT: data.i = obj.data.i; break; case S_DOUBLE: data.f = obj.data.f; break; case S_VAR: data.var = obj.data.var; break; case S_STRING: data.str.string = obj.data.str.string; data.str.refcount = obj.data.str.refcount; *(data.str.refcount) += 1; break; case S_LIST: case S_TUPLE: data.list.list = obj.data.list.list; data.list.refcount = obj.data.list.refcount; *(data.list.refcount) += 1; break; case S_NONE: case S_UNINIT: case S_THIS: break; case S_SHAPEMAPOBJ: case S_SHAPEMAP: data.graph.map.shape = obj.data.graph.map.shape; data.graph.node = obj.data.graph.node; break; case S_POINTMAPOBJ: case S_POINTMAP: data.graph.map.point = obj.data.graph.map.point; data.graph.node = obj.data.graph.node; break; case S_OPEN_BRACKET: case S_CLOSE_BRACKET: case S_OPEN_SQR_BRACKET_LIST: case S_OPEN_SQR_BRACKET_ACCESS: case S_CLOSE_SQR_BRACKET: case S_COMMA: case S_CONST_LIST: case S_CONST_TUPLE: data.count = obj.data.count; break; default: throw SalaError("Cannot instantiate unknown type"); } } inline SalaObj& SalaObj::operator = (const SalaObj& obj) { if (this != &obj) { reset(); type = obj.type; switch(obj.type) { case S_FUNCTION: data.func = obj.data.func; break; case S_BOOL: data.b = obj.data.b; break; case S_INT: data.i = obj.data.i; break; case S_DOUBLE: data.f = obj.data.f; break; case S_VAR: data.var = obj.data.var; break; case S_STRING: data.str.string = obj.data.str.string; data.str.refcount = obj.data.str.refcount; *(data.str.refcount) += 1; break; case S_LIST: case S_TUPLE: data.list.list = obj.data.list.list; data.list.refcount = obj.data.list.refcount; *(data.list.refcount) += 1; break; case S_NONE: case S_UNINIT: case S_THIS: break; case S_SHAPEMAPOBJ: case S_SHAPEMAP: data.graph.map.shape = obj.data.graph.map.shape; data.graph.node = obj.data.graph.node; break; case S_POINTMAPOBJ: case S_POINTMAP: data.graph.map.point = obj.data.graph.map.point; data.graph.node = obj.data.graph.node; break; case S_OPEN_BRACKET: case S_CLOSE_BRACKET: case S_OPEN_SQR_BRACKET_LIST: case S_OPEN_SQR_BRACKET_ACCESS: case S_CLOSE_SQR_BRACKET: case S_COMMA: case S_CONST_LIST: case S_CONST_TUPLE: data.count = obj.data.count; break; default: throw SalaError("Cannot instantiate unknown type"); } } return *this; } inline SalaObj::~SalaObj() { reset(); } inline void SalaObj::reset() { if (type & S_STRING) { *(data.str.refcount) -= 1; if (*(data.str.refcount) == 0) { delete data.str.refcount; delete data.str.string; } data.str.refcount = NULL; data.str.string = NULL; } else if (type & S_LIST) { *(data.list.refcount) -= 1; if (*(data.list.refcount) == 0) { delete data.str.refcount; delete data.list.list; } data.str.refcount = NULL; data.list.list = NULL; } type = S_NONE; } inline bool SalaObj::toBool() const { switch(type) { case S_BOOL: return data.b; case S_INT: return data.i != 0; case S_DOUBLE: return data.f != 0.0; default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a boolean value")); } return false; } inline int SalaObj::toInt() const { switch(type) { case S_BOOL: return data.b ? 1 : 0; case S_INT: return data.i; case S_DOUBLE: return int(std::floor(data.f)); // ensure properly implemented default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to an integer value")); } return 0; } inline double SalaObj::toDouble() const { switch(type) { case S_BOOL: return data.b ? 1.0 : 0.0; case S_INT: return double(data.i); case S_DOUBLE: return data.f; default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a floating point number")); } return 0.0; } inline std::string SalaObj::toString() const { switch(type) { case S_INT: return dXstring::formatString(data.i); case S_DOUBLE: return dXstring::formatString(data.f); case S_STRING: return *(data.str.string); default: throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a string")); } return std::string(); } inline const std::string& SalaObj::toStringRef() const { if (type != S_STRING) { throw SalaError(std::string("Cannot convert ") + getTypeIndefArt() + getTypeStr() + std::string(" to a string reference")); } return *(data.str.string); } inline SalaObj operator + (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: throw SalaError("Cannot add booleans"); case SalaObj::S_INT: return SalaObj(a.data.i + b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f + b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) + b.data.f) : (a.data.f + double(b.data.i)); case SalaObj::S_STRING: return SalaObj(*(a.data.str.string) + *(b.data.str.string)); default: throw SalaError(std::string("Cannot add ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" to ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator - (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: throw SalaError("Cannot subtract booleans"); case SalaObj::S_INT: return SalaObj(a.data.i - b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f - b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) - b.data.f) : (a.data.f - double(b.data.i)); default: throw SalaError(std::string("Cannot subtract ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" from ") + a.getTypeIndefArt() + a.getTypeStr()); } return SalaObj(); } inline SalaObj operator - (SalaObj& a) { switch (a.type) { case SalaObj::S_BOOL: throw SalaError("Cannot minus booleans"); case SalaObj::S_INT: return SalaObj(-a.data.i); case SalaObj::S_DOUBLE: return SalaObj(-a.data.f); default: throw SalaError(std::string("Cannot minus ") + a.getTypeIndefArt() + a.getTypeStr()); } return SalaObj(); } inline SalaObj operator * (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: return SalaObj(a.data.i * b.data.i); case SalaObj::S_DOUBLE: return SalaObj(a.data.f * b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) * b.data.f) : (a.data.f * double(b.data.i)); default: throw SalaError(std::string("Cannot multiply ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator % (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: return SalaObj(a.data.i % b.data.i); case SalaObj::S_DOUBLE: return SalaObj(fmod(a.data.f,b.data.f)); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? fmod(double(a.data.i),b.data.f) : fmod(a.data.f,double(b.data.i)); default: throw SalaError(std::string("Cannot multiply ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + b.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } inline SalaObj operator / (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_INT: if (b.data.i != 0) return SalaObj(a.data.i / b.data.i); else throw SalaError("Integer divide by zero error"); case SalaObj::S_DOUBLE: return SalaObj(a.data.f / b.data.f); case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) / b.data.f) : (a.data.f / double(b.data.i)); default: throw SalaError(std::string("Cannot divide ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" by ") + a.getTypeIndefArt() + b.getTypeStr()); } return SalaObj(); } // assume already bools (use convert to bool first) inline bool operator && (SalaObj& a, SalaObj& b) { return a.data.b && b.data.b; } // assume already bools (use convert to bool first) inline bool operator || (SalaObj& a, SalaObj& b) { return a.data.b || b.data.b; } // assume already bools (use convert to bool first) inline bool operator ! (SalaObj& a) { return !a.data.b; } inline bool operator == (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_NONE: return true; // none == none case SalaObj::S_BOOL: return a.data.b == b.data.b; case SalaObj::S_INT: return a.data.i == b.data.i; case SalaObj::S_DOUBLE: return a.data.f == b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) == b.data.f) : (a.data.f == double(b.data.i)); case SalaObj::S_STRING: return a.data.str == b.data.str; case SalaObj::S_LIST: return a.data.list == b.data.list; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '=='")); } return false; } inline SalaObj op_is(SalaObj& a, SalaObj& b) { // note, op_is is forgiving: does not complain if cannot compare, just returns false switch (a.type & b.type) { case SalaObj::S_NONE: return true; // none is none case SalaObj::S_BOOL: return a.data.b == b.data.b; case SalaObj::S_INT: return a.data.i == b.data.i; case SalaObj::S_DOUBLE: return a.data.f == b.data.f; // n.b., no number! int is not double and v.v. case SalaObj::S_STRING: return a.data.str.string == b.data.str.string; // n.b.: pointer compare! case SalaObj::S_LIST: return a.data.list.list == b.data.list.list; // n.b.: pointer compare! } return false; } inline bool operator != (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b != b.data.b; case SalaObj::S_INT: return a.data.i != b.data.i; case SalaObj::S_DOUBLE: return a.data.f != b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) != b.data.f) : (a.data.f != double(b.data.i)); case SalaObj::S_STRING: return a.data.str != b.data.str; case SalaObj::S_LIST: return a.data.list != b.data.list; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '!='")); } return false; } inline bool operator < (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b < b.data.b; case SalaObj::S_INT: return a.data.i < b.data.i; case SalaObj::S_DOUBLE: return a.data.f < b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) < b.data.f) : (a.data.f < double(b.data.i)); case SalaObj::S_STRING: return a.data.str < b.data.str; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '<'")); } return false; } inline bool operator > (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b > b.data.b; case SalaObj::S_INT: return a.data.i > b.data.i; case SalaObj::S_DOUBLE: return a.data.f > b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) > b.data.f) : (a.data.f > double(b.data.i)); case SalaObj::S_STRING: return a.data.str > b.data.str; default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '>'")); } return false; } inline bool operator <= (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b <= b.data.b; case SalaObj::S_INT: return a.data.i <= b.data.i; case SalaObj::S_DOUBLE: return a.data.f <= b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) <= b.data.f) : (a.data.f <= double(b.data.i)); default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '<='")); } return false; } inline bool operator >= (SalaObj& a, SalaObj& b) { switch (a.type | b.type) { case SalaObj::S_BOOL: return a.data.b >= b.data.b; case SalaObj::S_INT: return a.data.i >= b.data.i; case SalaObj::S_DOUBLE: return a.data.f >= b.data.f; case SalaObj::S_NUMBER: return (a.type == SalaObj::S_INT) ? (double(a.data.i) >= b.data.f) : (a.data.f >= double(b.data.i)); default: throw SalaError(std::string("Cannot compare ") + a.getTypeIndefArt() + a.getTypeStr() + std::string(" with ") + b.getTypeIndefArt() + b.getTypeStr() + std::string(" using '>='")); } return false; } // list operations: note -> precheck in program and sort into list and string inline SalaObj& SalaObj::list_at(int i) { if (i < 0) i += (int)data.list.list->size(); if (i < 0 || size_t(i) >= data.list.list->size()) throw SalaError("Index out of range"); return data.list.list->at(i); } inline SalaObj SalaObj::char_at(int i) // actually returns a string of the char { if (i < 0) i += data.str.length(); if (i < 0 || i >= static_cast(data.str.length())) throw SalaError("String index out of range"); return SalaObj(std::string(1,data.str.char_at(i))); } inline int SalaObj::length() { if (type & S_LIST) return (int)data.list.list->size(); else if (type == S_STRING) return (int)data.str.length(); throw SalaError("Cannot get the length of " + getTypeIndefArt() + getTypeStr()); } ///////////////////////////////////////////////////////////////////////////////////// inline const std::string SalaObj::getTypeStr() const { switch(type) { case S_NONE: return "none"; case S_UNINIT: return "uninitialised variable"; case S_FUNCTION: return "function"; case S_BOOL: return "boolean"; case S_INT: return "integer"; case S_DOUBLE: return "float"; case S_STRING: return "string"; case S_LIST: return "list"; case S_TUPLE: return "tuple"; case S_THIS: return "this"; default: break; } if (type & S_GRAPHOBJ) { return "graph object"; } else if (type & S_MAP) { return "graph"; } return "unknown type"; } inline const std::string SalaObj::getTypeIndefArt() const { switch(type & ~S_GRAPHOBJ) { case S_FUNCTION: case S_BOOL: case S_DOUBLE: case S_STRING: case S_TUPLE: case S_LIST: case S_SHAPEMAP: case S_POINTMAP: return "a "; case S_INT: case S_UNINIT: return "an "; case S_NONE: case S_THIS: return ""; default: return "an "; // unknown type } return std::string(); } ///////////////////////////////////////////////////////////////////////////////////// // comparisons for lists (must be after the associated SalaObj comparisons have been declared) inline bool operator == (const SalaList& a, const SalaList& b) { if (a.list->size() != a.list->size()) return false; for (size_t i = 0; i < a.list->size(); i++) { if (a.list->at(i) != b.list->at(i)) return false; } return true; } inline bool operator != (const SalaList& a, const SalaList& b) { if (a.list->size() != a.list->size()) return true; for (size_t i = 0; i < a.list->size(); i++) { if (a.list->at(i) != b.list->at(i)) return true; } return false; } ///////////////////////////////////////////// // helpers for parser: struct SalaBuffer { int bufpos; char buffer[128]; SalaBuffer() { bufpos = -1; buffer[0] = '\0'; } void add(char c) { bufpos++; if (bufpos > 127) throw SalaError("Overlong string of characters"); buffer[bufpos] = c; } void clear() { bufpos = -1; buffer[0] = '\0'; } operator std::string() { buffer[bufpos + 1] = '\0'; return std::string(buffer); } bool empty() { return bufpos == -1; } }; /////////////////////////////////////////////////// ///////////////////////////////////////////// // Operator and function names struct SalaFuncLabel { SalaObj::Func func; std::string name; std::string desc; SalaFuncLabel(SalaObj::Func f = SalaObj::S_FNULL, const std::string& str = std::string(), const std::string& des = std::string()) { func = f; name = str; desc = des; } }; struct SalaMemberFuncLabel : public SalaFuncLabel { SalaObj::Type type; SalaMemberFuncLabel(SalaObj::Type t = SalaObj::S_NONE, SalaObj::Func f = SalaObj::S_FNULL, const std::string& str = std::string(), const std::string& des = std::string()) { type = t; func = f; name = str; desc = des; } }; ================================================ FILE: salalib/segmmodules/CMakeLists.txt ================================================ target_sources(salalib PRIVATE segmangular.cpp segmmetric.cpp segmtopological.cpp segmtulip.cpp segmtopologicalpd.cpp segmmetricpd.cpp segmtulipdepth.cpp PUBLIC segmangular.h segmmetric.h segmtopological.h segmtulip.h segmhelpers.h segmmetricpd.h segmtopologicalpd.h segmtulipdepth.h) ================================================ FILE: salalib/segmmodules/segmangular.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmangular.h" #include "salalib/options.h" #include "genlib/stringutils.h" bool SegmentAngular::run(Communicator *comm, ShapeGraph &map, bool) { if (map.getMapType() != ShapeMap::SEGMENTMAP) { return false; } AttributeTable &attributes = map.getAttributeTable(); time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getConnections().size()); } // note: radius must be sorted lowest to highest, but if -1 occurs ("radius n") it needs to be last... // ...to ensure no mess ups, we'll re-sort here: bool radius_n = false; std::vector radii; for (double radius : m_radius_set) { if (radius < 0) { radius_n = true; } else { radii.push_back(radius); } } if (radius_n) { radii.push_back(-1.0); } std::vector depth_col, count_col, total_col; // first enter table values for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; attributes.insertOrResetColumn(depth_col_text.c_str()); std::string count_col_text = std::string("Angular Node Count") + radius_text; attributes.insertOrResetColumn(count_col_text.c_str()); std::string total_col_text = std::string("Angular Total Depth") + radius_text; attributes.insertOrResetColumn(total_col_text.c_str()); } for (int radius : radii) { std::string radius_text = makeRadiusText(Options::RADIUS_ANGULAR, radius); std::string depth_col_text = std::string("Angular Mean Depth") + radius_text; depth_col.push_back(attributes.getColumnIndex(depth_col_text.c_str())); std::string count_col_text = std::string("Angular Node Count") + radius_text; count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); std::string total_col_text = std::string("Angular Total Depth") + radius_text; total_col.push_back(attributes.getColumnIndex(total_col_text.c_str())); } std::vector covered(map.getShapeCount()); size_t i = 0; for (auto & iter : attributes){ for (size_t j = 0; j < map.getShapeCount(); j++) { covered[j] = false; } std::vector> anglebins; anglebins.push_back(std::make_pair(0.0f, SegmentData(0, i, SegmentRef(), 0, 0.0, 0))); std::vector total_depth; std::vector node_count; for (size_t r = 0; r < radii.size(); r++) { total_depth.push_back(0.0); node_count.push_back(0); } // node_count includes this one, but will be added in next algo: while (anglebins.size()) { auto iter = anglebins.begin(); SegmentData lineindex = iter->second; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; double depth_to_line = iter->first; total_depth[lineindex.coverage] += depth_to_line; node_count[lineindex.coverage] += 1; anglebins.erase(iter); Connector &line = map.getConnections()[lineindex.ref]; if (lineindex.dir != -1) { for (auto &segconn : line.m_forward_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; size_t rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } if (lineindex.dir != 1) { for (auto &segconn : line.m_back_segconns) { if (!covered[segconn.first.ref]) { double angle = depth_to_line + segconn.second; size_t rbin = lineindex.coverage; while (rbin != radii.size() && radii[rbin] != -1 && angle > radii[rbin]) { rbin++; } if (rbin != radii.size()) { depthmapX::insert_sorted( anglebins, std::make_pair(float(angle), SegmentData(segconn.first, SegmentRef(), 0, 0.0, rbin))); } } } } } else { anglebins.erase(iter); } } AttributeRow &row = iter.getRow(); // set the attributes for this node: int curs_node_count = 0; double curs_total_depth = 0.0; for (size_t r = 0; r < radii.size(); r++) { curs_node_count += node_count[r]; curs_total_depth += total_depth[r]; row.setValue(count_col[r], float(curs_node_count)); if (curs_node_count > 1) { // note -- node_count includes this one -- mean depth as per p.108 Social Logic of Space double mean_depth = curs_total_depth / double(curs_node_count - 1); row.setValue(depth_col[r], float(mean_depth)); row.setValue(total_col[r], float(curs_total_depth)); } else { row.setValue(depth_col[r], -1); row.setValue(total_col[r], -1); } } // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, i); } } i++; } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(depth_col.back()); return true; } ================================================ FILE: salalib/segmmodules/segmangular.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/isegment.h" class SegmentAngular : ISegment { private: std::set m_radius_set; public: std::string getAnalysisName() const override { return "Angular Analysis"; } bool run(Communicator *comm, ShapeGraph &map, bool) override; SegmentAngular(std::set radius_set) : m_radius_set(radius_set) {} }; ================================================ FILE: salalib/segmmodules/segmhelpers.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once struct TopoMetSegmentRef { int ref; int dir; double dist; int previous; bool done; TopoMetSegmentRef(int r = -1, int d = -1, double di = 0.0, int p = -1) { ref = r; dir = d; dist = di; previous = p; done = false; } }; // should be double not float! struct TopoMetSegmentChoice { double choice; double wchoice; TopoMetSegmentChoice() { choice = 0.0; wchoice = 0.0; } }; struct SegInfo { double length; int layer; SegInfo() { length = 0.0f; layer = 0; } }; ================================================ FILE: salalib/segmmodules/segmmetric.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmmetric.h" #include "genlib/stringutils.h" bool SegmentMetric::run(Communicator *comm, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); bool retvar = true; time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, (m_sel_only ? map.getSelSet().size() : map.getConnections().size())); } int reccount = 0; // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue(attributes.getColumnIndex("Axial Line Ref"))); seglengths.push_back(row.getValue(attributes.getColumnIndex("Segment Length"))); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } std::string prefix, suffix; int maxbin = 512; prefix = "Metric "; if (m_radius != -1.0) { suffix = dXstring::formatString(m_radius, " R%.f metric"); } std::string choicecol = prefix + "Choice" + suffix; std::string wchoicecol = prefix + "Choice [SLW]" + suffix; std::string meandepthcol = prefix + "Mean Depth" + suffix; std::string wmeandepthcol = prefix + std::string("Mean Depth [SLW]") + suffix; std::string totaldcol = prefix + "Total Depth" + suffix; std::string totalcol = prefix + "Total Nodes" + suffix; std::string wtotalcol = prefix + "Total Length" + suffix; // if (!m_sel_only) { attributes.insertOrResetColumn(choicecol.c_str()); attributes.insertOrResetColumn(wchoicecol.c_str()); } attributes.insertOrResetColumn(meandepthcol.c_str()); attributes.insertOrResetColumn(wmeandepthcol.c_str()); attributes.insertOrResetColumn(totaldcol.c_str()); attributes.insertOrResetColumn(totalcol.c_str()); attributes.insertOrResetColumn(wtotalcol.c_str()); // std::vector seen(map.getShapeCount()); std::vector audittrail(map.getShapeCount()); std::vector choicevals(map.getShapeCount()); for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); if (m_sel_only && !row.isSelected()) { continue; } for (size_t i = 0; i < map.getShapeCount(); i++) { seen[i] = 0xffffffff; } std::vector list[512]; // 512 bins! int bin = 0; list[bin].push_back(cursor); double rootseglength = seglengths[cursor]; audittrail[cursor] = TopoMetSegmentRef(cursor, Connector::SEG_CONN_ALL, rootseglength * 0.5, -1); int open = 1; unsigned int segdepth = 0; double total = 0.0, wtotal = 0.0, wtotaldepth = 0.0, totalsegdepth = 0.0, totalmetdepth = 0.0; while (open != 0) { while (list[bin].size() == 0) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // if (here.done) { continue; } else { here.done = true; } // double len = seglengths[here.ref]; totalsegdepth += segdepth; totalmetdepth += here.dist - len * 0.5; // preloaded with length ahead wtotal += len; wtotaldepth += len * (here.dist - len * 0.5); total += 1; // Connector &axline = map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; if (seen[connected_cursor] > segdepth && static_cast(connected_cursor) != cursor) { bool seenalready = (seen[connected_cursor] == 0xffffffff) ? false : true; float length = seglengths[connected_cursor]; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); seen[connected_cursor] = segdepth; if (m_radius == -1 || here.dist + length < m_radius) { // puts in a suitable bin ahead of us... open++; // // better to divide by 511 but have 512 bins... list[(bin + int(floor(0.5 + 511 * length / maxseglength))) % 512].push_back(connected_cursor); } // not sure why this is outside the radius restriction // (sel_only: with restricted selection set, not all lines will be labelled) // (seenalready: need to check that we're not doing this twice, given the seen can go twice) // Quick mod - TV if (!m_sel_only && connected_cursor > int(cursor) && !seenalready) { // only one way paths, saves doing this twice int subcur = connected_cursor; while (subcur != -1) { // in this method of choice, start and end lines are included choicevals[subcur].choice += 1; choicevals[subcur].wchoice += (rootseglength * length); subcur = audittrail[subcur].previous; } } } iter++; } } // also put in mean depth: // row.setValue(meandepthcol.c_str(), totalmetdepth / (total - 1)); row.setValue(totaldcol.c_str(), totalmetdepth); row.setValue(wmeandepthcol.c_str(), wtotaldepth / (wtotal - rootseglength)); row.setValue(totalcol.c_str(), total); row.setValue(wtotalcol.c_str(), wtotal); // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } } comm->CommPostMessage(Communicator::CURRENT_RECORD, reccount); } reccount++; } if (!m_sel_only) { // note, I've stopped sel only from calculating choice values: for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); row.setValue(choicecol.c_str(), choicevals[cursor].choice); row.setValue(wchoicecol.c_str(), choicevals[cursor].wchoice); } } if (!m_sel_only) { map.setDisplayedAttribute(attributes.getColumnIndex(choicecol.c_str())); } else { map.setDisplayedAttribute(attributes.getColumnIndex(meandepthcol.c_str())); } return retvar; } ================================================ FILE: salalib/segmmodules/segmmetric.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/isegment.h" class SegmentMetric : ISegment { private: double m_radius; bool m_sel_only; public: std::string getAnalysisName() const override { return "Metric Analysis"; } bool run(Communicator *comm, ShapeGraph &map, bool) override; SegmentMetric(double radius, bool sel_only) : m_radius(radius), m_sel_only(sel_only) {} }; ================================================ FILE: salalib/segmmodules/segmmetricpd.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmmetricpd.h" #include "genlib/stringutils.h" bool SegmentMetricPD::run(Communicator *, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); bool retvar = true; // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow &row = map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue("Axial Line Ref")); seglengths.push_back(row.getValue("Segment Length")); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } int maxbin; std::string prefix; prefix = "Metric "; maxbin = 512; std::string depthcol = prefix + "Step Depth"; attributes.insertOrResetColumn(depthcol.c_str()); std::vector seen(map.getShapeCount()); std::vector audittrail(map.getShapeCount()); std::vector list[512]; // 512 bins! int open = 0; for (size_t i = 0; i < map.getShapeCount(); i++) { seen[i] = 0xffffffff; } for (auto &cursor : map.getSelSet()) { seen[cursor] = 0; open++; double length = seglengths[cursor]; audittrail[cursor] = TopoMetSegmentRef(cursor, Connector::SEG_CONN_ALL, length * 0.5, -1); // better to divide by 511 but have 512 bins... list[(int(floor(0.5 + 511 * length / maxseglength))) % 512].push_back(cursor); AttributeRow &row = map.getAttributeRowFromShapeIndex(cursor); row.setValue(depthcol.c_str(), 0); } unsigned int segdepth = 0; int bin = 0; while (open != 0) { while (list[bin].size() == 0) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // this is necessary using unsigned ints for "seen", as it is possible to add a node twice if (here.done) { continue; } else { here.done = true; } Connector &axline = map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; if (seen[connected_cursor] > segdepth) { float length = seglengths[connected_cursor]; seen[connected_cursor] = segdepth; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); // puts in a suitable bin ahead of us... open++; // // better to divide by 511 but have 512 bins... list[(bin + int(floor(0.5 + 511 * length / maxseglength))) % 512].push_back(connected_cursor); AttributeRow &row = map.getAttributeRowFromShapeIndex(connected_cursor); row.setValue(depthcol.c_str(), here.dist + length * 0.5); } iter++; } } map.setDisplayedAttribute(attributes.getColumnIndex(depthcol.c_str())); return retvar; } ================================================ FILE: salalib/segmmodules/segmmetricpd.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/isegment.h" class SegmentMetricPD : ISegment { public: std::string getAnalysisName() const override { return "Metric Analysis"; } bool run(Communicator *, ShapeGraph &map, bool) override; }; ================================================ FILE: salalib/segmmodules/segmtopological.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmtopological.h" #include "genlib/stringutils.h" bool SegmentTopological::run(Communicator *comm, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); bool retvar = true; time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, (m_sel_only ? map.getSelSet().size() : map.getConnections().size())); } int reccount = 0; // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue(attributes.getColumnIndex("Axial Line Ref"))); seglengths.push_back(row.getValue(attributes.getColumnIndex("Segment Length"))); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } std::string prefix, suffix; int maxbin; prefix = "Topological "; maxbin = 2; if (m_radius != -1.0) { suffix = dXstring::formatString(m_radius, " R%.f metric"); } std::string choicecol = prefix + "Choice" + suffix; std::string wchoicecol = prefix + "Choice [SLW]" + suffix; std::string meandepthcol = prefix + "Mean Depth" + suffix; std::string wmeandepthcol = prefix + std::string("Mean Depth [SLW]") + suffix; std::string totaldcol = prefix + "Total Depth" + suffix; std::string totalcol = prefix + "Total Nodes" + suffix; std::string wtotalcol = prefix + "Total Length" + suffix; // if (!m_sel_only) { attributes.insertOrResetColumn(choicecol.c_str()); attributes.insertOrResetColumn(wchoicecol.c_str()); } attributes.insertOrResetColumn(meandepthcol.c_str()); attributes.insertOrResetColumn(wmeandepthcol.c_str()); attributes.insertOrResetColumn(totaldcol.c_str()); attributes.insertOrResetColumn(totalcol.c_str()); attributes.insertOrResetColumn(wtotalcol.c_str()); // std::vector seen(map.getShapeCount()); std::vector audittrail(map.getShapeCount()); std::vector choicevals(map.getShapeCount()); for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); if (m_sel_only && !row.isSelected()) { continue; } for (size_t i = 0; i < map.getShapeCount(); i++) { seen[i] = 0xffffffff; } std::vector list[512]; // 512 bins! int bin = 0; list[bin].push_back(cursor); double rootseglength = seglengths[cursor]; audittrail[cursor] = TopoMetSegmentRef(cursor, Connector::SEG_CONN_ALL, rootseglength * 0.5, -1); int open = 1; unsigned int segdepth = 0; double total = 0.0, wtotal = 0.0, wtotaldepth = 0.0, totalsegdepth = 0.0, totalmetdepth = 0.0; while (open != 0) { while (list[bin].size() == 0) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // if (here.done) { continue; } else { here.done = true; } // double len = seglengths[here.ref]; totalsegdepth += segdepth; totalmetdepth += here.dist - len * 0.5; // preloaded with length ahead wtotal += len; wtotaldepth += len * segdepth; total += 1; // Connector &axline = map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; if (seen[connected_cursor] > segdepth && static_cast(connected_cursor) != cursor) { bool seenalready = (seen[connected_cursor] == 0xffffffff) ? false : true; float length = seglengths[connected_cursor]; int axialref = axialrefs[connected_cursor]; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); seen[connected_cursor] = segdepth; if (m_radius == -1 || here.dist + length < m_radius) { // puts in a suitable bin ahead of us... open++; // if (axialrefs[here.ref] == axialref) { list[bin].push_back(connected_cursor); } else { list[(bin + 1) % 2].push_back(connected_cursor); seen[connected_cursor] = segdepth + 1; // this is so if another node is connected directly to this one but // is found later it is still handled -- note it can result in the // connected cursor being added twice } } // not sure why this is outside the radius restriction // (sel_only: with restricted selection set, not all lines will be labelled) // (seenalready: need to check that we're not doing this twice, given the seen can go twice) // Quick mod - TV if (!m_sel_only && connected_cursor > int(cursor) && !seenalready) { // only one way paths, saves doing this twice int subcur = connected_cursor; while (subcur != -1) { // in this method of choice, start and end lines are included choicevals[subcur].choice += 1; choicevals[subcur].wchoice += (rootseglength * length); subcur = audittrail[subcur].previous; } } } iter++; } } // also put in mean depth: row.setValue(meandepthcol.c_str(), totalsegdepth / (total - 1)); row.setValue(totaldcol.c_str(), totalsegdepth); row.setValue(wmeandepthcol.c_str(), wtotaldepth / (wtotal - rootseglength)); row.setValue(totalcol.c_str(), total); row.setValue(wtotalcol.c_str(), wtotal); // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } } comm->CommPostMessage(Communicator::CURRENT_RECORD, reccount); } reccount++; } if (!m_sel_only) { // note, I've stopped sel only from calculating choice values: for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); row.setValue(choicecol.c_str(), choicevals[cursor].choice); row.setValue(wchoicecol.c_str(), choicevals[cursor].wchoice); } } if (!m_sel_only) { map.setDisplayedAttribute(attributes.getColumnIndex(choicecol.c_str())); } else { map.setDisplayedAttribute(attributes.getColumnIndex(meandepthcol.c_str())); } return retvar; } ================================================ FILE: salalib/segmmodules/segmtopological.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/isegment.h" class SegmentTopological : ISegment { private: double m_radius; bool m_sel_only; public: std::string getAnalysisName() const override { return "Topological Analysis"; } bool run(Communicator *comm, ShapeGraph &map, bool) override; SegmentTopological(double radius, bool sel_only) : m_radius(radius), m_sel_only(sel_only) {} }; ================================================ FILE: salalib/segmmodules/segmtopologicalpd.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmtopologicalpd.h" #include "genlib/stringutils.h" bool SegmentTopologicalPD::run(Communicator *, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); bool retvar = true; // record axial line refs for topological analysis std::vector axialrefs; // quick through to find the longest seg length std::vector seglengths; float maxseglength = 0.0f; for (size_t cursor = 0; cursor < map.getShapeCount(); cursor++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(cursor); axialrefs.push_back(row.getValue("Axial Line Ref")); seglengths.push_back(row.getValue("Segment Length")); if (seglengths.back() > maxseglength) { maxseglength = seglengths.back(); } } int maxbin = 2; std::string prefix = "Topological "; std::string depthcol = prefix + "Step Depth"; attributes.insertOrResetColumn(depthcol.c_str()); std::vector seen(map.getShapeCount()); std::vector audittrail(map.getShapeCount()); std::vector list[512]; // 512 bins! int open = 0; for (size_t i = 0; i < map.getShapeCount(); i++) { seen[i] = 0xffffffff; } for (auto &cursor : map.getSelSet()) { seen[cursor] = 0; open++; double length = seglengths[cursor]; audittrail[cursor] = TopoMetSegmentRef(cursor, Connector::SEG_CONN_ALL, length * 0.5, -1); list[0].push_back(cursor); attributes.getRow(AttributeKey(cursor)).setValue(depthcol.c_str(), 0); } unsigned int segdepth = 0; int bin = 0; while (open != 0) { while (list[bin].size() == 0) { bin++; segdepth += 1; if (bin == maxbin) { bin = 0; } } // TopoMetSegmentRef &here = audittrail[list[bin].back()]; list[bin].pop_back(); open--; // this is necessary using unsigned ints for "seen", as it is possible to add a node twice if (here.done) { continue; } else { here.done = true; } Connector &axline = map.getConnections().at(here.ref); int connected_cursor = -2; auto iter = axline.m_back_segconns.begin(); bool backsegs = true; while (connected_cursor != -1) { if (backsegs && iter == axline.m_back_segconns.end()) { iter = axline.m_forward_segconns.begin(); backsegs = false; } if (!backsegs && iter == axline.m_forward_segconns.end()) { break; } connected_cursor = iter->first.ref; AttributeRow& row = map.getAttributeRowFromShapeIndex(connected_cursor); if (seen[connected_cursor] > segdepth) { float length = seglengths[connected_cursor]; int axialref = axialrefs[connected_cursor]; seen[connected_cursor] = segdepth; audittrail[connected_cursor] = TopoMetSegmentRef(connected_cursor, here.dir, here.dist + length, here.ref); // puts in a suitable bin ahead of us... open++; // if (axialrefs[here.ref] == axialref) { list[bin].push_back(connected_cursor); row.setValue(depthcol.c_str(), segdepth); } else { list[(bin + 1) % 2].push_back(connected_cursor); seen[connected_cursor] = segdepth + 1; // this is so if another node is connected directly to this one but is found later it is // still handled -- note it can result in the connected cursor being added twice row.setValue(depthcol.c_str(), segdepth + 1); } } iter++; } } map.setDisplayedAttribute(attributes.getColumnIndex(depthcol.c_str())); return retvar; } ================================================ FILE: salalib/segmmodules/segmtopologicalpd.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/segmmodules/segmhelpers.h" #include "salalib/isegment.h" class SegmentTopologicalPD : ISegment { public: std::string getAnalysisName() const override { return "Topological Analysis"; } bool run(Communicator *, ShapeGraph &map, bool) override; }; ================================================ FILE: salalib/segmmodules/segmtulip.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmtulip.h" #include "genlib/stringutils.h" bool SegmentTulip::run(Communicator *comm, ShapeGraph &map, bool) { if (map.getMapType() != ShapeMap::SEGMENTMAP) { return false; } // TODO: Understand what these parameters do. They were never truly provided in the original function int weighting_col2 = m_weighted_measure_col2; int routeweight_col = m_routeweight_col; bool interactive = m_interactive; AttributeTable &attributes = map.getAttributeTable(); int processed_rows = 0; time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, (m_sel_only ? map.getSelSet().size() : map.getConnections().size())); } // note: radius must be sorted lowest to highest, but if -1 occurs ("radius n") it needs to be last... // ...to ensure no mess ups, we'll re-sort here: bool radius_n = false; std::vector radius_unconverted; for (int radius : m_radius_set) { if (radius == -1.0) { radius_n = true; } else { radius_unconverted.push_back(radius); } } if (radius_n) { radius_unconverted.push_back(-1.0); } // retrieve weighted col data, as this may well be overwritten in the new analysis: std::vector weights; std::vector routeweights; // EF std::string weighting_col_text; int tulip_bins = m_tulip_bins; if (m_weighted_measure_col != -1) { weighting_col_text = attributes.getColumnName(m_weighted_measure_col); for (size_t i = 0; i < map.getConnections().size(); i++) { weights.push_back(map.getAttributeRowFromShapeIndex(i).getValue(m_weighted_measure_col)); } } else { // Normal run // TV for (size_t i = 0; i < map.getConnections().size(); i++) { weights.push_back(1.0f); } } // EF routeweight* std::string routeweight_col_text; if (routeweight_col != -1) { // we normalise the column values between 0 and 1 and reverse it so that high values can be treated as a 'low // cost' - similar to the angular cost double max_value = attributes.getColumn(routeweight_col).getStats().max; routeweight_col_text = attributes.getColumnName(routeweight_col); for (size_t i = 0; i < map.getConnections().size(); i++) { routeweights.push_back(1.0 - (map.getAttributeRowFromShapeIndex(i).getValue(routeweight_col) / max_value)); // scale and revert! } } else { // Normal run // TV for (size_t i = 0; i < map.getConnections().size(); i++) { routeweights.push_back(1.0f); } } //*EF routeweight // EFEF* // for origin-destination weighting std::vector weights2; std::string weighting_col_text2; if (weighting_col2 != -1) { weighting_col_text2 = attributes.getColumnName(weighting_col2); for (size_t i = 0; i < map.getConnections().size(); i++) { weights2.push_back(map.getAttributeRowFromShapeIndex(i).getValue(weighting_col2)); } } else { // Normal run // TV for (size_t i = 0; i < map.getConnections().size(); i++) { weights2.push_back(1.0f); } } //*EFEF std::string tulip_text = std::string("T") + dXstring::formatString(tulip_bins, "%d"); // first enter the required attribute columns: size_t r; for (r = 0; r < radius_unconverted.size(); r++) { std::string radius_text = makeRadiusText(m_radius_type, radius_unconverted[r]); if (m_choice) { // EF routeweight * if (routeweight_col != -1) { std::string choice_col_text = tulip_text + " Choice [Route weight by " + routeweight_col_text + "]" + radius_text; attributes.insertOrResetColumn(choice_col_text.c_str()); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = tulip_text + " Choice [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; attributes.insertOrResetColumn(w_choice_col_text.c_str()); } // EFEF* if (weighting_col2 != -1) { std::string w_choice_col_text2 = tulip_text + " Choice [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + "-" + weighting_col_text2 + " Wgt]]" + radius_text; attributes.insertOrResetColumn(w_choice_col_text2.c_str()); } //*EFEF } //*EF routeweight else { // Normal run // TV std::string choice_col_text = tulip_text + " Choice" + radius_text; attributes.insertOrResetColumn(choice_col_text.c_str()); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = tulip_text + " Choice [" + weighting_col_text + " Wgt]" + radius_text; attributes.insertOrResetColumn(w_choice_col_text.c_str()); } // EFEF* if (weighting_col2 != -1) { std::string w_choice_col_text2 = tulip_text + " Choice [" + weighting_col_text + "-" + weighting_col_text2 + " Wgt]" + radius_text; attributes.insertOrResetColumn(w_choice_col_text2.c_str()); } //*EFEF } } // EF routeweight * if (routeweight_col != -1) { std::string integ_col_text = tulip_text + " Integration [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_integ_col_text = tulip_text + " Integration [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; std::string count_col_text = tulip_text + " Node Count [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string td_col_text = tulip_text + " Total Depth [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary // '[' comes after 'R' in ASCII, so this column will come after Mean Depth R... std::string w_td_text = tulip_text + " Total Depth [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; std::string total_weight_text = tulip_text + " Total " + weighting_col_text + " [Route weight by " + routeweight_col_text + "]" + radius_text; attributes.insertOrResetColumn(integ_col_text.c_str()); attributes.insertOrResetColumn(count_col_text.c_str()); attributes.insertOrResetColumn(td_col_text.c_str()); if (m_weighted_measure_col != -1) { attributes.insertOrResetColumn(w_integ_col_text.c_str()); attributes.insertOrResetColumn(w_td_text.c_str()); attributes.insertOrResetColumn(total_weight_text.c_str()); } } //*EF routeweight else { // Normal run // TV std::string integ_col_text = tulip_text + " Integration" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_integ_col_text = tulip_text + " Integration [" + weighting_col_text + " Wgt]" + radius_text; std::string count_col_text = tulip_text + " Node Count" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string td_col_text = tulip_text + " Total Depth" + radius_text; // <- note, the fact this is a tulip is unnecessary // '[' comes after 'R' in ASCII, so this column will come after Mean Depth R... std::string w_td_text = tulip_text + " Total Depth [" + weighting_col_text + " Wgt]" + radius_text; std::string total_weight_text = tulip_text + " Total " + weighting_col_text + radius_text; attributes.insertOrResetColumn(integ_col_text.c_str()); attributes.insertOrResetColumn(count_col_text.c_str()); attributes.insertOrResetColumn(td_col_text.c_str()); if (m_weighted_measure_col != -1) { attributes.insertOrResetColumn(w_integ_col_text.c_str()); attributes.insertOrResetColumn(w_td_text.c_str()); attributes.insertOrResetColumn(total_weight_text.c_str()); } } } std::vector choice_col, w_choice_col, w_choice_col2, count_col, integ_col, w_integ_col, td_col, w_td_col, total_weight_col; // then look them up! eek.... for (r = 0; r < radius_unconverted.size(); r++) { std::string radius_text = makeRadiusText(m_radius_type, radius_unconverted[r]); if (m_choice) { // EF routeweight * if (routeweight_col != -1) { std::string choice_col_text = tulip_text + " Choice [Route weight by " + routeweight_col_text + "]" + radius_text; choice_col.push_back(attributes.getColumnIndex(choice_col_text.c_str())); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = tulip_text + " Choice [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; w_choice_col.push_back(attributes.getColumnIndex(w_choice_col_text.c_str())); } // EFEF* if (weighting_col2 != -1) { std::string w_choice_col_text2 = tulip_text + " Choice [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + "-" + weighting_col_text2 + " Wgt]]" + radius_text; w_choice_col2.push_back(attributes.getColumnIndex(w_choice_col_text2.c_str())); } //*EFEF } //* EF routeweight else { // Normal run // TV std::string choice_col_text = tulip_text + " Choice" + radius_text; choice_col.push_back(attributes.getColumnIndex(choice_col_text.c_str())); if (m_weighted_measure_col != -1) { std::string w_choice_col_text = tulip_text + " Choice [" + weighting_col_text + " Wgt]" + radius_text; w_choice_col.push_back(attributes.getColumnIndex(w_choice_col_text.c_str())); } // EFEF* if (weighting_col2 != -1) { std::string w_choice_col_text2 = tulip_text + " Choice [" + weighting_col_text + "-" + weighting_col_text2 + " Wgt]" + radius_text; w_choice_col2.push_back(attributes.getColumnIndex(w_choice_col_text2.c_str())); } //*EFEF } } // EF routeweight * if (routeweight_col != -1) { std::string integ_col_text = tulip_text + " Integration [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_integ_col_text = tulip_text + " Integration [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; std::string count_col_text = tulip_text + " Node Count [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string td_col_text = tulip_text + " Total Depth [Route weight by " + routeweight_col_text + "]" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_td_text = tulip_text + " Total Depth [[Route weight by " + routeweight_col_text + "][" + weighting_col_text + " Wgt]]" + radius_text; std::string total_weight_col_text = tulip_text + " Total " + weighting_col_text + " [Route weight by " + routeweight_col_text + "]" + radius_text; integ_col.push_back(attributes.getColumnIndex(integ_col_text.c_str())); count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); td_col.push_back(attributes.getColumnIndex(td_col_text.c_str())); if (m_weighted_measure_col != -1) { // '[' comes after 'R' in ASCII, so this column will come after Mean Depth R... w_integ_col.push_back(attributes.getColumnIndex(w_integ_col_text.c_str())); w_td_col.push_back(attributes.getColumnIndex(w_td_text.c_str())); total_weight_col.push_back(attributes.getColumnIndex(total_weight_col_text.c_str())); } } //* EF routeweight else { // Normal run // TV std::string integ_col_text = tulip_text + " Integration" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_integ_col_text = tulip_text + " Integration [" + weighting_col_text + " Wgt]" + radius_text; std::string count_col_text = tulip_text + " Node Count" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string td_col_text = tulip_text + " Total Depth" + radius_text; // <- note, the fact this is a tulip is unnecessary std::string w_td_text = tulip_text + " Total Depth [" + weighting_col_text + " Wgt]" + radius_text; std::string total_weight_col_text = tulip_text + " Total " + weighting_col_text + radius_text; integ_col.push_back(attributes.getColumnIndex(integ_col_text.c_str())); count_col.push_back(attributes.getColumnIndex(count_col_text.c_str())); td_col.push_back(attributes.getColumnIndex(td_col_text.c_str())); if (m_weighted_measure_col != -1) { // '[' comes after 'R' in ASCII, so this column will come after Mean Depth R... w_integ_col.push_back(attributes.getColumnIndex(w_integ_col_text.c_str())); w_td_col.push_back(attributes.getColumnIndex(w_td_text.c_str())); total_weight_col.push_back(attributes.getColumnIndex(total_weight_col_text.c_str())); } } } tulip_bins /= 2; // <- actually use semicircle of tulip bins tulip_bins += 1; std::vector> bins(tulip_bins); // TODO: Replace these with STL AnalysisInfo ***audittrail; unsigned int **uncovered; audittrail = new AnalysisInfo **[map.getConnections().size()]; uncovered = new unsigned int *[map.getConnections().size()]; for (size_t i = 0; i < map.getConnections().size(); i++) { audittrail[i] = new AnalysisInfo *[radius_unconverted.size()]; for (size_t j = 0; j < radius_unconverted.size(); j++) { audittrail[i][j] = new AnalysisInfo[2]; } uncovered[i] = new unsigned int[2]; } std::vector radius; for (r = 0; r < radius_unconverted.size(); r++) { if (m_radius_type == Options::RADIUS_ANGULAR && radius_unconverted[r] != -1) { radius.push_back(floor(radius_unconverted[r] * tulip_bins * 0.5)); } else { radius.push_back(radius_unconverted[r]); } } // entered once for each segment int length_col = attributes.getColumnIndex("Segment Length"); std::vector lengths; if (length_col != -1) { for (size_t i = 0; i < map.getConnections().size(); i++) { AttributeRow& row = map.getAttributeRowFromShapeIndex(i); lengths.push_back(row.getValue(length_col)); } } int radiussize = radius.size(); int radiusmask = 0; for (int i = 0; i < radiussize; i++) { radiusmask |= (1 << i); } for (size_t cursor = 0; cursor < map.getConnections().size(); cursor++) { AttributeRow &row = map.getAttributeRowFromShapeIndex(cursor); if (m_sel_only) { // could use m_selection_set.searchindex(rowid) to find // if this row is selected as m_selection_set is ordered for axial and segment maps, etc // BUT, actually quicker to check the tag in the attributes that shows it's selected if (!row.isSelected()) { continue; } } for (int k = 0; k < tulip_bins; k++) { bins[k].clear(); } for (size_t j = 0; j < map.getConnections().size(); j++) { for (int dir = 0; dir < 2; dir++) { for (int k = 0; k < radiussize; k++) { audittrail[j][k][dir].clearLine(); } uncovered[j][dir] = radiusmask; } } double rootseglength = row.getValue(length_col); double rootweight = (m_weighted_measure_col != -1) ? weights[cursor] : 0.0; // setup: direction 0 (both ways), segment i, previous -1, segdepth (step depth) 0, metricdepth 0.5 * // rootseglength, bin 0 SegmentData segmentData(0, cursor, SegmentRef(), 0, 0.5 * rootseglength, radiusmask); auto it = std::lower_bound(bins[0].begin(), bins[0].end(), segmentData); if (it == bins[0].end() || segmentData != *it) { bins[0].insert(it, segmentData); } // this version below is only designed to be used temporarily -- // could be on an option? // bins[0].push_back(SegmentData(0,rowid,SegmentRef(),0,0.0,radiusmask)); int depthlevel = 0; int opencount = 1; size_t currentbin = 0; while (opencount) { while (!bins[currentbin].size()) { depthlevel++; currentbin++; if (currentbin == static_cast(tulip_bins)) { currentbin = 0; } } SegmentData lineindex = bins[currentbin].back(); bins[currentbin].pop_back(); // opencount--; int ref = lineindex.ref; int dir = (lineindex.dir == 1) ? 0 : 1; int coverage = lineindex.coverage & uncovered[ref][dir]; if (coverage != 0) { int rbin = 0; int rbinbase; if (lineindex.previous.ref != -1) { uncovered[ref][dir] &= ~coverage; while (((coverage >> rbin) & 0x1) == 0) rbin++; rbinbase = rbin; while (rbin < radiussize) { if (((coverage >> rbin) & 0x1) == 1) { audittrail[ref][rbin][dir].depth = depthlevel; audittrail[ref][rbin][dir].previous = lineindex.previous; audittrail[lineindex.previous.ref][rbin][(lineindex.previous.dir == 1) ? 0 : 1].leaf = false; } rbin++; } } else { rbinbase = 0; uncovered[ref][0] &= ~coverage; uncovered[ref][1] &= ~coverage; } Connector &line = map.getConnections()[ref]; float seglength; int extradepth; if (lineindex.dir != -1) { for (auto &segconn : line.m_forward_segconns) { rbin = rbinbase; SegmentRef conn = segconn.first; if ((uncovered[conn.ref][(conn.dir == 1 ? 0 : 1)] & coverage) != 0) { // EF routeweight* if (routeweight_col != -1) { // EF here we do the weighting of the angular cost by the // weight of the next segment // note that the content of the routeweights array is scaled between 0 and 1 and is // reversed // such that: = 1.0-(attributes.getValue(i, routeweight_col)/max_value) extradepth = (int)floor(segconn.second * tulip_bins * 0.5 * routeweights[conn.ref]); } //*EF routeweight else { extradepth = (int)floor(segconn.second * tulip_bins * 0.5); } seglength = lengths[conn.ref]; switch (m_radius_type) { case Options::RADIUS_ANGULAR: while (rbin != radiussize && radius[rbin] != -1 && depthlevel + extradepth > (int)radius[rbin]) { rbin++; } break; case Options::RADIUS_METRIC: while (rbin != radiussize && radius[rbin] != -1 && lineindex.metricdepth + seglength * 0.5 > radius[rbin]) { rbin++; } break; case Options::RADIUS_STEPS: if (rbin != radiussize && radius[rbin] != -1 && lineindex.segdepth >= (int)radius[rbin]) { rbin++; } break; } if ((coverage >> rbin) != 0) { SegmentData sd(conn, SegmentRef(1, lineindex.ref), lineindex.segdepth + 1, lineindex.metricdepth + seglength, (coverage >> rbin) << rbin); size_t bin = (currentbin + tulip_bins + extradepth) % tulip_bins; depthmapX::insert_sorted(bins[bin], sd); opencount++; } } } } if (lineindex.dir != 1) { for (auto &segconn : line.m_back_segconns) { rbin = rbinbase; SegmentRef conn = segconn.first; if ((uncovered[conn.ref][(conn.dir == 1 ? 0 : 1)] & coverage) != 0) { // EF routeweight* if (routeweight_col != -1) { // EF here we do the weighting of the angular cost by the // weight of the next segment // note that the content of the routeweights array is scaled between 0 and 1 and is // reversed // such that: = 1.0-(attributes.getValue(i, routeweight_col)/max_value) extradepth = (int)floor(segconn.second * tulip_bins * 0.5 * routeweights[conn.ref]); } //*EF routeweight else { extradepth = (int)floor(segconn.second * tulip_bins * 0.5); } seglength = lengths[conn.ref]; switch (m_radius_type) { case Options::RADIUS_ANGULAR: while (rbin != radiussize && radius[rbin] != -1 && depthlevel + extradepth > (int)radius[rbin]) { rbin++; } break; case Options::RADIUS_METRIC: while (rbin != radiussize && radius[rbin] != -1 && lineindex.metricdepth + seglength * 0.5 > radius[rbin]) { rbin++; } break; case Options::RADIUS_STEPS: if (rbin != radiussize && radius[rbin] != -1 && lineindex.segdepth >= (int)radius[rbin]) { rbin++; } break; } if ((coverage >> rbin) != 0) { SegmentData sd(conn, SegmentRef(-1, lineindex.ref), lineindex.segdepth + 1, lineindex.metricdepth + seglength, (coverage >> rbin) << rbin); size_t bin = (currentbin + tulip_bins + extradepth) % tulip_bins; depthmapX::insert_sorted(bins[bin], sd); opencount++; } } } } } } // set the attributes for this node: for (int k = 0; k < radiussize; k++) { // note, curs_total_depth must use double as mantissa can get too long for int in large systems double curs_node_count = 0.0, curs_total_depth = 0.0; double curs_total_weight = 0.0, curs_total_weighted_depth = 0.0; size_t j; for (j = 0; j < map.getConnections().size(); j++) { // find dir according bool m0 = ((uncovered[j][0] >> k) & 0x1) == 0; bool m1 = ((uncovered[j][1] >> k) & 0x1) == 0; if ((m0 | m1) != 0) { int dir; if (m0 & m1) { // dir is the one with the lowest depth: if (audittrail[j][k][0].depth < audittrail[j][k][1].depth) dir = 0; else dir = 1; } else { // dir is simply the one that's filled in: dir = m0 ? 0 : 1; } curs_node_count++; curs_total_depth += audittrail[j][k][dir].depth; curs_total_weight += weights[j]; curs_total_weighted_depth += audittrail[j][k][dir].depth * weights[j]; // if (m_choice && audittrail[j][k][dir].leaf) { // note, graph may be directed (e.g., for one way streets), so both ways must be included from // now on: SegmentRef here = SegmentRef(dir == 0 ? 1 : -1, j); if (here.ref != static_cast(cursor)) { int choicecount = 0; double choiceweight = 0.0; // EFEF* double choiceweight2 = 0.0; //*EFEF while (here.ref != static_cast(cursor)) { // not rowid means not the current root for the path int heredir = (here.dir == 1) ? 0 : 1; // each node has the existing choicecount and choiceweight from previously encountered // nodes added to it audittrail[here.ref][k][heredir].choice += choicecount; // nb, weighted values calculated anyway to save time on 'if' audittrail[here.ref][k][heredir].weighted_choice += choiceweight; // EFEF* audittrail[here.ref][k][heredir].weighted_choice2 += choiceweight2; //*EFEF // if the node hasn't been encountered before, the choicecount and choiceweight is // incremented for all remaining nodes to be encountered on the backwards route from it if (!audittrail[here.ref][k][heredir].choicecovered) { // this node has not been encountered before: this adds the choicecount and weight // for this node, and flags it as visited choicecount++; choiceweight += weights[here.ref] * rootweight; // EFEF* choiceweight2 += weights2[here.ref] * rootweight; // rootweight! //*EFEF audittrail[here.ref][k][heredir].choicecovered = true; // note, for weighted choice, the start and end points have choice added to them: if (m_weighted_measure_col != -1) { audittrail[here.ref][k][heredir].weighted_choice += (weights[here.ref] * rootweight) / 2.0; // EFEF* if (weighting_col2 != -1) { audittrail[here.ref][k][heredir].weighted_choice2 += (weights2[here.ref] * rootweight) / 2.0; // rootweight! } //*EFEF } } here = audittrail[here.ref][k][heredir].previous; } // note, for weighted choice, the start and end points have choice added to them: // (this is the summed weight for all starting nodes encountered in this path) if (m_weighted_measure_col != -1) { audittrail[here.ref][k][(here.dir == 1) ? 0 : 1].weighted_choice += choiceweight / 2.0; // EFEF* if (weighting_col2 != -1) { audittrail[here.ref][k][(here.dir == 1) ? 0 : 1].weighted_choice2 += choiceweight2 / 2.0; } //*EFEF } } } } } double total_depth_conv = curs_total_depth / ((tulip_bins - 1.0f) * 0.5f); double total_weighted_depth_conv = curs_total_weighted_depth / ((tulip_bins - 1.0f) * 0.5f); // row.setValue(count_col[k], float(curs_node_count)); if (curs_node_count > 1) { // for dmap 8 and above, mean depth simply isn't calculated as for radius measures it is meaningless row.setValue(td_col[k], total_depth_conv); if (m_weighted_measure_col != -1) { row.setValue(total_weight_col[k], float(curs_total_weight)); row.setValue(w_td_col[k], float(total_weighted_depth_conv)); } } else { row.setValue(td_col[k], -1); if (m_weighted_measure_col != -1) { row.setValue(total_weight_col[k], -1.0f); row.setValue(w_td_col[k], -1.0f); } } // for dmap 10 an above, integration is included! if (total_depth_conv > 1e-9) { row.setValue(integ_col[k], (float)(curs_node_count * curs_node_count / total_depth_conv)); if (m_weighted_measure_col != -1) { row.setValue(w_integ_col[k], (float)(curs_total_weight * curs_total_weight / total_weighted_depth_conv)); } } else { row.setValue(integ_col[k], -1); if (m_weighted_measure_col != -1) { row.setValue(w_integ_col[k], -1.0f); } } } // processed_rows++; // if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { // interactive is usual Depthmap: throw an exception if cancelled if (interactive) { for (size_t i = 0; i < map.getConnections().size(); i++) { for (size_t j = 0; j < size_t(radiussize); j++) { delete[] audittrail[i][j]; } delete[] audittrail[i]; delete[] uncovered[i]; } delete[] audittrail; delete[] uncovered; throw Communicator::CancelledException(); } else { // in non-interactive mode, retain what's been processed already break; } } comm->CommPostMessage(Communicator::CURRENT_RECORD, cursor); } } } if (m_choice) { for (size_t cursor = 0; cursor < map.getConnections().size(); cursor++) { AttributeRow &row = attributes.getRow(AttributeKey(depthmapX::getMapAtIndex(map.getAllShapes(), cursor)->first)); for (size_t r = 0; r < radius.size(); r++) { // according to Eva's correction, total choice and total weighted choice // should already have been accumulated by radius at this stage double total_choice = audittrail[cursor][r][0].choice + audittrail[cursor][r][1].choice; double total_weighted_choice = audittrail[cursor][r][0].weighted_choice + audittrail[cursor][r][1].weighted_choice; // EFEF* double total_weighted_choice2 = audittrail[cursor][r][0].weighted_choice2 + audittrail[cursor][r][1].weighted_choice2; //*EFEF // normalised choice now excluded for two reasons: // a) not useful measure, b) in parallel calculations, cannot be calculated at this stage // n.b., it is possible through the front end: the new choice takes into account bidirectional routes, // so it should be normalised according to (n-1)(n-2) (maximum possible through routes) not // (n-1)(n-2)/2 the relativised segment length weighted choice equation was // (total_seg_length*total_seg_length-seg_length*seg_length)/2 again, drop the divide by 2 for the new // implementation // // row.setValue(choice_col[r], float(total_choice)); if (m_weighted_measure_col != -1) { row.setValue(w_choice_col[r], float(total_weighted_choice)); // EFEF* if (weighting_col2 != -1) { row.setValue(w_choice_col2[r], float(total_weighted_choice2)); } //*EFEF } } } } for (size_t i = 0; i < map.getConnections().size(); i++) { for (int j = 0; j < radiussize; j++) { delete[] audittrail[i][j]; } delete[] audittrail[i]; delete[] uncovered[i]; } delete[] audittrail; delete[] uncovered; map.setDisplayedAttribute(-2); // <- override if it's already showing if (m_choice) { map.setDisplayedAttribute(choice_col.back()); } else { map.setDisplayedAttribute(td_col.back()); } return processed_rows > 0; } ================================================ FILE: salalib/segmmodules/segmtulip.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/isegment.h" class SegmentTulip : ISegment { private: std::set m_radius_set; bool m_sel_only; int m_tulip_bins; int m_weighted_measure_col; int m_weighted_measure_col2; int m_routeweight_col; int m_radius_type; bool m_choice; bool m_interactive; public: std::string getAnalysisName() const override { return "Tulip Analysis"; } bool run(Communicator *comm, ShapeGraph &map, bool) override; SegmentTulip(std::set radius_set, bool sel_only, int tulip_bins, int weighted_measure_col, int radius_type, bool choice, bool interactive = false, int weighted_measure_col2 = -1, int routeweight_col = -1) : m_radius_set(radius_set), m_sel_only(sel_only), m_tulip_bins(tulip_bins), m_weighted_measure_col(weighted_measure_col), m_radius_type(radius_type), m_choice(choice), m_interactive(interactive), m_weighted_measure_col2(weighted_measure_col2), m_routeweight_col(routeweight_col) {} }; ================================================ FILE: salalib/segmmodules/segmtulipdepth.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/segmmodules/segmtulipdepth.h" #include "genlib/stringutils.h" // revised to use tulip bins for faster analysis of large spaces bool SegmentTulipDepth::run(Communicator *, ShapeGraph &map, bool) { AttributeTable &attributes = map.getAttributeTable(); std::string stepdepth_col_text = "Angular Step Depth"; int stepdepth_col = attributes.insertOrResetColumn(stepdepth_col_text.c_str()); // The original code set tulip_bins to 1024, divided by two and added one // in order to duplicate previous code (using a semicircle of tulip bins) size_t tulip_bins = 513; std::vector covered(map.getConnections().size()); for (size_t i = 0; i < map.getConnections().size(); i++) { covered[i] = false; } std::vector > bins(tulip_bins); int opencount = 0; for (auto& sel: map.getSelSet()) { int row = depthmapX::getMapAtIndex(map.getAllShapes(), sel)->first; if (row != -1) { bins[0].push_back(SegmentData(0,row,SegmentRef(),0,0.0,0)); opencount++; } } int depthlevel = 0; auto binIter = bins.begin(); int currentbin = 0; while (opencount) { while (binIter->empty()) { depthlevel++; binIter++; currentbin++; if (binIter == bins.end()) { binIter = bins.begin(); } } SegmentData lineindex; if (binIter->size() > 1) { // it is slightly slower to delete from an arbitrary place in the bin, // but it is necessary to use random paths to even out the number of times through equal paths int curr = pafrand() % binIter->size(); auto currIter = binIter->begin() + curr; lineindex = *currIter; binIter->erase(currIter); // note: do not clear choice values here! } else { lineindex = binIter->front(); binIter->pop_back(); } opencount--; if (!covered[lineindex.ref]) { covered[lineindex.ref] = true; Connector& line = map.getConnections()[lineindex.ref]; // convert depth from tulip_bins normalised to standard angle // (note the -1) double depth_to_line = depthlevel / ((tulip_bins - 1) * 0.5); map.getAttributeRowFromShapeIndex(lineindex.ref).setValue(stepdepth_col,depth_to_line); int extradepth; if (lineindex.dir != -1) { for (auto& segconn: line.m_forward_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } if (lineindex.dir != 1) { for (auto& segconn: line.m_back_segconns) { if (!covered[segconn.first.ref]) { extradepth = (int) floor(segconn.second * tulip_bins * 0.5); bins[(currentbin + tulip_bins + extradepth) % tulip_bins].push_back( SegmentData(segconn.first,lineindex.ref,lineindex.segdepth+1,0.0,0)); opencount++; } } } } } map.setDisplayedAttribute(-2); // <- override if it's already showing map.setDisplayedAttribute(stepdepth_col); return true; } ================================================ FILE: salalib/segmmodules/segmtulipdepth.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/isegment.h" class SegmentTulipDepth : ISegment { public: std::string getAnalysisName() const override { return "Tulip Analysis"; } bool run(Communicator *, ShapeGraph &map, bool) override; }; ================================================ FILE: salalib/shapemap.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #include "salalib/shapemap.h" #include "salalib/attributetable.h" #include "salalib/attributetablehelpers.h" #include "salalib/mgraph.h" // purely for the version info --- as phased out should replace #include "salalib/parsers/mapinfodata.h" // for mapinfo interface #include "genlib/comm.h" // for communicator #include "genlib/containerutils.h" #include "genlib/exceptions.h" #include "genlib/stringutils.h" #include #include #include #include #include #include #include #ifndef _WIN32 #define _finite finite #endif static const double TOLERANCE_A = 1e-9; // import TOLERANCE_B from axial map... static const double TOLERANCE_B = 1e-12; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool SalaShape::read(std::istream &stream) { // defaults m_draworder = -1; m_selected = false; stream.read((char *)&m_type, sizeof(m_type)); stream.read((char *)&m_region, sizeof(m_region)); stream.read((char *)&m_centroid, sizeof(m_centroid)); stream.read((char *)&m_area, sizeof(m_area)); stream.read((char *)&m_perimeter, sizeof(m_perimeter)); dXreadwrite::readIntoVector(stream, m_points); return true; } bool SalaShape::write(std::ofstream &stream) { stream.write((char *)&m_type, sizeof(m_type)); stream.write((char *)&m_region, sizeof(m_region)); stream.write((char *)&m_centroid, sizeof(m_centroid)); stream.write((char *)&m_area, sizeof(m_area)); stream.write((char *)&m_perimeter, sizeof(m_perimeter)); dXreadwrite::writeVector(stream, m_points); return true; } void SalaShape::setCentroidAreaPerim() { m_area = 0.0; m_perimeter = 0.0; m_centroid = Point2f(0, 0); for (size_t i = 0; i < m_points.size(); i++) { Point2f &p1 = m_points[i]; Point2f &p2 = m_points[(i + 1) % m_points.size()]; double a_i = (p1.x * p2.y - p2.x * p1.y) / 2.0; m_area += a_i; a_i /= 6.0; m_centroid.x += (p1.x + p2.x) * a_i; m_centroid.y += (p1.y + p2.y) * a_i; Point2f side = p2 - p1; m_perimeter += side.length(); } m_type &= ~SHAPE_CCW; if (sgn(m_area) == 1) { m_type |= SHAPE_CCW; } m_centroid.scale(2.0 / m_area); // note, *not* fabs(m_area) as it is then confused by clockwise ordered shapes m_area = fabs(m_area); if (isOpen()) { // take off the automatically collected final side Point2f side = m_points.back() - m_points.front(); m_perimeter -= side.length(); } } // allows override of the above (used for isovists) void SalaShape::setCentroid(const Point2f &p) { m_centroid = p; } // get the angular deviation along the length of a poly line: double SalaShape::getAngDev() const { double dev = 0.0; for (size_t i = 1; i < m_points.size() - 1; i++) { double ang = angle(m_points[i - 1], m_points[i], m_points[i + 1]); // Quick mod - TV #if defined(_MSC_VER) dev += abs(M_PI - ang); #else (M_PI - ang) < 0.0 ? dev += (ang - M_PI) : dev += (M_PI - ang); #endif } // convert to Iida Hillier units (0 to 2): dev /= M_PI * 0.5; return dev; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // the replacement for datalayers ShapeMap::ShapeMap(const std::string &name, int type) : m_pixel_shapes(0, 0), m_attributes(new AttributeTable()), m_attribHandle(new AttributeTableHandle(*m_attributes)) { m_name = name; m_map_type = type; m_hasgraph = false; // shape and object counters m_obj_ref = -1; // -1 is the shape ref column (which will be shown by default) m_displayed_attribute = -1; m_invalidate = false; // for polygons: m_show_lines = true; m_show_fill = true; m_show_centroids = false; // data (MUST be set before use) m_tolerance = 0.0; // note show is m_show = true; m_editable = false; m_bsp_tree = false; m_bsp_root = NULL; // m_hasMapInfoData = false; } ShapeMap::~ShapeMap() { if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } } ////////////////////////////////////////////////////////////////////////////////////////// // this can be reinit as well void ShapeMap::init(int size, const QtRegion &r) { m_display_shapes.clear(); m_rows = __min(__max(20, (int)sqrt((double)size)), 32768); m_cols = __min(__max(20, (int)sqrt((double)size)), 32768); if (m_region.atZero()) { m_region = r; } else { m_region = runion(m_region, r); } // calculate geom data: m_tolerance = __max(m_region.width(), m_region.height()) * TOLERANCE_A; // m_pixel_shapes = depthmapX::ColumnMatrix>(m_rows, m_cols); } // this makes an exact copy, keep the reference numbers and so on: void ShapeMap::copy(const ShapeMap &sourcemap, int copyflags) { if ((copyflags & ShapeMap::COPY_GEOMETRY) == ShapeMap::COPY_GEOMETRY) { m_shapes.clear(); init(sourcemap.m_shapes.size(), sourcemap.m_region); for (auto shape : sourcemap.m_shapes) { // using makeShape is actually easier than thinking about a total copy: makeShape(shape.second, shape.first); // note that addShape automatically adds the attribute row } } if ((copyflags & ShapeMap::COPY_ATTRIBUTES) == ShapeMap::COPY_ATTRIBUTES) { // assumes attribute rows are filled in already // TODO: Compatibility. The columns are sorted in the old implementation so // they are also passed sorted in the conversion: std::vector indices(sourcemap.m_attributes->getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return sourcemap.m_attributes->getColumnName(a) < sourcemap.m_attributes->getColumnName(b); }); for (int idx : indices) { int outcol = m_attributes->insertOrResetColumn(sourcemap.m_attributes->getColumnName(idx)); // n.b. outcol not necessarily the same as incol, although row position in table (j) should match auto targetIter = m_attributes->begin(); for (auto sourceIter = sourcemap.m_attributes->begin(); sourceIter != sourcemap.m_attributes->end(); sourceIter++) { targetIter->getRow().setValue(outcol, sourceIter->getRow().getValue(idx)); targetIter++; } } } if ((copyflags & ShapeMap::COPY_ATTRIBUTES) == ShapeMap::COPY_GRAPH) { if (sourcemap.m_hasgraph) { m_hasgraph = true; // straight copy: m_connectors = sourcemap.m_connectors; m_links = sourcemap.m_links; m_unlinks = sourcemap.m_unlinks; } } // copies mapinfodata (projection data) regardless of copy flags if (sourcemap.hasMapInfoData()) { m_mapinfodata = MapInfoData(); m_mapinfodata.m_coordsys = sourcemap.getMapInfoData().m_coordsys; m_mapinfodata.m_bounds = sourcemap.getMapInfoData().m_bounds; m_hasMapInfoData = true; } } // Zaps all memory structures, apart from mapinfodata void ShapeMap::clearAll() { if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_display_shapes.clear(); m_shapes.clear(); m_undobuffer.clear(); m_connectors.clear(); m_attributes->clear(); m_links.clear(); m_unlinks.clear(); m_region = QtRegion(); m_obj_ref = -1; m_displayed_attribute = -1; } /////////////////////////////////////////////////////////////////////////////////////////// int ShapeMap::makePointShapeWithRef(const Point2f &point, int shape_ref, bool tempshape, const std::map &extraAttributes) { bool bounds_good = true; if (!m_region.contains_touch(point)) { bounds_good = false; init(m_shapes.size(), QtRegion(point, point)); } m_shapes.insert(std::make_pair(shape_ref, SalaShape(point))); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } if (!tempshape) { auto &row = m_attributes->addRow(AttributeKey(shape_ref)); for (auto &attr : extraAttributes) { row.setValue(attr.first, attr.second); } m_newshape = true; } return shape_ref; } int ShapeMap::makePointShape(const Point2f &point, bool tempshape, const std::map &extraAttributes) { return makePointShapeWithRef(point, getNextShapeKey(), tempshape, extraAttributes); } int ShapeMap::makeLineShapeWithRef(const Line &line, int shape_ref, bool through_ui, bool tempshape, const std::map &extraAttributes) { // note, map must have editable flag on if we are to make a shape through the user interface: if (through_ui && !m_editable) { return -1; } bool bounds_good = true; if (!(m_region.contains_touch(line.start()) && m_region.contains_touch(line.end()))) { bounds_good = false; init(m_shapes.size(), line); } // note, shape constructor sets centroid, length etc m_shapes.insert(std::make_pair(shape_ref, SalaShape(line))); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } if (!tempshape) { auto &row = m_attributes->addRow(AttributeKey(shape_ref)); for (auto &attr : extraAttributes) { row.setValue(attr.first, attr.second); } m_newshape = true; } if (through_ui) { // manually add connections: if (m_hasgraph) { int rowid = depthmapX::findIndexFromKey(m_shapes, shape_ref); if (isAxialMap()) { connectIntersected(rowid, true); // "true" means line-line intersections only will be applied } else { connectIntersected(rowid, false); } } // if through ui, set undo counter: m_undobuffer.push_back(SalaEvent(SalaEvent::SALA_CREATED, shape_ref)); // update displayed attribute if through ui: invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); } return shape_ref; } int ShapeMap::getNextShapeKey() { if (m_shapes.size() == 0) return 0; return m_shapes.rbegin()->first + 1; } int ShapeMap::makeLineShape(const Line &line, bool through_ui, bool tempshape, const std::map &extraAttributes) { return makeLineShapeWithRef(line, getNextShapeKey(), through_ui, tempshape, extraAttributes); } int ShapeMap::makePolyShapeWithRef(const std::vector &points, bool open, int shape_ref, bool tempshape, const std::map &extraAttributes) { bool bounds_good = true; switch (points.size()) { case 0: return -1; case 1: return makePointShapeWithRef(points[0], shape_ref, tempshape); case 2: return makeLineShapeWithRef(Line(points[0], points[1]), shape_ref, false, tempshape); // false is not through ui: there really should be a through ui here? } QtRegion region(points[0], points[0]); size_t i; for (i = 1; i < points.size(); i++) { region.encompass(points[i]); } if (!m_region.contains_touch(region.bottom_left) || !m_region.contains_touch(region.top_right)) { bounds_good = false; init(m_shapes.size(), region); } size_t len = points.size(); // NOTE: This is commented out deliberately // Sometimes you really do want a polyline that forms a loop /* if (points.head() == points.tail()) { len--; open = false; } */ // not sure if it matters if the polygon is clockwise or anticlockwise... we'll soon tell! if (open) { m_shapes.insert(std::make_pair(shape_ref, SalaShape(SalaShape::SHAPE_POLY))); } else { m_shapes.insert(std::make_pair(shape_ref, SalaShape(SalaShape::SHAPE_POLY | SalaShape::SHAPE_CLOSED))); } for (i = 0; i < len; i++) { m_shapes.rbegin()->second.m_points.push_back(points[i]); } if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } if (!tempshape) { // set centroid now also adds a few other things: as well as area, perimeter m_shapes.rbegin()->second.setCentroidAreaPerim(); auto &row = m_attributes->addRow(AttributeKey(shape_ref)); for (auto &attr : extraAttributes) { row.setValue(attr.first, attr.second); } m_newshape = true; } return shape_ref; } int ShapeMap::makePolyShape(const std::vector &points, bool open, bool tempshape, const std::map &extraAttributes) { return makePolyShapeWithRef(points, open, getNextShapeKey(), tempshape, extraAttributes); } int ShapeMap::makeShape(const SalaShape &poly, int override_shape_ref, const std::map &extraAttributes) { // overridden shape cannot exist: if (override_shape_ref != -1 && m_shapes.find(override_shape_ref) != m_shapes.end()) { return -1; // failure! } bool bounds_good = true; if (!m_region.contains_touch(poly.m_region.bottom_left) || !m_region.contains_touch(poly.m_region.top_right)) { bounds_good = false; init(m_shapes.size(), poly.m_region); } int shape_ref; if (override_shape_ref == -1) { shape_ref = getNextShapeKey(); } else { shape_ref = override_shape_ref; } m_shapes.insert(std::make_pair(shape_ref, poly)); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } auto &row = m_attributes->addRow(AttributeKey(shape_ref)); for (auto &attr : extraAttributes) { row.setValue(attr.first, attr.second); } m_newshape = true; return shape_ref; } ////////////////////////////////////////////////////////////////////////////////////////// // n.b., only works from current selection (and uses point selected attribute) int ShapeMap::makeShapeFromPointSet(const PointMap &pointmap) { bool bounds_good = true; PixelRefVector selset; Point2f offset = Point2f(pointmap.getSpacing() / 2, pointmap.getSpacing() / 2); for (auto &sel : pointmap.getSelSet()) { selset.push_back(sel); if (!m_region.contains_touch(pointmap.depixelate(sel) - offset) || !m_region.contains_touch(pointmap.depixelate(sel) + offset)) { bounds_good = false; } } if (!bounds_good) { QtRegion r(pointmap.getRegion().bottom_left - offset, pointmap.getRegion().top_right + offset); init(m_shapes.size(), r); } std::map relations; for (size_t j = 0; j < selset.size(); j++) { PixelRef pix = selset[j]; auto relation = relations.insert(std::make_pair(pix, ShapeRef::SHAPE_EDGE)); if (pointmap.includes(pix.right()) && pointmap.getPoint(pix.right()).selected()) { relation.first->second &= ~ShapeRef::SHAPE_R; } if (pointmap.includes(pix.up()) && pointmap.getPoint(pix.up()).selected()) { relation.first->second &= ~ShapeRef::SHAPE_T; } if (pointmap.includes(pix.down()) && pointmap.getPoint(pix.down()).selected()) { relation.first->second &= ~ShapeRef::SHAPE_B; } if (pointmap.includes(pix.left()) && pointmap.getPoint(pix.left()).selected()) { relation.first->second &= ~ShapeRef::SHAPE_L; } } // now find pixel with SHAPE_B | SHAPE_L PixelRef minpix = NoPixel; for (auto &relation : relations) { if ((relation.second & (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) == (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) { if ((minpix == NoPixel) || (relation.first < (int)minpix)) { minpix = relation.first; } } } // now follow round anticlockwise... SalaShape poly(SalaShape::SHAPE_POLY | SalaShape::SHAPE_CLOSED); pointPixelBorder(pointmap, relations, poly, ShapeRef::SHAPE_L, minpix, minpix, true); for (auto relation : relations) { if (relation.second != 0) { // more than one shape! return -1; } } poly.setCentroidAreaPerim(); int new_shape_ref = getNextShapeKey(); m_shapes.insert(std::make_pair(new_shape_ref, poly)); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(new_shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } m_attributes->addRow(AttributeKey(new_shape_ref)); m_newshape = true; return new_shape_ref; } /////////////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::convertPointsToPolys(double poly_radius, bool selected_only) { // I'm not sure quite how easy this will be... QtRegion region; bool done_something = false; // replace the points with polys for (auto shape : m_shapes) { if (selected_only && !m_attributes->getRow(AttributeKey(shape.first)).isSelected()) { continue; } if (shape.second.isPoint()) { done_something = true; // remove old spatial index removePolyPixels(shape.first); // construct a poly from the point: Point2f p = shape.second.getCentroid(); // if (region.atZero()) { region = QtRegion(p, p); } // replace with a polygon: shape.second = SalaShape(SalaShape::SHAPE_POLY | SalaShape::SHAPE_CLOSED); for (int k = 0; k < 8; k++) { Point2f poly_p; if (k == 0) { poly_p.x = p.x + poly_radius; poly_p.y = p.y; } else if (k == 1) { poly_p.x = p.x + poly_radius * M_ROOT_1_2; poly_p.y = p.y + poly_radius * M_ROOT_1_2; } else if (k == 2) { poly_p.x = p.x; poly_p.y = p.y + poly_radius; } else if (k == 3) { poly_p.x = p.x - poly_radius * M_ROOT_1_2; poly_p.y = p.y + poly_radius * M_ROOT_1_2; } else if (k == 4) { poly_p.x = p.x - poly_radius; poly_p.y = p.y; } else if (k == 5) { poly_p.x = p.x - poly_radius * M_ROOT_1_2; poly_p.y = p.y - poly_radius * M_ROOT_1_2; } else if (k == 6) { poly_p.x = p.x; poly_p.y = p.y - poly_radius; } else if (k == 7) { poly_p.x = p.x + poly_radius * M_ROOT_1_2; poly_p.y = p.y - poly_radius * M_ROOT_1_2; } region.encompass(poly_p); shape.second.m_points.push_back(poly_p); } shape.second.setCentroidAreaPerim(); } } if (done_something) { // spatially reindex (simplest just to redo everything) init(m_shapes.size(), region); for (auto shape : m_shapes) { makePolyPixels(shape.first); } } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::moveShape(int shaperef, const Line &line, bool undoing) { bool bounds_good = true; auto shapeIter = m_shapes.find(shaperef); if (shapeIter == m_shapes.end()) { return false; } // remove shape from the pixel grid removePolyPixels(shaperef); // done first, as all interface references use this list if (!undoing) { // set undo counter, but only if this is not an undo itself: m_undobuffer.push_back(SalaEvent(SalaEvent::SALA_MOVED, shaperef)); m_undobuffer.back().m_geometry = shapeIter->second; m_undobuffer.back().m_geometry.m_selected = false; // <- this m_selected really shouldn't be used -- should use attributes, but for some reason it is! } if (!(m_region.contains_touch(line.start()) && m_region.contains_touch(line.end()))) { bounds_good = false; init(m_shapes.size(), line); } shapeIter->second = SalaShape(line); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shaperef); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } int rowid = std::distance(m_shapes.begin(), shapeIter); AttributeRow &row = m_attributes->getRow(AttributeKey(shapeIter->first)); // change connections: if (m_hasgraph) { // const std::vector oldconnections = m_connectors[size_t(rowid)].m_connections; // int conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); int leng_col = -1; // if (isAxialMap()) { // line connections optimised for line-line intersection m_connectors[size_t(rowid)].m_connections = getLineConnections(shaperef, TOLERANCE_B * __max(m_region.height(), m_region.width())); } else { m_connectors[size_t(rowid)].m_connections = getShapeConnections(shaperef, TOLERANCE_B * __max(m_region.height(), m_region.width())); } std::vector &newconnections = m_connectors[size_t(rowid)].m_connections; row.setValue(conn_col, float(newconnections.size())); if (isAxialMap()) { leng_col = m_attributes->getOrInsertLockedColumn("Line Length"); row.setValue(leng_col, (float)depthmapX::getMapAtIndex(m_shapes, rowid)->second.getLength()); } // // now go through our old connections, and remove ourself: for (int oldconnection : oldconnections) { if (oldconnection != rowid) { // <- exclude self! auto &connections = m_connectors[size_t(oldconnection)].m_connections; depthmapX::findAndErase(connections, rowid); auto &oldConnectionRow = getAttributeRowFromShapeIndex(oldconnection); oldConnectionRow.incrValue(conn_col, -1.0f); } } // now go through our new connections, and add ourself: for (int newconnection : m_connectors[size_t(rowid)].m_connections) { if (newconnection != rowid) { // <- exclude self! depthmapX::insert_sorted(m_connectors[size_t(newconnection)].m_connections, rowid); auto &newConnectionRow = getAttributeRowFromShapeIndex(newconnection); newConnectionRow.incrValue(conn_col); } } // now check any unlinks still exist in our newconnections are unlinked again (argh...) for (auto revIter = m_unlinks.rbegin(); revIter != m_unlinks.rend(); ++revIter) { int connb = -1; if (revIter->a == rowid) connb = revIter->b; else if (revIter->b == rowid) connb = revIter->a; if (connb != -1) { if (std::find(newconnections.begin(), newconnections.end(), connb) == newconnections.end()) { // no longer required: m_unlinks.erase(std::next(revIter).base()); } else { // enforce: depthmapX::findAndErase(newconnections, connb); depthmapX::findAndErase(m_connectors[size_t(connb)].m_connections, rowid); auto &connbRow = getAttributeRowFromShapeIndex(connb); connbRow.incrValue(conn_col, -1.0f); row.incrValue(conn_col, -1.0f); } } } // now check any links are actually required (argh...) for (auto revIter = m_links.rbegin(); revIter != m_links.rend(); ++revIter) { int connb = -1; if (revIter->a == rowid) connb = revIter->b; else if (revIter->b == rowid) connb = revIter->a; if (connb != -1) { if (std::find(newconnections.begin(), newconnections.end(), connb) != newconnections.end()) { // no longer required: m_links.erase(std::next(revIter).base()); } else { // enforce: depthmapX::insert_sorted(newconnections, connb); depthmapX::insert_sorted(m_connectors[size_t(connb)].m_connections, rowid); auto &connbRow = getAttributeRowFromShapeIndex(connb); connbRow.incrValue(conn_col); row.incrValue(conn_col); } } } // update displayed attribute for any changes: invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); } return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////// // some functions to make a polygon from the UI int ShapeMap::polyBegin(const Line &line) { // add geometry bool bounds_good = true; if (!(m_region.contains_touch(line.start()) && m_region.contains_touch(line.end()))) { bounds_good = false; init(m_shapes.size(), line); } int new_shape_ref = getNextShapeKey(); m_shapes.insert(std::make_pair(new_shape_ref, SalaShape(line))); m_shapes.rbegin()->second.m_centroid = line.getCentre(); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(new_shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } // insert into attributes m_attributes->addRow(AttributeKey(new_shape_ref)); // would usually set attributes here, but actually, really want // to set the attributes only when the user completes the drawing // change connections: if (m_hasgraph) { // dummy for now to ensure there is a row in the connector table // so all indices match... m_connectors.push_back(Connector()); } // flag new shape m_newshape = true; // set undo counter: m_undobuffer.push_back(SalaEvent(SalaEvent::SALA_CREATED, new_shape_ref)); // update displayed attribute invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); return new_shape_ref; } bool ShapeMap::polyAppend(int shape_ref, const Point2f &point) { // don't do anything too complex: SalaShape &shape = m_shapes.rbegin()->second; // check you can actually do this first if (!(shape.isLine() || shape.isPolyLine())) { return false; } // junk the old shape pixels: removePolyPixels(shape_ref); bool bounds_good = true; if (!m_region.contains_touch(point)) { bounds_good = false; init(m_shapes.size(), QtRegion(point, point)); } if (shape.m_type == SalaShape::SHAPE_LINE) { // convert it to a poly line: shape.m_type = SalaShape::SHAPE_POLY; shape.m_points.push_back(shape.m_region.t_start()); shape.m_points.push_back(shape.m_region.t_end()); } // add new point: shape.m_points.push_back(point); if (bounds_good) { // note: also sets polygon bounding box: makePolyPixels(shape_ref); } else { // pixelate all polys in the pixel new structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } } shape.setCentroidAreaPerim(); return true; } bool ShapeMap::polyClose(int shape_ref) { // don't do anything too complex: SalaShape &shape = m_shapes.rbegin()->second; // check you can actually do this first if (!shape.isPolyLine()) { return false; } // junk the old shape pixels: removePolyPixels(shape_ref); shape.m_type |= SalaShape::SHAPE_CLOSED; makePolyPixels(shape_ref); return true; } bool ShapeMap::polyCancel(int shape_ref) { // don't do anything too complex: SalaShape &shape = m_shapes.rbegin()->second; // check you can actually do this first if (!(shape.isLine() || shape.isPolyLine())) { return false; } m_undobuffer.pop_back(); removeShape(shape_ref, true); // update displayed attribute invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::removeSelected() { // note, map must have editable flag on if we are to remove shape: if (!m_editable) { return false; } // pray that the selection set is in order! // (it should be: code currently uses add() throughout) for (auto &shapeRef : m_selection_set) { removeShape(shapeRef); } m_selection_set.clear(); invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); return true; } void ShapeMap::removeShape(int shaperef, bool undoing) { // remove shape from four keys: the pixel grid, the poly list, the attributes and the connections removePolyPixels(shaperef); // done first, as all interface references use this list auto shapeIter = m_shapes.find(shaperef); size_t rowid = std::distance(m_shapes.begin(), shapeIter); if (!undoing) { // <- if not currently undoing another event, then add to the undo buffer: m_undobuffer.push_back(SalaEvent(SalaEvent::SALA_DELETED, shaperef)); m_undobuffer.back().m_geometry = shapeIter->second; m_undobuffer.back().m_geometry.m_selected = false; // <- this m_selected really shouldn't be used -- should use attributes, but for some reason it is! } if (m_hasgraph) { // note that the connections have no key for speed when processing, // we rely on the index order matching the index order of the shapes // and the attributes, and simply change all references (ick!) int conn_col = m_attributes->getColumnIndex("Connectivity"); // TODO: Replace with iterators for (size_t i = m_connectors.size() - 1; static_cast(i) != -1; i--) { if (i == rowid) { continue; // it's going to be removed anyway } for (size_t j = m_connectors[i].m_connections.size() - 1; static_cast(j) != -1; j--) { if (m_connectors[i].m_connections[j] == int(rowid)) { m_connectors[i].m_connections.erase(m_connectors[i].m_connections.begin() + int(j)); if (conn_col != -1) { auto &row = getAttributeRowFromShapeIndex(i); row.incrValue(conn_col, -1.0f); } } else if (m_connectors[i].m_connections[j] > int(rowid)) { m_connectors[i].m_connections[j] -= 1; } } // note, you cannot delete from a segment map, it's just too messy! } m_connectors.erase(m_connectors.begin() + int(rowid)); // take out explicit links and unlinks (note, undo won't restore these): for (auto revIter = m_links.rbegin(); revIter != m_links.rend(); ++revIter) { if (revIter->a == static_cast(rowid) || revIter->b == static_cast(rowid)) { m_links.erase(std::next(revIter).base()); } else { if (revIter->a > int(rowid)) revIter->a -= 1; if (revIter->b > int(rowid)) revIter->b -= 1; } } for (auto revIter = m_unlinks.rbegin(); revIter != m_unlinks.rend(); ++revIter) { if (revIter->a == static_cast(rowid) || revIter->b == static_cast(rowid)) { m_unlinks.erase(std::next(revIter).base()); } else { if (revIter->a > int(rowid)) revIter->a -= 1; if (revIter->b > int(rowid)) revIter->b -= 1; } } } if (shapeIter != m_shapes.end()) { shapeIter = m_shapes.erase(shapeIter); } // n.b., shaperef should have been used to create the row in the first place: const AttributeKey shapeRefKey(shaperef); m_attributes->removeRow(shapeRefKey); m_newshape = true; m_invalidate = true; } void ShapeMap::undo() { if (m_undobuffer.size() == 0) { return; } SalaEvent &event = m_undobuffer.back(); if (event.m_action == SalaEvent::SALA_CREATED) { removeShape( event.m_shape_ref, true); // <- note, must tell remove shape it's an undo, or it will add this remove to the undo stack! } else if (event.m_action == SalaEvent::SALA_DELETED) { makeShape(event.m_geometry, event.m_shape_ref); int rowid = std::distance(m_shapes.begin(), m_shapes.find(event.m_shape_ref)); auto &row = m_attributes->getRow(AttributeKey(event.m_shape_ref)); if (rowid != -1 && m_hasgraph) { // redo connections... n.b. TO DO this is intended to use the slower "any connection" method, so it can // handle any sort of graph // ...but that doesn't exist yet, so for the moment do lines: // // insert new connector at the row: m_connectors[rowid] = Connector(); // // now go through all connectors, ensuring they're reindexed above this one: // Argh! ...but, remember the reason we're doing this is for fast processing elsewhere // -- this is a user triggered *undo*, they'll just have to wait: for (size_t i = 0; i < m_connectors.size(); i++) { for (size_t j = 0; j < m_connectors[i].m_connections.size(); j++) { if (m_connectors[i].m_connections[j] >= rowid) { m_connectors[i].m_connections[j] += 1; } } } // it gets worse, the links and unlinks will also be all over the shop due to the inserted row: size_t j; for (j = 0; j < m_links.size(); j++) { if (m_links[j].a >= rowid) m_links[j].a += 1; if (m_links[j].b >= rowid) m_links[j].b += 1; } for (j = 0; j < m_unlinks.size(); j++) { if (m_unlinks[j].a >= rowid) m_unlinks[j].a += 1; if (m_unlinks[j].b >= rowid) m_unlinks[j].b += 1; } // // calculate this line's connections m_connectors[size_t(rowid)].m_connections = getLineConnections(event.m_shape_ref, TOLERANCE_B * __max(m_region.height(), m_region.width())); // update: int conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); row.setValue(conn_col, float(m_connectors[rowid].m_connections.size())); // if (event.m_geometry.isLine()) { int leng_col = m_attributes->getOrInsertLockedColumn("Line Length"); row.setValue(leng_col, (float)depthmapX::getMapAtIndex(m_shapes, rowid)->second.getLength()); } // // now go through our connections, and add ourself: const std::vector &connections = m_connectors[size_t(rowid)].m_connections; for (int connection : connections) { if (connection != rowid) { // <- exclude self! depthmapX::insert_sorted(m_connectors[size_t(connection)].m_connections, rowid); auto &row = getAttributeRowFromShapeIndex(connection); row.incrValue(conn_col); } } } } else if (event.m_action == SalaEvent::SALA_MOVED) { moveShape(event.m_shape_ref, event.m_geometry.getLine(), true); // <- note, must tell remove shape it's an undo, or it will add this remove to the undo stack! } m_undobuffer.pop_back(); m_newshape = true; invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); } /////////////////////////////////////////////////////////////////////////////////////////////////////// void ShapeMap::makePolyPixels(int polyref) { ShapeRef shapeRef = ShapeRef(polyref); // first add into pixels, and ensure you have a bl, tr for the set (useful for testing later) SalaShape &poly = m_shapes.find(polyref)->second; if (poly.isClosed()) { std::map relations; for (size_t k = 0; k < poly.m_points.size(); k++) { int nextk = int((k + 1) % poly.m_points.size()); Line li(poly.m_points[k], poly.m_points[nextk]); if (k == 0) { poly.m_region = li; } else { poly.m_region = runion(poly.m_region, li); } PixelRefVector pixels = pixelateLine(li); // debug // int duplicate_shaperefs = 0; // end debug for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); auto it = depthmapX::findBinary(pixShapes, shapeRef); if (it == pixShapes.end()) { pixShapes.push_back(shapeRef); it = pixShapes.end() - 1; } it->m_polyrefs.push_back(k); relations.insert(std::make_pair(pixels[i], ShapeRef::SHAPE_EDGE)); } } // erase joined sides, and look for min: PixelRef minpix = NoPixel; for (auto &relation : relations) { PixelRef pix = relation.first; PixelRef nextpix; nextpix = pix.right(); if (includes(nextpix)) { auto &pixShapes = m_pixel_shapes(static_cast(nextpix.y), static_cast(nextpix.x)); if (depthmapX::findBinary(pixShapes, shapeRef) != pixShapes.end()) { relation.second &= ~ShapeRef::SHAPE_R; } } nextpix = pix.up(); if (includes(nextpix)) { auto &pixShapes = m_pixel_shapes(static_cast(nextpix.y), static_cast(nextpix.x)); if (depthmapX::findBinary(pixShapes, shapeRef) != pixShapes.end()) { relation.second &= ~ShapeRef::SHAPE_T; } } nextpix = pix.down(); if (includes(nextpix)) { auto &pixShapes = m_pixel_shapes(static_cast(nextpix.y), static_cast(nextpix.x)); if (depthmapX::findBinary(pixShapes, shapeRef) != pixShapes.end()) { relation.second &= ~ShapeRef::SHAPE_B; } } nextpix = pix.left(); if (includes(nextpix)) { auto &pixShapes = m_pixel_shapes(static_cast(nextpix.y), static_cast(nextpix.x)); if (depthmapX::findBinary(pixShapes, shapeRef) != pixShapes.end()) { relation.second &= ~ShapeRef::SHAPE_L; } } if ((relation.second & (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) == (ShapeRef::SHAPE_B | ShapeRef::SHAPE_L)) { if ((minpix == NoPixel) || (relation.first < int(minpix))) { minpix = relation.first; } } } shapePixelBorder(relations, polyref, ShapeRef::SHAPE_L, minpix, minpix, true); // go through any that aren't on the outer border: this will be internal edges, and will cause problems // for point in polygon algorithms! for (auto &relation : relations) { PixelRef pix = relation.first; std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); const auto iter = depthmapX::findBinary(pixShapes, shapeRef); if (iter == pixShapes.end()) throw new depthmapX::RuntimeException("Poly reference not found"); unsigned char &tags = iter->m_tags; if (tags == 0x00) { tags |= ShapeRef::SHAPE_INTERNAL_EDGE; } } // now, any remaining tags are internal sides, and need to be cleared through fill // we could go either direction, but we just go left to right: for (auto &relation : relations) { PixelRef pix = relation.first; if (relation.second & ShapeRef::SHAPE_R) { bool lastWasNotFound = true; while (lastWasNotFound) { PixelRef nextpix = pix.right(); if (!includes(nextpix)) { // this shouldn't happen break; } // returns -1 if cannot add due to already existing: lastWasNotFound = false; std::vector &pixelShapes = m_pixel_shapes(static_cast(nextpix.y), static_cast(nextpix.x)); const auto it = depthmapX::findBinary(pixelShapes, shapeRef); if (it == pixelShapes.end()) { lastWasNotFound = true; pixelShapes.push_back(ShapeRef(polyref, ShapeRef::SHAPE_CENTRE)); } pix = nextpix; } } } // Done...! This polygon is registered in the pixel polygon structure } else { // Open shapes much easier! switch (poly.m_type & SalaShape::SHAPE_TYPE) { case SalaShape::SHAPE_POINT: { PixelRef pix = pixelate(poly.m_centroid); std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); const auto it = depthmapX::findBinary(pixShapes, shapeRef); if (it == pixShapes.end()) { pixShapes.push_back(ShapeRef(polyref, ShapeRef::SHAPE_OPEN)); } } break; case SalaShape::SHAPE_LINE: { PixelRefVector pixels = pixelateLine(poly.m_region); for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); const auto it = depthmapX::findBinary(pixShapes, shapeRef); if (it == pixShapes.end()) { pixShapes.push_back(ShapeRef(polyref, ShapeRef::SHAPE_OPEN)); } } } break; case SalaShape::SHAPE_POLY: for (size_t k = 0; k < poly.m_points.size() - 1; k++) { int nextk = (k + 1); Line li(poly.m_points[k], poly.m_points[nextk]); if (k == 0) { poly.m_region = li; } else { poly.m_region = runion(poly.m_region, li); } PixelRefVector pixels = pixelateLine(li); for (size_t i = 0; i < pixels.size(); i++) { PixelRef pix = pixels[i]; std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); auto it = depthmapX::findBinary(pixShapes, shapeRef); if (it == pixShapes.end()) { pixShapes.push_back(ShapeRef(polyref, ShapeRef::SHAPE_OPEN)); it = pixShapes.end() - 1; } it->m_polyrefs.push_back(k); } } break; } } } ///////////////////////////////////////////////////////////////////////////////////////////////// void ShapeMap::shapePixelBorder(std::map &relations, int polyref, int side, PixelRef currpix, PixelRef minpix, bool first) { if (!first && currpix == minpix && side == ShapeRef::SHAPE_L) { // looped: return; } auto relation = relations.find(currpix); if (relation->second & side) { std::vector &pixShapes = m_pixel_shapes(static_cast(currpix.y), static_cast(currpix.x)); const auto iter = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (iter == pixShapes.end()) throw new depthmapX::RuntimeException("Poly reference not found"); iter->m_tags |= side; relation->second &= ~side; // <- clear to check all have been done later side <<= 1; if (side > ShapeRef::SHAPE_T) { side = ShapeRef::SHAPE_L; } shapePixelBorder(relations, polyref, side, currpix, minpix, false); } else { currpix.move(moveDir(side)); side >>= 1; if (side < ShapeRef::SHAPE_L) { side = ShapeRef::SHAPE_T; } shapePixelBorder(relations, polyref, side, currpix, minpix, false); } } // note that this is almost exactly the same as shapePixelBorder void ShapeMap::pointPixelBorder(const PointMap &pointmap, std::map &relations, SalaShape &poly, int side, PixelRef currpix, PixelRef minpix, bool first) { if (!first && currpix == minpix && side == ShapeRef::SHAPE_L) { // looped: return; } auto relation = relations.find(currpix); if (relation->second & side) { poly.m_points.push_back(pointmap.depixelate(currpix) + pointOffset(pointmap, side)); relation->second &= ~side; // <- clear to check all have been done later side <<= 1; if (side > ShapeRef::SHAPE_T) { side = ShapeRef::SHAPE_L; } pointPixelBorder(pointmap, relations, poly, side, currpix, minpix, false); } else { currpix.move(moveDir(side)); side >>= 1; if (side < ShapeRef::SHAPE_L) { side = ShapeRef::SHAPE_T; } pointPixelBorder(pointmap, relations, poly, side, currpix, minpix, false); } } ///////////////////////////////////////////////////////////////////////////////////////////////// void ShapeMap::removePolyPixels(int polyref) { auto shapeIter = m_shapes.find(polyref); if (shapeIter == m_shapes.end()) { return; } SalaShape &poly = shapeIter->second; if (poly.isClosed()) { // easiest just to use scan lines to find internal pixels rather than trace a complex border: PixelRef minpix = pixelate(poly.m_region.bottom_left); PixelRef maxpix = pixelate(poly.m_region.top_right); for (int x = minpix.x; x <= maxpix.x; x++) { for (int y = minpix.y; y <= maxpix.y; y++) { std::vector &pixShapes = m_pixel_shapes(static_cast(y), static_cast(x)); const auto it = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (it != pixShapes.end()) pixShapes.erase(it); } } } else { // open shapes easier still, as no need to find internal pixels: switch (poly.m_type & SalaShape::SHAPE_TYPE) { case SalaShape::SHAPE_POINT: { PixelRef pix = pixelate(poly.m_centroid); std::vector &pixShapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); const auto it = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (it != pixShapes.end()) pixShapes.erase(it); } break; case SalaShape::SHAPE_LINE: { PixelRefVector list = pixelateLine(poly.m_region); for (size_t i = 0; i < list.size(); i++) { std::vector &pixShapes = m_pixel_shapes(static_cast(list[i].y), static_cast(list[i].x)); const auto it = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (it != pixShapes.end()) pixShapes.erase(it); } } break; case SalaShape::SHAPE_POLY: for (size_t k = 0; k < poly.m_points.size() - 1; k++) { size_t nextk = (k + 1); Line li(poly.m_points[k], poly.m_points[nextk]); PixelRefVector list = pixelateLine(li); for (size_t i = 0; i < list.size(); i++) { std::vector &pixShapes = m_pixel_shapes(static_cast(list[i].y), static_cast(list[i].x)); const auto it = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (it != pixShapes.end()) pixShapes.erase(it); } } break; } } } ///////////////////////////////////////////////////////////////////////////////////////////////// int ShapeMap::moveDir(int side) { int dir = PixelRef::NODIR; switch (side) { case ShapeRef::SHAPE_L: dir = PixelRef::NEGHORIZONTAL; break; case ShapeRef::SHAPE_B: dir = PixelRef::NEGVERTICAL; break; case ShapeRef::SHAPE_R: dir = PixelRef::HORIZONTAL; break; case ShapeRef::SHAPE_T: dir = PixelRef::VERTICAL; break; } return dir; } Point2f ShapeMap::pointOffset(const PointMap &pointmap, int side) { Point2f p; switch (side) { case ShapeRef::SHAPE_L: p = Point2f(-pointmap.getSpacing() / 2, 0.0); break; case ShapeRef::SHAPE_B: p = Point2f(0.0, -pointmap.getSpacing() / 2); break; case ShapeRef::SHAPE_R: p = Point2f(pointmap.getSpacing() / 2, 0.0); break; case ShapeRef::SHAPE_T: p = Point2f(0.0, pointmap.getSpacing() / 2); break; } return p; } // Point in poly testing (returns topmost displayed poly) int ShapeMap::pointInPoly(const Point2f &p) const { if (!m_region.contains(p)) { return -1; } std::vector testedshapes; PixelRef pix = pixelate(p); const std::vector &shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); int drawlast = -1; int draworder = -1; for (const ShapeRef &shape : shapes) { auto iter = depthmapX::findBinary(testedshapes, shape.m_shape_ref); if (iter != testedshapes.end()) { continue; } testedshapes.insert(iter, int(shape.m_shape_ref)); int shapeindex = testPointInPoly(p, shape); // if there's a shapeindex, then add: int currentDrawOrder = m_attribHandle->findInIndex(AttributeKey(shape.m_shape_ref)); if (shapeindex != -1 && currentDrawOrder > draworder) { drawlast = shapeindex; draworder = currentDrawOrder; } } return drawlast; } // Point in specific poly (by reference) bool ShapeMap::pointInPoly(const Point2f &p, int polyref) const { PixelRef pix = pixelate(p); const std::vector &shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); const auto iter = depthmapX::findBinary(shapes, ShapeRef(polyref)); if (iter != shapes.end()) { return (testPointInPoly(p, *iter) != -1); } return false; } // similar to above, but builds a list std::vector ShapeMap::pointInPolyList(const Point2f &p) const { std::vector shapeindexlist; if (!m_region.contains(p)) { return shapeindexlist; } std::vector testedshapes; PixelRef pix = pixelate(p); const std::vector &shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); for (const ShapeRef &shape : shapes) { auto iter = depthmapX::findBinary(testedshapes, shape.m_shape_ref); if (iter != testedshapes.end()) { continue; } testedshapes.insert(iter, int(shape.m_shape_ref)); int shapeindex = testPointInPoly(p, shape); // if there's a shapeindex, then add (note it is an add -- you may be passed a list again to expand) if (shapeindex != -1) { shapeindexlist.push_back(shapeindex); } } std::sort(shapeindexlist.begin(), shapeindexlist.end()); return shapeindexlist; } // note, lineref is only used as an "exclude self" test when called from getShapeConnections std::vector ShapeMap::lineInPolyList(const Line &li_orig, size_t lineref, double tolerance) const { std::vector shapeindexlist; if (!intersect_region(m_region, li_orig)) { return shapeindexlist; } Line li = li_orig; if (!m_region.contains(li.start()) || !m_region.contains(li.end())) { li.crop(m_region); } shapeindexlist = pointInPolyList(li.start()); std::vector endShapeIndexList = pointInPolyList(li.end()); shapeindexlist.insert(shapeindexlist.end(), endShapeIndexList.begin(), endShapeIndexList.end()); // only now pixelate and test for any other shapes: PixelRefVector list = pixelateLine(li); for (size_t i = 0; i < list.size(); i++) { PixelRef pix = list[i]; if (includes(pix)) { const std::vector &shapes = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); for (const ShapeRef &shape : shapes) { // slow to do this as it can repeat -- really need to use a linetest like structure to avoid retest of // polygon lines if (shape.m_shape_ref != lineref && shape.m_tags & (ShapeRef::SHAPE_EDGE | ShapeRef::SHAPE_INTERNAL_EDGE | ShapeRef::SHAPE_OPEN)) { auto shapeIter = m_shapes.find(shape.m_shape_ref); const SalaShape &poly = shapeIter->second; switch (poly.m_type & (SalaShape::SHAPE_LINE | SalaShape::SHAPE_POLY)) { case SalaShape::SHAPE_LINE: if (intersect_region(li, poly.m_region)) { // note: in this case m_region is stored as a line: if (intersect_line(li, poly.m_region, tolerance)) { shapeindexlist.push_back(int(std::distance(m_shapes.begin(), shapeIter))); } } break; case SalaShape::SHAPE_POLY: { for (size_t k = 0; k < shape.m_polyrefs.size(); k++) { Line lineb = Line(poly.m_points[shape.m_polyrefs[k]], poly.m_points[((shape.m_polyrefs[k] + 1) % poly.m_points.size())]); if (intersect_region(li, lineb)) { if (intersect_line(li, lineb, tolerance)) { shapeindexlist.push_back(int(std::distance(m_shapes.begin(), shapeIter))); } } } } break; default: break; } } } } } std::sort(shapeindexlist.begin(), shapeindexlist.end()); return shapeindexlist; } std::vector ShapeMap::polyInPolyList(int polyref, double tolerance) const { std::vector shapeindexlist; auto shapeIter = m_shapes.find(polyref); if (shapeIter == m_shapes.end()) { return shapeindexlist; } const SalaShape &poly = shapeIter->second; if (poly.isClosed()) { // <- it ought to be, you shouldn't be using this function if not! std::vector testedlist; // easiest just to use scan lines to find internal pixels rather than trace a complex border: PixelRef minpix = pixelate(poly.m_region.bottom_left); PixelRef maxpix = pixelate(poly.m_region.top_right); // pass one: shape centre of either object coincident automatically adds int x; for (x = minpix.x; x <= maxpix.x; x++) { for (int y = minpix.y; y <= maxpix.y; y++) { const std::vector &pixShapes = m_pixel_shapes(static_cast(y), static_cast(x)); const auto iter = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (iter != pixShapes.end()) { // this has us in it, now looked through everything else: for (const ShapeRef &shapeRef : pixShapes) { if (*iter != shapeRef && ((iter->m_tags & ShapeRef::SHAPE_CENTRE) || (shapeRef.m_tags & ShapeRef::SHAPE_CENTRE))) { auto iter = depthmapX::findBinary(testedlist, shapeRef.m_shape_ref); if (iter == testedlist.end()) { testedlist.insert(iter, shapeRef.m_shape_ref); shapeindexlist.push_back( int(depthmapX::findIndexFromKey(m_shapes, int(shapeRef.m_shape_ref)))); } } } } } } // that was the easy bit... now, pass 2, for non centre things: for (x = minpix.x; x <= maxpix.x; x++) { for (int y = minpix.y; y <= maxpix.y; y++) { const std::vector &pixShapes = m_pixel_shapes(static_cast(y), static_cast(x)); const auto iter = depthmapX::findBinary(pixShapes, ShapeRef(polyref)); if (iter != pixShapes.end()) { const ShapeRef &shaperef = *iter; if ((shaperef.m_tags & ShapeRef::SHAPE_CENTRE) == 0) { // this has us in it, now looked through everything else: for (auto &shaperefb : pixShapes) { auto iter = depthmapX::findBinary(testedlist, shaperefb.m_shape_ref); if (shaperef != shaperefb && iter == testedlist.end()) { auto shapeIter = m_shapes.find(shaperefb.m_shape_ref); size_t indexb = std::distance(m_shapes.begin(), shapeIter); const SalaShape &polyb = shapeIter->second; if (polyb.isPoint()) { if (testPointInPoly(polyb.getPoint(), shaperef) != -1) { shapeindexlist.push_back(int(indexb)); } } else if (polyb.isLine()) { if (testPointInPoly(polyb.getLine().start(), shaperef) != -1 || testPointInPoly(polyb.getLine().end(), shaperef) != -1) { testedlist.insert(iter, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); } else { for (size_t k = 0; k < shaperef.m_polyrefs.size(); k++) { Line line = Line( poly.m_points[shaperef.m_polyrefs[k]], poly.m_points[((shaperef.m_polyrefs[k] + 1) % poly.m_points.size())]); if (intersect_region(line, polyb.getLine())) { if (intersect_line(line, polyb.getLine(), tolerance)) { testedlist.insert(iter, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); break; } } } } } else if (polyb.isPolyLine()) { if (testPointInPoly(polyb.m_points[shaperefb.m_polyrefs[0]], shaperef) != -1) { testedlist.insert(iter, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); } else { for (size_t k = 0; k < shaperef.m_polyrefs.size(); k++) { for (size_t kk = 0; kk < shaperefb.m_polyrefs.size(); kk++) { Line line = Line(poly.m_points[shaperef.m_polyrefs[k]], poly.m_points[((shaperef.m_polyrefs[k] + 1) % poly.m_points.size())]); Line lineb = Line(polyb.m_points[shaperefb.m_polyrefs[kk]], polyb.m_points[((shaperefb.m_polyrefs[kk] + 1) % polyb.m_points.size())]); if (intersect_region(line, lineb)) { if (intersect_line(line, lineb, tolerance)) { auto iterInternal = depthmapX::findBinary(testedlist, shaperefb.m_shape_ref); if (iterInternal == testedlist.end()) { testedlist.insert(iterInternal, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); break; } } } } } } } else { // poly to poly, ick! // first test one entirely inside the other // any point at all will suffice to check this: however, we need to check that the // polyref point *itself* is within the pixel, not just part of the line associated // with it... if ((pixelate(polyb.m_points[shaperefb.m_polyrefs[0]]) == PixelRef(x, y) && testPointInPoly(polyb.m_points[shaperefb.m_polyrefs[0]], shaperef) != -1) || (pixelate(poly.m_points[shaperef.m_polyrefs[0]]) == PixelRef(x, y) && testPointInPoly(poly.m_points[shaperef.m_polyrefs[0]], shaperefb) != -1)) { testedlist.insert(iter, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); } else { // now check crossing bool breakit = false; for (size_t k = 0; k < shaperef.m_polyrefs.size() && !breakit; k++) { for (size_t kk = 0; kk < shaperefb.m_polyrefs.size(); kk++) { Line line = Line(poly.m_points[shaperef.m_polyrefs[k]], poly.m_points[((shaperef.m_polyrefs[k] + 1) % poly.m_points.size())]); Line lineb = Line(polyb.m_points[shaperefb.m_polyrefs[kk]], polyb.m_points[((shaperefb.m_polyrefs[kk] + 1) % polyb.m_points.size())]); if (intersect_region(line, lineb)) { if (intersect_line(line, lineb, tolerance)) { testedlist.insert(iter, shaperefb.m_shape_ref); shapeindexlist.push_back(int(indexb)); breakit = true; break; } } } } } } } } } } } } } else { throw depthmapX::RuntimeException("this function is to be used for polygons only"); } std::sort(shapeindexlist.begin(), shapeindexlist.end()); return shapeindexlist; } std::vector ShapeMap::shapeInPolyList(const SalaShape &shape) // note: no const due to poly in poly testing { std::vector shapeindexlist; if (!intersect_region(m_region, shape.m_region)) { // quick test that actually coincident return shapeindexlist; } if (shape.isPoint()) { shapeindexlist = pointInPolyList(shape.getPoint()); } else if (shape.isLine()) { shapeindexlist = lineInPolyList(shape.getLine()); } else if (shape.isPolyLine()) { for (size_t i = 1; i < shape.m_points.size() - 1; i++) { Line li(shape.m_points[i], shape.m_points[i - 1]); shapeindexlist = lineInPolyList(li); } } else { // first *add* the poly temporarily (note this may grow pixel set): int ref = makePolyShape(shape.m_points, false, true); // false is closed poly, true is temporary shape // do test: shapeindexlist = polyInPolyList(ref); // clean up: removePolyPixels(ref); m_shapes.erase(m_shapes.find(ref)); } return shapeindexlist; } // helper for point in poly -- // currently needs slight rewrite to avoid problem if point is in line with a vertex // (counter incremented twice on touching implies not in poly when is) int ShapeMap::testPointInPoly(const Point2f &p, const ShapeRef &shape) const { auto shapeIter = m_shapes.end(); // simplist: in shape centre if (shape.m_tags & ShapeRef::SHAPE_CENTRE) { shapeIter = m_shapes.find(shape.m_shape_ref); } // check not an open shape (cannot be inside) else if ((shape.m_tags & ShapeRef::SHAPE_OPEN) == 0) { auto tempShapeIter = m_shapes.find(shape.m_shape_ref); const SalaShape &poly = tempShapeIter->second; if (poly.m_region.contains_touch(p)) { // next simplest, on the outside border: int alpha = 0; int counter = 0; int parity = 0; if (shape.m_tags & ShapeRef::SHAPE_EDGE) { // run a test line to the edge: if (shape.m_tags & (ShapeRef::SHAPE_L | ShapeRef::SHAPE_R)) { if (shape.m_tags & ShapeRef::SHAPE_L) { parity = -1; } else if (shape.m_tags & ShapeRef::SHAPE_R) { parity = +1; } for (size_t j = 0; j < shape.m_polyrefs.size(); j++) { Line lineb = Line(poly.m_points[shape.m_polyrefs[j]], poly.m_points[((shape.m_polyrefs[j] + 1) % poly.m_points.size())]); if (lineb.bottom_left.y <= p.y && lineb.top_right.y >= p.y) { // crosses or touches... but we need to check // touching exception: if (lineb.t_start().y == p.y) { if (parity * lineb.t_start().x >= parity * p.x) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.t_end().y == p.y) { if (parity * lineb.t_end().x >= parity * p.x) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't horizontal, so we can find the intersection point: else if (parity * (lineb.grad(XAXIS) * (p.y - lineb.ay()) + lineb.ax()) >= parity * p.x) { counter++; } } } } else { if (shape.m_tags & ShapeRef::SHAPE_B) { parity = -1; } else if (shape.m_tags & ShapeRef::SHAPE_T) { parity = +1; } for (size_t j = 0; j < shape.m_polyrefs.size(); j++) { Line lineb = Line(poly.m_points[shape.m_polyrefs[j]], poly.m_points[((shape.m_polyrefs[j] + 1) % poly.m_points.size())]); if (lineb.bottom_left.x <= p.x && lineb.top_right.x >= p.x) { // crosses or touches... but we need to check // touching exception: if (lineb.top_right.x == p.x) { if (parity * lineb.by() >= parity * p.y) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.bottom_left.x == p.x) { if (parity * lineb.ay() >= parity * p.y) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't vertical, so we can find the intersection point: else if (parity * (lineb.grad(YAXIS) * (p.x - lineb.ax()) + lineb.ay()) >= parity * p.y) { counter++; } } } } if (counter % 2 != 0 && alpha == 0) { shapeIter = tempShapeIter; } } // and now the pig -- it's somewhere in the middle of the poly: else if (shape.m_tags & ShapeRef::SHAPE_INTERNAL_EDGE) { std::vector testnodes; size_t j; for (j = 0; j < size_t(shape.m_polyrefs.size()); j++) { depthmapX::addIfNotExists(testnodes, int(shape.m_polyrefs[j])); } PixelRef pix2 = pixelate(p); pix2.move(PixelRef::NEGVERTICAL); // move pix2 down, search for this shape... const std::vector *pixelShapes = &m_pixel_shapes(static_cast(pix2.y), static_cast(pix2.x)); // bit of code duplication like this, but easier on params to this function: auto iter = std::find(pixelShapes->begin(), pixelShapes->end(), shape.m_shape_ref); while (iter != pixelShapes->end()) { for (size_t k = 0; k < iter->m_polyrefs.size(); k++) { depthmapX::addIfNotExists(testnodes, int(iter->m_polyrefs[k])); } pix2.move(PixelRef::NEGVERTICAL); // move pix2 down, search for this shape... if (includes(pix2)) { pixelShapes = &m_pixel_shapes(static_cast(pix2.y), static_cast(pix2.x)); iter = std::find(pixelShapes->begin(), pixelShapes->end(), shape.m_shape_ref); } else { iter = pixelShapes->end(); } } int alpha = 0; int counter = 0; int parity = -1; for (j = 0; j < testnodes.size(); j++) { Line lineb = Line(poly.m_points[testnodes[j]], poly.m_points[((testnodes[j] + 1) % poly.m_points.size())]); if (lineb.bottom_left.x <= p.x && lineb.top_right.x >= p.x) { // crosses or touches... but we need to check // touching exception: if (lineb.top_right.x == p.x) { if (parity * lineb.by() >= parity * p.y) { alpha -= 1; counter++; } } // the other touching exception else if (lineb.bottom_left.x == p.x) { if (parity * lineb.ay() >= parity * p.y) { alpha += 1; // n.b., no counter here } } // at this stage we know the line isn't vertical, so we can find the intersection point: else if (parity * (lineb.grad(YAXIS) * (p.x - lineb.ax()) + lineb.ay()) >= parity * p.y) { counter++; } } } if (counter % 2 != 0 && alpha == 0) { shapeIter = m_shapes.find(shape.m_shape_ref); } } } } return (shapeIter == m_shapes.end()) ? -1 : std::distance(m_shapes.begin(), shapeIter); // note convert to -1 } // also note that you may want to find a close poly line or point // if you can't find a point in poly (or even if you can) // (see also getClosestVertex below) // returns a rowid *not* a shape key int ShapeMap::getClosestOpenGeom(const Point2f &p) const { if (!m_region.contains(p)) { return -1; } PixelRef pix = pixelate(p); auto shapeIter = m_shapes.end(); double mindist = -1; const std::vector &shapeRefs = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); for (const ShapeRef &ref : shapeRefs) { if (ref.m_tags & ShapeRef::SHAPE_OPEN) { double thisdist = -1.0; auto tempShapeIter = m_shapes.find(ref.m_shape_ref); const SalaShape &poly = tempShapeIter->second; switch (poly.m_type) { case SalaShape::SHAPE_POINT: thisdist = dist(p, poly.m_centroid); case SalaShape::SHAPE_LINE: thisdist = dist(p, poly.m_region); // note, in this case m_region is a line break; case SalaShape::SHAPE_POLY: case SalaShape::SHAPE_POLY | SalaShape::SHAPE_CCW: // note CCW should never have happened, but it has for (size_t j = 0; j < ref.m_polyrefs.size(); j++) { Line line(poly.m_points[ref.m_polyrefs[j]], poly.m_points[ref.m_polyrefs[j] + 1]); double tempthisdist = dist(p, line); if (tempthisdist != -1 && (thisdist == -1 || tempthisdist < thisdist)) { thisdist = tempthisdist; } } break; } if (thisdist != -1.0 && (mindist == -1 || thisdist < mindist)) { mindist = thisdist; shapeIter = tempShapeIter; } } } return (shapeIter == m_shapes.end()) ? -1 : std::distance(m_shapes.begin(), shapeIter); // note conversion to -1 } Point2f ShapeMap::getClosestVertex(const Point2f &p) const { Point2f vertex; // null by default if (!m_region.contains(p)) { return vertex; // will be null in this case } PixelRef pix = pixelate(p); double mindist = -1.0; const std::vector &shapeRefs = m_pixel_shapes(static_cast(pix.y), static_cast(pix.x)); for (const ShapeRef &ref : shapeRefs) { double thisdist = -1.0; Point2f thisvertex; const SalaShape &poly = m_shapes.find(ref.m_shape_ref)->second; switch (poly.m_type) { case SalaShape::SHAPE_POINT: thisvertex = poly.m_centroid; thisdist = dist(p, thisvertex); break; case SalaShape::SHAPE_LINE: { double d1 = dist(p, poly.m_region.start()); double d2 = dist(p, poly.m_region.end()); if (d1 < d2) { thisvertex = poly.m_region.start(); thisdist = d1; } else { thisvertex = poly.m_region.end(); thisdist = d2; } } break; default: // either a poly line or a polygon for (size_t j = 0; j < ref.m_polyrefs.size(); j++) { double d1 = dist(p, poly.m_points[ref.m_polyrefs[j]]); // note this can be used for both open / closed with the % poly.size() double d2 = dist(p, poly.m_points[(ref.m_polyrefs[j] + 1) % poly.m_points.size()]); if (thisdist == -1 || d1 < thisdist) { thisvertex = poly.m_points[ref.m_polyrefs[j]]; thisdist = d1; } if (d2 < thisdist) { thisvertex = poly.m_points[(ref.m_polyrefs[j] + 1) % poly.m_points.size()]; thisdist = d2; } } break; } if (thisdist != -1.0 && (mindist == -1.0 || thisdist < mindist)) { mindist = thisdist; vertex = thisvertex; } } return vertex; } // nb, uses full BSP tree test: #include "isovist.h" int ShapeMap::getClosestLine(const Point2f &p) const { // not the best place to check this, but we must all the same: if (m_newshape) { m_bsp_tree = false; } if (!m_bsp_tree) { makeBSPtree(); } int index = -1; if (m_bsp_tree) { // <- check there is actually something in the tree! Isovist iso; index = iso.getClosestLine(m_bsp_root, p); } return index; } // code to add intersections when shapes are added to the graph one by one: int ShapeMap::connectIntersected(int rowid, bool linegraph) { auto shaperefIter = depthmapX::getMapAtIndex(m_shapes, rowid); int conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); int leng_col = -1; if (linegraph) { // historically line length has always been added at this point leng_col = m_attributes->getOrInsertLockedColumn("Line Length"); } // all indices should match... this grows connectors if necessary to same length as shapes while (m_connectors.size() < m_shapes.size()) { m_connectors.push_back(Connector()); } m_connectors[size_t(rowid)].m_connections = linegraph ? getLineConnections(shaperefIter->first, TOLERANCE_B * __max(m_region.height(), m_region.width())) : getShapeConnections(shaperefIter->first, TOLERANCE_B * __max(m_region.height(), m_region.width())); auto &row = getAttributeRowFromShapeIndex(rowid); row.setValue(conn_col, float(m_connectors[size_t(rowid)].m_connections.size())); if (linegraph) { row.setValue(leng_col, (float)shaperefIter->second.getLength()); } // now go through our connections, and add ourself: const std::vector &connections = m_connectors[size_t(rowid)].m_connections; for (int connection : connections) { if (connection != rowid) { // <- exclude self! depthmapX::insert_sorted(m_connectors[size_t(connection)].m_connections, rowid); auto &connectionRow = getAttributeRowFromShapeIndex(connection); connectionRow.incrValue(conn_col); } } return m_connectors[size_t(rowid)].m_connections.size(); } // this assumes this is a line map (to speed up axial map creation) // use the other version, getShapeConnections for arbitrary shape-shape connections // note, connections are listed by rowid in list, *not* reference number // (so they may vary: must be checked carefully when shapes are removed / added) std::vector ShapeMap::getLineConnections(int lineref, double tolerance) { std::vector connections; SalaShape &poly = m_shapes.find(lineref)->second; if (!poly.isLine()) { return std::vector(); } const Line &l = poly.getLine(); std::unordered_set shapesToTest; // As of version 10, self-connections are *not* added // In the past: // it's useful to have yourself in your connections list // (apparently! -- this needs checking, as most of the time it is then checked to exclude self again!) // connections.add(m_shapes.searchindex(lineref)); shapesToTest.insert(lineref); PixelRefVector list = pixelateLine(l); for (size_t i = 0; i < list.size(); i++) { const std::vector &shapeRefs = m_pixel_shapes(static_cast(list[i].y), static_cast(list[i].x)); for (const ShapeRef &shape : shapeRefs) { shapesToTest.insert(shape); } } for (ShapeRef shape : shapesToTest) { if ((shape.m_tags & ShapeRef::SHAPE_OPEN) == ShapeRef::SHAPE_OPEN) { const Line &line = m_shapes.find(int(shape.m_shape_ref))->second.getLine(); if (intersect_region(line, l, line.length() * tolerance)) { // n.b. originally this followed the logic that we must normalise intersect_line properly: tolerance * // line length one * line length two in fact, works better if it's just line.length() * tolerance... if (intersect_line(line, l, line.length() * tolerance)) { depthmapX::insert_sorted(connections, depthmapX::findIndexFromKey(m_shapes, int(shape.m_shape_ref))); } } } } return connections; } // this is only problematic as there is lots of legacy code with shape-in-shape testing, std::vector ShapeMap::getShapeConnections(int shaperef, double tolerance) { // In versions prior to 10, note that unlike getLineConnections, self-connection is excluded by all of the // following functions As of version 10, both getShapeConnections and getLineConnections exclude self-connection std::vector connections; auto shapeIter = m_shapes.find(shaperef); if (shapeIter != m_shapes.end()) { SalaShape &shape = shapeIter->second; if (shape.isPoint()) { // a point is simple, it never intersects itself: connections = pointInPolyList(shape.getPoint()); } else if (shape.isPolygon()) { // a closed poly is actually quite simple too as we already have code using a polyref: connections = polyInPolyList(shaperef, tolerance); } else if (shape.isLine()) { // line is a bit slow because there's no tested shape as in getLineConnections, but similar: connections = lineInPolyList(shape.getLine(), shaperef, tolerance); } else if (shape.isPolyLine()) { // this is the worst for efficiency: potential for many possible retries of the same shape: for (size_t i = 1; i < shape.m_points.size() - 1; i++) { Line li(shape.m_points[i - 1], shape.m_points[i]); connections = lineInPolyList(li, shaperef, tolerance); } } } return connections; } // for any geometry, not just line to lines void ShapeMap::makeShapeConnections() { if (m_hasgraph) { m_connectors.clear(); m_attributes->clear(); m_links.clear(); m_unlinks.clear(); // note, expects these to be numbered 0, 1... int conn_col = m_attributes->insertOrResetLockedColumn("Connectivity"); int i = -1; for (auto shape : m_shapes) { i++; int key = shape.first; auto &row = m_attributes->addRow(AttributeKey(key)); // all indices should match... m_connectors.push_back(Connector()); m_connectors[i].m_connections = getShapeConnections(key, TOLERANCE_B * __max(m_region.height(), m_region.width())); row.setValue(conn_col, float(m_connectors[i].m_connections.size())); } m_displayed_attribute = -1; // <- override if it's already showing setDisplayedAttribute(conn_col); } } ///////////////////////////////////////////////////////////////////////////////// // note: uses rowid not key double ShapeMap::getLocationValue(const Point2f &point) const { double val = -1.0; int x = pointInPoly(point); if (x == -1) { // try looking for a polyline instead x = getClosestOpenGeom(point); } if (x != -1) { int key = getShapeRefFromIndex(x)->first; if (m_displayed_attribute == -1) { val = static_cast(key); } else { auto &row = m_attributes->getRow(AttributeKey(key)); val = row.getValue(m_displayed_attribute); } } return (x == -1) ? -2.0 : val; // -2.0 is returned when point cannot be associated with a poly } const std::map ShapeMap::getShapesInRegion(const QtRegion &r) const { std::map shapesInRegion; if (r.bottom_left == r.top_right) { // note: uses index not key int index = pointInPoly(r.bottom_left); if (index == -1) { // try looking for a polyline instead index = getClosestOpenGeom(r.bottom_left); } if (index != -1) { shapesInRegion.insert(*getShapeRefFromIndex(index)); } } else { PixelRef bl = pixelate(r.bottom_left); PixelRef tr = pixelate(r.top_right); for (int i = bl.x; i <= tr.x; i++) { for (int j = bl.y; j <= tr.y; j++) { const std::vector &shapeRefs = m_pixel_shapes(static_cast(j), static_cast(i)); for (const ShapeRef &shapeRef : shapeRefs) { // relies on indices of shapes and attributes being aligned auto shape = m_shapes.find(shapeRef.m_shape_ref); if(shape != m_shapes.end()) { shapesInRegion.insert(*shape); } } } } } return shapesInRegion; } bool ShapeMap::setCurSel(QtRegion &r, bool add) { if (add == false) { clearSel(); } std::map shapesInRegion = getShapesInRegion(r); for (auto shape: shapesInRegion) { shape.second.m_selected = true; if (m_selection_set.insert(shape.first).second) { auto &row = m_attributes->getRow(AttributeKey(shape.first)); row.setSelection(true); } } return !shapesInRegion.empty(); } // this version is used by setSelSet in MetaGraph, ultimately called from CTableView and PlotView bool ShapeMap::setCurSel(const std::vector &selset, bool add) { // note: override cursel, can only be used with analysed pointdata: if (!add) { clearSel(); } for (int shapeRef : selset) { if (m_selection_set.insert(shapeRef).second) { auto &row = m_attributes->getRow(AttributeKey(shapeRef)); row.setSelection(true); } m_shapes.at(shapeRef).m_selected = true; } return !m_selection_set.empty(); } // this version is used when setting a selection set via the scripting language bool ShapeMap::setCurSelDirect(const std::vector &selset, bool add) { // note: override cursel, can only be used with analysed pointdata: if (!add) { clearSel(); } for (int shapeRef : selset) { if (m_selection_set.insert(shapeRef).second) { auto &row = m_attributes->getRow(AttributeKey(shapeRef)); row.setSelection(true); } m_shapes.at(shapeRef).m_selected = true; } return !m_selection_set.empty(); } float ShapeMap::getDisplayedSelectedAvg() { return (m_attributes->getSelAvg(m_displayed_attribute)); } bool ShapeMap::clearSel() { // note, only clear if need be, as m_attributes->deselectAll is slow if (m_selection_set.size()) { m_attributes->deselectAllRows(); for (auto &shapeRef : m_selection_set) { m_shapes.at(shapeRef).m_selected = false; } m_selection_set.clear(); } return true; } QtRegion ShapeMap::getSelBounds() { QtRegion r; if (m_selection_set.size()) { for (auto &shapeRef : m_selection_set) { r = runion(r, m_shapes.at(shapeRef).getBoundingBox()); } } return r; } bool ShapeMap::selectionToLayer(const std::string &name) { bool retvar = false; if (m_selection_set.size()) { dXreimpl::pushSelectionToLayer(*m_attributes, m_layers, name); retvar = m_layers.isLayerVisible(m_layers.getLayerIndex(name)); if (retvar) { clearSel(); } } return retvar; } ///////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::read(std::istream &stream) { // turn off selection / editable etc m_editable = false; m_show = true; // <- by default show m_map_type = ShapeMap::EMPTYMAP; // clear old BSP tree (if exists) m_bsp_tree = false; m_bsp_root = NULL; // clear old: m_display_shapes.clear(); m_shapes.clear(); m_attributes->clear(); m_connectors.clear(); m_links.clear(); m_unlinks.clear(); m_undobuffer.clear(); // name m_name = dXstring::readString(stream); stream.read((char *)&m_map_type, sizeof(m_map_type)); stream.read((char *)&m_show, sizeof(m_show)); stream.read((char *)&m_editable, sizeof(m_editable)); // PixelBase read // read extents: stream.read((char *)&m_region, sizeof(m_region)); // read rows / cols int rows, cols; stream.read(reinterpret_cast(&rows), sizeof(rows)); stream.read(reinterpret_cast(&cols), sizeof(cols)); m_rows = static_cast(rows); m_cols = static_cast(cols); // calculate geom data: m_tolerance = __max(m_region.width(), m_region.height()) * TOLERANCE_A; // read next object ref to be used: stream.read((char *)&m_obj_ref, sizeof(m_obj_ref)); int depr_int; stream.read((char *)&depr_int, sizeof(depr_int)); // read shape data int count = 0; stream.read((char *)&count, sizeof(count)); for (int j = 0; j < count; j++) { int key; stream.read((char *)&key, sizeof(key)); auto iter = m_shapes.insert(std::make_pair(key, SalaShape())).first; iter->second.read(stream); } // read object data (currently unused) // PK: As the above comment (and others regarding the m_objects // functionality) suggest, these are no longer used so they can // just be skipped if ever found stream.read((char *)&count, sizeof(count)); for (int k = 0; k < count; k++) { int key; stream.read((char *)&key, sizeof(key)); unsigned int size; stream.read((char *)&size, sizeof(size)); stream.ignore(sizeof(int) * std::streamsize(size)); } // read attribute data m_attributes->read(stream, m_layers); stream.read((char *)&m_displayed_attribute, sizeof(m_displayed_attribute)); if (int(m_displayed_attribute) >= 0) { std::vector indices(m_attributes->getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return m_attributes->getColumnName(a) < m_attributes->getColumnName(b); }); m_displayed_attribute = indices[m_displayed_attribute]; } // prepare pixel map: m_pixel_shapes = depthmapX::ColumnMatrix>(m_rows, m_cols); // Now add the pixel shapes pixel map: // pixelate all polys in the pixel structure: for (auto shape : m_shapes) { makePolyPixels(shape.first); } // shape connections: count = 0; stream.read((char *)&count, sizeof(count)); for (int i = 0; i < count; i++) { m_connectors.push_back(Connector()); m_connectors[size_t(i)].read(stream); } dXreadwrite::readIntoVector(stream, m_links); dXreadwrite::readIntoVector(stream, m_unlinks); // some miscellaneous extra data for mapinfo files m_hasMapInfoData = false; char x = stream.get(); if (x == 'm') { m_mapinfodata = MapInfoData(); m_mapinfodata.read(stream); m_hasMapInfoData = true; } invalidateDisplayedAttribute(); setDisplayedAttribute(m_displayed_attribute); return true; } bool ShapeMap::write(std::ofstream &stream) { // name dXstring::writeString(stream, m_name); stream.write((char *)&m_map_type, sizeof(m_map_type)); stream.write((char *)&m_show, sizeof(m_show)); stream.write((char *)&m_editable, sizeof(m_editable)); // PixelBase write // write extents: stream.write((char *)&m_region, sizeof(m_region)); // write rows / cols int rows = static_cast(m_rows); int cols = static_cast(m_cols); stream.write(reinterpret_cast(&rows), sizeof(rows)); stream.write(reinterpret_cast(&cols), sizeof(cols)); // write next object ref to be used: stream.write((char *)&m_obj_ref, sizeof(m_obj_ref)); // left here for backwards-compatibility // TODO: Remove at next iteration of the .graph file format int largest_shape_ref = m_shapes.empty() ? -1 : m_shapes.rbegin()->first; stream.write((char *)&largest_shape_ref, sizeof(largest_shape_ref)); // write shape data int count = m_shapes.size(); stream.write((char *)&count, sizeof(count)); for (auto shape : m_shapes) { int key = shape.first; stream.write((char *)&key, sizeof(key)); shape.second.write(stream); } // write object data (currently unused) count = 0; stream.write((char *)&count, sizeof(count)); // write attribute data m_attributes->write(stream, m_layers); // TODO: Compatibility. The attribute columns will be stored sorted alphabetically // so the displayed attribute needs to match that int sortedDisplayedAttribute = m_attributes->getColumnSortedIndex(m_displayed_attribute); stream.write((char *)&sortedDisplayedAttribute, sizeof(sortedDisplayedAttribute)); // write connections data count = m_connectors.size(); stream.write((char *)&count, sizeof(count)); for (int i = 0; i < count; i++) { m_connectors[i].write(stream); } dXreadwrite::writeVector(stream, m_links); dXreadwrite::writeVector(stream, m_unlinks); // some miscellaneous extra data for mapinfo files if (m_hasMapInfoData) { stream.put('m'); m_mapinfodata.write(stream); } else { stream.put('x'); } return true; } bool ShapeMap::output(std::ofstream &stream, char delimiter) { stream << "Ref"; if ((m_map_type & LINEMAP) == 0) { stream << delimiter << "cx" << delimiter << "cy"; } else { stream << delimiter << "x1" << delimiter << "y1" << delimiter << "x2" << delimiter << "y2"; } // TODO: For compatibility write the columns in alphabetical order // but the physical columns in the order inserted std::vector indices(m_attributes->getNumColumns()); std::iota(indices.begin(), indices.end(), static_cast(0)); std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { return m_attributes->getColumnName(a) < m_attributes->getColumnName(b); }); for (int idx : indices) { stream << delimiter << m_attributes->getColumnName(idx); } stream << std::endl; for (auto iter = m_attributes->begin(); iter != m_attributes->end(); iter++) { int key = iter->getKey().value; if (isObjectVisible(m_layers, iter->getRow())) { stream << key; auto shape = m_shapes[key]; if ((m_map_type & LINEMAP) == 0) { stream << delimiter << shape.m_centroid.x << delimiter << shape.m_centroid.y; } else { stream.precision(12); // TODO: Here for compatibility with old version const Line &li = shape.getLine(); stream << delimiter << li.start().x << delimiter << li.start().y << delimiter << li.end().x << delimiter << li.end().y; } stream.precision(8); // TODO: Here for compatibility with old version for (int idx : indices) { stream << delimiter << iter->getRow().getValue(idx); } stream << std::endl; } } return true; } bool ShapeMap::importPoints(const std::vector &points, const depthmapX::Table &data) { // assumes that points and data come in the same order std::vector shape_refs; for (auto &point : points) { shape_refs.push_back(makePointShape(point)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importPointsWithRefs(const std::map &points, const depthmapX::Table &data) { // assumes that points and data come in the same order std::vector shape_refs; for (auto &point : points) { shape_refs.push_back(makePointShapeWithRef(point.second, point.first)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importLines(const std::vector &lines, const depthmapX::Table &data) { // assumes that lines and data come in the same order std::vector shape_refs; for (auto &line : lines) { shape_refs.push_back(makeLineShape(line)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importLinesWithRefs(const std::map &lines, const depthmapX::Table &data) { // assumes that lines and data come in the same order std::vector shape_refs; for (auto &line : lines) { shape_refs.push_back(makeLineShapeWithRef(line.second, line.first)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importPolylines(const std::vector &polylines, const depthmapX::Table &data) { // assumes that lines and data come in the same order std::vector shape_refs; for (auto &polyline : polylines) { shape_refs.push_back(makePolyShape(polyline.m_vertices, !polyline.m_closed)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importPolylinesWithRefs(const std::map &polylines, const depthmapX::Table &data) { // assumes that lines and data come in the same order std::vector shape_refs; for (auto &polyline : polylines) { shape_refs.push_back( makePolyShapeWithRef(polyline.second.m_vertices, !polyline.second.m_closed, polyline.first)); } bool dataImported = importData(data, shape_refs); invalidateDisplayedAttribute(); setDisplayedAttribute(-1); return dataImported; } bool ShapeMap::importData(const depthmapX::Table &data, std::vector shape_refs) { for (auto &column : data) { std::string colName = column.first; std::replace(colName.begin(), colName.end(), '_', ' '); dXstring::makeInitCaps(colName); if (colName.empty()) continue; int colIndex = m_attributes->insertOrResetColumn(colName); if (colIndex == -1) { // error adding column (e.g., duplicate column names) continue; } std::unordered_map colcodes; for (size_t i = 0; i < column.second.size(); i++) { std::string cellValue = column.second[i]; double value = 0; if (dXstring::isDouble(cellValue)) { value = stod(cellValue); } else { std::unordered_map::iterator cellAt = colcodes.find(cellValue); if (cellAt == colcodes.end()) { // TODO: // It seems that the original intention here was that if we are past 32 unique // values, we should stop trying to make the column categorical and fill the rest // of the values with -1.0f. It's not possible to test the original implementation // because the app crashes if we load a file with more than 32 unique values. When // and if we have a robust implementation of an attribute table that allows for // both categorical and plain string attributes this should be re-examined for a // better way to classify the column as either. Meanwhile after this threshold (32) // we set the whole column to -1 so that it does not give the impression it worked // when it's actually half-baked if (colcodes.size() >= 32) { for (size_t j = 0; j < column.second.size(); j++) { m_attributes->getRow(AttributeKey(shape_refs[j])).setValue(colIndex, -1.0f); } continue; } else { value = colcodes.size(); colcodes.insert(std::make_pair(cellValue, colcodes.size())); } } else { value = cellAt->second; } } m_attributes->getRow(AttributeKey(shape_refs[i])).setValue(colIndex, value); } } return true; } ////////////////////////////////////////////////////////////////////////////////// void ShapeMap::setDisplayedAttribute(int col) { if (!m_invalidate && m_displayed_attribute == col) { return; } m_displayed_attribute = col; m_invalidate = true; // always override at this stage: m_attribHandle->setDisplayColIndex(m_displayed_attribute); m_invalidate = false; } ////////////////////////////////////////////////////////////////////////////////// // this is all very similar to spacepixel, apart from a few minor details void ShapeMap::makeViewportShapes(const QtRegion &viewport) const { if (m_invalidate) { return; } if (m_display_shapes.empty() || m_newshape) { m_display_shapes.assign(m_shapes.size(), -1); m_newshape = false; } m_current = -1; // note: findNext expects first to be labelled -1 PixelRef bl = pixelate(viewport.bottom_left); PixelRef tr = pixelate(viewport.top_right); for (int i = bl.x; i <= tr.x; i++) { for (int j = bl.y; j <= tr.y; j++) { const std::vector &shapeRefs = m_pixel_shapes(static_cast(j), static_cast(i)); for (const ShapeRef &shape : shapeRefs) { // copy the index to the correct draworder position (draworder is formatted on display attribute) int x = std::distance(m_shapes.begin(), m_shapes.find(shape.m_shape_ref)); AttributeKey shapeRefKey(shape.m_shape_ref); if (isObjectVisible(m_layers, m_attributes->getRow(shapeRefKey))) { m_display_shapes[m_attribHandle->findInIndex(shapeRefKey)] = x; } } } } m_curlinkline = -1; m_curunlinkpoint = -1; } bool ShapeMap::findNextShape(bool &nextlayer) const { // note: will not work immediately after a new poly has been added: makeViewportShapes first if (m_invalidate || m_newshape) { return false; } while (++m_current < (int)m_shapes.size() && m_display_shapes[m_current] == -1) ; if (m_current < (int)m_shapes.size()) { return true; } else { m_current = (int)m_shapes.size(); nextlayer = true; return false; } } const SalaShape &ShapeMap::getNextShape() const { int x = m_display_shapes[m_current]; // x has display order in it m_display_shapes[m_current] = -1; // you've drawn it return depthmapX::getMapAtIndex(m_shapes, x)->second; } /////////////////////////////////////////////////////////////////////////////////// std::vector SalaShape::getClippingSet(QtRegion &clipframe) const { std::vector edgeset; bool last_inside = (clipframe.contains_touch(m_points[0])) ? true : false; bool found_inside = last_inside; for (size_t i = 1; i < m_points.size(); i++) { bool next_inside = (clipframe.contains_touch(m_points[i])) ? true : false; found_inside |= next_inside; if (last_inside != next_inside) { if (last_inside) { EdgeU eu = clipframe.getCutEdgeU(m_points[i - 1], m_points[i]); edgeset.push_back(SalaEdgeU(i, false, eu)); } else { EdgeU eu = clipframe.getCutEdgeU(m_points[i], m_points[i - 1]); edgeset.push_back(SalaEdgeU(i - 1, true, eu)); } } last_inside = next_inside; } if (!found_inside) { // note: deliberately add a single empty SalaEdgeU if this polygon is never inside the frame edgeset.push_back(SalaEdgeU()); } return edgeset; } /////////////////////////////////////////////////////////////////////////////////// // copied from SpacePixel PixelRef ShapeMap::pixelate(const Point2f &p, bool constrain, int) const { PixelRef r; Point2f p1 = p; p1.normalScale(m_region); if (constrain) { if (p1.x <= 0.0) { r.x = 0; } else if (p1.x >= 1.0) { r.x = m_cols - 1; } else { r.x = short(floor(p1.x * m_cols)); } } else { r.x = short(floor(p1.x * m_cols)); } if (constrain) { if (p1.y <= 0.0) { r.y = 0; } else if (p1.y >= 1.0) { r.y = m_rows - 1; } else { r.y = short(floor(p1.y * m_rows)); } } else { r.y = short(floor(p1.y * m_rows)); } return r; } void ShapeMap::copyMapInfoBaseData(const ShapeMap &sourceMap) { m_mapinfodata = MapInfoData(); m_mapinfodata.m_coordsys = sourceMap.getMapInfoData().m_coordsys; m_mapinfodata.m_bounds = sourceMap.getMapInfoData().m_bounds; m_hasMapInfoData = true; } /////////////////////////////////////////////////////////////////////////////////// int ShapeMap::loadMifMap(std::istream &miffile, std::istream &midfile) { m_mapinfodata = MapInfoData(); int retvar = m_mapinfodata.import(miffile, midfile, *this); if (retvar == MINFO_OK) m_hasMapInfoData = true; return retvar; } /////////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::outputMifMap(std::ostream &miffile, std::ostream &midfile) { if (!m_hasMapInfoData) { MapInfoData mapinfodata; mapinfodata.exportFile(miffile, midfile, *this); } else { m_mapinfodata.exportFile(miffile, midfile, *this); } return true; } ///////////////////////////////////////////////////////////////////////////////// // Code for explicit linking / unlinking bool ShapeMap::linkShapes(const Point2f &p) { if (m_selection_set.size() != 1) { return false; } int index1 = std::distance(m_shapes.begin(), m_shapes.find(*m_selection_set.begin())); // note: uses rowid not key int index2 = pointInPoly(p); if (index2 == -1) { // try looking for a polyline instead index2 = getClosestOpenGeom(p); } if (index2 == -1) { return false; } clearSel(); linkShapes(index1, index2); return true; } bool ShapeMap::linkShapesFromRefs(int ref1, int ref2, bool refresh) { int index1 = depthmapX::findIndexFromKey(m_shapes, ref1); int index2 = depthmapX::findIndexFromKey(m_shapes, ref2); return linkShapes(index1, index2, refresh); } bool ShapeMap::linkShapes(int index1, int index2, bool refresh) { int conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); bool update = false; if (index1 != index2) { // link these lines... // first look for explicit unlinks and clear OrderedIntPair link(index1, index2); auto unlinkiter = std::find(m_unlinks.begin(), m_unlinks.end(), link); if (unlinkiter != m_unlinks.end()) { m_unlinks.erase(unlinkiter); update = true; } else { // then check not linked already auto &connections1 = m_connectors[size_t(index1)].m_connections; auto &connections2 = m_connectors[size_t(index2)].m_connections; auto linkIter1 = std::find(connections1.begin(), connections1.end(), index2); auto linkIter2 = std::find(connections2.begin(), connections2.end(), index1); if (linkIter1 == connections1.end() && linkIter2 == connections2.end()) { // finally, link the two lines depthmapX::addIfNotExists(m_links, link); update = true; } } } if (update) { depthmapX::insert_sorted(m_connectors[size_t(index1)].m_connections, index2); depthmapX::insert_sorted(m_connectors[size_t(index2)].m_connections, index1); auto &row1 = getAttributeRowFromShapeIndex(index1); auto &row2 = getAttributeRowFromShapeIndex(index2); row1.incrValue(conn_col); row2.incrValue(conn_col); if (refresh && getDisplayedAttribute() == conn_col) { invalidateDisplayedAttribute(); setDisplayedAttribute(conn_col); // <- reflect changes to connectivity counts } } return update; } // this version is used to link segments in segment analysis // note it only links one way! bool ShapeMap::linkShapes(int id1, int dir1, int id2, int dir2, float weight) { bool success = false; Connector &connector = m_connectors[size_t(id1)]; if (dir1 == 1) { success = depthmapX::addIfNotExists(connector.m_forward_segconns, SegmentRef(dir2, id2), weight); } else { success = depthmapX::addIfNotExists(connector.m_back_segconns, SegmentRef(dir2, id2), weight); } // checking success != -1 avoids duplicate entries adding to connectivity if (success) { int conn_col = m_attributes->getOrInsertLockedColumn("Connectivity"); auto &row = getAttributeRowFromShapeIndex(id1); row.incrValue(conn_col); int weight_col = m_attributes->getOrInsertLockedColumn("Weighted Connectivity"); row.incrValue(weight_col, weight); } return true; } bool ShapeMap::unlinkShapes(const Point2f &p) { if (m_selection_set.size() != 1) { return false; } int index1 = std::distance(m_shapes.begin(), m_shapes.find(*m_selection_set.begin())); int index2 = pointInPoly(p); if (index2 == -1) { // try looking for a polyline instead index2 = getClosestOpenGeom(p); } if (index2 == -1) { return false; } clearSel(); unlinkShapes(index1, index2); return true; } bool ShapeMap::unlinkShapesFromRefs(int ref1, int ref2, bool refresh) { int index1 = depthmapX::findIndexFromKey(m_shapes, ref1); int index2 = depthmapX::findIndexFromKey(m_shapes, ref2); return unlinkShapes(index1, index2, refresh); } // note: uses rowids rather than shape key bool ShapeMap::unlinkShapes(int index1, int index2, bool refresh) { int conn_col = m_attributes->getColumnIndex("Connectivity"); bool update = false; if (index1 != index2) { // unlink these shapes... // first look for explicit links and clear OrderedIntPair unlink(index1, index2); auto linkiter = std::find(m_links.begin(), m_links.end(), unlink); if (linkiter != m_links.end()) { m_links.erase(linkiter); update = true; } else { // then check if linked already auto &connections1 = m_connectors[size_t(index1)].m_connections; auto &connections2 = m_connectors[size_t(index2)].m_connections; auto linkIter1 = std::find(connections1.begin(), connections1.end(), index2); auto linkIter2 = std::find(connections2.begin(), connections2.end(), index1); if (linkIter1 != connections1.end() && linkIter2 != connections2.end()) { // finally, unlink the two shapes depthmapX::addIfNotExists(m_unlinks, unlink); update = true; } } } if (update && conn_col != -1) { depthmapX::findAndErase(m_connectors[size_t(index1)].m_connections, index2); depthmapX::findAndErase(m_connectors[size_t(index2)].m_connections, index1); auto &row1 = getAttributeRowFromShapeIndex(index1); auto &row2 = getAttributeRowFromShapeIndex(index2); row1.incrValue(conn_col, -1.0f); row2.incrValue(conn_col, -1.0f); if (refresh && getDisplayedAttribute() == conn_col) { invalidateDisplayedAttribute(); setDisplayedAttribute(conn_col); // <- reflect changes to connectivity counts } } return update; } bool ShapeMap::unlinkShapesByKey(int key1, int key2, bool refresh) { int conn_col = m_attributes->getColumnIndex("Connectivity"); bool update = false; int index1 = std::distance(m_shapes.begin(), m_shapes.find(key1)); int index2 = std::distance(m_shapes.begin(), m_shapes.find(key2)); if (key1 != key2) { // unlink these shapes... // first look for explicit links and clear OrderedIntPair unlink(index1, index2); auto linkiter = std::find(m_links.begin(), m_links.end(), unlink); if (linkiter != m_links.end()) { m_links.erase(linkiter); update = true; } else { // then check if linked already auto &connections1 = m_connectors[size_t(index1)].m_connections; auto &connections2 = m_connectors[size_t(index2)].m_connections; auto linkIter1 = std::find(connections1.begin(), connections1.end(), index2); auto linkIter2 = std::find(connections2.begin(), connections2.end(), index1); if (linkIter1 != connections1.end() && linkIter2 != connections2.end()) { // finally, unlink the two shapes depthmapX::addIfNotExists(m_unlinks, unlink); update = true; } } } if (update && conn_col != -1) { depthmapX::findAndErase(m_connectors[size_t(index1)].m_connections, index2); depthmapX::findAndErase(m_connectors[size_t(index2)].m_connections, index1); auto &row1 = m_attributes->getRow(AttributeKey(key1)); auto &row2 = m_attributes->getRow(AttributeKey(key1)); row1.incrValue(conn_col, -1.0f); row2.incrValue(conn_col, -1.0f); if (refresh && getDisplayedAttribute() == conn_col) { invalidateDisplayedAttribute(); setDisplayedAttribute(conn_col); // <- reflect changes to connectivity counts } } return update; } bool ShapeMap::clearLinks() { for (size_t i = 0; i < m_unlinks.size(); i++) { OrderedIntPair link = m_unlinks[i]; depthmapX::insert_sorted(m_connectors[size_t(link.a)].m_connections, link.b); depthmapX::insert_sorted(m_connectors[size_t(link.b)].m_connections, link.a); } m_unlinks.clear(); for (size_t j = 0; j < m_links.size(); j++) { OrderedIntPair link = m_links[j]; depthmapX::findAndErase(m_connectors[size_t(link.a)].m_connections, link.b); depthmapX::findAndErase(m_connectors[size_t(link.b)].m_connections, link.a); } m_links.clear(); return true; } bool ShapeMap::unlinkShapeSet(std::istream &idset, int refcol) { std::string line; std::vector> unlinks; do { std::pair unlink; dXstring::safeGetline(idset, line); if (!line.empty()) { auto tokens = dXstring::split(line, '\t'); if (tokens.size() < 2) { return false; } try { unlink.first = stoi(tokens[0]); unlink.second = stoi(tokens[1]); unlinks.push_back(unlink); } catch (const std::invalid_argument) { ; } catch (const std::out_of_range) { ; } // don't do anything if it can't parse the numbers, just ignore (e.g., first line) } } while (!idset.eof()); if (refcol != -1) { // not using the standard "Ref", find the proper key std::vector idx = refcol != -1 ? makeAttributeIndex(*m_attributes, refcol) : std::vector(); AttributeKey dummykey(-1); AttributeRowImpl dummyrow(*m_attributes); for (size_t i = 0; i < unlinks.size(); i++) { auto iter = depthmapX::findBinary(idx, AttributeIndexItem(dummykey, unlinks[i].first, dummyrow)); unlinks[i].first = (iter == idx.end()) ? -1 : iter->key.value; iter = depthmapX::findBinary(idx, AttributeIndexItem(dummykey, unlinks[i].second, dummyrow)); unlinks[i].second = (iter == idx.end()) ? -1 : iter->key.value; } } for (size_t i = 0; i < unlinks.size(); i++) { unlinkShapesByKey(unlinks[i].first, unlinks[i].second, false); } int conn_col = m_attributes->getColumnIndex("Connectivity"); if (getDisplayedAttribute() == conn_col) { invalidateDisplayedAttribute(); setDisplayedAttribute(conn_col); // <- reflect changes to connectivity counts } return true; } ///////////////////////////////////////////////////////////////////////////////// bool ShapeMap::findNextLinkLine() const { if (m_curlinkline < (int)m_links.size()) { m_curlinkline++; } return (m_curlinkline < (int)m_links.size()); } Line ShapeMap::getNextLinkLine() const { // note, links are stored directly by rowid, not by key: if (m_curlinkline < (int)m_links.size()) { return Line(depthmapX::getMapAtIndex(m_shapes, m_links[m_curlinkline].a)->second.getCentroid(), depthmapX::getMapAtIndex(m_shapes, m_links[m_curlinkline].b)->second.getCentroid()); } return Line(); } std::vector ShapeMap::getAllLinkLines() { std::vector linkLines; for (size_t i = 0; i < m_links.size(); i++) { linkLines.push_back(SimpleLine(depthmapX::getMapAtIndex(m_shapes, m_links[i].a)->second.getCentroid(), depthmapX::getMapAtIndex(m_shapes, m_links[i].b)->second.getCentroid())); } return linkLines; } // note: these functions would need slight work for arbitrary shape overlaps bool ShapeMap::findNextUnlinkPoint() const { if (m_curunlinkpoint < (int)m_unlinks.size()) { m_curunlinkpoint++; } return (m_curunlinkpoint < (int)m_unlinks.size()); } Point2f ShapeMap::getNextUnlinkPoint() const { // note, links are stored directly by rowid, not by key: if (m_curunlinkpoint < (int)m_unlinks.size()) { return intersection_point(depthmapX::getMapAtIndex(m_shapes, m_unlinks[m_curunlinkpoint].a)->second.getLine(), depthmapX::getMapAtIndex(m_shapes, m_unlinks[m_curunlinkpoint].b)->second.getLine(), TOLERANCE_A); } return Point2f(); } std::vector ShapeMap::getAllUnlinkPoints() { std::vector unlinkPoints; for (size_t i = 0; i < m_unlinks.size(); i++) { unlinkPoints.push_back(intersection_point(depthmapX::getMapAtIndex(m_shapes, m_unlinks[i].a)->second.getLine(), depthmapX::getMapAtIndex(m_shapes, m_unlinks[i].b)->second.getLine(), TOLERANCE_A)); } return unlinkPoints; } void ShapeMap::outputUnlinkPoints(std::ofstream &stream, char delim) { stream << "x" << delim << "y" << std::endl; stream.precision(12); for (size_t i = 0; i < m_unlinks.size(); i++) { // note, links are stored directly by rowid, not by key: Point2f p = intersection_point(depthmapX::getMapAtIndex(m_shapes, m_unlinks[i].a)->second.getLine(), depthmapX::getMapAtIndex(m_shapes, m_unlinks[i].b)->second.getLine(), TOLERANCE_A); stream << p.x << delim << p.y << std::endl; } } ///////////////////////////////////////////////////////////////////////////////////////////////// bool ShapeMap::makeBSPtree() const { if (m_bsp_tree) { return true; } std::vector partitionlines; for (auto shape : m_shapes) { if (shape.second.isLine()) { partitionlines.push_back(TaggedLine(shape.second.getLine(), shape.first)); } } if (partitionlines.size()) { // // Now we'll try the BSP tree: // if (m_bsp_root) { delete m_bsp_root; m_bsp_root = NULL; } m_bsp_root = new BSPNode(); BSPTree::make(NULL, 0, partitionlines, m_bsp_root); m_bsp_tree = true; } partitionlines.clear(); return m_bsp_tree; } ///////////////////////////////////////////////////////////////////////////////// // SPECIALS BELOW //////////////////////////////////////////////////////////////////////////////////////////////// int findwinner(double *bins, int bincount, int &difficult, int &impossible) { difficult = 0; impossible = 0; // double total = 0.0; // double maxvalue = -1.0; int maxbin = -1; int i; for (i = 0; i < bincount; i++) { if (i == 0 || bins[i] > maxvalue) { maxvalue = bins[i]; maxbin = i; } total += bins[i]; } if (maxvalue > total * 0.8) { return maxbin; } int lastwinner = maxbin; // no immediate clear winner, so see if across two adjacent bins: double savebin = bins[bincount - 1]; double savebins0 = bins[0]; for (i = 0; i < bincount - 1; i++) { double lastbin = savebin; savebin = bins[i]; bins[i] += bins[i + 1] + lastbin; } bins[bincount - 1] += savebins0 + savebin; // now check again for a clear winner: maxvalue = -1.0; maxbin = -1; for (i = 0; i < bincount; i++) { if (i == 0 || bins[i] > maxvalue) { maxvalue = bins[i]; maxbin = i; } } // if it's a tie, the last winner wins it: if (maxbin != lastwinner && maxvalue == bins[lastwinner]) { maxbin = lastwinner; } // if (maxvalue > total * 0.8) { return maxbin; } // // now it's at least hard: if (maxvalue > total * 0.6) { difficult = 1; return maxbin; } // // if not even this is true, it's really a guess in the dark: impossible = 1; return maxbin; } // Quick mod - TV #if defined(_MSC_VER) #include #endif std::vector ShapeMap::getAllShapesAsLines() const { std::vector lines; const std::map &allShapes = getAllShapes(); for (auto refShape : allShapes) { SalaShape &shape = refShape.second; if (shape.isLine()) { lines.push_back(SimpleLine(shape.getLine())); } else if (shape.isPolyLine() || shape.isPolygon()) { for (size_t n = 0; n < shape.m_points.size() - 1; n++) { lines.push_back(SimpleLine(shape.m_points[n], shape.m_points[n + 1])); } if (shape.isPolygon()) { lines.push_back(SimpleLine(shape.m_points.back(), shape.m_points.front())); } } } return lines; } std::vector> ShapeMap::getAllLinesWithColour() { std::vector> colouredLines; std::map &allShapes = getAllShapes(); int k = -1; for (auto &refShape : allShapes) { k++; SalaShape &shape = refShape.second; PafColor colour(dXreimpl::getDisplayColor(AttributeKey(refShape.first), m_attributes->getRow(AttributeKey(refShape.first)), *m_attribHandle.get(), true)); if (shape.isLine()) { colouredLines.push_back(std::pair(SimpleLine(shape.getLine()), colour)); } else if (shape.isPolyLine()) { for (size_t n = 0; n < shape.m_points.size() - 1; n++) { colouredLines.push_back( std::pair(SimpleLine(shape.m_points[n], shape.m_points[n + 1]), colour)); } } } return colouredLines; } std::vector, PafColor>> ShapeMap::getAllPolygonsWithColour() { std::vector, PafColor>> colouredPolygons; std::map &allShapes = getAllShapes(); for (auto &refShape : allShapes) { SalaShape &shape = refShape.second; if (shape.isPolygon()) { std::vector vertices; for (size_t n = 0; n < shape.m_points.size(); n++) { vertices.push_back(shape.m_points[n]); } vertices.push_back(shape.m_points.back()); PafColor colour(dXreimpl::getDisplayColor(AttributeKey(refShape.first), m_attributes->getRow(AttributeKey(refShape.first)), *m_attribHandle.get(), true)); colouredPolygons.push_back(std::make_pair(vertices, colour)); } } return colouredPolygons; } std::vector> ShapeMap::getAllPointsWithColour() { std::vector> colouredPoints; std::map &allShapes = getAllShapes(); for (auto &refShape : allShapes) { SalaShape &shape = refShape.second; if (shape.isPoint()) { PafColor colour(dXreimpl::getDisplayColor(AttributeKey(refShape.first), m_attributes->getRow(AttributeKey(refShape.first)), *m_attribHandle.get(), true)); colouredPoints.push_back(std::make_pair(shape.getCentroid(), colour)); } } return colouredPoints; } ================================================ FILE: salalib/shapemap.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #pragma once #include "salalib/attributetable.h" #include "salalib/attributetablehelpers.h" #include "salalib/attributetableview.h" #include "salalib/connector.h" #include "salalib/importtypedefs.h" #include "salalib/layermanagerimpl.h" #include "salalib/parsers/mapinfodata.h" #include "salalib/spacepix.h" #include "genlib/bsptree.h" #include "genlib/containerutils.h" #include "genlib/p2dpoly.h" #include "genlib/readwritehelpers.h" #include "genlib/stringutils.h" #include #include #include #include // each pixel has various lists of information: struct ShapeRef { enum { SHAPE_REF_NULL = 0xFFFFFFFF }; enum { SHAPE_L = 0x01, SHAPE_B = 0x02, SHAPE_R = 0x04, SHAPE_T = 0x08 }; enum { SHAPE_EDGE = 0x0f, SHAPE_INTERNAL_EDGE = 0x10, SHAPE_CENTRE = 0x20, SHAPE_OPEN = 0x40 }; unsigned char m_tags; unsigned int m_shape_ref; std::vector m_polyrefs; ShapeRef(unsigned int sref = SHAPE_REF_NULL, unsigned char tags = 0x00) { m_shape_ref = sref; m_tags = tags; } friend bool operator==(const ShapeRef &a, const ShapeRef &b); friend bool operator!=(const ShapeRef &a, const ShapeRef &b); friend bool operator<(const ShapeRef &a, const ShapeRef &b); friend bool operator>(const ShapeRef &a, const ShapeRef &b); }; inline bool operator==(const ShapeRef &a, const ShapeRef &b) { return a.m_shape_ref == b.m_shape_ref; } inline bool operator!=(const ShapeRef &a, const ShapeRef &b) { return a.m_shape_ref != b.m_shape_ref; } inline bool operator<(const ShapeRef &a, const ShapeRef &b) { return a.m_shape_ref < b.m_shape_ref; } inline bool operator>(const ShapeRef &a, const ShapeRef &b) { return a.m_shape_ref > b.m_shape_ref; } struct ShapeRefHash { public: size_t operator()(const ShapeRef &shapeRef) const { return shapeRef.m_shape_ref; } }; ///////////////////////////////////////////////////////////////////////////////////////////////// // this is a helper for cutting polygons to fit a viewport / cropping frame struct SalaEdgeU : public EdgeU { int index; bool entry; // or exit SalaEdgeU() : EdgeU() { index = -1; entry = false; } SalaEdgeU(int i, bool e, const EdgeU &eu) : EdgeU(eu) { index = i; entry = e; } }; ///////////////////////////////////////////////////////////////////////////////////////////////// class PointMap; class SalaShape { public: std::vector m_points; enum { SHAPE_POINT = 0x01, SHAPE_LINE = 0x02, SHAPE_POLY = 0x04, SHAPE_CIRCLE = 0x08, SHAPE_TYPE = 0x0f, SHAPE_CLOSED = 0x40, SHAPE_CCW = 0x80 }; friend class ShapeMap; protected: unsigned char m_type; Point2f m_centroid; // centre of mass, but also used as for point if object is a point Line m_region; // bounding box, but also used as a line if object is a line, hence type double m_area; double m_perimeter; // these are all temporary data which are recalculated on reload mutable bool m_selected; mutable float m_color; mutable int m_draworder; public: SalaShape(unsigned char type = 0) { m_type = type; m_draworder = -1; m_selected = false; m_area = 0.0; m_perimeter = 0.0; } SalaShape(const Point2f &point) { m_type = SHAPE_POINT; m_draworder = -1; m_selected = false; m_region = Line(point, point); m_centroid = point; m_area = 0.0; m_perimeter = 0.0; } SalaShape(const Line &line) { m_type = SHAPE_LINE; m_draworder = -1; m_selected = false; m_region = line; m_centroid = m_region.getCentre(); m_area = 0.0; m_perimeter = m_region.length(); } // bool isOpen() const { return (m_type & SHAPE_CLOSED) == 0; } bool isClosed() const { return (m_type & SHAPE_CLOSED) == SHAPE_CLOSED; } bool isPoint() const { return (m_type == SHAPE_POINT); } bool isLine() const { return (m_type == SHAPE_LINE); } bool isPolyLine() const { return (m_type & (SHAPE_POLY | SHAPE_CLOSED)) == SHAPE_POLY; } bool isPolygon() const { return (m_type & (SHAPE_POLY | SHAPE_CLOSED)) == (SHAPE_POLY | SHAPE_CLOSED); } bool isCCW() const { return (m_type & SHAPE_CCW) == SHAPE_CCW; } // const Point2f &getPoint() const { return m_centroid; } const Line &getLine() const { return m_region; } const QtRegion &getBoundingBox() const { return m_region; } // double getArea() const { return m_area; } double getPerimeter() const { return m_perimeter; } // duplicate function, but easier to understand naming convention double getLength() const { return m_perimeter; } // void setCentroidAreaPerim(); void setCentroid(const Point2f &p); // duplicate function, but easier to understand naming convention const Point2f &getCentroid() const { return m_centroid; } // double getAngDev() const; // std::vector getClippingSet(QtRegion &clipframe) const; // bool read(std::istream &stream); bool write(std::ofstream &stream); std::vector getAsLines() const { std::vector lines; if (isLine()) { lines.push_back(getLine()); } else if (isPolyLine() || isPolygon()) { for (size_t j = 0; j < m_points.size() - 1; j++) { lines.push_back(Line(m_points[j], m_points[j + 1])); } if (isClosed()) { lines.push_back(Line(m_points[m_points.size() - 1], m_points[0])); } } return lines; } }; ///////////////////////////////////////////////////////////////////////////////////////////////// struct SalaEvent { enum { SALA_NULL_EVENT, SALA_CREATED, SALA_DELETED, SALA_MOVED }; int m_action; int m_shape_ref; SalaShape m_geometry; SalaEvent(int action = SALA_NULL_EVENT, int shape_ref = -1) { m_action = action; m_shape_ref = shape_ref; } }; ///////////////////////////////////////////////////////////////////////////////////////////////// // Quick mod - TV class MapInfoData; class ShapeMap : public PixelBase { friend class AxialMaps; friend class MapInfoData; public: // now shapemaps cover a multitude of different types, record here: // (note, allline maps are automatically generated and have extra information recorded for line reduction) // Do not change numeric values! They are saved to file. // Note the Pesh map does auto-overlap of shape-shape (yet...), so can be used for an arbitrary shape map enum { EMPTYMAP = 0x0000, DRAWINGMAP = 0x0001, DATAMAP = 0x0002, POINTMAP = 0x0004, CONVEXMAP = 0x0008, ALLLINEMAP = 0x0010, AXIALMAP = 0x0020, SEGMENTMAP = 0x0040, PESHMAP = 0x0080, LINEMAP = 0x0070 }; enum { COPY_NAME = 0x0001, COPY_GEOMETRY = 0x0002, COPY_ATTRIBUTES = 0x0004, COPY_GRAPH = 0x0008, COPY_ALL = 0x000f }; protected: std::string m_name; int m_map_type; bool m_hasgraph; // counters int m_obj_ref; mutable bool m_newshape; // if a new shape has been added // // quick grab for shapes depthmapX::ColumnMatrix> m_pixel_shapes; // i rows of j columns // // allow quick closest line test (note only works for a given layer, with many layers will be tricky) mutable BSPNode *m_bsp_root = nullptr; mutable bool m_bsp_tree = false; // std::map m_shapes; // std::vector m_undobuffer; // std::unique_ptr m_attributes; std::unique_ptr m_attribHandle; LayerManagerImpl m_layers; // // for graph functionality // Note: this list is stored PACKED for optimal performance on graph analysis // ALWAYS check it is in the same order as the shape list and attribute table std::vector m_connectors; // // for geometric operations double m_tolerance; // for screen drawing mutable std::vector m_display_shapes; mutable int m_current; mutable bool m_invalidate; // private: void moveData(ShapeMap& other) { m_show = other.isShown(); m_shapes = std::move(other.m_shapes); m_hasgraph = other.m_hasgraph; m_connectors = std::move(other.m_connectors); m_links = std::move(other.m_links); m_unlinks = std::move(other.m_unlinks); m_mapinfodata = std::move(other.m_mapinfodata); m_hasMapInfoData = other.m_hasMapInfoData; m_displayed_attribute = other.m_displayed_attribute; m_display_shapes = std::move(other.m_display_shapes); m_rows = other.m_rows; m_cols = other.m_cols; m_region = std::move(other.m_region); m_map_type = other.m_map_type; } public: ShapeMap(const std::string &name = std::string(), int type = EMPTYMAP); virtual ~ShapeMap(); void copy(const ShapeMap &shapemap, int copyflags = 0); ShapeMap(ShapeMap &&other) : m_name(std::move(other.m_name)), m_pixel_shapes(std::move(other.m_pixel_shapes)), m_attributes(std::move(other.m_attributes)), m_attribHandle(std::move(other.m_attribHandle)), m_layers(std::move(other.m_layers)) { moveData(other); } ShapeMap &operator=(ShapeMap &&other) { m_name = std::move(other.m_name); m_pixel_shapes = std::move(other.m_pixel_shapes); m_attributes = std::move(other.m_attributes); m_attribHandle = std::move(other.m_attribHandle); m_layers = std::move(other.m_layers); moveData(other); return *this; } ShapeMap(const ShapeMap &) = delete; ShapeMap &operator=(const ShapeMap &other) = delete; // TODO: These three functions should be refactored out of the code as much as possible // they are only left here because they're being used by various components that still // access the attribute table through indices. Once these are removed these functions // should only appear sparingly or removed entirely. The bits of the application // that still use them are the connections of the axial/segment maps and the point // in polygon functions. const std::map::const_iterator getShapeRefFromIndex(size_t index) const { return depthmapX::getMapAtIndex(m_shapes, index); } AttributeRow &getAttributeRowFromShapeIndex(size_t index) { return m_attributes->getRow(AttributeKey(getShapeRefFromIndex(index)->first)); } const AttributeRow &getAttributeRowFromShapeIndex(size_t index) const { return m_attributes->getRow(AttributeKey(getShapeRefFromIndex(index)->first)); } void clearAll(); // num shapes total size_t getShapeCount() const { return m_shapes.size(); } // num shapes for this object (note, request by object rowid // -- on interrogation, this is what you will usually receive) size_t getShapeCount(int rowid) const { return depthmapX::getMapAtIndex(m_shapes, rowid)->second.m_points.size(); } // int getIndex(int rowid) const { return depthmapX::getMapAtIndex(m_shapes, rowid)->first; } // // add shape tools void makePolyPixels(int shaperef); void shapePixelBorder(std::map &relations, int shaperef, int side, PixelRef currpix, PixelRef minpix, bool first); // remove shape tools void removePolyPixels(int shaperef); // // void init(int size, const QtRegion &r); int getNextShapeKey(); // convert a single point into a shape int makePointShapeWithRef(const Point2f &point, int shape_ref, bool tempshape = false, const std::map &extraAttributes = std::map()); int makePointShape(const Point2f &point, bool tempshape = false, const std::map &extraAttributes = std::map()); // or a single line into a shape int makeLineShapeWithRef(const Line &line, int shape_ref, bool through_ui = false, bool tempshape = false, const std::map &extraAttributes = std::map()); int makeLineShape(const Line &line, bool through_ui = false, bool tempshape = false, const std::map &extraAttributes = std::map()); // or a polygon into a shape int makePolyShapeWithRef(const std::vector &points, bool open, int shape_ref, bool tempshape = false, const std::map &extraAttributes = std::map()); int makePolyShape(const std::vector &points, bool open, bool tempshape = false, const std::map &extraAttributes = std::map()); public: // or make a shape from a shape int makeShape(const SalaShape &shape, int override_shape_ref = -1, const std::map &extraAttributes = std::map()); // convert points to polygons bool convertPointsToPolys(double poly_radius, bool selected_only); // convert a selected pixels to a layer object (note, uses selection attribute on pixel, you must select to make // this work): int makeShapeFromPointSet(const PointMap &pointmap); // // move a shape (currently only a line shape) -- in the future should use SalaShape bool moveShape(int shaperef, const Line &line, bool undoing = false); // delete selected shapes bool removeSelected(); // delete a shape void removeShape(int shaperef, bool undoing = false); // void setShapeAttributes(int rowid, const SalaShape &shape); // // some UI polygon creation tools: int polyBegin(const Line &line); bool polyAppend(int shape_ref, const Point2f &point); bool polyClose(int shape_ref); bool polyCancel(int shape_ref); // some shape creation tools for the scripting language or DLL interface public: bool canUndo() const { return m_undobuffer.size() != 0; } void undo(); // // helpers: Point2f pointOffset(const PointMap &pointmap, int side); int moveDir(int side); // void pointPixelBorder(const PointMap &pointmap, std::map &relations, SalaShape &shape, int side, PixelRef currpix, PixelRef minpix, bool first); // slower point in topmost poly test: int pointInPoly(const Point2f &p) const; // test if point is inside a particular shape bool pointInPoly(const Point2f &p, int shaperef) const; // retrieve lists of polys point intersects: std::vector pointInPolyList(const Point2f &p) const; std::vector lineInPolyList(const Line &li, size_t lineref = -1, double tolerance = 0.0) const; std::vector polyInPolyList(int polyref, double tolerance = 0.0) const; std::vector shapeInPolyList(const SalaShape &shape); // helper to make actual test of point in shape: int testPointInPoly(const Point2f &p, const ShapeRef &shape) const; // also allow look for a close polyline: int getClosestOpenGeom(const Point2f &p) const; // this version uses a BSP tree to find closest line (currently only line shapes) int getClosestLine(const Point2f &p) const; // this version simply finds the closest vertex to the point Point2f getClosestVertex(const Point2f &p) const; // Connect a particular shape into the graph int connectIntersected(int rowid, bool linegraph); // Get the connections for a particular line std::vector getLineConnections(int lineref, double tolerance); // Get arbitrary shape connections for a particular shape std::vector getShapeConnections(int polyref, double tolerance); // Make all connections void makeShapeConnections(); // bool makeBSPtree() const; // const std::vector &getConnections() const { return m_connectors; } std::vector &getConnections() { return m_connectors; } // bool isAllLineMap() const { return m_map_type == ALLLINEMAP; } bool isSegmentMap() const { return m_map_type == SEGMENTMAP; } bool isAxialMap() const { return m_map_type == ALLLINEMAP || m_map_type == AXIALMAP; } bool isPeshMap() const { return m_map_type == PESHMAP; } int getMapType() const { return m_map_type; } // Attribute functionality protected: // which attribute is currently displayed: mutable int m_displayed_attribute; public: const std::string &getName() const { return m_name; } int addAttribute(const std::string &name) { return m_attributes->insertOrResetColumn(name); } void removeAttribute(int col) { m_attributes->removeColumn(col); } // I don't want to do this, but every so often you will need to update this table // use const version by preference AttributeTable &getAttributeTable() { return *m_attributes.get(); } const AttributeTable &getAttributeTable() const { return *m_attributes.get(); } LayerManagerImpl &getLayers() { return m_layers; } const LayerManagerImpl &getLayers() const { return m_layers; } AttributeTableHandle &getAttributeTableHandle() { return *m_attribHandle.get(); } const AttributeTableHandle &getAttributeTableHandle() const { return *m_attribHandle.get(); } public: // layer functionality bool isLayerVisible(int layerid) const { return m_layers.isLayerVisible(layerid); } void setLayerVisible(int layerid, bool show) { m_layers.setLayerVisible(layerid, show); } bool selectionToLayer(const std::string &name = std::string("Unnamed")); public: double getDisplayMinValue() const { return (m_displayed_attribute != -1) ? m_attributes->getColumn(m_displayed_attribute).getStats().min : 0; } double getDisplayMaxValue() const { return (m_displayed_attribute != -1) ? m_attributes->getColumn(m_displayed_attribute).getStats().max : (m_shapes.size() > 0 ? m_shapes.rbegin()->first : 0); } const DisplayParams &getDisplayParams() const { return m_attributes->getColumn(m_displayed_attribute).getDisplayParams(); } // make a local copy of the display params for access speed: void setDisplayParams(const DisplayParams &dp, bool apply_to_all = false) { if (apply_to_all) m_attributes->setDisplayParams(dp); else m_attributes->getColumn(m_displayed_attribute).setDisplayParams(dp); } // mutable bool m_show_lines; mutable bool m_show_fill; mutable bool m_show_centroids; void getPolygonDisplay(bool &show_lines, bool &show_fill, bool &show_centroids) { show_lines = m_show_lines; show_fill = m_show_fill; show_centroids = m_show_centroids; } void setPolygonDisplay(bool show_lines, bool show_fill, bool show_centroids) { m_show_lines = show_lines; m_show_fill = show_fill; m_show_centroids = show_centroids; } // public: void setDisplayedAttribute(int col); // use set displayed attribute instead unless you are deliberately changing the column order: void overrideDisplayedAttribute(int attribute) { m_displayed_attribute = attribute; } // now, there is a slightly odd thing here: the displayed attribute can go out of step with the underlying // attribute data if there is a delete of an attribute in idepthmap.h, so it just needs checking before returning! int getDisplayedAttribute() const { if (m_displayed_attribute == m_attribHandle->getDisplayColIndex()) return m_displayed_attribute; if (m_attribHandle->getDisplayColIndex() != -2) { m_displayed_attribute = m_attribHandle->getDisplayColIndex(); } return m_displayed_attribute; } // void invalidateDisplayedAttribute() { m_invalidate = true; } // double getDisplayedAverage() { return m_attributes->getColumn(m_displayed_attribute).getStats().total / m_attributes->getNumRows(); } // protected: mutable bool m_show; // used when shape map is a drawing layer bool m_editable; std::set m_selection_set; // note: uses keys public: // Selection bool hasSelectedElements() const { return !m_selection_set.empty(); } const std::map getShapesInRegion(const QtRegion &r) const; bool setCurSel(QtRegion &r, bool add = false); bool setCurSel(const std::vector &selset, bool add = false); bool setCurSelDirect(const std::vector &selset, bool add = false); float getDisplayedSelectedAvg(); bool clearSel(); std::set &getSelSet() { return m_selection_set; } const std::set &getSelSet() const { return m_selection_set; } size_t getSelCount() { return m_selection_set.size(); } QtRegion getSelBounds(); // To showing bool isShown() const { return m_show; } void setShow(bool on = true) const { m_show = on; } // To all editing bool isEditable() const { return m_editable; } void setEditable(bool on = true) { m_editable = on; } protected: bool m_hasMapInfoData = false; MapInfoData m_mapinfodata; public: bool hasMapInfoData() const { return m_hasMapInfoData; } int loadMifMap(std::istream &miffile, std::istream &midfile); bool outputMifMap(std::ostream &miffile, std::ostream &midfile); const MapInfoData &getMapInfoData() const { return m_mapinfodata; } public: // Screen void makeViewportShapes(const QtRegion &viewport) const; bool findNextShape(bool &nextlayer) const; const SalaShape &getNextShape() const; const PafColor getShapeColor() const { AttributeKey key(m_display_shapes[m_current]); const AttributeRow &row = m_attributes->getRow(key); return dXreimpl::getDisplayColor(key, row, *m_attribHandle.get(), true); ; } bool getShapeSelected() const { return depthmapX::getMapAtIndex(m_shapes, m_display_shapes[m_current])->second.m_selected; } // double getLocationValue(const Point2f &point) const; // Quick mod - TV #if !defined(_MSC_VER) #define __max(x, y) ((x < y) ? y : x) #define __min(x, y) ((x < y) ? x : y) #endif // double getSpacing() const { return __max(m_region.width(), m_region.height()) / (10 * log((double)10 + m_shapes.size())); } // // dangerous: accessor for the shapes themselves: const std::map &getAllShapes() const { return m_shapes; } std::map &getAllShapes() { return m_shapes; } // required for PixelBase, have to implement your own version of pixelate PixelRef pixelate(const Point2f &p, bool constrain = true, int = 1) const; // public: // file bool read(std::istream &stream); bool write(std::ofstream &stream); // bool output(std::ofstream &stream, char delimiter = '\t'); // // links and unlinks protected: std::vector m_links; std::vector m_unlinks; mutable int m_curlinkline; mutable int m_curunlinkpoint; public: bool clearLinks(); bool linkShapes(const Point2f &p); bool linkShapesFromRefs(int ref1, int ref2, bool refresh = true); bool linkShapes(int index1, int index2, bool refresh = true); bool linkShapes(int id1, int dir1, int id2, int dir2, float weight); bool unlinkShapes(const Point2f &p); bool unlinkShapesFromRefs(int index1, int index2, bool refresh = true); bool unlinkShapes(int index1, int index2, bool refresh = true); bool unlinkShapesByKey(int key1, int key2, bool refresh = true); bool unlinkShapeSet(std::istream &idset, int refcol); public: // generic for all types of graphs bool findNextLinkLine() const; Line getNextLinkLine() const; std::vector getAllLinkLines(); // specific to axial line graphs bool findNextUnlinkPoint() const; Point2f getNextUnlinkPoint() const; std::vector getAllUnlinkPoints(); void outputUnlinkPoints(std::ofstream &stream, char delim); public: std::vector getAllShapesAsLines() const; std::vector> getAllLinesWithColour(); std::vector, PafColor>> getAllPolygonsWithColour(); std::vector> getAllPointsWithColour(); bool importLines(const std::vector &lines, const depthmapX::Table &data); bool importLinesWithRefs(const std::map &lines, const depthmapX::Table &data); bool importPoints(const std::vector &points, const depthmapX::Table &data); bool importPointsWithRefs(const std::map &points, const depthmapX::Table &data); bool importPolylines(const std::vector &lines, const depthmapX::Table &data); bool importPolylinesWithRefs(const std::map &lines, const depthmapX::Table &data); void copyMapInfoBaseData(const ShapeMap &sourceMap); private: bool importData(const depthmapX::Table &data, std::vector shape_refs); }; ================================================ FILE: salalib/spacepix.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines // spatial data #include "salalib/spacepix.h" #include "genlib/stringutils.h" #include "genlib/readwritehelpers.h" #include "genlib/containerutils.h" #include #include #include #ifndef _WIN32 #define _finite finite #endif /* // Algorithm from Chi // make sure dx > dy dx = x1 - x0; dy = y1 - y0; x = x0; y = y0; d = 2*dy - dx; inc1 = 2*dy; inc2 = 2*(dy-dx); while (x < x1) { if (d <= 0) { d += inc1; x += 1; } else { d += inc2; x++; y++; } pixel_list.push_back( PixelRef(x,y) ); } */ PixelRefVector PixelBase::pixelateLine(Line l, int scalefactor) const { PixelRefVector pixel_list; // this is *not* correct for lines that are off the edge... // should use non-constrained version (false), and find where line enters the region PixelRef a = pixelate(l.start(), true, scalefactor); PixelRef b = pixelate(l.end(), true, scalefactor); l.normalScale(m_region); pixel_list.push_back(a); int scaledcols = m_cols * scalefactor; int scaledrows = m_rows * scalefactor; int parity = 1; // Line goes upwards if (a.y > b.y) { parity = -1; // Line goes downwards a.y *= -1; b.y *= -1; // Set ay and by saves work on comparisons later on } // special case 1 if (a.x == b.x) { while (a.y < b.y) { a.y += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } } else if (a.y == b.y) { while (a.x < b.x) { a.x += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); // Lines always go left to right } } else { double hw_ratio = l.height() / l.width(); // Working all of these out leaves less scope for floating point error double wh_ratio = l.width() / l.height(); double x0_const = l.ay() - double(parity) * hw_ratio * l.ax(); double y0_const = l.ax() - double(parity) * wh_ratio * l.ay(); while (a.x < b.x || a.y < b.y) { PixelRef e; e.y = parity * int(double(scaledrows) * (x0_const + parity * hw_ratio * (double(a.x + 1) / double(scaledcols)))); // Note when decending 1.5 -> 1 and ascending 1.5 -> 2 if (parity < 0) { e.x = int(double(scaledcols) * (y0_const + wh_ratio * (double(a.y) / double(scaledrows)))); } else { e.x = int(double(scaledcols) * (y0_const + wh_ratio * (double(a.y + 1) / double(scaledrows)))); } if (a.y < e.y) { while (a.y < e.y && a.y < b.y) { a.y += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } if (a.x < b.x) { a.x += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } } else if (a.x < e.x) { while (a.x < e.x && a.x < b.x) { a.x += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } if (a.y < b.y) { a.y += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } } else { // Special case: exactly diagonal step (should only require one step): // (Should actually never happen) (Doesn't: checked with RFH) a.x += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); a.y += 1; pixel_list.push_back(PixelRef(a.x, parity * a.y)); } } } return pixel_list; } // this version includes all pixels through which the line passes with touching // counting as both pixels. PixelRefVector PixelBase::pixelateLineTouching(Line l, double tolerance) const { PixelRefVector pixel_list; // now assume that scaling to region then scaling up is going to give pixelation // this is not necessarily the case! l.normalScale(m_region); l.scale(Point2f(m_cols, m_rows)); // but it does give us a nice line... int dir; double grad, constant; if (l.width() > l.height()) { dir = XAXIS; grad = l.grad(YAXIS); constant = l.constant(YAXIS); } else { dir = YAXIS; grad = l.grad(XAXIS); constant = l.constant(XAXIS); } PixelRef bounds(m_cols, m_rows); if (dir == XAXIS) { int first = (int)floor(l.ax() - tolerance); int last = (int)floor(l.bx() + tolerance); for (int i = first; i <= last; i++) { int j1 = (int)floor((first == i ? l.ax() : double(i)) * grad + constant - l.sign() * tolerance); int j2 = (int)floor((last == i ? l.bx() : double(i + 1)) * grad + constant + l.sign() * tolerance); if (bounds.encloses(PixelRef(i, j1))) { pixel_list.push_back(PixelRef(i, j1)); } if (j1 != j2) { if (bounds.encloses(PixelRef(i, j2))) { pixel_list.push_back(PixelRef(i, j2)); } if (abs(j2 - j1) == 2) { // this rare event happens if lines are exactly diagonal int j3 = (j1 + j2) / 2; if (bounds.encloses(PixelRef(i, j3))) { pixel_list.push_back(PixelRef(i, j3)); } } } } } else { int first = (int)floor(l.bottom_left.y - tolerance); int last = (int)floor(l.top_right.y + tolerance); for (int i = first; i <= last; i++) { int j1 = (int)floor((first == i ? l.bottom_left.y : double(i)) * grad + constant - l.sign() * tolerance); int j2 = (int)floor((last == i ? l.top_right.y : double(i + 1)) * grad + constant + l.sign() * tolerance); if (bounds.encloses(PixelRef(j1, i))) { pixel_list.push_back(PixelRef(j1, i)); } if (j1 != j2) { if (bounds.encloses(PixelRef(j2, i))) { pixel_list.push_back(PixelRef(j2, i)); } if (abs(j2 - j1) == 2) { // this rare event happens if lines are exactly diagonal int j3 = (j1 + j2) / 2; if (bounds.encloses(PixelRef(j3, i))) { pixel_list.push_back(PixelRef(j3, i)); } } } } } return pixel_list; } // this version for a quick set of pixels PixelRefVector PixelBase::quickPixelateLine(PixelRef p, PixelRef q) { PixelRefVector list; double dx = q.x - p.x; double dy = q.y - p.y; int polarity = -1; double t = 0; // Quick mod - TV #if defined(_MSC_VER) if (abs(dx) == abs(dy)) { #else if (fabs(dx) == fabs(dy)) { #endif polarity = 0; } #if defined(_MSC_VER) else if (abs(dx) > abs(dy)) { t = abs(dx); #else else if (fabs(dx) > fabs(dy)) { t = fabs(dx); #endif polarity = 1; } else { #if defined(_MSC_VER) t = abs(dy); #else t = fabs(dy); #endif polarity = 2; } dx /= t; dy /= t; double ppx = p.x + 0.5; double ppy = p.y + 0.5; for (int i = 0; i <= t; i++) { if (polarity == 1 && fabs(floor(ppy) - ppy) < 1e-9) { list.push_back(PixelRef((short)floor(ppx), (short)floor(ppy + 0.5))); list.push_back(PixelRef((short)floor(ppx), (short)floor(ppy - 0.5))); } else if (polarity == 2 && fabs(floor(ppx) - ppx) < 1e-9) { list.push_back(PixelRef((short)floor(ppx + 0.5), (short)floor(ppy))); list.push_back(PixelRef((short)floor(ppx - 0.5), (short)floor(ppy))); } else { list.push_back(PixelRef((short)floor(ppx), (short)floor(ppy))); } ppx += dx; ppy += dy; } return list; } SpacePixel::SpacePixel(const std::string &name) : m_pixel_lines(0, 0) { m_name = name; m_show = true; m_edit = false; m_cols = 0; m_rows = 0; m_ref = -1; m_test = 0; m_newline = false; m_style = 0; m_color = 0; } SpacePixel::SpacePixel(const SpacePixel &spacepixel) : m_pixel_lines(spacepixel.m_pixel_lines.rows(), spacepixel.m_pixel_lines.columns()) { // n.b., not strictly allowed construct(spacepixel); } SpacePixel &SpacePixel::operator=(const SpacePixel &spacepixel) { if (this != &spacepixel) { construct(spacepixel); } return *this; } void SpacePixel::construct(const SpacePixel &spacepixel) { m_name = spacepixel.m_name; m_show = spacepixel.m_show; m_edit = spacepixel.m_edit; m_rows = spacepixel.m_rows; m_cols = spacepixel.m_cols; m_region = spacepixel.m_region; m_ref = spacepixel.m_ref; m_test = spacepixel.m_test; m_lines = spacepixel.m_lines; m_newline = true; if (!m_rows || !m_cols) { m_display_lines.clear(); return; } m_pixel_lines = spacepixel.m_pixel_lines; m_color = spacepixel.m_color; m_style = spacepixel.m_style; // m_pixel_height = spacepixel.m_pixel_height; // m_pixel_width = spacepixel.m_pixel_width; } PixelRef SpacePixel::pixelate(const Point2f &p, bool constrain, int) const { PixelRef r; Point2f p1 = p; p1.normalScale(m_region); r.x = short(p1.x * double(m_cols - 1e-9)); if (constrain) { if (r.x >= static_cast(m_cols)) r.x = m_cols - 1; else if (r.x < 0) r.x = 0; } r.y = short(p1.y * double(m_rows - 1e-9)); if (constrain) { if (r.y >= static_cast(m_rows)) r.y = m_rows - 1; else if (r.y < 0) r.y = 0; } return r; } void SpacePixel::makeViewportLines(const QtRegion &viewport) const { if (m_display_lines.empty() || m_newline) { m_display_lines = std::vector(m_lines.size()); m_newline = false; std::fill(m_display_lines.begin(), m_display_lines.end(), 0); } m_current = -1; // note: findNext expects first to be labelled -1 /* // Fixing bounding rectangle: normalisation removed QtRegion r_viewport = viewport; r_viewport.normalScale( m_region ); */ PixelRef bl = pixelate(viewport.bottom_left); PixelRef tr = pixelate(viewport.top_right); for (int i = bl.x; i <= tr.x; i++) { for (int j = bl.y; j <= tr.y; j++) { auto &pixel_lines = m_pixel_lines(static_cast(j), static_cast(i)); for (int pixel_line : pixel_lines) { m_display_lines[size_t(depthmapX::findIndexFromKey(m_lines, pixel_line))] = 1; } } } } // expect to be used as: // // if (findNext()) // getNext(); bool SpacePixel::findNextLine(bool &nextlayer) const { if (m_newline) // after adding a line you must reinitialise the display lines return false; while (++m_current < (int)m_lines.size() && m_display_lines[m_current] == 0) ; if (m_current < (int)m_lines.size()) { return true; } else { m_current = (int)m_lines.size(); nextlayer = true; return false; } } const Line &SpacePixel::getNextLine() const { m_display_lines[m_current] = 0; // You've drawn it /* // Fixing: removed rectangle scaling l.denormalScale( m_region ); */ return m_lines.find(m_current)->second.line; } void SpacePixel::initLines(int size, const Point2f &min, const Point2f &max, double density) { m_display_lines.clear(); m_lines.clear(); m_ref = -1; m_test = 0; // work out extents... m_region = QtRegion(min, max); double wh_ratio = m_region.width() / m_region.height(); double hw_ratio = m_region.height() / m_region.width(); m_rows = (int)sqrt(double(size) * wh_ratio * density); m_cols = (int)sqrt(double(size) * hw_ratio * density); if (m_rows < 1) m_rows = 1; if (m_cols < 1) m_cols = 1; // could work these two out on the fly, but it's easier to have them stored: // m_pixel_height = m_region.height() / double(m_rows); // m_pixel_width = m_region.width() / double(m_cols); m_pixel_lines = depthmapX::RowMatrix>(static_cast(m_rows), static_cast(m_cols)); } void SpacePixel::reinitLines(double density) { m_display_lines.clear(); double wh_ratio = m_region.width() / m_region.height(); double hw_ratio = m_region.height() / m_region.width(); m_rows = (int)sqrt(double(m_lines.size()) * wh_ratio * density); m_cols = (int)sqrt(double(m_lines.size()) * hw_ratio * density); if (m_rows < 1) m_rows = 1; if (m_cols < 1) m_cols = 1; m_pixel_lines = depthmapX::RowMatrix>(static_cast(m_rows), static_cast(m_cols)); // now re-add the lines: for (auto line : m_lines) { PixelRefVector list = pixelateLine(line.second.line); for (size_t j = 0; j < list.size(); j++) { // note: m_pixel_lines will be reordered by sortPixelLines m_pixel_lines(static_cast(list[j].y), static_cast(list[j].x)).push_back(line.first); } } // and finally sort: sortPixelLines(); // flag as newline just in case: m_newline = true; } // Add line: pixelate the line void SpacePixel::addLine(const Line &line) { // Fairly simple: just pixelates the line! m_ref++; // need unique keys for the lines so they can be added / removed at any time m_lines.insert(std::make_pair(m_ref, LineTest(line, 0))); m_newline = true; PixelRefVector list = pixelateLine(line); for (size_t i = 0; i < list.size(); i++) { // note: m_pixel_lines will be reordered by sortPixelLines m_pixel_lines(static_cast(list[i].y), static_cast(list[i].x)).push_back(m_ref); } } int SpacePixel::addLineDynamic(const Line &line) { m_ref++; // need unique keys for the lines so they can be added / removed at any time m_lines.insert(std::make_pair(m_ref, LineTest(line, 0))); m_newline = true; PixelRefVector list = pixelateLine(line); for (size_t i = 0; i < list.size(); i++) { // note: dynamic lines could be dodgy... only pixelate bits that fall in range if (list[i].x >= 0 && list[i].y >= 0 && static_cast(list[i].x) < m_cols && static_cast(list[i].y) < m_rows) { // note, this probably won't be reordered on dynamic m_pixel_lines(static_cast(list[i].y), static_cast(list[i].x)).push_back(m_ref); } } return m_ref; } void SpacePixel::sortPixelLines() { for (size_t i = 0; i < static_cast(m_cols); i++) { for (size_t j = 0; j < static_cast(m_rows); j++) { std::vector &pixel_lines = m_pixel_lines(j, i); // tidy up in case of removal for (auto rev_iter = pixel_lines.rbegin(); rev_iter != pixel_lines.rend(); ++rev_iter) { if (m_lines.find(*rev_iter) == m_lines.end()) { pixel_lines.erase(std::next(rev_iter).base()); } } std::sort(pixel_lines.begin(), pixel_lines.end()); } } } bool SpacePixel::intersect(const Line &l, double tolerance) { m_test++; // note loops! (but vary rarely: inevitabley, lines will have been marked before it loops) PixelRefVector list = pixelateLine(l); for (size_t i = 0; i < list.size(); i++) { auto &pixel_lines = m_pixel_lines(static_cast(list[i].y), static_cast(list[i].x)); for (int lineref : pixel_lines) { LineTest &linetest = m_lines.find(lineref)->second; if (linetest.test != m_test) { if (intersect_region(linetest.line, l)) { if (intersect_line(linetest.line, l, tolerance)) { return true; } } linetest.test = m_test; } } } return false; } bool SpacePixel::intersect_exclude(const Line &l, double tolerance) { m_test++; // note loops! (but vary rarely: inevitabley, lines will have been marked before it loops) PixelRefVector list = pixelateLine(l); for (size_t i = 0; i < list.size(); i++) { auto &pixel_lines = m_pixel_lines(static_cast(list[i].y), static_cast(list[i].x)); for (int lineref : pixel_lines) { LineTest &linetest = m_lines.find(lineref)->second; if (linetest.test != m_test) { if (intersect_region(linetest.line, l)) { if (intersect_line(linetest.line, l, tolerance)) { if (linetest.line.start() != l.start() && linetest.line.start() != l.end() && linetest.line.end() != l.start() && linetest.line.end() != l.end()) { return true; } } } linetest.test = m_test; } } } return false; } void SpacePixel::cutLine(Line &l, short dir) { m_test++; double tolerance = l.length() * 1e-9; std::set loc; PixelRefVector vec = pixelateLine(l); int axis; if (l.width() >= l.height()) { axis = XAXIS; } else { axis = YAXIS; } Point2f truestart = (dir == l.direction()) ? l.start() : l.end(); Point2f trueend = (dir == l.direction()) ? l.end() : l.start(); bool found = false; std::vector touching_lines; for (size_t i = 0; i < vec.size() && !found; i++) { // depending on direction of line either move head to tail or tail to head PixelRef pix = (dir == l.direction()) ? vec[i] : vec[vec.size() - 1 - i]; auto &pixel_lines = m_pixel_lines(static_cast(pix.y), static_cast(pix.x)); for (int lineref : pixel_lines) { // try { LineTest &linetest = m_lines.find(lineref)->second; if (linetest.test != m_test) { if (intersect_region(linetest.line, l, tolerance * linetest.line.length())) { switch (intersect_line_distinguish(linetest.line, l, tolerance * linetest.line.length())) { case 0: break; case 2: { loc.insert(l.intersection_point(linetest.line, axis)); } break; case 1: if (truestart != linetest.line.start() && truestart != linetest.line.end()) { if (!touching_lines.size()) { touching_lines.push_back(linetest.line); } else { Point2f a, b; int pair = -1; // if there may be more than one touches in the same pixel, we have to build a list of // possibles... for (size_t k = 0; k < touching_lines.size() && pair == -1; k++) { if (linetest.line.start() == touching_lines[k].start() || linetest.line.end() == touching_lines[k].end()) { a = linetest.line.end() - linetest.line.start(); pair = k; } else if (linetest.line.start() == touching_lines[k].end() || linetest.line.end() == touching_lines[k].start()) { a = linetest.line.start() - linetest.line.end(); pair = k; } if (pair != -1) { b = touching_lines[pair].end() - touching_lines[pair].start(); Point2f p = trueend - truestart; double oa = det(p, a); double ob = det(p, b); if (sgn(oa) != sgn(ob) || fabs(oa) < tolerance * linetest.line.length() || fabs(ob) < tolerance * linetest.line.length()) { // crossed if (fabs(oa) > tolerance * linetest.line.length()) { // checks not parallel... loc.insert(l.intersection_point(linetest.line, axis)); } else if (fabs(ob) > tolerance * linetest.line.length()) { loc.insert(l.intersection_point(touching_lines[pair], axis)); } else { // parallel with both lines ... this shouldn't happen... std::cerr << "couldn't chop at boundary" << std::endl; } } } pair = -1; } touching_lines.push_back(linetest.line); } } break; default: break; } } linetest.test = m_test; } //} // catch (pexception) { // the lineref may have been deleted -- this is supposed to be tidied up // just ignore... // cerr << "cut line exception -- missing line?" << endl; //} } if (loc.size()) { // there's no guarantee the loc actually happened in this pixel... // check the first loc actually occurred in this pixel... if ((dir == l.direction() && (axis == XAXIS || l.sign() == 1)) || (dir != l.direction() && (axis == YAXIS && l.sign() == -1))) { if (pix == pixelate(l.point_on_line(*loc.begin(), axis))) { found = true; } } else { if (pix == pixelate(l.point_on_line(*loc.rbegin(), axis))) { found = true; } } } } if (loc.size()) { // it intersected... double pos; if (dir == l.direction()) { if (axis == XAXIS) { pos = *loc.begin(); l.by() = l.ay() + l.sign() * l.height() * (pos - l.ax()) / l.width(); l.bx() = pos; } else if (l.sign() == 1) { pos = *loc.begin(); l.bx() = l.ax() + l.width() * (pos - l.ay()) / l.height(); l.by() = pos; } else { pos = *loc.rbegin(); l.bx() = l.ax() + l.width() * (l.ay() - pos) / l.height(); l.by() = pos; } } else { if (axis == XAXIS) { pos = *loc.rbegin(); l.ay() = l.by() - l.sign() * l.height() * (l.bx() - pos) / l.width(); l.ax() = pos; } else if (l.sign() == 1) { pos = *loc.rbegin(); l.ax() = l.bx() - l.width() * (l.by() - pos) / l.height(); l.ay() = pos; } else { pos = *loc.begin(); l.ax() = l.bx() - l.width() * (pos - l.by()) / l.height(); l.ay() = pos; } } } } bool SpacePixel::read(std::istream &stream) { // clear anything that was there: m_display_lines.clear(); m_lines.clear(); // read name: m_name = dXstring::readString(stream); stream.read((char *)&m_show, sizeof(m_show)); if (m_name.empty()) { m_name = ""; } m_edit = false; // <- just default to not editable on read stream.read((char *)&m_color, sizeof(m_color)); // read extents: stream.read((char *)&m_region, sizeof(m_region)); // read rows / cols int rows, cols; stream.read(reinterpret_cast(&rows), sizeof(rows)); stream.read(reinterpret_cast(&cols), sizeof(cols)); m_rows = static_cast(rows); m_cols = static_cast(cols); // could work these two out on the fly, but it's easier to have them stored: // m_pixel_height = m_region.height() / double(m_rows); // m_pixel_width = m_region.width() / double(m_cols); // prepare loader: m_pixel_lines = depthmapX::RowMatrix>(static_cast(m_rows), static_cast(m_cols)); stream.read((char *)&m_ref, sizeof(m_ref)); dXreadwrite::readIntoMap(stream, m_lines); // now load into structure: int n = -1; for (auto line : m_lines) { n++; PixelRefVector list = pixelateLine(line.second.line); for (size_t m = 0; m < list.size(); m++) { // note: m_pixel_lines is an *ordered* list! --- used by other ops. m_pixel_lines(static_cast(list[m].y), static_cast(list[m].x)).push_back(n); } } return true; } bool SpacePixel::write(std::ofstream &stream) { // write name: dXstring::writeString(stream, m_name); stream.write((char *)&m_show, sizeof(m_show)); stream.write((char *)&m_color, sizeof(m_color)); // write extents: stream.write((char *)&m_region, sizeof(m_region)); // write rows / cols int rows = static_cast(m_rows); int cols = static_cast(m_cols); stream.write(reinterpret_cast(&rows), sizeof(rows)); stream.write(reinterpret_cast(&cols), sizeof(cols)); // write lines: stream.write((char *)&m_ref, sizeof(m_ref)); dXreadwrite::writeMap(stream, m_lines); return true; } ================================================ FILE: salalib/spacepix.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #pragma once #include "salalib/pafcolor.h" #include "salalib/pixelref.h" #include "genlib/p2dpoly.h" #include "genlib/pafmath.h" #include "genlib/simplematrix.h" #include "genlib/stringutils.h" #include #include class SalaShape; class PixelBase { protected: size_t m_rows; size_t m_cols; QtRegion m_region; public: PixelBase() { ; } // constrain is constrain to bounding box (i.e., in row / col bounds) virtual PixelRef pixelate(const Point2f &, bool constrain = true, int scalefactor = 1) const = 0; PixelRefVector pixelateLine(Line l, int scalefactor = 1) const; PixelRefVector pixelateLineTouching(Line l, double tolerance) const; PixelRefVector quickPixelateLine(PixelRef p, PixelRef q); bool includes(const PixelRef pix) const { return (pix.x >= 0 && pix.x < static_cast(m_cols) && pix.y >= 0 && pix.y < static_cast(m_rows)); } size_t getCols() const { return m_cols; } size_t getRows() const { return m_rows; } const QtRegion &getRegion() const { return m_region; } }; ///////////////////////////////////////////// // couple of quick helpers struct LineTest { Line line; unsigned int test; LineTest(const Line &l = Line(), int t = -1) { line = l; test = t; } // operator Line() {return line;} }; struct LineKey { unsigned int file : 4; unsigned int layer : 6; unsigned int lineref : 20; operator int() { return *(int *)this; } LineKey(int value = 0) { *(int *)this = value; } friend bool operator<(LineKey a, LineKey b); friend bool operator>(LineKey a, LineKey b); friend bool operator==(LineKey a, LineKey b); }; inline bool operator<(LineKey a, LineKey b) { return int(a) < int(b); } inline bool operator>(LineKey a, LineKey b) { return int(a) > int(b); } inline bool operator==(LineKey a, LineKey b) { return int(a) == int(b); } ///////////////////////////////////////////// class SpacePixel : public PixelBase { friend class PointMap; friend class AxialMaps; friend class AxialPolygons; friend class ShapeMap; // for transfer to everything being ShapeMaps protected: bool m_lock; mutable bool m_newline; protected: PafColor m_color; int m_style; // allows for bold / dotted lines etc std::string m_name; bool m_show; bool m_edit; depthmapX::RowMatrix> m_pixel_lines; int m_ref; std::map m_lines; // // for screen drawing mutable std::vector m_display_lines; mutable int m_current; // // for line testing mutable unsigned int m_test; // public: SpacePixel(const std::string &name = std::string("Default")); // SpacePixel(const SpacePixel &spacepixel); SpacePixel &operator=(const SpacePixel &spacepixel); void construct(const SpacePixel &spacepixel); // PixelRef pixelate(const Point2f &p, bool constrain = true, int = 1) const; // PixelRefVector pixelate( const Line& l ) const; // void initLines(int size, const Point2f &min, const Point2f &max, double density = 1.0); void reinitLines(double density); // just reinitialises pixel lines, keeps lines, current ref and test setting // void addLine(const Line &l); void sortPixelLines(); // int addLineDynamic(const Line &l); virtual void makeViewportLines(const QtRegion &viewport) const; virtual bool findNextLine(bool &) const; virtual const Line &getNextLine() const; // bool intersect(const Line &l, double tolerance = 0.0); bool intersect_exclude(const Line &l, double tolerance = 0.0); void cutLine(Line &l, short dir); QtRegion &getRegion() const { return (QtRegion &)m_region; } void setRegion(QtRegion ®ion) { m_region = region; } // const std::map &getAllLines() const // Danger! Use solely to look at the raw line data { return m_lines; } // // For easy layer manipulation: void setName(const std::string &name) { m_name = name; } std::string getName() { return m_name; } void setShow(bool show = true) { m_show = show; } bool isShown() const { return m_show; } void setEditable(bool edit = true) { m_edit = edit; } bool isEditable() const { return m_edit; } public: virtual bool read(std::istream &stream); virtual bool write(std::ofstream &stream); friend bool operator==(const SpacePixel &a, const SpacePixel &b); }; // simply check they are the same name... useful for findindex from the group inline bool operator==(const SpacePixel &a, const SpacePixel &b) { return a.m_name == b.m_name; } ================================================ FILE: salalib/spacepixfile.cpp ================================================ #include "salalib/spacepixfile.h" void SpacePixelFile::makeViewportShapes( const QtRegion& viewport ) const { m_current_layer = -1; for (size_t i = m_spacePixels.size() - 1; static_cast(i) != -1; i--) { if (m_spacePixels[i].isShown()) { m_current_layer = (int) i; m_spacePixels[i].makeViewportShapes( (viewport.atZero() ? m_region : viewport) ); } } } bool SpacePixelFile::findNextShape(bool& nextlayer) const { if (m_current_layer == -1) return false; while (!m_spacePixels[m_current_layer].findNextShape(nextlayer)) { while (++m_current_layer < (int)m_spacePixels.size() && !m_spacePixels[m_current_layer].isShown()); if (m_current_layer == static_cast(m_spacePixels.size())) { m_current_layer = -1; return false; } } return true; } bool SpacePixelFile::read( std::istream& stream ) { m_name = dXstring::readString(stream); stream.read( (char *) &m_region, sizeof(m_region) ); int count; stream.read( (char *) &count, sizeof(count) ); for (int i = 0; i < count; i++) { m_spacePixels.emplace_back(); m_spacePixels.back().read(stream); } if (m_name.empty()) { m_name = ""; } return true; } bool SpacePixelFile::write( std::ofstream& stream ) { dXstring::writeString(stream, m_name); stream.write( (char *) &m_region, sizeof(m_region) ); // Quick mod - TV int count = m_spacePixels.size(); stream.write( (char *) &count, sizeof(count) ); for (auto& spacePixel: m_spacePixels) { spacePixel.write(stream); } return true; } ================================================ FILE: salalib/spacepixfile.h ================================================ #pragma once #include "salalib/shapemap.h" #include "genlib/p2dpoly.h" #include #include class SpacePixelFile { protected: std::string m_name; // <- file name mutable int m_current_layer; public: std::deque m_spacePixels; QtRegion m_region; // easier public for now // SpacePixelFile(const std::string& name = std::string()) { m_name = name; m_current_layer = -1; } SpacePixelFile(SpacePixelFile&& other): m_name(other.m_name), m_current_layer(other.m_current_layer), m_spacePixels(std::move(other.m_spacePixels)), m_region(std::move(other.m_region)) {} SpacePixelFile& operator =(SpacePixelFile&& other) { m_name = other.m_name; m_current_layer = other.m_current_layer; m_spacePixels = std::move(other.m_spacePixels); m_region = std::move(other.m_region); return *this; } SpacePixelFile(const SpacePixelFile&) = delete; SpacePixelFile& operator =(const SpacePixelFile&) = delete; void setName(const std::string& name) { m_name = name; } const std::string& getName() const { return m_name; } // QtRegion& getRegion() const { return (QtRegion&) m_region; } // // Screen functionality: void makeViewportShapes( const QtRegion& viewport = QtRegion() ) const; bool findNextShape(bool& nextlayer) const; const SalaShape& getNextShape() const { return m_spacePixels[m_current_layer].getNextShape(); } // Is any one sublayer shown? bool isShown() const { for (size_t i = 0; i < m_spacePixels.size(); i++) if (m_spacePixels[i].isShown()) return true; return false; } // public: bool read(std::istream &stream); bool write(std::ofstream& stream); }; ================================================ FILE: salalib/sparksieve2.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines ///////////////////////////////////////////////////////////////////////////////// // New spark sieve implemementation (more accurate) #include #include #include #include #include "sparksieve2.h" sparkSieve2::sparkSieve2( const Point2f& centre, double maxdist ) { m_centre = centre; m_maxdist = maxdist; m_gaps.push_back( sparkZone2(0.0, 1.0) ); } sparkSieve2::~sparkSieve2() { } bool sparkSieve2::testblock( const Point2f& point, const std::vector& lines, double tolerance ) { Line l(m_centre, point); // maxdist is to construct graphs with a maximum visible distance: (-1.0 is infinite) if (m_maxdist != -1.0 && l.length() > m_maxdist) { return true; } for (auto line: lines) { // Note: must check regions intersect before using this intersect_line test -- see notes on intersect_line if (intersect_region(l,line,tolerance) && intersect_line(l,line,tolerance)) { return true; } } return false; } // void sparkSieve2::block( const std::vector& lines, int q ) { for (auto line: lines) { double a = tanify(line.start(), q); double b = tanify(line.end(), q); sparkZone2 block; if (a < b) { block.start = a - 1e-10; // 1e-10 required for floating point error block.end = b + 1e-10; } else { block.start = b - 1e-10; // 1e-10 required for floating point error block.end = a + 1e-10; } // this creates a list of blocks sorted by start location m_blocks.push_back(block); } std::sort( m_blocks.begin(), m_blocks.end() ); m_blocks.erase( std::unique( m_blocks.begin(), m_blocks.end() ), m_blocks.end() ); } void sparkSieve2::collectgarbage() { auto iter = m_gaps.begin(); auto blockIter = m_blocks.begin(); for (; blockIter != m_blocks.end() && iter != m_gaps.end();) { if (blockIter->end < iter->start) { blockIter++; continue; } bool create = true; if (blockIter->start <= iter->start) { create = false; if (blockIter->end > iter->start) { // simply move the start in front of us iter->start = blockIter->end; } } if (blockIter->end >= iter->end) { create = false; if (blockIter->start < iter->end) { // move the end behind us iter->end = blockIter->start; } } if (iter->end <= iter->start + 1e-10) { // 1e-10 required for floating point error iter = m_gaps.erase(iter); continue; // on the next iteration, stay with this block } else if (blockIter->end > iter->end) { ++iter; continue; // on the next iteration, stay with this block } else if (create) { // add a new gap (has to be behind us), and move the start in front of us m_gaps.insert(iter, sparkZone2( iter->start, blockIter->start ) ); iter->start = blockIter->end; } blockIter++; } // reset blocks for next row: m_blocks.clear(); } /* q quadrants: * * \ 6 | 7 / * 0 \ | / 1 * - - - - * 2 / | \ 3 * / 4 | 5 \ */ double sparkSieve2::tanify( const Point2f& point, int q ) { switch (q) { case 0: return (point.y - m_centre.y) / (m_centre.x - point.x); break; case 1: return (point.y - m_centre.y) / (point.x - m_centre.x); break; case 2: return (m_centre.y - point.y) / (m_centre.x - point.x); break; case 3: return (m_centre.y - point.y) / (point.x - m_centre.x); break; case 4: return (m_centre.x - point.x) / (m_centre.y - point.y); break; case 5: return (point.x - m_centre.x) / (m_centre.y - point.y); break; case 6: return (m_centre.x - point.x) / (point.y - m_centre.y); break; case 7: return (point.x - m_centre.x) / (point.y - m_centre.y); break; } return -1.0; } ================================================ FILE: salalib/sparksieve2.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2011-2012, Tasos Varoudis // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This is my code to make a set of axial lines from a set of boundary lines #ifndef __SPARKSIEVE2_H__ #define __SPARKSIEVE2_H__ #include #include "genlib/p2dpoly.h" #include #include class sparkSieve2 { public: struct sparkZone2{ double start; double end; bool remove; sparkZone2( double s = 0.0, double e = 0.0 ) { start = s; end = e; remove = false; } // to allow ordered lists: friend bool operator == (const sparkZone2& a, const sparkZone2& b); friend bool operator != (const sparkZone2& a, const sparkZone2& b); friend bool operator < (const sparkZone2& a, const sparkZone2& b); friend bool operator > (const sparkZone2& a, const sparkZone2& b); }; private: Point2f m_centre; double m_maxdist; // for creating graphs that only see out a certain distance: set to -1.0 for infinite std::vector m_blocks; public: std::list m_gaps; public: sparkSieve2( const Point2f& centre, double maxdist = -1.0 ); ~sparkSieve2(); bool testblock(const Point2f& point, const std::vector &lines, double tolerance ); void block(const std::vector &lines, int q ); void collectgarbage(); double tanify( const Point2f& point, int q ); // bool hasGaps() const { return (!m_gaps.empty()); } }; inline bool operator == (const sparkSieve2::sparkZone2& a, const sparkSieve2::sparkZone2& b) { return (a.start == b.start && a.end == b.end); } inline bool operator != (const sparkSieve2::sparkZone2& a, const sparkSieve2::sparkZone2& b) { return (a.start != b.start || a.end != b.end); } inline bool operator < (const sparkSieve2::sparkZone2& a, const sparkSieve2::sparkZone2& b) { return (a.start == b.start) ? (a.end > b.end) : (a.start < b.start); } inline bool operator > (const sparkSieve2::sparkZone2& a, const sparkSieve2::sparkZone2& b) { return (a.start == b.start) ? (a.end < b.end) : (a.start > b.start); } #endif ================================================ FILE: salalib/tidylines.cpp ================================================ #include "salalib/tidylines.h" #include "salalib/tolerances.h" // helper -- a little class to tidy up a set of lines void TidyLines::tidy(std::vector& lines, const QtRegion& region) { m_region = region; double maxdim = std::max(m_region.width(),m_region.height()); // simple first pass -- remove very short lines lines.erase( std::remove_if(lines.begin(), lines.end(), [maxdim](const Line& line) {return line.length() < maxdim * TOLERANCE_B;}), lines.end()); // now load up m_lines... initLines(lines.size(),m_region.bottom_left,m_region.top_right); for (auto& line: lines) { addLine(line); } sortPixelLines(); std::vector removelist; for (size_t i = 0; i < lines.size(); i++) { // n.b., as m_lines have just been made, note that what's in m_lines matches whats in lines // we will use this later! m_test++; m_lines[i].test = m_test; PixelRefVector list = pixelateLine( m_lines[i].line ); for (size_t a = 0; a < list.size(); a++) { auto pixel_lines = m_pixel_lines(static_cast(list[a].y), static_cast(list[a].x)); for (int j: pixel_lines) { if (m_lines[j].test != m_test && j > (int)i && intersect_region(lines[i],lines[j],TOLERANCE_B * maxdim)) { m_lines[j].test = m_test; int axis_i = (lines[i].width() >= lines[i].height()) ? XAXIS : YAXIS; int axis_j = (lines[j].width() >= lines[j].height()) ? XAXIS : YAXIS; int axis_reverse = (axis_i == XAXIS) ? YAXIS : XAXIS; if (axis_i == axis_j && fabs(lines[i].grad(axis_reverse) - lines[j].grad(axis_reverse)) < TOLERANCE_A && fabs(lines[i].constant(axis_reverse) - lines[j].constant(axis_reverse)) < (TOLERANCE_B * maxdim)) { // check for overlap and merge int parity = (axis_i == XAXIS) ? 1 : lines[i].sign(); if ((lines[i].start()[axis_i] * parity + TOLERANCE_B * maxdim) > (lines[j].start()[axis_j] * parity) && (lines[i].start()[axis_i] * parity) < (lines[j].end()[axis_j] * parity + TOLERANCE_B * maxdim)) { int end = ((lines[i].end()[axis_i] * parity) > (lines[j].end()[axis_j] * parity)) ? i : j; lines[j].bx() = lines[end].bx(); lines[j].by() = lines[end].by(); removelist.push_back(i); continue; // <- don't do this any more, we've zapped it and replaced it with the later line } if ((lines[j].start()[axis_j] * parity + TOLERANCE_B * maxdim) > (lines[i].start()[axis_i] * parity) && (lines[j].start()[axis_j] * parity) < (lines[i].end()[axis_i] * parity + TOLERANCE_B * maxdim)) { int end = ((lines[i].end()[axis_i] * parity) > (lines[j].end()[axis_j] * parity)) ? i : j; lines[j].ax() = lines[i].ax(); lines[j].ay() = lines[i].ay(); lines[j].bx() = lines[end].bx(); lines[j].by() = lines[end].by(); removelist.push_back(i); continue; // <- don't do this any more, we've zapped it and replaced it with the later line } } } } } } // comes out sorted, remove duplicates just in case removelist.erase(std::unique(removelist.begin(), removelist.end()), removelist.end()); for(auto iter = removelist.rbegin(); iter != removelist.rend(); ++iter) lines.erase(lines.begin() + *iter); removelist.clear(); // always clear this list, it's reused } void TidyLines::quicktidy(std::map>& lines, const QtRegion& region) { m_region = region; double avglen = 0.0; for (auto line: lines) { avglen += line.second.first.length(); } avglen /= lines.size(); double tolerance = avglen * 10e-6; auto iter = lines.begin(), end = lines.end(); for(; iter != end; ) { if (iter->second.first.length() < tolerance) { iter = lines.erase(iter); } else { ++iter; } } // now load up m_lines... initLines(lines.size(),m_region.bottom_left,m_region.top_right); for (auto line: lines) { addLine(line.second.first); } sortPixelLines(); // and chop duplicate lines: std::vector removelist; int i = -1; for (auto line: lines) { i++; PixelRef start = pixelate(line.second.first.start()); auto& pixel_lines = m_pixel_lines(static_cast(start.y), static_cast(start.x)); for (int k: pixel_lines) { if (k > int(i) && approxeq(m_lines[i].line.start(),m_lines[k].line.start(),tolerance)) { if (approxeq(m_lines[i].line.end(),m_lines[k].line.end(),tolerance)) { removelist.push_back(line.first); break; } } } } for(int remove: removelist) { lines.erase(remove); } removelist.clear(); // always clear this list, it's reused} } ================================================ FILE: salalib/tidylines.h ================================================ #pragma once #include "salalib/spacepix.h" #include "genlib/p2dpoly.h" // helpers... a class to tidy up ugly maps people may give me... class TidyLines : public SpacePixel { public: void tidy(std::vector &lines, const QtRegion& region); void quicktidy(std::map > &lines, const QtRegion& region); }; ================================================ FILE: salalib/tolerances.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2018 Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once static const double TOLERANCE_A = 1e-9; static const double TOLERANCE_B = 1e-12; static const double TOLERANCE_C = 1e-6; ================================================ FILE: salalib/vgamodules/CMakeLists.txt ================================================ target_sources(salalib PRIVATE vgaisovist.cpp vgaangular.cpp vgametric.cpp vgathroughvision.cpp vgavisuallocal.cpp vgavisualglobal.cpp vgaangulardepth.cpp vgametricdepth.cpp vgavisualglobaldepth.cpp PUBLIC vgaangular.h vgametric.h vgavisualglobal.h vgaangulardepth.h vgametricdepth.h vgavisualglobaldepth.h vgaisovist.h vgathroughvision.h vgavisuallocal.h) ================================================ FILE: salalib/vgamodules/vgaangular.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgaangular.h" #include "genlib/stringutils.h" bool VGAAngular::run(Communicator *comm, PointMap &map, bool) { time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } std::string radius_text; if (m_radius != -1.0) { if (map.getRegion().width() > 100.0) { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.f"); } else if (map.getRegion().width() < 1.0) { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.4f"); } else { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.2f"); } } AttributeTable &attributes = map.getAttributeTable(); // n.b. these must be entered in alphabetical order to preserve col indexing: std::string mean_depth_col_text = std::string("Angular Mean Depth") + radius_text; int mean_depth_col = attributes.getOrInsertColumn(mean_depth_col_text.c_str()); std::string total_detph_col_text = std::string("Angular Total Depth") + radius_text; int total_depth_col = attributes.getOrInsertColumn(total_detph_col_text.c_str()); std::string count_col_text = std::string("Angular Node Count") + radius_text; int count_col = attributes.getOrInsertColumn(count_col_text.c_str()); // TODO: Binary compatibility. Remove in re-examination total_depth_col = attributes.getOrInsertColumn(total_detph_col_text.c_str()); int count = 0; for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); if (map.getPoint(curs).filled()) { if (m_gates_only) { count++; continue; } // TODO: Break out miscs/dist/cumangle into local variables and remove from Point class for (auto &point : map.getPoints()) { point.m_misc = 0; point.m_dist = 0.0f; point.m_cumangle = -1.0f; } float total_angle = 0.0f; int total_nodes = 0; // note that m_misc is used in a different manner to analyseGraph / PointDepth // here it marks the node as used in calculation only std::set search_list; search_list.insert(AngularTriple(0.0f, curs, NoPixel)); map.getPoint(curs).m_cumangle = 0.0f; while (search_list.size()) { std::set::iterator it = search_list.begin(); AngularTriple here = *it; search_list.erase(it); if (m_radius != -1.0 && here.angle > m_radius) { break; } Point &p = map.getPoint(here.pixel); // nb, the filled check is necessary as diagonals seem to be stored with 'gaps' left in if (p.filled() && p.m_misc != ~0) { p.getNode().extractAngular(search_list, &map, here); p.m_misc = ~0; if (!p.getMergePixel().empty()) { Point &p2 = map.getPoint(p.getMergePixel()); if (p2.m_misc != ~0) { p2.m_cumangle = p.m_cumangle; p2.getNode().extractAngular(search_list, &map, AngularTriple(here.angle, p.getMergePixel(), NoPixel)); p2.m_misc = ~0; } } total_angle += p.m_cumangle; total_nodes += 1; } } AttributeRow &row = map.getAttributeTable().getRow(AttributeKey(curs)); if (total_nodes > 0) { row.setValue(mean_depth_col, float(double(total_angle) / double(total_nodes))); } row.setValue(total_depth_col, total_angle); row.setValue(count_col, float(total_nodes)); count++; // <- increment count } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } map.setDisplayedAttribute(-2); map.setDisplayedAttribute(mean_depth_col); return true; } ================================================ FILE: salalib/vgamodules/vgaangular.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAAngular : IVGA { private: double m_radius; bool m_gates_only; public: std::string getAnalysisName() const override { return "Angular Analysis"; } bool run(Communicator *, PointMap &map, bool) override; VGAAngular(double radius, bool gates_only) : m_radius(radius), m_gates_only(gates_only) {} }; ================================================ FILE: salalib/vgamodules/vgaangulardepth.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgaangulardepth.h" #include "genlib/stringutils.h" bool VGAAngularDepth::run(Communicator *, PointMap &map, bool) { AttributeTable &attributes = map.getAttributeTable(); // n.b., insert columns sets values to -1 if the column already exists int path_angle_col = attributes.insertOrResetColumn("Angular Step Depth"); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { PixelRef pix = iter->getKey().value; map.getPoint(pix).m_misc = 0; map.getPoint(pix).m_dist = 0.0f; map.getPoint(pix).m_cumangle = -1.0f; } std::set search_list; // contains root point for (auto &sel : map.getSelSet()) { search_list.insert(AngularTriple(0.0f, sel, NoPixel)); map.getPoint(sel).m_cumangle = 0.0f; } // note that m_misc is used in a different manner to analyseGraph / PointDepth // here it marks the node as used in calculation only while (search_list.size()) { std::set::iterator it = search_list.begin(); AngularTriple here = *it; search_list.erase(it); Point &p = map.getPoint(here.pixel); // nb, the filled check is necessary as diagonals seem to be stored with 'gaps' left in if (p.filled() && p.m_misc != ~0) { p.getNode().extractAngular(search_list, &map, here); p.m_misc = ~0; AttributeRow &row = map.getAttributeTable().getRow(AttributeKey(here.pixel)); row.setValue(path_angle_col, float(p.m_cumangle)); if (!p.getMergePixel().empty()) { Point &p2 = map.getPoint(p.getMergePixel()); if (p2.m_misc != ~0) { p2.m_cumangle = p.m_cumangle; AttributeRow &mergePixelRow = map.getAttributeTable().getRow(AttributeKey(p.getMergePixel())); mergePixelRow.setValue(path_angle_col, float(p2.m_cumangle)); p2.getNode().extractAngular(search_list, &map, AngularTriple(here.angle, p.getMergePixel(), NoPixel)); p2.m_misc = ~0; } } } } map.setDisplayedAttribute(-2); map.setDisplayedAttribute(path_angle_col); return true; } ================================================ FILE: salalib/vgamodules/vgaangulardepth.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAAngularDepth : IVGA { public: std::string getAnalysisName() const override { return "Angular Depth"; } bool run(Communicator *comm, PointMap &map, bool) override; }; ================================================ FILE: salalib/vgamodules/vgaisovist.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgaisovist.h" #include "salalib/isovist.h" #include "genlib/stringutils.h" bool VGAIsovist::run(Communicator *comm, PointMap &map, bool simple_version) { map.m_hasIsovistAnalysis = false; // note, BSP tree plays with comm counting... if(comm) { comm->CommPostMessage(Communicator::NUM_STEPS, 2); comm->CommPostMessage(Communicator::CURRENT_STEP, 1); } BSPNode bspRoot = makeBSPtree(comm, map.getDrawingFiles()); AttributeTable &attributes = map.getAttributeTable(); if(comm) comm->CommPostMessage(Communicator::CURRENT_STEP, 2); time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } int count = 0; for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); if (map.getPoint(curs).filled()) { count++; if (map.getPoint(curs).contextfilled() && !curs.iseven()) { continue; } Isovist isovist; isovist.makeit(&bspRoot, map.depixelate(curs), map.getRegion(), 0, 0); AttributeRow &row = attributes.getRow(AttributeKey(curs)); isovist.setData(attributes, row, simple_version); Node &node = map.getPoint(curs).getNode(); std::vector *occ = node.m_occlusion_bins; for (size_t k = 0; k < 32; k++) { occ[k].clear(); node.bin(static_cast(k)).setOccDistance(0.0f); } for (size_t k = 0; k < isovist.getOcclusionPoints().size(); k++) { const PointDist &pointdist = isovist.getOcclusionPoints().at(k); int bin = whichbin(pointdist.m_point - map.depixelate(curs)); // only occlusion bins with a certain distance recorded (arbitrary scale note!) if (pointdist.m_dist > 1.5) { PixelRef pix = map.pixelate(pointdist.m_point); if (pix != curs) { occ[bin].push_back(pix); } } node.bin(bin).setOccDistance(static_cast(pointdist.m_dist)); } } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } map.m_hasIsovistAnalysis = true; return true; } BSPNode VGAIsovist::makeBSPtree(Communicator *communicator, const std::vector& drawingFiles) { std::vector partitionlines; for (const auto &pixelGroup : drawingFiles) { for (const auto &pixel : pixelGroup.m_spacePixels) { // chooses the first editable layer it can find: if (pixel.isShown()) { auto refShapes = pixel.getAllShapes(); int k = -1; for (const auto &refShape : refShapes) { k++; std::vector newLines = refShape.second.getAsLines(); // I'm not sure what the tagging was meant for any more, // tagging at the moment tags the *polygon* it was original attached to // must check it is not a zero length line: for (const Line &line : newLines) { if (line.length() > 0.0) { partitionlines.push_back(TaggedLine(line, k)); } } } } } } BSPNode bspRoot; if (partitionlines.size()) { time_t atime = 0; if(communicator) { communicator->CommPostMessage(Communicator::NUM_RECORDS, static_cast(partitionlines.size())); qtimer(atime, 0); } BSPTree::make(communicator, atime, partitionlines, &bspRoot); } return bspRoot; } ================================================ FILE: salalib/vgamodules/vgaisovist.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAIsovist : IVGA { public: std::string getAnalysisName() const override { return "Isovist Analysis"; } bool run(Communicator *comm, PointMap &map, bool simple_version) override; BSPNode makeBSPtree(Communicator *communicator, const std::vector &drawingFiles); }; ================================================ FILE: salalib/vgamodules/vgametric.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgametric.h" #include "genlib/stringutils.h" // This is a slow algorithm, but should give the correct answer // for demonstrative purposes bool VGAMetric::run(Communicator *comm, PointMap &map, bool) { time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } std::string radius_text; if (m_radius != -1.0) { if (m_radius > 100.0) { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.f"); } else if (map.getRegion().width() < 1.0) { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.4f"); } else { radius_text = std::string(" R") + dXstring::formatString(m_radius, "%.2f"); } } AttributeTable &attributes = map.getAttributeTable(); // n.b. these must be entered in alphabetical order to preserve col indexing: std::string mspa_col_text = std::string("Metric Mean Shortest-Path Angle") + radius_text; int mspa_col = attributes.insertOrResetColumn(mspa_col_text.c_str()); std::string mspl_col_text = std::string("Metric Mean Shortest-Path Distance") + radius_text; int mspl_col = attributes.insertOrResetColumn(mspl_col_text.c_str()); std::string dist_col_text = std::string("Metric Mean Straight-Line Distance") + radius_text; int dist_col = attributes.insertOrResetColumn(dist_col_text.c_str()); std::string count_col_text = std::string("Metric Node Count") + radius_text; int count_col = attributes.insertOrResetColumn(count_col_text.c_str()); int count = 0; for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); if (map.getPoint(curs).filled()) { if (m_gates_only) { count++; continue; } // TODO: Break out miscs/dist/cumangle into local variables and remove from Point class for (auto &point : map.getPoints()) { point.m_misc = 0; point.m_dist = -1.0f; point.m_cumangle = 0.0f; } float euclid_depth = 0.0f; float total_depth = 0.0f; float total_angle = 0.0f; int total_nodes = 0; // note that m_misc is used in a different manner to analyseGraph / PointDepth // here it marks the node as used in calculation only std::set search_list; search_list.insert(MetricTriple(0.0f, curs, NoPixel)); while (search_list.size()) { std::set::iterator it = search_list.begin(); MetricTriple here = *it; search_list.erase(it); if (m_radius != -1.0 && (here.dist * map.getSpacing()) > m_radius) { break; } Point &p = map.getPoint(here.pixel); // nb, the filled check is necessary as diagonals seem to be stored with 'gaps' left in if (p.filled() && p.m_misc != ~0) { p.getNode().extractMetric(search_list, &map, here); p.m_misc = ~0; if (!p.getMergePixel().empty()) { Point &p2 = map.getPoint(p.getMergePixel()); if (p2.m_misc != ~0) { p2.m_cumangle = p.m_cumangle; p2.getNode().extractMetric(search_list, &map, MetricTriple(here.dist, p.getMergePixel(), NoPixel)); p2.m_misc = ~0; } } total_depth += float(here.dist * map.getSpacing()); total_angle += p.m_cumangle; euclid_depth += float(map.getSpacing() * dist(here.pixel, curs)); total_nodes += 1; } } AttributeRow &row = attributes.getRow(AttributeKey(curs)); row.setValue(mspa_col, float(double(total_angle) / double(total_nodes))); row.setValue(mspl_col, float(double(total_depth) / double(total_nodes))); row.setValue(dist_col, float(double(euclid_depth) / double(total_nodes))); row.setValue(count_col, float(total_nodes)); count++; // <- increment count } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } map.overrideDisplayedAttribute(-2); map.setDisplayedAttribute(mspl_col); return true; } ================================================ FILE: salalib/vgamodules/vgametric.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAMetric : IVGA { private: double m_radius; bool m_gates_only; public: std::string getAnalysisName() const override { return "Metric Analysis"; } bool run(Communicator *comm, PointMap &map, bool) override; VGAMetric(double radius, bool gates_only) : m_radius(radius), m_gates_only(gates_only) {} }; ================================================ FILE: salalib/vgamodules/vgametricdepth.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgametricdepth.h" #include "genlib/stringutils.h" bool VGAMetricDepth::run(Communicator *, PointMap &map, bool) { AttributeTable &attributes = map.getAttributeTable(); // n.b., insert columns sets values to -1 if the column already exists int path_angle_col = attributes.insertOrResetColumn("Metric Step Shortest-Path Angle"); int path_length_col = attributes.insertOrResetColumn("Metric Step Shortest-Path Length"); int dist_col = -1; if (map.getSelSet().size() == 1) { // Note: Euclidean distance is currently only calculated from a single point dist_col = attributes.insertOrResetColumn("Metric Straight-Line Distance"); } for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { PixelRef pix = iter->getKey().value; map.getPoint(pix).m_misc = 0; map.getPoint(pix).m_dist = -1.0f; map.getPoint(pix).m_cumangle = 0.0f; } // in order to calculate Penn angle, the MetricPair becomes a metric triple... std::set search_list; // contains root point for (auto &sel : map.getSelSet()) { search_list.insert(MetricTriple(0.0f, sel, NoPixel)); } // note that m_misc is used in a different manner to analyseGraph / PointDepth // here it marks the node as used in calculation only while (search_list.size()) { std::set::iterator it = search_list.begin(); MetricTriple here = *it; search_list.erase(it); Point &p = map.getPoint(here.pixel); // nb, the filled check is necessary as diagonals seem to be stored with 'gaps' left in if (p.filled() && p.m_misc != ~0) { p.getNode().extractMetric(search_list, &map, here); p.m_misc = ~0; AttributeRow &row = map.getAttributeTable().getRow(AttributeKey(here.pixel)); row.setValue(path_length_col, float(map.getSpacing() * here.dist)); row.setValue(path_angle_col, float(p.m_cumangle)); if (map.getSelSet().size() == 1) { // Note: Euclidean distance is currently only calculated from a single point row.setValue(dist_col, float(map.getSpacing() * dist(here.pixel, *map.getSelSet().begin()))); } if (!p.getMergePixel().empty()) { Point &p2 = map.getPoint(p.getMergePixel()); if (p2.m_misc != ~0) { p2.m_cumangle = p.m_cumangle; AttributeRow &mergePixelRow = map.getAttributeTable().getRow(AttributeKey(p.getMergePixel())); mergePixelRow.setValue(path_length_col, float(map.getSpacing() * here.dist)); mergePixelRow.setValue(path_angle_col, float(p2.m_cumangle)); if (map.getSelSet().size() == 1) { // Note: Euclidean distance is currently only calculated from a single point mergePixelRow.setValue( dist_col, float(map.getSpacing() * dist(p.getMergePixel(), *map.getSelSet().begin()))); } p2.getNode().extractMetric(search_list, &map, MetricTriple(here.dist, p.getMergePixel(), NoPixel)); p2.m_misc = ~0; } } } } map.setDisplayedAttribute(-2); map.setDisplayedAttribute(path_length_col); return true; } ================================================ FILE: salalib/vgamodules/vgametricdepth.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAMetricDepth : IVGA { public: std::string getAnalysisName() const override { return "Metric Depth"; } bool run(Communicator *, PointMap &map, bool) override; }; ================================================ FILE: salalib/vgamodules/vgathroughvision.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgathroughvision.h" #include "salalib/agents/agenthelpers.h" #include "genlib/stringutils.h" // This is a slow algorithm, but should give the correct answer // for demonstrative purposes bool VGAThroughVision::run(Communicator *comm, PointMap &map, bool) { time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } AttributeTable &attributes = map.getAttributeTable(); // current version (not sure of differences!) for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); map.getPoint(curs).m_misc = 0; } } bool hasGateColumn = map.getAttributeTable().hasColumn(g_col_gate); int count = 0; for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { std::vector seengates; PixelRef curs = PixelRef(static_cast(i), static_cast(j)); Point &p = map.getPoint(curs); if (map.getPoint(curs).filled()) { p.getNode().first(); while (!p.getNode().is_tail()) { PixelRef x = p.getNode().cursor(); PixelRefVector pixels = map.quickPixelateLine(x, curs); for (size_t k = 1; k < pixels.size() - 1; k++) { PixelRef key = pixels[k]; map.getPoint(key).m_misc += 1; // TODO: Undocumented functionality. Shows how many times a gate is passed? if (hasGateColumn) { auto iter = attributes.find(AttributeKey(key)); if (iter != attributes.end()) { int gate = static_cast(iter->getRow().getValue(g_col_gate)); if (gate != -1) { auto gateIter = depthmapX::findBinary(seengates, gate); if (gateIter == seengates.end()) { iter->getRow().incrValue(g_col_gate_counts); seengates.insert(gateIter, int(gate)); } } } } } p.getNode().next(); } // only increment count for actual filled points count++; } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } int col = attributes.getOrInsertColumn("Through vision"); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { PixelRef pix = iter->getKey().value; iter->getRow().setValue(col, static_cast(map.getPoint(pix).m_misc)); map.getPoint(pix).m_misc = 0; } map.overrideDisplayedAttribute(-2); map.setDisplayedAttribute(col); return true; } ================================================ FILE: salalib/vgamodules/vgathroughvision.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAThroughVision : IVGA { public: std::string getAnalysisName() const override { return "Through Vision Analysis"; } bool run(Communicator *comm, PointMap &map, bool) override; }; ================================================ FILE: salalib/vgamodules/vgavisualglobal.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgavisualglobal.h" #include "genlib/stringutils.h" bool VGAVisualGlobal::run(Communicator *comm, PointMap &map, bool simple_version) { time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } AttributeTable &attributes = map.getAttributeTable(); int entropy_col = -1, rel_entropy_col = -1, integ_dv_col = -1, integ_pv_col = -1, integ_tk_col = -1, depth_col = -1, count_col = -1; std::string radius_text; if (m_radius != -1) { radius_text = std::string(" R") + dXstring::formatString(int(m_radius), "%d"); } // n.b. these must be entered in alphabetical order to preserve col indexing: // dX simple version test // TV #ifndef _COMPILE_dX_SIMPLE_VERSION if (!simple_version) { std::string entropy_col_text = std::string("Visual Entropy") + radius_text; entropy_col = attributes.insertOrResetColumn(entropy_col_text.c_str()); } #endif std::string integ_dv_col_text = std::string("Visual Integration [HH]") + radius_text; integ_dv_col = attributes.insertOrResetColumn(integ_dv_col_text.c_str()); #ifndef _COMPILE_dX_SIMPLE_VERSION if (!simple_version) { std::string integ_pv_col_text = std::string("Visual Integration [P-value]") + radius_text; integ_pv_col = attributes.insertOrResetColumn(integ_pv_col_text.c_str()); std::string integ_tk_col_text = std::string("Visual Integration [Tekl]") + radius_text; integ_tk_col = attributes.insertOrResetColumn(integ_tk_col_text.c_str()); std::string depth_col_text = std::string("Visual Mean Depth") + radius_text; depth_col = attributes.insertOrResetColumn(depth_col_text.c_str()); std::string count_col_text = std::string("Visual Node Count") + radius_text; count_col = attributes.insertOrResetColumn(count_col_text.c_str()); std::string rel_entropy_col_text = std::string("Visual Relativised Entropy") + radius_text; rel_entropy_col = attributes.insertOrResetColumn(rel_entropy_col_text.c_str()); } #endif int count = 0; depthmapX::RowMatrix miscs(map.getRows(), map.getCols()); depthmapX::RowMatrix extents(map.getRows(), map.getCols()); for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(i, j); if (map.getPoint(curs).filled()) { if ((map.getPoint(curs).contextfilled() && !curs.iseven()) || (m_gates_only)) { count++; continue; } for (size_t ii = 0; ii < map.getCols(); ii++) { for (size_t jj = 0; jj < map.getRows(); jj++) { miscs(jj, ii) = 0; extents(jj, ii) = PixelRef(ii, jj); } } int total_depth = 0; int total_nodes = 0; std::vector distribution; std::vector search_tree; search_tree.push_back(PixelRefVector()); search_tree.back().push_back(curs); int level = 0; while (search_tree[level].size()) { search_tree.push_back(PixelRefVector()); const PixelRefVector &searchTreeAtLevel = search_tree[level]; distribution.push_back(0); for (auto currLvlIter = searchTreeAtLevel.rbegin(); currLvlIter != searchTreeAtLevel.rend(); currLvlIter++) { int &pmisc = miscs(currLvlIter->y, currLvlIter->x); Point &p = map.getPoint(*currLvlIter); if (p.filled() && pmisc != ~0) { total_depth += level; total_nodes += 1; distribution.back() += 1; if ((int)m_radius == -1 || (level < (int)m_radius && (!p.contextfilled() || currLvlIter->iseven()))) { extractUnseen(p.getNode(), search_tree[level + 1], miscs, extents); pmisc = ~0; if (!p.getMergePixel().empty()) { PixelRef mergePixel = p.getMergePixel(); int &p2misc = miscs(mergePixel.y, mergePixel.x); Point &p2 = map.getPoint(mergePixel); if (p2misc != ~0) { extractUnseen(p2.getNode(), search_tree[level + 1], miscs, extents); // did say p.misc p2misc = ~0; } } } else { pmisc = ~0; } } search_tree[level].pop_back(); } level++; } AttributeRow &row = attributes.getRow(AttributeKey(curs)); // only set to single float precision after divide // note -- total_nodes includes this one -- mean depth as per p.108 Social Logic of Space if (!simple_version) { row.setValue(count_col, float(total_nodes)); // note: total nodes includes this one } // ERROR !!!!!! if (total_nodes > 1) { double mean_depth = double(total_depth) / double(total_nodes - 1); if (!simple_version) { row.setValue(depth_col, float(mean_depth)); } // total nodes > 2 to avoid divide by 0 (was > 3) if (total_nodes > 2 && mean_depth > 1.0) { double ra = 2.0 * (mean_depth - 1.0) / double(total_nodes - 2); // d-value / p-values from Depthmap 4 manual, note: node_count includes this one double rra_d = ra / dvalue(total_nodes); double rra_p = ra / pvalue(total_nodes); double integ_tk = teklinteg(total_nodes, total_depth); row.setValue(integ_dv_col, float(1.0 / rra_d)); if (!simple_version) { row.setValue(integ_pv_col, float(1.0 / rra_p)); } if (total_depth - total_nodes + 1 > 1) { if (!simple_version) { row.setValue(integ_tk_col, float(integ_tk)); } } else { if (!simple_version) { row.setValue(integ_tk_col, -1.0f); } } } else { row.setValue(integ_dv_col, (float)-1); if (!simple_version) { row.setValue(integ_pv_col, (float)-1); row.setValue(integ_tk_col, (float)-1); } } double entropy = 0.0, rel_entropy = 0.0, factorial = 1.0; // n.b., this distribution contains the root node itself in distribution[0] // -> chopped from entropy to avoid divide by zero if only one node for (size_t k = 1; k < distribution.size(); k++) { if (distribution[k] > 0) { double prob = double(distribution[k]) / double(total_nodes - 1); entropy -= prob * log2(prob); // Formula from Turner 2001, "Depthmap" factorial *= double(k + 1); double q = (pow(mean_depth, double(k)) / double(factorial)) * exp(-mean_depth); rel_entropy += (float)prob * log2(prob / q); } } if (!simple_version) { row.setValue(entropy_col, float(entropy)); row.setValue(rel_entropy_col, float(rel_entropy)); } } else { if (!simple_version) { row.setValue(depth_col, (float)-1); row.setValue(entropy_col, (float)-1); row.setValue(rel_entropy_col, (float)-1); } } count++; // <- increment count if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } } for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); map.getPoint(curs).m_misc = miscs(j, i); map.getPoint(curs).m_extent = extents(j, i); } } map.setDisplayedAttribute(integ_dv_col); return true; } void VGAVisualGlobal::extractUnseen(Node &node, PixelRefVector &pixels, depthmapX::RowMatrix &miscs, depthmapX::RowMatrix &extents) { for (int i = 0; i < 32; i++) { Bin &bin = node.bin(i); for (auto pixVec : bin.m_pixel_vecs) { for (PixelRef pix = pixVec.start(); pix.col(bin.m_dir) <= pixVec.end().col(bin.m_dir);) { int &misc = miscs(pix.y, pix.x); PixelRef &extent = extents(pix.y, pix.x); if (misc == 0) { pixels.push_back(pix); misc |= (1 << i); } // 10.2.02 revised --- diagonal was breaking this as it was extent in diagonal or horizontal if (!(bin.m_dir & PixelRef::DIAGONAL)) { if (extent.col(bin.m_dir) >= pixVec.end().col(bin.m_dir)) break; extent.col(bin.m_dir) = pixVec.end().col(bin.m_dir); } pix.move(bin.m_dir); } } } } ================================================ FILE: salalib/vgamodules/vgavisualglobal.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" #include "genlib/simplematrix.h" class VGAVisualGlobal : IVGA { private: double m_radius; bool m_gates_only; public: std::string getAnalysisName() const override { return "Global Visibility Analysis"; } bool run(Communicator *comm, PointMap &map, bool simple_version) override; void extractUnseen(Node &node, PixelRefVector &pixels, depthmapX::RowMatrix &miscs, depthmapX::RowMatrix &extents); VGAVisualGlobal(double radius, bool gates_only) : m_radius(radius), m_gates_only(gates_only) {} }; ================================================ FILE: salalib/vgamodules/vgavisualglobaldepth.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgavisualglobaldepth.h" #include "genlib/stringutils.h" bool VGAVisualGlobalDepth::run(Communicator *, PointMap &map, bool) { AttributeTable &attributes = map.getAttributeTable(); // n.b., insert columns sets values to -1 if the column already exists int col = attributes.insertOrResetColumn("Visual Step Depth"); for (auto iter = attributes.begin(); iter != attributes.end(); iter++) { PixelRef pix = iter->getKey().value; map.getPoint(pix).m_misc = 0; map.getPoint(pix).m_extent = pix; } std::vector search_tree; search_tree.push_back(PixelRefVector()); for (auto &sel : map.getSelSet()) { // need to convert from ints (m_selection_set) to pixelrefs for this op: search_tree.back().push_back(sel); } size_t level = 0; while (search_tree[level].size()) { search_tree.push_back(PixelRefVector()); const PixelRefVector& searchTreeAtLevel = search_tree[level]; for (auto currLvlIter = searchTreeAtLevel.rbegin(); currLvlIter != searchTreeAtLevel.rend(); currLvlIter++) { Point &p = map.getPoint(*currLvlIter); if (p.filled() && p.m_misc != ~0) { AttributeRow &row = attributes.getRow(AttributeKey(*currLvlIter)); row.setValue(col, float(level)); if (!p.contextfilled() || currLvlIter->iseven() || level == 0) { p.getNode().extractUnseen(search_tree[level + 1], &map); p.m_misc = ~0; if (!p.getMergePixel().empty()) { Point &p2 = map.getPoint(p.getMergePixel()); if (p2.m_misc != ~0) { AttributeRow &mergePixelRow = attributes.getRow(AttributeKey(p.getMergePixel())); mergePixelRow.setValue(col, float(level)); p2.getNode().extractUnseen(search_tree[level + 1], &map); // did say p.misc p2.m_misc = ~0; } } } else { p.m_misc = ~0; } } } level++; } // force redisplay: map.setDisplayedAttribute(-2); map.setDisplayedAttribute(col); return true; } void VGAVisualGlobalDepth::extractUnseen(Node &node, PixelRefVector &pixels, depthmapX::RowMatrix &miscs, depthmapX::RowMatrix &extents) { for (int i = 0; i < 32; i++) { Bin &bin = node.bin(i); for (auto pixVec : bin.m_pixel_vecs) { for (PixelRef pix = pixVec.start(); pix.col(bin.m_dir) <= pixVec.end().col(bin.m_dir);) { int &misc = miscs(pix.y, pix.x); PixelRef &extent = extents(pix.y, pix.x); if (misc == 0) { pixels.push_back(pix); misc |= (1 << i); } // 10.2.02 revised --- diagonal was breaking this as it was extent in diagonal or horizontal if (!(bin.m_dir & PixelRef::DIAGONAL)) { if (extent.col(bin.m_dir) >= pixVec.end().col(bin.m_dir)) break; extent.col(bin.m_dir) = pixVec.end().col(bin.m_dir); } pix.move(bin.m_dir); } } } } ================================================ FILE: salalib/vgamodules/vgavisualglobaldepth.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" #include "genlib/simplematrix.h" class VGAVisualGlobalDepth : IVGA { public: std::string getAnalysisName() const override { return "Global Visibility Depth"; } bool run(Communicator *comm, PointMap &map, bool simple_version) override; void extractUnseen(Node &node, PixelRefVector &pixels, depthmapX::RowMatrix &miscs, depthmapX::RowMatrix &extents); }; ================================================ FILE: salalib/vgamodules/vgavisuallocal.cpp ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "salalib/vgamodules/vgavisuallocal.h" #include "genlib/stringutils.h" bool VGAVisualLocal::run(Communicator *comm, PointMap &map, bool simple_version) { time_t atime = 0; if (comm) { qtimer(atime, 0); comm->CommPostMessage(Communicator::NUM_RECORDS, map.getFilledPointCount()); } int cluster_col = -1, control_col = -1, controllability_col = -1; if (!simple_version) { cluster_col = map.getAttributeTable().insertOrResetColumn("Visual Clustering Coefficient"); control_col = map.getAttributeTable().insertOrResetColumn("Visual Control"); controllability_col = map.getAttributeTable().insertOrResetColumn("Visual Controllability"); } int count = 0; for (size_t i = 0; i < map.getCols(); i++) { for (size_t j = 0; j < map.getRows(); j++) { PixelRef curs = PixelRef(static_cast(i), static_cast(j)); if (map.getPoint(curs).filled()) { if ((map.getPoint(curs).contextfilled() && !curs.iseven()) || (m_gates_only)) { count++; continue; } AttributeRow &row = map.getAttributeTable().getRow(AttributeKey(curs)); // This is much easier to do with a straight forward list: PixelRefVector neighbourhood; PixelRefVector totalneighbourhood; map.getPoint(curs).getNode().contents(neighbourhood); // only required to match previous non-stl output. Without this // the output differs by the last digit of the float std::sort(neighbourhood.begin(), neighbourhood.end()); int cluster = 0; float control = 0.0f; for (size_t i = 0; i < neighbourhood.size(); i++) { int intersect_size = 0, retro_size = 0; Point &retpt = map.getPoint(neighbourhood[i]); if (retpt.filled() && retpt.hasNode()) { retpt.getNode().first(); while (!retpt.getNode().is_tail()) { retro_size++; if (std::find(neighbourhood.begin(), neighbourhood.end(), retpt.getNode().cursor()) != neighbourhood.end()) { intersect_size++; } if (std::find(totalneighbourhood.begin(), totalneighbourhood.end(), retpt.getNode().cursor()) == totalneighbourhood.end()) { totalneighbourhood.push_back( retpt.getNode().cursor()); // <- note add does nothing if member already exists } retpt.getNode().next(); } control += 1.0f / float(retro_size); cluster += intersect_size; } } #ifndef _COMPILE_dX_SIMPLE_VERSION if (!simple_version) { if (neighbourhood.size() > 1) { row.setValue(cluster_col, float(cluster / double(neighbourhood.size() * (neighbourhood.size() - 1.0)))); row.setValue(control_col, float(control)); row.setValue(controllability_col, float(double(neighbourhood.size()) / double(totalneighbourhood.size()))); } else { row.setValue(cluster_col, -1); row.setValue(control_col, -1); row.setValue(controllability_col, -1); } } #endif count++; // <- increment count } if (comm) { if (qtimer(atime, 500)) { if (comm->IsCancelled()) { throw Communicator::CancelledException(); } comm->CommPostMessage(Communicator::CURRENT_RECORD, count); } } } } #ifndef _COMPILE_dX_SIMPLE_VERSION if (!simple_version) map.setDisplayedAttribute(cluster_col); #endif return true; } ================================================ FILE: salalib/vgamodules/vgavisuallocal.h ================================================ // sala - a component of the depthmapX - spatial network analysis platform // Copyright (C) 2000-2010, University College London, Alasdair Turner // Copyright (C) 2011-2012, Tasos Varoudis // Copyright (C) 2017-2018, Petros Koutsolampros // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #pragma once #include "salalib/ivga.h" #include "salalib/pixelref.h" #include "salalib/pointdata.h" class VGAVisualLocal : IVGA { private: bool m_gates_only; public: std::string getAnalysisName() const override { return "Local Visibility Analysis"; } bool run(Communicator *comm, PointMap &map, bool simple_version) override; VGAVisualLocal(bool gates_only) : m_gates_only(gates_only) {} }; ================================================ FILE: testdata/barnsbury_axial.RT1 ================================================ DUMMY TEXT A00 00005306350001844680000530732000183731 DUMMY TEXT A01 00005306550001842670000531386000184568 DUMMY TEXT A02 00005307810001843220000530814000184178 DUMMY TEXT A03 00005306670001842030000531124000184392 DUMMY TEXT A04 00005307980001842070000530856000184149 DUMMY TEXT A05 00005307470001841450000530810000184207 DUMMY TEXT A06 00005307530001841640000530781000183967 DUMMY TEXT A07 00005306380001841230000531070000184116 DUMMY TEXT A08 00005308370001839670000530855000184153 DUMMY TEXT A09 00005307760001839700000530838000183968 DUMMY TEXT A10 00005308030001836730000530817000183970 DUMMY TEXT A11 00005308030001837420000530916000183745 DUMMY TEXT A12 00005309120001836630000530932000184418 DUMMY TEXT A13 00005309950001841910000531426000184272 DUMMY TEXT A14 00005309920001842600000531006000184067 DUMMY TEXT A15 00005310650001842640000531069000184200 DUMMY TEXT A16 00005310140001842820000531076000184252 DUMMY TEXT A17 00005310550001842540000531446000184352 DUMMY TEXT A18 00005311010001844550000531227000184068 DUMMY TEXT A19 00005312140001840670000531445000184127 DUMMY TEXT A20 00005311660001838830000531225000184081 DUMMY TEXT A21 00005311030001839440000531189000183939 DUMMY TEXT A22 00005312740001845280000531297000184441 DUMMY TEXT A23 00005313320001845830000531443000184125 DUMMY TEXT A24 00005310260001841140000531441000184200 DUMMY TEXT A25 00005313790001837260000531438000184206 DUMMY TEXT A26 00005313700001835110000531409000184011 DUMMY TEXT A27 00005312870001837160000531396000183759 DUMMY TEXT A28 00005312940001837770000531391000183726 DUMMY TEXT A29 00005313030001839670000531311000183765 DUMMY TEXT A30 00005310690001838800000531403000183913 DUMMY TEXT A31 00005310550001839730000531081000183854 DUMMY TEXT A32 00005309790001838530000531006000183971 DUMMY TEXT A33 00005310020001839650000531057000183972 DUMMY TEXT A34 00005306750001838810000531237000183892 DUMMY TEXT A35 00005312460001839010000531247000183877 DUMMY TEXT A36 00005313780001840390000531423000184035 DUMMY TEXT A37 00005313650001840480000531385000184035 DUMMY TEXT A38 00005313600001841120000531368000184041 DUMMY TEXT A39 00005311760001839320000531212000183499 DUMMY TEXT A40 00005311910001835230000531385000183575 DUMMY TEXT A41 00005309040001836810000531226000183515 DUMMY TEXT A42 00005310870001835040000531157000183893 DUMMY TEXT A43 00005310290001838910000531030000183855 DUMMY TEXT A44 00005311820001837480000531275000183743 DUMMY TEXT A45 00005312400001837410000531312000183782 DUMMY TEXT A46 00005312380001837540000531308000183714 DUMMY TEXT A47 00005312930001835470000531303000183726 DUMMY TEXT A48 00005307070001835750000530731000183750 DUMMY TEXT A49 00005307110001836900000530973000183658 DUMMY TEXT A50 00005311390001841420000531154000184098 DUMMY TEXT A51 00005310910001840890000531155000184099 DUMMY TEXT A52 00005310600001841270000531065000184023 DUMMY TEXT A53 00005309150001840350000531213000184017 DUMMY TEXT A54 00005312810001840880000531294000184020 DUMMY TEXT A55 00005312630001840150000531322000184027 DUMMY TEXT A56 00005312670001840230000531279000183953 DUMMY TEXT A57 00005312760001839540000531332000183964 DUMMY TEXT A58 00005313150001840330000531330000183957 DUMMY TEXT A59 00005308050001838140000530917000183816 DUMMY TEXT A60 00005311370001843380000531389000184417 ================================================ FILE: testdata/barnsbury_extended1.dxf ================================================ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1032 9 $ACADMAINTVER 90 29 9 $DWGCODEPAGE 3 ANSI_1252 9 $LASTSAVEDBY 1 petros 9 $REQUIREDVERSIONS 160 0 9 $INSBASE 10 0.0 20 0.0 30 0.0 9 $EXTMIN 10 529323.2560585713 20 181958.3850119969 30 0.0 9 $EXTMAX 10 537745.3426184553 20 188578.5076793431 30 0.0 9 $LIMMIN 10 0.0 20 0.0 9 $LIMMAX 10 12.0 20 9.0 9 $ORTHOMODE 70 0 9 $REGENMODE 70 1 9 $FILLMODE 70 1 9 $QTEXTMODE 70 0 9 $MIRRTEXT 70 0 9 $LTSCALE 40 1.0 9 $ATTMODE 70 1 9 $TEXTSIZE 40 0.2 9 $TRACEWID 40 0.05 9 $TEXTSTYLE 7 Standard 9 $CLAYER 8 0 9 $CELTYPE 6 ByLayer 9 $CECOLOR 62 256 9 $CELTSCALE 40 1.0 9 $DISPSILH 70 0 9 $DIMSCALE 40 1.0 9 $DIMASZ 40 0.18 9 $DIMEXO 40 0.0625 9 $DIMDLI 40 0.38 9 $DIMRND 40 0.0 9 $DIMDLE 40 0.0 9 $DIMEXE 40 0.18 9 $DIMTP 40 0.0 9 $DIMTM 40 0.0 9 $DIMTXT 40 0.18 9 $DIMCEN 40 0.09 9 $DIMTSZ 40 0.0 9 $DIMTOL 70 0 9 $DIMLIM 70 0 9 $DIMTIH 70 1 9 $DIMTOH 70 1 9 $DIMSE1 70 0 9 $DIMSE2 70 0 9 $DIMTAD 70 0 9 $DIMZIN 70 0 9 $DIMBLK 1 9 $DIMASO 70 1 9 $DIMSHO 70 1 9 $DIMPOST 1 9 $DIMAPOST 1 9 $DIMALT 70 0 9 $DIMALTD 70 2 9 $DIMALTF 40 25.4 9 $DIMLFAC 40 1.0 9 $DIMTOFL 70 0 9 $DIMTVP 40 0.0 9 $DIMTIX 70 0 9 $DIMSOXD 70 0 9 $DIMSAH 70 0 9 $DIMBLK1 1 9 $DIMBLK2 1 9 $DIMSTYLE 2 Standard 9 $DIMCLRD 70 0 9 $DIMCLRE 70 0 9 $DIMCLRT 70 0 9 $DIMTFAC 40 1.0 9 $DIMGAP 40 0.09 9 $DIMJUST 70 0 9 $DIMSD1 70 0 9 $DIMSD2 70 0 9 $DIMTOLJ 70 1 9 $DIMTZIN 70 0 9 $DIMALTZ 70 0 9 $DIMALTTZ 70 0 9 $DIMUPT 70 0 9 $DIMDEC 70 4 9 $DIMTDEC 70 4 9 $DIMALTU 70 2 9 $DIMALTTD 70 2 9 $DIMTXSTY 7 Standard 9 $DIMAUNIT 70 0 9 $DIMADEC 70 0 9 $DIMALTRND 40 0.0 9 $DIMAZIN 70 0 9 $DIMDSEP 70 46 9 $DIMATFIT 70 3 9 $DIMFRAC 70 0 9 $DIMLDRBLK 1 9 $DIMLUNIT 70 2 9 $DIMLWD 70 -2 9 $DIMLWE 70 -2 9 $DIMTMOVE 70 0 9 $DIMFXL 40 1.0 9 $DIMFXLON 70 0 9 $DIMJOGANG 40 0.7853981633974483 9 $DIMTFILL 70 0 9 $DIMTFILLCLR 70 0 9 $DIMARCSYM 70 0 9 $DIMLTYPE 6 9 $DIMLTEX1 6 9 $DIMLTEX2 6 9 $DIMTXTDIRECTION 70 0 9 $LUNITS 70 2 9 $LUPREC 70 4 9 $SKETCHINC 40 0.1 9 $FILLETRAD 40 0.0 9 $AUNITS 70 0 9 $AUPREC 70 0 9 $MENU 1 . 9 $ELEVATION 40 0.0 9 $PELEVATION 40 0.0 9 $THICKNESS 40 0.0 9 $LIMCHECK 70 0 9 $CHAMFERA 40 0.0 9 $CHAMFERB 40 0.0 9 $CHAMFERC 40 0.0 9 $CHAMFERD 40 0.0 9 $SKPOLY 70 0 9 $TDCREATE 40 2458404.565312500 9 $TDUCREATE 40 2458404.523645833 9 $TDUPDATE 40 2458404.623425926 9 $TDUUPDATE 40 2458404.581759259 9 $TDINDWG 40 0.0581134259 9 $TDUSRTIMER 40 0.0581134259 9 $USRTIMER 70 1 9 $ANGBASE 50 0.0 9 $ANGDIR 70 0 9 $PDMODE 70 0 9 $PDSIZE 40 0.0 9 $PLINEWID 40 0.0 9 $SPLFRAME 70 0 9 $SPLINETYPE 70 6 9 $SPLINESEGS 70 8 9 $HANDSEED 5 659 9 $SURFTAB1 70 6 9 $SURFTAB2 70 6 9 $SURFTYPE 70 6 9 $SURFU 70 6 9 $SURFV 70 6 9 $UCSBASE 2 9 $UCSNAME 2 9 $UCSORG 10 0.0 20 0.0 30 0.0 9 $UCSXDIR 10 1.0 20 0.0 30 0.0 9 $UCSYDIR 10 0.0 20 1.0 30 0.0 9 $UCSORTHOREF 2 9 $UCSORTHOVIEW 70 0 9 $UCSORGTOP 10 0.0 20 0.0 30 0.0 9 $UCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $UCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $UCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $UCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $UCSORGBACK 10 0.0 20 0.0 30 0.0 9 $PUCSBASE 2 9 $PUCSNAME 2 9 $PUCSORG 10 0.0 20 0.0 30 0.0 9 $PUCSXDIR 10 1.0 20 0.0 30 0.0 9 $PUCSYDIR 10 0.0 20 1.0 30 0.0 9 $PUCSORTHOREF 2 9 $PUCSORTHOVIEW 70 0 9 $PUCSORGTOP 10 0.0 20 0.0 30 0.0 9 $PUCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $PUCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $PUCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $PUCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $PUCSORGBACK 10 0.0 20 0.0 30 0.0 9 $USERI1 70 0 9 $USERI2 70 0 9 $USERI3 70 0 9 $USERI4 70 0 9 $USERI5 70 0 9 $USERR1 40 0.0 9 $USERR2 40 0.0 9 $USERR3 40 0.0 9 $USERR4 40 0.0 9 $USERR5 40 0.0 9 $WORLDVIEW 70 1 9 $SHADEDGE 70 3 9 $SHADEDIF 70 70 9 $TILEMODE 70 1 9 $MAXACTVP 70 64 9 $PINSBASE 10 0.0 20 0.0 30 0.0 9 $PLIMCHECK 70 0 9 $PEXTMIN 10 1.000000000000000E+20 20 1.000000000000000E+20 30 1.000000000000000E+20 9 $PEXTMAX 10 -1.000000000000000E+20 20 -1.000000000000000E+20 30 -1.000000000000000E+20 9 $PLIMMIN 10 0.0 20 0.0 9 $PLIMMAX 10 12.0 20 9.0 9 $UNITMODE 70 0 9 $VISRETAIN 70 1 9 $PLINEGEN 70 0 9 $PSLTSCALE 70 1 9 $TREEDEPTH 70 3020 9 $CMLSTYLE 2 Standard 9 $CMLJUST 70 0 9 $CMLSCALE 40 1.0 9 $PROXYGRAPHICS 70 1 9 $MEASUREMENT 70 0 9 $CELWEIGHT 370 -1 9 $ENDCAPS 280 0 9 $JOINSTYLE 280 0 9 $LWDISPLAY 290 0 9 $INSUNITS 70 0 9 $HYPERLINKBASE 1 9 $STYLESHEET 1 9 $XEDIT 290 1 9 $CEPSNTYPE 380 0 9 $PSTYLEMODE 290 1 9 $FINGERPRINTGUID 2 {2B8CF25F-82C1-5146-94DB-BDE3530BDA2A} 9 $VERSIONGUID 2 {0C0159B8-69B3-CE49-BF34-83025D685E03} 9 $EXTNAMES 290 1 9 $PSVPSCALE 40 0.0 9 $OLESTARTUP 290 0 9 $SORTENTS 280 127 9 $INDEXCTL 280 0 9 $HIDETEXT 280 0 9 $XCLIPFRAME 280 2 9 $HALOGAP 280 0 9 $OBSCOLOR 70 257 9 $OBSLTYPE 280 0 9 $INTERSECTIONDISPLAY 280 0 9 $INTERSECTIONCOLOR 70 257 9 $DIMASSOC 280 1 9 $PROJECTNAME 1 9 $CAMERADISPLAY 290 0 9 $LENSLENGTH 40 50.0 9 $CAMERAHEIGHT 40 0.0 9 $STEPSPERSEC 40 2.0 9 $STEPSIZE 40 6.0 9 $3DDWFPREC 40 2.0 9 $PSOLWIDTH 40 0.25 9 $PSOLHEIGHT 40 4.0 9 $LOFTANG1 40 1.570796326794896 9 $LOFTANG2 40 1.570796326794896 9 $LOFTMAG1 40 0.0 9 $LOFTMAG2 40 0.0 9 $LOFTPARAM 70 7 9 $LOFTNORMALS 280 1 9 $LATITUDE 40 37.795 9 $LONGITUDE 40 -122.394 9 $NORTHDIRECTION 40 0.0 9 $TIMEZONE 70 -8000 9 $LIGHTGLYPHDISPLAY 280 1 9 $TILEMODELIGHTSYNCH 280 1 9 $CMATERIAL 347 11 9 $SOLIDHIST 280 0 9 $SHOWHIST 280 1 9 $DWFFRAME 280 2 9 $DGNFRAME 280 0 9 $REALWORLDSCALE 290 1 9 $INTERFERECOLOR 62 1 9 $INTERFEREOBJVS 345 33 9 $INTERFEREVPVS 346 30 9 $CSHADOW 280 0 9 $SHADOWPLANELOCATION 40 0.0 0 ENDSEC 0 SECTION 2 CLASSES 0 CLASS 1 ACDBDICTIONARYWDFLT 2 AcDbDictionaryWithDefault 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 MATERIAL 2 AcDbMaterial 3 ObjectDBX Classes 90 1153 91 3 280 0 281 0 0 CLASS 1 VISUALSTYLE 2 AcDbVisualStyle 3 ObjectDBX Classes 90 4095 91 24 280 0 281 0 0 CLASS 1 SCALE 2 AcDbScale 3 ObjectDBX Classes 90 1153 91 17 280 0 281 0 0 CLASS 1 TABLESTYLE 2 AcDbTableStyle 3 ObjectDBX Classes 90 4095 91 1 280 0 281 0 0 CLASS 1 MLEADERSTYLE 2 AcDbMLeaderStyle 3 ACDB_MLEADERSTYLE_CLASS 90 4095 91 1 280 0 281 0 0 CLASS 1 ACDBSECTIONVIEWSTYLE 2 AcDbSectionViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 ACDBDETAILVIEWSTYLE 2 AcDbDetailViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 SORTENTSTABLE 2 AcDbSortentsTable 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 DICTIONARYVAR 2 AcDbDictionaryVar 3 ObjectDBX Classes 90 0 91 27 280 0 281 0 0 CLASS 1 CELLSTYLEMAP 2 AcDbCellStyleMap 3 ObjectDBX Classes 90 1152 91 3 280 0 281 0 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 8 330 0 100 AcDbSymbolTable 70 1 0 VPORT 5 B3 330 8 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *Active 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 532607.1185847557 22 184421.2568788754 13 0.0 23 0.0 14 1.0 24 1.0 15 0.0 25 0.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 5191.861925766842 41 1.549218031278748 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 1000 73 1 74 3 75 0 76 0 77 0 78 0 281 0 65 1 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 348 2F 60 3 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 1001 ACAD_NAV_VCDISPLAY 1070 1 0 ENDTAB 0 TABLE 2 LTYPE 5 5 330 0 100 AcDbSymbolTable 70 2 0 LTYPE 5 5A 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByBlock 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 5B 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByLayer 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 5C 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 Continuous 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 2 102 {ACAD_XDICTIONARY 360 345 102 } 330 0 100 AcDbSymbolTable 70 1 0 LAYER 5 54 102 {ACAD_XDICTIONARY 360 340 102 } 330 2 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 62 7 6 Continuous 370 -3 390 F 347 21 348 0 0 ENDTAB 0 TABLE 2 STYLE 5 3 330 0 100 AcDbSymbolTable 70 2 0 STYLE 5 55 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Standard 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 0 STYLE 5 59 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Annotative 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 0 ENDTAB 0 TABLE 2 VIEW 5 6 330 0 100 AcDbSymbolTable 70 3 0 ENDTAB 0 TABLE 2 UCS 5 7 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 9 330 0 100 AcDbSymbolTable 70 4 0 APPID 5 56 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 APPID 5 5D 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnotative 70 0 0 APPID 5 B2 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_NAV_VCDISPLAY 70 0 0 APPID 5 F2 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_EXEMPT_FROM_CAD_STANDARDS 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 A 330 0 100 AcDbSymbolTable 70 3 100 AcDbDimStyleTable 71 1 340 57 0 DIMSTYLE 105 57 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Standard 70 0 340 55 0 DIMSTYLE 105 58 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Annotative 70 0 340 55 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 1 330 0 100 AcDbSymbolTable 70 1 0 BLOCK_RECORD 5 6F 102 {ACAD_XDICTIONARY 360 135 102 } 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Model_Space 340 72 70 0 280 1 281 0 0 BLOCK_RECORD 5 6B 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space 340 6E 70 0 280 1 281 0 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 70 330 6F 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *Model_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Model_Space 1 0 ENDBLK 5 71 330 6F 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 6C 330 6B 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space 1 0 ENDBLK 5 6D 330 6B 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LINE 5 73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530635.6962680001 20 184468.675646 30 0.0 11 530732.3778539999 21 183731.866556 31 0.0 0 LINE 5 74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530655.0804069999 20 184267.843134 30 0.0 11 531386.6646780001 21 184568.766995 31 0.0 0 LINE 5 75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530781.419478 20 184322.997346 30 0.0 11 530814.78724 21 184178.968574 31 0.0 0 LINE 5 76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530667.7613100001 20 184203.901437 30 0.0 11 531124.6861069999 21 184392.857349 31 0.0 0 LINE 5 77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530798.725861 20 184207.390438 30 0.0 11 530856.762846 21 184149.487013 31 0.0 0 LINE 5 78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530747.8703240001 20 184145.998012 30 0.0 11 530810.7554050001 21 184207.340453 31 0.0 0 LINE 5 79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530753.9386890001 20 184164.022852 30 0.0 11 530781.427723 21 183967.049235 31 0.0 0 LINE 5 7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530638.0708449999 20 184123.954322 30 0.0 11 531070.9777789999 21 184116.826362 31 0.0 0 LINE 5 7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530837.4941380001 20 183967.908989 30 0.0 11 530855.6744979999 21 184153.675814 31 0.0 0 LINE 5 7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530776.9259189999 20 183970.168342 30 0.0 11 530838.1125180001 21 183968.488823 31 0.0 0 LINE 5 7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530803.8790240001 20 183673.983124 30 0.0 11 530817.351454 21 183970.908131 31 0.0 0 LINE 5 7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530803.31836 20 183742.403539 30 0.0 11 530916.415863 21 183745.002795 31 0.0 0 LINE 5 7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530912.1861470001 20 183663.646083 30 0.0 11 530932.996681 21 184479.6069563149 31 0.0 0 LINE 5 80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530995.2139119999 20 184191.1051 30 0.0 11 531426.867596 21 184272.091918 31 0.0 0 LINE 5 81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530992.995991 20 184260.565217 30 0.0 11 531006.3035189999 21 184067.090599 31 0.0 0 LINE 5 82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531065.5030580001 20 184264.454104 30 0.0 11 531069.386482 21 184200.262479 31 0.0 0 LINE 5 83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531014.2600029999 20 184282.658893 30 0.0 11 531076.262863 21 184252.777446 31 0.0 0 LINE 5 84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.8563370001 20 184254.05708 30 0.0 11 531446.820644 21 184352.768824 31 0.0 0 LINE 5 85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531101.674141 20 184455.949289 30 0.0 11 531227.444303 21 184068.530187 31 0.0 0 LINE 5 86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531214.16151 20 184067.600453 30 0.0 11 531445.270572 21 184127.80322 31 0.0 0 LINE 5 87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531166.2824399999 20 183883.173244 30 0.0 11 531225.605654 21 184081.636435 31 0.0 0 LINE 5 88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531103.958023 20 183944.145791 30 0.0 11 531189.2449350001 21 183939.966987 31 0.0 0 LINE 5 89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531199.1268957056 20 184509.5863229855 30 0.0 11 531222.4027027056 21 184422.5212449855 31 0.0 0 LINE 5 8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531332.5770770001 20 184583.962646 30 0.0 11 531443.794706 21 184125.074001 31 0.0 0 LINE 5 8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531026.4544489999 20 184114.297086 30 0.0 11 531441.626255 21 184200.71235 31 0.0 0 LINE 5 8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531379.0874670001 20 183726.907975 30 0.0 11 531438.2045550001 21 184206.79061 31 0.0 0 LINE 5 8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531367.365093476 20 183473.8360188434 30 0.0 11 531409.569458 21 184011.596484 31 0.0 0 LINE 5 8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531287.1303 20 183716.111065 30 0.0 11 531396.253684 21 183759.488649 31 0.0 0 LINE 5 8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531294.394199 20 183777.773415 30 0.0 11 531391.413833 21 183726.268158 31 0.0 0 LINE 5 90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531303.999695 20 183967.539095 30 0.0 11 531311.931444 21 183765.686875 31 0.0 0 LINE 5 91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531069.774 20 183880.95388 30 0.0 11 531403.294966 21 183913.414588 31 0.0 0 LINE 5 92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.773886 20 183973.477395 30 0.0 11 531081.1604290001 21 183854.721389 31 0.0 0 LINE 5 93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530979.070082 20 183853.471746 30 0.0 11 531006.056167 21 183971.198048 31 0.0 0 LINE 5 94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531002.3706249999 20 183965.559662 30 0.0 11 531057.7609460001 21 183972.597647 31 0.0 0 LINE 5 95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530675.0499439999 20 183881.16382 30 0.0 11 531237.536258 21 183892.420597 31 0.0 0 LINE 5 96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531246.803707 20 183901.647956 30 0.0 11 531247.100529 21 183877.364907 31 0.0 0 LINE 5 97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531378.13104 20 184039.148597 30 0.0 11 531423.297484 21 184035.389673 31 0.0 0 LINE 5 98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531365.8376540001 20 184048.645878 30 0.0 11 531385.9885830001 21 184035.489644 31 0.0 0 LINE 5 99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531360.008395 20 184112.477607 30 0.0 11 531368.607994 21 184041.148025 31 0.0 0 LINE 5 9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531176.638237 20 183932.709065 30 0.0 11 531212.5949479999 21 183499.852969 31 0.0 0 LINE 5 9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531191.28971 20 183523.406227 30 0.0 11 531385.782456 21 183575.241389 31 0.0 0 LINE 5 9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530904.180192 20 183681.79089 30 0.0 11 531226.595062 21 183515.558473 31 0.0 0 LINE 5 9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531087.294754 20 183504.461649 30 0.0 11 531157.6993310001 21 183893.960157 31 0.0 0 LINE 5 9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531029.2082989999 20 183891.140964 30 0.0 11 531030.2306869999 21 183855.631128 31 0.0 0 LINE 5 9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531182.681866 20 183748.751722 30 0.0 11 531275.851057 21 183743.153325 31 0.0 0 LINE 5 A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531240.7600770001 20 183741.113908 30 0.0 11 531312.920852 21 183782.89195 31 0.0 0 LINE 5 A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531238.3195390001 20 183754.010217 30 0.0 11 531308.0562649999 21 183714.501526 31 0.0 0 LINE 5 A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531293.948966 20 183547.909213 30 0.0 11 531303.2823749999 21 183726.188181 31 0.0 0 LINE 5 A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530707.321114 20 183575.611283 30 0.0 11 530731.6605340001 21 183750.551207 31 0.0 0 LINE 5 A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530711.864142 20 183690.118506 30 0.0 11 530973.265559 21 183658.367594 31 0.0 0 LINE 5 A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531139.131454 20 184142.888902 30 0.0 11 531154.5332279999 21 184098.471616 31 0.0 0 LINE 5 A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531091.4007950001 20 184089.16428 30 0.0 11 531155.7864770001 21 184099.901207 31 0.0 0 LINE 5 A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531060.2262189999 20 184127.683254 30 0.0 11 531065.6514689999 21 184023.503075 31 0.0 0 LINE 5 A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530915.1048979999 20 184035.689587 30 0.0 11 531213.1391220001 21 184017.404821 31 0.0 0 LINE 5 A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531281.4989239999 20 184088.374506 30 0.0 11 531294.732247 21 184020.813845 31 0.0 0 LINE 5 AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531263.3103189999 20 184015.655322 30 0.0 11 531322.3284660001 21 184027.032065 31 0.0 0 LINE 5 AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531267.276193 20 184023.293136 30 0.0 11 531279.9983229999 21 183953.103227 31 0.0 0 LINE 5 AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531276.7909939999 20 183954.982689 30 0.0 11 531332.164824 21 183964.220045 31 0.0 0 LINE 5 AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531315.9385439999 20 184033.420237 30 0.0 11 531330.6065079999 21 183957.32202 31 0.0 0 LINE 5 AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530805.297175 20 183814.47291 30 0.0 11 530917.998915 21 183816.172423 31 0.0 0 LINE 5 AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531137.2515800001 20 184338.103022 30 0.0 11 531389.731841 21 184417.270361 31 0.0 0 LINE 5 B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531482.3151479505 20 184748.9871594448 30 0.0 11 531515.6829099504 21 184604.9583874448 31 0.0 0 LINE 5 B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531368.6569799505 20 184629.8912504447 30 0.0 11 531825.5817769504 21 184818.8471624447 31 0.0 0 LINE 5 B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531499.6215309505 20 184633.3802514448 30 0.0 11 531557.6585159504 21 184575.4768264448 31 0.0 0 LINE 5 BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531448.7659939505 20 184571.9878254447 30 0.0 11 531511.6510749504 21 184633.3302664447 31 0.0 0 LINE 5 BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531455.263586 20 184588.2416564698 30 0.0 11 531482.7526199998 21 184391.2680394698 31 0.0 0 LINE 5 BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531253.86750234 20 184551.3453196492 30 0.0 11 531771.8734489504 21 184542.8161754447 31 0.0 0 LINE 5 BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531538.3898079505 20 184393.8988024447 30 0.0 11 531556.5701679504 21 184579.6656274448 31 0.0 0 LINE 5 BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531477.8215889504 20 184396.1581554448 30 0.0 11 531539.0081879505 21 184394.4786364447 31 0.0 0 LINE 5 BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531504.7746939504 20 184099.9729374447 30 0.0 11 531518.2471239504 21 184396.8979444447 31 0.0 0 LINE 5 C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531504.2140299504 20 184168.3933524448 30 0.0 11 531617.3115329505 21 184170.9926084448 31 0.0 0 LINE 5 C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531613.0818169504 20 184089.6358964447 30 0.0 11 531633.8923509504 21 184844.9097024448 31 0.0 0 LINE 5 C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531696.1095819504 20 184617.0949134447 30 0.0 11 532336.8255974543 21 184713.6317642464 31 0.0 0 LINE 5 C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531693.8916609504 20 184686.5550304448 30 0.0 11 531707.1991889504 21 184493.0804124447 31 0.0 0 LINE 5 C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531766.3987279504 20 184690.4439174447 30 0.0 11 531770.2821519504 21 184626.2522924448 31 0.0 0 LINE 5 C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531715.1556729503 20 184708.6487064448 30 0.0 11 531777.1585329505 21 184678.7672594447 31 0.0 0 LINE 5 C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531756.7520069505 20 184680.0468934447 30 0.0 11 531893.0496688435 21 184714.4597021531 31 0.0 0 LINE 5 C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531802.5698109504 20 184881.9391024447 30 0.0 11 531928.3399729504 21 184494.5200004447 31 0.0 0 LINE 5 C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531915.0571799504 20 184493.5902664447 30 0.0 11 532146.1662419505 21 184553.7930334447 31 0.0 0 LINE 5 C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531867.1781099504 20 184309.1630574448 30 0.0 11 531926.5013239504 21 184507.6262484447 31 0.0 0 LINE 5 CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531804.8536929503 20 184370.1356044448 30 0.0 11 531890.1406049505 21 184365.9568004447 31 0.0 0 LINE 5 CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531914.954988917 20 184937.2488970258 30 0.0 11 531938.230795917 21 184850.1838190259 31 0.0 0 LINE 5 CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531727.3501189504 20 184540.2868994447 30 0.0 11 532142.5219249505 21 184626.7021634447 31 0.0 0 LINE 5 D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.0259699504 20 184142.1008784448 30 0.0 11 532097.1493539504 21 184185.4784624447 31 0.0 0 LINE 5 D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531995.2898689503 20 184203.7632284447 30 0.0 11 532092.3095029504 21 184152.2579714447 31 0.0 0 LINE 5 D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532004.8953649504 20 184393.5289084448 30 0.0 11 532012.8271139505 21 184191.6766884448 31 0.0 0 LINE 5 D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531770.6696699504 20 184306.9436934447 30 0.0 11 532197.7006858273 21 184339.4044014448 31 0.0 0 LINE 5 D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531756.6695559503 20 184399.4672084447 30 0.0 11 531782.0560989504 21 184280.7112024448 31 0.0 0 LINE 5 D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531679.9657519504 20 184279.4615594447 30 0.0 11 531706.9518369503 21 184397.1878614447 31 0.0 0 LINE 5 D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531703.2662949504 20 184391.5494754448 30 0.0 11 531758.6566159504 21 184398.5874604448 31 0.0 0 LINE 5 D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531375.9456139504 20 184307.1536334448 30 0.0 11 531938.4319279503 21 184318.4104104447 31 0.0 0 LINE 5 D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531947.6993769504 20 184327.6377694447 30 0.0 11 531947.9961989505 21 184303.3547204447 31 0.0 0 LINE 5 D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532079.0267099504 20 184465.1384104447 30 0.0 11 532156.3508382652 21 184461.3794864448 31 0.0 0 LINE 5 DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532066.7333239505 20 184474.6356914448 30 0.0 11 532086.8842529504 21 184461.4794574448 31 0.0 0 LINE 5 DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532060.9040649504 20 184538.4674204447 30 0.0 11 532069.5036639504 21 184467.1378384447 31 0.0 0 LINE 5 DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531877.5339069504 20 184358.6988784447 30 0.0 11 531913.4906179503 21 184005.4836986493 31 0.0 0 LINE 5 DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531605.0758619504 20 184107.7807034448 30 0.0 11 531784.3258864618 21 184010.3328863243 31 0.0 0 LINE 5 DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531761.9190629788 20 183988.7626476783 30 0.0 11 531858.5950009506 21 184319.9499704448 31 0.0 0 LINE 5 E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.1039689503 20 184317.1307774448 30 0.0 11 531731.1263569504 21 184281.6209414447 31 0.0 0 LINE 5 E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531883.5775359503 20 184174.7415354448 30 0.0 11 531976.7467269504 21 184169.1431384447 31 0.0 0 LINE 5 E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531941.6557469504 20 184167.1037214447 30 0.0 11 532013.8165219504 21 184208.8817634447 31 0.0 0 LINE 5 E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531939.2152089505 20 184180.0000304447 30 0.0 11 532008.9519349504 21 184140.4913394448 31 0.0 0 LINE 5 E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531994.8446359504 20 184026.5398393117 30 0.0 11 532004.1780449503 21 184152.1779944448 31 0.0 0 LINE 5 E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531409.1658425192 20 184133.617550475 30 0.0 11 531674.1612289504 21 184084.3574074447 31 0.0 0 LINE 5 E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531840.0271239504 20 184568.8787154448 30 0.0 11 531855.4288979504 21 184524.4614294448 31 0.0 0 LINE 5 E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531792.2964649504 20 184515.1540934448 30 0.0 11 531856.6821469506 21 184525.8910204447 31 0.0 0 LINE 5 E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531761.1218889504 20 184553.6730674448 30 0.0 11 531766.5471389503 21 184449.4928884447 31 0.0 0 LINE 5 EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531616.0005679503 20 184461.6794004447 30 0.0 11 531914.0347919505 21 184443.3946344448 31 0.0 0 LINE 5 EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531982.3945939504 20 184514.3643194447 30 0.0 11 531995.6279169504 21 184446.8036584448 31 0.0 0 LINE 5 EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531964.2059889504 20 184441.6451354448 30 0.0 11 532023.2241359505 21 184453.0218784447 31 0.0 0 LINE 5 ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531968.1718629504 20 184449.2829494447 30 0.0 11 531980.8939929504 21 184379.0930404447 31 0.0 0 LINE 5 EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531977.6866639504 20 184380.9725024447 30 0.0 11 532033.0604939504 21 184390.2098584447 31 0.0 0 LINE 5 EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532016.8342139503 20 184459.4100504447 30 0.0 11 532031.5021779503 21 184383.3118334448 31 0.0 0 LINE 5 F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531506.1928449503 20 184240.4627234447 30 0.0 11 531618.8945849504 21 184242.1622364448 31 0.0 0 LINE 5 F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531838.1472499504 20 184764.0928354447 30 0.0 11 532090.6275109504 21 184843.2601744448 31 0.0 0 LINE 5 F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531898.1410099429 20 185489.5773460393 30 0.0 11 532384.9456462926 21 183588.3773949871 31 0.0 0 LINE 5 FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532034.5704961169 20 184072.7659341317 30 0.0 11 532153.81876062 21 183879.2475727824 31 0.0 0 LINE 5 FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531848.4441497004 20 184056.3091599104 30 0.0 11 531872.7555329125 21 183888.2560305589 31 0.0 0 LINE 5 104 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531400.0540388189 20 183972.7571852804 30 0.0 11 532184.2443917333 21 184077.3429025231 31 0.0 0 LINE 5 105 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531934.003528394 20 183974.8942294735 30 0.0 11 532082.7807717206 21 183561.6762489006 31 0.0 0 LINE 5 106 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532002.2213451149 20 183988.1590894068 30 0.0 11 531813.3438607319 21 183944.1725686889 31 0.0 0 LINE 5 107 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532017.6216248512 20 183917.199737725 30 0.0 11 531954.8704583398 21 183903.1307362112 31 0.0 0 LINE 5 108 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532027.4228756862 20 183970.6899285112 30 0.0 11 532007.8099904357 21 183904.7157649685 31 0.0 0 LINE 5 109 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532005.8194622598 20 183925.0652505675 30 0.0 11 532165.6070012576 21 183554.8422905387 31 0.0 0 LINE 5 10A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532215.3406327096 20 183914.506790095 30 0.0 11 531850.025606886 21 183726.0905468235 31 0.0 0 LINE 5 10B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531846.9898456826 20 183739.0551582372 30 0.0 11 531943.2723962861 21 183520.502093417 31 0.0 0 LINE 5 10C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531657.2879060011 20 183756.915025109 30 0.0 11 531862.6710068011 21 183729.9954447442 31 0.0 0 LINE 5 10D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531707.542847412 20 183828.1640623365 30 0.0 11 531717.0163799135 21 183743.3019863348 31 0.0 0 LINE 5 10F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532612.061878647 20 183803.7866919309 30 0.0 11 531940.3427695725 21 183521.5239075487 31 0.0 0 LINE 5 110 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531863.1594357444 20 183931.8064504249 30 0.0 11 532014.6676634007 21 183535.7250404825 31 0.0 0 LINE 5 111 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531536.9533087979 20 183521.91630484 30 0.0 11 532020.1225745254 21 183540.0721337803 31 0.0 0 LINE 5 112 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531322.8230960096 20 183496.2175151871 30 0.0 11 531822.8598906507 21 183537.2174611747 31 0.0 0 LINE 5 113 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531511.6320955302 20 183610.9754424221 30 0.0 11 531571.8542817987 21 183510.1646492979 31 0.0 0 LINE 5 114 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531573.6637703916 20 183613.6364478867 30 0.0 11 531538.2870985667 21 183509.6456215089 31 0.0 0 LINE 5 115 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531762.5332163358 20 183634.4117035529 30 0.0 11 531564.5281508437 21 183594.3963889772 31 0.0 0 LINE 5 116 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531647.8000830325 20 183818.5796003908 30 0.0 11 531724.9336515695 21 183527.7567185295 31 0.0 0 LINE 5 117 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531562.2020126962 20 183850.0654772609 30 0.0 11 531683.6345265603 21 183848.7965788212 31 0.0 0 LINE 5 118 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531664.5618179023 20 183949.0972884033 30 0.0 11 531554.5510755348 21 183899.2438278418 31 0.0 0 LINE 5 119 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531559.3441468586 20 183903.9768061644 30 0.0 11 531563.459261181 21 183848.292995883 31 0.0 0 LINE 5 11A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531576.9778841278 20 184241.5424111468 30 0.0 11 531576.9801121507 21 184241.5301770692 31 0.0 0 LINE 5 11B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531688.3652557219 20 183680.3696937222 30 0.0 11 531664.4402060374 21 183676.2047723989 31 0.0 0 LINE 5 11C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531845.0466985964 20 183572.6468079129 30 0.0 11 531848.5375890713 21 183527.4588575618 31 0.0 0 LINE 5 11D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531852.4623111796 20 183586.2972429151 30 0.0 11 531842.6874311459 21 183564.3063776991 31 0.0 0 LINE 5 11E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531914.5479255571 20 183602.2297999917 30 0.0 11 531845.5021105826 21 183582.3668242385 31 0.0 0 LINE 5 11F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531707.8411943863 20 183754.5901321862 30 0.0 11 531365.7560113711 21 183674.7938172478 31 0.0 0 LINE 5 122 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531374.0607747642 20 183774.5071494866 30 0.0 11 531666.5682496065 21 183767.1082814454 31 0.0 0 LINE 5 123 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531643.2974167897 20 183893.5059139139 30 0.0 11 531608.4049033558 21 183886.834614473 31 0.0 0 LINE 5 124 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531527.2010051643 20 183719.29209353 30 0.0 11 531536.5299245022 21 183626.4222304713 31 0.0 0 LINE 5 125 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531528.9213936644 20 183660.7390828553 30 0.0 11 531581.6708679228 21 183596.1629633728 31 0.0 0 LINE 5 126 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531541.263570164 20 183665.2046948853 30 0.0 11 531513.379763223 21 183590.0605605288 31 0.0 0 LINE 5 127 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531346.6694038719 20 183577.4244724932 30 0.0 11 531524.155712167 21 183596.6367946471 31 0.0 0 LINE 5 129 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531909.3516392598 20 183825.1299313012 30 0.0 11 531867.9584077485 21 183802.8429323334 31 0.0 0 LINE 5 12A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531848.70377308 20 183863.6836230238 30 0.0 11 531869.5695376331 21 183801.8336633017 31 0.0 0 LINE 5 12B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531881.7592038701 20 183900.6011533052 30 0.0 11 531779.7769291967 21 183878.6339348538 31 0.0 0 LINE 5 12C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531767.8030984371 20 184029.1975708737 30 0.0 11 531797.2733862307 21 183732.0608456437 31 0.0 0 LINE 5 12D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531878.2349730312 20 183675.8916353841 30 0.0 11 531813.6487009317 21 183652.0551673432 31 0.0 0 LINE 5 12E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531803.5459941819 20 183682.2525717864 30 0.0 11 531824.1875434457 21 183625.8034938436 31 0.0 0 LINE 5 12F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531811.718444662 20 183679.5552745401 30 0.0 11 531744.4550535487 21 183655.8042296553 31 0.0 0 LINE 5 130 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531745.7990662274 20 183659.270202339 30 0.0 11 531763.7475182558 21 183606.0776947413 31 0.0 0 LINE 5 131 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531829.4751229565 20 183633.1302494412 30 0.0 11 531756.6892737099 21 183606.5161939831 31 0.0 0 LINE 5 133 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532101.7684936581 20 183858.112361732 30 0.0 11 532220.1805946465 21 183621.4853892659 31 0.0 0 LINE 5 134 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531603.2015619726 20 184097.5481402789 30 0.0 11 531677.7782680863 21 183688.04728826 31 0.0 0 LINE 5 137 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530735.9131272892 20 184226.3356863664 30 0.0 11 530283.9544628965 21 184816.224090947 31 0.0 0 LINE 5 138 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530031.1888274785 20 184139.9555640059 30 0.0 11 532155.7272385915 21 185032.5284892478 31 0.0 0 LINE 5 139 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530736.1824591328 20 184432.3874965597 30 0.0 11 530658.0779895487 21 184557.9159257529 31 0.0 0 LINE 5 13A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530571.6050156501 20 184436.4223187819 30 0.0 11 531028.5298126501 21 184625.3782307819 31 0.0 0 LINE 5 13B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530666.7818999167 20 184526.4514665502 30 0.0 11 530666.9708656795 21 184608.4335532921 31 0.0 0 LINE 5 13C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530587.4192474452 20 184533.9936815043 30 0.0 11 530675.262569967 21 184534.9832109703 31 0.0 0 LINE 5 13D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530604.4459568053 20 184525.5195397091 30 0.0 11 530484.7853398737 21 184684.3766753369 31 0.0 0 LINE 5 13E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530494.1205644549 20 184472.0484992076 30 0.0 11 530795.5503186188 21 184782.8528180704 31 0.0 0 LINE 5 13F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530525.0832024871 20 184723.3672426156 30 0.0 11 530669.1589131753 21 184604.6995201719 31 0.0 0 LINE 5 140 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530483.8014128733 20 184678.989008366 30 0.0 11 530525.9304985947 21 184723.3935218478 31 0.0 0 LINE 5 141 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530293.6891368917 20 184907.7016572334 30 0.0 11 530512.942028526 21 184707.017488296 31 0.0 0 LINE 5 142 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530341.6169557605 20 184858.8693757858 30 0.0 11 530423.5169519545 21 184936.9090576151 31 0.0 0 LINE 5 143 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530363.0611291584 20 184991.515820703 30 0.0 11 530950.6381382885 21 184434.1646856795 31 0.0 0 LINE 5 144 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530794.3778468289 20 184676.7579559348 30 0.0 11 531157.1550750989 21 184924.2987611555 31 0.0 0 LINE 5 145 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530841.8667898658 20 184626.0191412416 30 0.0 11 530714.6380901394 21 184772.3829895024 31 0.0 0 LINE 5 146 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530895.9427945592 20 184674.477204796 30 0.0 11 530853.3539856806 21 184722.662670036 31 0.0 0 LINE 5 147 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530872.5246082747 20 184625.397131656 30 0.0 11 530895.3127741604 21 184690.3429168817 31 0.0 0 LINE 5 148 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530881.7703476819 20 184675.0240901761 30 0.0 11 531228.261643328 21 184881.2784956878 31 0.0 0 LINE 5 149 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531056.8004158705 20 184564.4609387729 30 0.0 11 530872.2051953306 21 184927.5536250086 31 0.0 0 LINE 5 14A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530862.1453565096 20 184918.8302863079 30 0.0 11 531068.2731269009 21 185039.441703539 31 0.0 0 LINE 5 14B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530697.9914463482 20 185015.5737333332 30 0.0 11 530880.1604013233 21 184916.9768076993 31 0.0 0 LINE 5 14C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530696.9350081967 20 184928.3907741009 30 0.0 11 530754.3600034362 21 184991.5864201783 31 0.0 0 LINE 5 14D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531230.2997171692 20 184634.8808927253 30 0.0 11 531185.2838804869 21 184712.9556354173 31 0.0 0 LINE 5 14E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531310.6762763139 20 184636.9221898522 30 0.0 11 531065.3007066001 21 185040.3313857042 31 0.0 0 LINE 5 14F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530762.244886776 20 184753.1969188066 30 0.0 11 531117.1883003287 21 184985.2538073602 31 0.0 0 LINE 5 150 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530857.7930969276 20 185213.7272284981 30 0.0 11 531119.0590254821 21 184978.5341598309 31 0.0 0 LINE 5 151 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530551.2309914298 20 185447.3752691109 30 0.0 11 530733.9839065221 21 185290.855504596 31 0.0 0 LINE 5 159 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530348.8181148427 20 184670.0431449962 30 0.0 11 530754.9648854495 21 185059.3532645555 31 0.0 0 LINE 5 15A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530768.0427135953 20 185059.3665338815 30 0.0 11 530751.1019407378 21 185076.7666714392 31 0.0 0 LINE 5 15B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530958.1276376176 20 185054.7821770324 30 0.0 11 530999.5616859051 21 185101.4584959087 31 0.0 0 LINE 5 15C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530956.1327284902 20 185039.3761384984 30 0.0 11 530961.1058763477 21 185062.9221409832 31 0.0 0 LINE 5 15D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530997.0898474322 20 184990.0711256135 30 0.0 11 530952.7982457301 21 185046.6406968503 31 0.0 0 LINE 5 15E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530292.8641702958 20 185138.907267058 30 0.0 11 530369.4465080707 21 185353.2161854958 31 0.0 0 LINE 5 160 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530370.209055034 20 184973.0161857821 30 0.0 11 530279.2606443146 21 185168.0844213306 31 0.0 0 LINE 5 167 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530155.8545585965 20 184909.1432228739 30 0.0 11 530296.6434578779 21 184802.4901862823 31 0.0 0 LINE 5 168 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530239.946090109 20 184831.2897865306 30 0.0 11 530402.572414678 21 185038.3924175608 31 0.0 0 LINE 5 169 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530862.2055151921 20 184812.5389120712 30 0.0 11 530841.7372332032 21 184854.8610028793 31 0.0 0 LINE 5 16A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530790.4707324915 20 184816.8599962522 30 0.0 11 530843.6341425299 21 184854.7341230553 31 0.0 0 LINE 5 16B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530795.6071824628 20 184767.5732594106 30 0.0 11 530725.8663087268 21 184845.1564635503 31 0.0 0 LINE 5 16C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530627.8983637173 20 184730.1996766032 30 0.0 11 530825.9688616006 21 184953.6427548386 31 0.0 0 LINE 5 16D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530924.4874933892 20 184951.6836966566 30 0.0 11 530886.1381600594 21 185008.8579249901 31 0.0 0 LINE 5 16E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530860.2504800935 20 184990.3167291071 30 0.0 11 530910.0659924778 21 185023.9468745498 31 0.0 0 LINE 5 16F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530868.4525274285 20 184987.7108168294 30 0.0 11 530827.8842952691 21 185046.3852955798 31 0.0 0 LINE 5 170 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530826.9412049412 20 185042.789476152 30 0.0 11 530872.6657967761 21 185075.3601914692 31 0.0 0 LINE 5 171 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530910.0543372351 20 185014.9114050643 30 0.0 11 530866.6906180778 21 185079.1428277431 31 0.0 0 LINE 5 179 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531418.7837954784 20 184696.3400722527 30 0.0 11 531280.8903155291 21 184879.4025017154 31 0.0 0 LINE 5 17A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531365.823685466 20 184738.3257753346 30 0.0 11 531592.6022829192 21 184976.3217497332 31 0.0 0 LINE 5 17B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531322.1351667875 20 184916.8361742784 30 0.0 11 531466.2108774758 21 184798.1684518348 31 0.0 0 LINE 5 17C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531280.8533771736 20 184872.4579400288 30 0.0 11 531322.982462895 21 184916.8624535107 31 0.0 0 LINE 5 17D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531090.7411011921 20 185101.1705888962 30 0.0 11 531309.9939928264 21 184900.4864199589 31 0.0 0 LINE 5 17F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531234.6183701311 20 185110.4794756935 30 0.0 11 531708.2884303343 21 184665.0084063687 31 0.0 0 LINE 5 180 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531591.4298111294 20 184870.2268875977 30 0.0 11 531810.6718730136 21 185019.8265656036 31 0.0 0 LINE 5 181 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531638.9187541661 20 184819.4880729046 30 0.0 11 531511.6900544397 21 184965.8519211652 31 0.0 0 LINE 5 182 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531692.9947588596 20 184867.9461364589 30 0.0 11 531650.4059499809 21 184916.131601699 31 0.0 0 LINE 5 183 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531669.5765725752 20 184818.8660633189 30 0.0 11 531692.3647384609 21 184883.8118485445 31 0.0 0 LINE 5 184 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531678.8223119822 20 184868.493021839 30 0.0 11 532025.3136076283 21 185074.7474273507 31 0.0 0 LINE 5 185 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531803.886242807 20 184855.9649338027 30 0.0 11 531669.257159631 21 185121.0225566715 31 0.0 0 LINE 5 186 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531659.1973208101 20 185112.2992179708 30 0.0 11 531865.3250912014 21 185232.9106352019 31 0.0 0 LINE 5 187 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531525.0175778789 20 185192.8194795596 30 0.0 11 531677.2123656238 21 185110.4457393622 31 0.0 0 LINE 5 188 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531361.9808639693 20 184957.7832641063 30 0.0 11 531551.4119677366 21 185185.0553518411 31 0.0 0 LINE 5 18B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531559.2968510764 20 184946.6658504695 30 0.0 11 531914.240264629 21 185178.722739023 31 0.0 0 LINE 5 18C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531495.5870839868 20 185514.328262188 30 0.0 11 531683.1901243598 21 185202.3268566529 31 0.0 0 LINE 5 18D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531462.5997031672 20 185412.663348532 30 0.0 11 531570.4877017599 21 185459.0282866746 31 0.0 0 LINE 5 18E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531511.2935385215 20 185374.1416658756 30 0.0 11 531543.5981320771 21 185479.1274464145 31 0.0 0 LINE 5 194 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531145.8700791432 20 184863.5120766591 30 0.0 11 531379.5250384659 21 185080.3303849344 31 0.0 0 LINE 5 199 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531364.8828980397 20 185058.1671364388 30 0.0 11 531313.3430297857 21 185456.7339505713 31 0.0 0 LINE 5 19D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531306.0542879552 20 185343.6943371587 30 0.0 11 531471.2618974371 21 185366.875736194 31 0.0 0 LINE 5 19E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531447.4325044233 20 185362.2124236505 30 0.0 11 531528.0241316422 21 185383.6033531333 31 0.0 0 LINE 5 19F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531454.8133421622 20 185351.359117895 30 0.0 11 531476.2768427921 21 185428.5825972159 31 0.0 0 LINE 5 1A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531385.8070593463 20 185499.2874665739 30 0.0 11 531481.1514824921 21 185416.9376060774 31 0.0 0 LINE 5 1A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531046.8204185548 20 185009.8251670371 30 0.0 11 531131.4314460383 21 185132.7716499767 31 0.0 0 LINE 5 1A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531659.2574794926 20 185006.0078437341 30 0.0 11 531638.7891975036 21 185048.3299345422 31 0.0 0 LINE 5 1A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531587.5226967918 20 185010.328927915 30 0.0 11 531640.6861068304 21 185048.2030547182 31 0.0 0 LINE 5 1A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531592.6591467632 20 184961.0421910735 30 0.0 11 531522.9182730272 21 185038.6253952131 31 0.0 0 LINE 5 1A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531424.9503280177 20 184923.6686082661 30 0.0 11 531623.020825901 21 185147.1116865014 31 0.0 0 LINE 5 1A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531721.5394576896 20 185145.1526283194 30 0.0 11 531683.1901243598 21 185202.3268566529 31 0.0 0 LINE 5 1A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531522.4751258036 20 185175.0126803835 30 0.0 11 531707.1179567783 21 185217.4158062127 31 0.0 0 LINE 5 1AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531190.971715833 20 185002.7164624653 30 0.0 11 531271.9560624464 21 185081.1135679418 31 0.0 0 LINE 5 1AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531510.9794785422 20 185470.5053524346 30 0.0 11 531383.9700559601 21 186031.2293542523 31 0.0 0 LINE 5 1AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531446.5789296222 20 185494.6210341629 30 0.0 11 531394.3170697989 21 185715.8408406318 31 0.0 0 LINE 5 1AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531303.1927971798 20 185374.8117721197 30 0.0 11 531201.7089334832 21 185510.9511236965 31 0.0 0 LINE 5 1B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531179.1304861695 20 185309.1540542189 30 0.0 11 531945.5235833686 21 185894.4094584342 31 0.0 0 LINE 5 1B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531306.2594945883 20 185492.8769809982 30 0.0 11 531119.7299674333 21 185890.4829456162 31 0.0 0 LINE 5 1B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531363.9212119025 20 185531.6681318393 30 0.0 11 531199.1434766117 21 185429.4046678644 31 0.0 0 LINE 5 1B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531324.7054493229 20 185592.7788688038 30 0.0 11 531270.3457337778 21 185558.4180331335 31 0.0 0 LINE 5 1B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531369.4236081366 20 185561.8345429817 30 0.0 11 531308.9422635012 21 185594.6866734165 31 0.0 0 LINE 5 1B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531321.9057846517 20 185578.8749408755 30 0.0 11 531173.5376807172 21 185953.8202748729 31 0.0 0 LINE 5 1B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531458.9627071512 20 185734.036583085 30 0.0 11 531071.0819022518 21 185609.6976292752 31 0.0 0 LINE 5 1B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531078.0896100116 20 185598.3755699595 30 0.0 11 530991.8880389454 21 185821.0975061012 31 0.0 0 LINE 5 1B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530956.4097734758 20 185451.7474070975 30 0.0 11 531082.7918483163 21 185615.8646001648 31 0.0 0 LINE 5 1B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531042.3088874028 20 185436.8032889021 30 0.0 11 530989.0780830456 21 185503.5700563008 31 0.0 0 LINE 5 1BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531427.9086440181 20 185996.2182578582 30 0.0 11 530990.5357910721 21 185818.3049727551 31 0.0 0 LINE 5 1BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531225.67491972 20 185473.3432035857 30 0.0 11 531053.182121386 21 185860.7466894662 31 0.0 0 LINE 5 1BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530705.244826224 20 185533.1168306179 30 0.0 11 531060.1140837642 21 185861.5220430019 31 0.0 0 LINE 5 1BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530750.2210620191 20 185452.1857979919 30 0.0 11 530721.6518899537 21 185566.0863253691 31 0.0 0 LINE 5 1C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530796.0140686663 20 185494.1144299564 30 0.0 11 530697.5223713036 21 185542.7455561081 31 0.0 0 LINE 5 1C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530944.3922051937 20 185612.8039722922 30 0.0 11 530775.9576853574 21 185501.2824771057 31 0.0 0 LINE 5 1C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530993.2462747479 20 185401.3925582406 30 0.0 11 530842.445202569 21 185661.7511045552 31 0.0 0 LINE 5 1C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530910.7632248174 20 185339.3410325321 30 0.0 11 530866.5377199338 21 185054.4967921601 31 0.0 0 LINE 5 1C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531241.8445475884 20 185051.9469660791 30 0.0 11 531241.8374840348 21 185051.9572004795 31 0.0 0 LINE 5 1C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531058.6997013602 20 185297.1334434182 30 0.0 11 530922.2746789083 21 185514.9725242263 31 0.0 0 LINE 5 1C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530924.3468199957 20 185527.8851535635 30 0.0 11 530904.4681140505 21 185513.935543462 31 0.0 0 LINE 5 1C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530959.1812899459 20 185714.807207831 30 0.0 11 530929.7367229487 21 185749.2623184473 31 0.0 0 LINE 5 1CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530974.0721419792 20 185710.3813506865 30 0.0 11 530951.6203425609 21 185719.0452490875 31 0.0 0 LINE 5 1CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531029.2769113626 20 185742.952861627 30 0.0 11 530966.368846218 21 185708.2478517434 31 0.0 0 LINE 5 1CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530990.5554871495 20 185489.0985828673 30 0.0 11 530692.0265768201 21 185303.9764231624 31 0.0 0 LINE 5 1CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530835.9437799745 20 185306.8642317253 30 0.0 11 530970.1789346107 21 185451.086004182 31 0.0 0 LINE 5 1CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531368.1091655744 20 185350.5718122836 30 0.0 11 530668.7795996761 21 185311.5128716326 31 0.0 0 LINE 5 1CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530837.7457079078 20 185386.5022824307 30 0.0 11 530778.7567006423 21 185458.8357962565 31 0.0 0 LINE 5 1D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530797.6081421722 20 185429.1683182495 30 0.0 11 530789.3411006597 21 185512.1396281498 31 0.0 0 LINE 5 1D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530809.4994571749 20 185434.7241835344 30 0.0 11 530736.6862803595 21 185468.2262566015 31 0.0 0 LINE 5 1D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530609.7436608612 20 185359.4255856905 30 0.0 11 530748.9595424861 21 185471.1817544603 31 0.0 0 LINE 5 1D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531183.0307102225 20 185581.4869541878 30 0.0 11 531137.9864403011 21 185568.0287342017 31 0.0 0 LINE 5 1D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531167.3269023387 20 185511.358919597 30 0.0 11 531138.4141562844 21 185569.8811441243 31 0.0 0 LINE 5 1D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531226.956583333 20 185337.0486008117 30 0.0 11 531037.9542343994 21 185568.2127058122 31 0.0 0 LINE 5 1D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.5968811997 20 185665.1585449819 30 0.0 11 530905.7031021065 21 185592.1718504262 31 0.0 0 LINE 5 1DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531342.5419517839 20 185694.0402766141 30 0.0 11 531259.2409286286 21 185945.1870251501 31 0.0 0 LINE 5 1DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530564.9552335094 20 184893.4794901465 30 0.0 11 530687.4949689912 21 184780.9839569827 31 0.0 0 LINE 5 1DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530476.7429703214 20 184939.4505193447 30 0.0 11 530406.7340426724 21 184768.7171604471 31 0.0 0 LINE 5 1E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531173.3663268639 20 185528.1064924517 30 0.0 11 531070.7327473466 21 185471.5685231011 31 0.0 0 LINE 5 1E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531054.9475551248 20 184568.1054545053 30 0.0 11 531230.7725863385 21 184476.7284847849 31 0.0 0 LINE 5 1E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533270.7018874835 20 183269.704674172 30 0.0 11 533995.2261483039 21 183104.4788902862 31 0.0 0 LINE 5 1E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533457.9214482086 20 183355.7642878445 30 0.0 11 533604.5737555198 21 183337.0347532795 31 0.0 0 LINE 5 1E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533530.1315517867 20 183207.8193128204 30 0.0 11 533511.6243141418 21 183701.9266786306 31 0.0 0 LINE 5 1E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533572.3429516997 20 183331.8438445227 30 0.0 11 533646.7981581808 21 183366.1588628451 31 0.0 0 LINE 5 1E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533612.2522464815 20 183262.8325135418 30 0.0 11 533576.567616609 21 183343.107264685 31 0.0 0 LINE 5 1E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533597.4568488472 20 183274.7830833879 30 0.0 11 533791.7168653863 21 183232.1532961663 31 0.0 0 LINE 5 1E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533594.7911288029 20 183152.2117233308 30 0.0 11 533751.8214958982 21 183555.6973923812 31 0.0 0 LINE 5 1EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.3821678945 20 183285.0285129525 30 0.0 11 533642.492107029 21 183366.5930041412 31 0.0 0 LINE 5 1EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.2284528752 20 183229.0149493306 30 0.0 11 533810.0531847598 21 183285.8097756414 31 0.0 0 LINE 5 1EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534074.3386399248 20 183151.4269752421 30 0.0 11 533800.5742660043 21 183267.181170518 31 0.0 0 LINE 5 1ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534009.9822550737 20 183174.6632241171 30 0.0 11 534046.8228962966 21 183281.6238171917 31 0.0 0 LINE 5 1EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.646702763 20 183249.4026584481 30 0.0 11 533363.7016999166 21 183552.296365491 31 0.0 0 LINE 5 1EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533655.8537941067 20 183510.4459319125 30 0.0 11 533729.8187339051 21 183943.3581115531 31 0.0 0 LINE 5 1F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533589.946866456 20 183532.4891602347 30 0.0 11 533776.0005197917 21 183477.7757597539 31 0.0 0 LINE 5 1F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533611.4813241646 20 183601.8337010309 30 0.0 11 533673.0261102665 21 183583.1820253481 31 0.0 0 LINE 5 1F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533576.6132530237 20 183560.1026257608 30 0.0 11 533626.1680009311 21 183607.8685391599 31 0.0 0 LINE 5 1F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533617.8809475537 20 183589.176602051 30 0.0 11 533661.0930421482 21 183990.087829921 31 0.0 0 LINE 5 1F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533444.4675323084 20 183702.2585308958 30 0.0 11 533851.4514544708 21 183685.6518652057 31 0.0 0 LINE 5 1F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533847.7102810031 20 183672.8729522521 30 0.0 11 533871.5176046772 21 183910.5049850937 31 0.0 0 LINE 5 1F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534004.0299181535 20 183563.9235520484 30 0.0 11 533838.5224367574 21 183688.479384923 31 0.0 0 LINE 5 1F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533925.2076230635 20 183526.6538560638 30 0.0 11 533958.7459745272 21 183605.1809134549 31 0.0 0 LINE 5 1F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533207.3255747524 20 183960.3049635265 30 0.0 11 533517.743220695 21 183803.8631234574 31 0.0 0 LINE 5 1F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533404.6134673158 20 183963.2474941249 30 0.0 11 533873.5643870205 21 183908.1731405794 31 0.0 0 LINE 5 1FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533738.7306447869 20 183513.0669599583 30 0.0 11 533801.8809645519 21 183932.4084239981 31 0.0 0 LINE 5 1FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534224.47460254 20 183709.2127634093 30 0.0 11 533794.9927018023 21 183931.3106481514 31 0.0 0 LINE 5 1FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534457.7232899407 20 183610.3296057948 30 0.0 11 533968.0924029948 21 183836.668115154 31 0.0 0 LINE 5 1FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534202.6632789288 20 183619.2296539358 30 0.0 11 534199.8836010037 21 183736.6255700483 31 0.0 0 LINE 5 1FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534147.3617370868 20 183647.456398454 30 0.0 11 534229.3554706404 21 183720.5496849997 31 0.0 0 LINE 5 1FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533972.7437243368 20 183722.3685368734 30 0.0 11 534164.7865490214 21 183659.7044734213 31 0.0 0 LINE 5 200 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533972.5943166301 20 183472.651390221 30 0.0 11 534057.9839914489 21 183796.6861657618 31 0.0 0 LINE 5 201 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533880.9676565471 20 183491.6555787594 30 0.0 11 534001.1484391712 21 183474.2186921551 31 0.0 0 LINE 5 202 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533966.8649116843 20 183378.0488408435 30 0.0 11 533865.8384516585 21 183444.2408746609 31 0.0 0 LINE 5 203 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533869.8459157255 20 183438.8265558422 30 0.0 11 533882.4827401662 21 183493.2134252263 31 0.0 0 LINE 5 204 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.3120588305 20 183102.5693639709 30 0.0 11 534020.1041949207 21 183633.953815103 31 0.0 0 LINE 5 205 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534014.6697131808 20 183645.8490315072 30 0.0 11 534037.5443778956 21 183637.6940154909 31 0.0 0 LINE 5 206 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533931.3368567337 20 183816.7552329881 30 0.0 11 533950.5478562621 21 183857.8048940144 31 0.0 0 LINE 5 207 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.161300471 20 183808.5253846964 30 0.0 11 533937.4969419636 21 183822.8529595328 31 0.0 0 LINE 5 208 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533856.2782318213 20 183825.2273517097 30 0.0 11 533926.1545818143 21 183808.5193272029 31 0.0 0 LINE 5 209 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533961.1739025831 20 183590.8382696407 30 0.0 11 534379.5749554227 21 183474.2284763425 31 0.0 0 LINE 5 20A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534350.0885551939 20 183462.4292674622 30 0.0 11 534369.0260173707 21 183662.8181014637 31 0.0 0 LINE 5 20B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534101.8508752668 20 183248.1966110715 30 0.0 11 534369.7091801646 21 183492.8116011192 31 0.0 0 LINE 5 20C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534331.7371032914 20 183358.3280084779 30 0.0 11 533990.9335592428 21 183559.6209208238 31 0.0 0 LINE 5 20D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533948.953081579 20 183438.1485673899 30 0.0 11 533982.607720473 21 183426.774957106 31 0.0 0 LINE 5 20E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534135.7799619498 20 183532.6183973673 30 0.0 11 534173.3870155533 21 183618.0440944372 31 0.0 0 LINE 5 20F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534163.1125968062 20 183584.4290320622 30 0.0 11 534148.9959986748 21 183666.607520118 31 0.0 0 LINE 5 210 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534150.1714181212 20 183586.619216026 30 0.0 11 534211.4401009357 21 183638.2941240943 31 0.0 0 LINE 5 211 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534362.7636945454 20 183567.208368469 30 0.0 11 534198.8229231334 21 183637.8760868667 31 0.0 0 LINE 5 212 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534133.0534407664 20 183026.7152225984 30 0.0 11 533977.4553795874 21 183110.2952903923 31 0.0 0 LINE 5 213 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534027.2513479877 20 183070.7431726557 30 0.0 11 534147.8091657108 21 183304.8470679847 31 0.0 0 LINE 5 214 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533751.0505647677 20 183628.6602944098 30 0.0 11 533798.0520979916 21 183627.6775367849 31 0.0 0 LINE 5 215 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533784.854580768 20 183565.2423212487 30 0.0 11 533797.1467362854 21 183629.3492675242 31 0.0 0 LINE 5 216 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533737.9064232348 20 183549.3855860542 30 0.0 11 533837.4861916935 21 183518.2919734023 31 0.0 0 LINE 5 217 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533773.7742595558 20 183381.3482958636 30 0.0 11 533894.426477489 21 183654.4815484178 31 0.0 0 LINE 5 218 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533851.6151786993 20 183743.2337394579 30 0.0 11 533919.5664651833 21 183732.1799429354 31 0.0 0 LINE 5 219 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533913.4912480489 20 183700.922309379 30 0.0 11 533923.3192982251 21 183760.2180207445 31 0.0 0 LINE 5 21A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533907.7061656309 20 183707.2939010718 30 0.0 11 533977.9455113938 21 183694.8476074883 31 0.0 0 LINE 5 21B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533975.0691473797 20 183692.4926410805 30 0.0 11 533985.6377707644 21 183747.6278747745 31 0.0 0 LINE 5 21C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533915.1095672107 20 183756.444406914 30 0.0 11 533991.5652424396 21 183743.7709100099 31 0.0 0 LINE 5 21D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533943.085985443 20 183201.5481465576 30 0.0 11 533980.6329200526 21 183307.8251348707 31 0.0 0 LINE 5 21E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533567.3344408619 20 183694.6941674654 30 0.0 11 533580.779713257 21 183958.953461359 31 0.0 0 LINE 5 21F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533299.3400004697 20 184222.45492858 30 0.0 11 533281.5900181469 21 184813.9041900183 31 0.0 0 LINE 5 220 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533203.5044763441 20 184131.5129678913 30 0.0 11 533448.5161786756 21 184142.2478269584 31 0.0 0 LINE 5 221 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533425.5537299617 20 183189.4530703633 30 0.0 11 533355.5667372975 21 184507.1397523095 31 0.0 0 LINE 5 222 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533416.2853748554 20 184137.0569182016 30 0.0 11 533490.7405813366 21 184171.371936524 31 0.0 0 LINE 5 223 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533456.1946696371 20 184068.0455872208 30 0.0 11 533420.5100397649 21 184148.3203383639 31 0.0 0 LINE 5 224 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533443.2091147538 20 184079.7836062105 30 0.0 11 533637.4691312929 21 184037.1538189889 31 0.0 0 LINE 5 225 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533407.8651870973 20 183878.1092921243 30 0.0 11 533595.7639190539 21 184360.9104660599 31 0.0 0 LINE 5 226 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533654.3245910503 20 184090.2415866314 30 0.0 11 533486.4345301848 21 184171.8060778201 31 0.0 0 LINE 5 227 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533631.1708760309 20 184034.2280230095 30 0.0 11 533653.9956079154 21 184091.0228493203 31 0.0 0 LINE 5 228 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.2810630806 20 183956.640048921 30 0.0 11 533644.51668916 21 184072.3942441969 31 0.0 0 LINE 5 229 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533853.9246782293 20 183979.876297796 30 0.0 11 533890.7653194523 21 184086.8368908706 31 0.0 0 LINE 5 22A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533965.5891259187 20 184054.615732127 30 0.0 11 533264.55379769 21 184336.4331711375 31 0.0 0 LINE 5 22B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533499.7962172624 20 184315.6590055914 30 0.0 11 533573.7611570609 21 184748.571185232 31 0.0 0 LINE 5 22C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533433.8892896117 20 184337.7022339136 30 0.0 11 533619.9429429473 21 184282.9888334328 31 0.0 0 LINE 5 22D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533455.4237473202 20 184407.0467747098 30 0.0 11 533516.9685334222 21 184388.3950990269 31 0.0 0 LINE 5 22E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533420.5556761794 20 184365.3156994397 30 0.0 11 533470.1104240868 21 184413.0816128387 31 0.0 0 LINE 5 22F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533461.8233707093 20 184394.3896757299 30 0.0 11 533505.0354653038 21 184795.3009035999 31 0.0 0 LINE 5 230 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533288.409955464 20 184507.4716045747 30 0.0 11 533695.3938776265 21 184490.8649388846 31 0.0 0 LINE 5 231 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533691.6527041588 20 184478.0860259309 30 0.0 11 533715.4600278328 21 184715.7180587726 31 0.0 0 LINE 5 232 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533847.9723413094 20 184369.1366257273 30 0.0 11 533682.4648599131 21 184493.6924586019 31 0.0 0 LINE 5 233 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533769.1500462192 20 184331.8669297427 30 0.0 11 533802.6883976829 21 184410.3939871337 31 0.0 0 LINE 5 234 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533280.1746114135 20 184638.1115223118 30 0.0 11 533369.9039828841 21 184629.7013561934 31 0.0 0 LINE 5 235 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533248.5558904716 20 184768.4605678038 30 0.0 11 533717.5068101762 21 184713.3862142584 31 0.0 0 LINE 5 236 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533582.6730679426 20 184318.2800336372 30 0.0 11 533645.8233877078 21 184737.6214976771 31 0.0 0 LINE 5 237 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.0039373072 20 184485.2255270968 30 0.0 11 533638.9351249581 21 184736.5237218303 31 0.0 0 LINE 5 238 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534046.6057020844 20 184424.4427276146 30 0.0 11 534043.8260241595 21 184541.8386437273 31 0.0 0 LINE 5 239 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533991.3041602425 20 184452.6694721329 30 0.0 11 534073.2978937962 21 184525.7627586786 31 0.0 0 LINE 5 23A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533816.6861474925 20 184527.5816105521 30 0.0 11 534008.728972177 21 184464.9175471002 31 0.0 0 LINE 5 23B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533816.5367397858 20 184277.8644638999 30 0.0 11 533901.9264146046 21 184601.8992394407 31 0.0 0 LINE 5 23C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533724.9100797029 20 184296.8686524383 30 0.0 11 533845.0908623268 21 184279.431765834 31 0.0 0 LINE 5 23D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.80733484 20 184183.2619145225 30 0.0 11 533709.7808748142 21 184249.4539483398 31 0.0 0 LINE 5 23E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533713.7883388812 20 184244.0396295211 30 0.0 11 533726.4251633219 21 184298.4264989052 31 0.0 0 LINE 5 23F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533679.2544819863 20 183907.7824376498 30 0.0 11 533864.0466180764 21 184439.1668887819 31 0.0 0 LINE 5 240 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533858.6121363364 20 184451.062105186 30 0.0 11 533881.4868010512 21 184442.9070891699 31 0.0 0 LINE 5 241 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533775.2792798894 20 184621.968306667 30 0.0 11 533794.4902794179 21 184663.0179676933 31 0.0 0 LINE 5 242 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533762.1037236266 20 184613.7384583753 30 0.0 11 533781.4393651193 21 184628.0660332116 31 0.0 0 LINE 5 243 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533700.2206549769 20 184630.4404253886 30 0.0 11 533770.0970049699 21 184613.7324008818 31 0.0 0 LINE 5 244 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533805.1163257388 20 184396.0513433196 30 0.0 11 534148.8336143433 21 184307.1003803216 31 0.0 0 LINE 5 245 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533945.7932984225 20 184053.4096847504 30 0.0 11 534099.4280930914 21 184187.6594453309 31 0.0 0 LINE 5 246 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534111.8739580623 20 184159.1560880029 30 0.0 11 533834.8759823985 21 184364.8339945026 31 0.0 0 LINE 5 247 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533792.8955047349 20 184243.3616410688 30 0.0 11 533826.5501436287 21 184231.9880307849 31 0.0 0 LINE 5 248 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533979.7223851056 20 184337.8314710463 30 0.0 11 534017.3294387088 21 184423.2571681159 31 0.0 0 LINE 5 249 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534007.0550199618 20 184389.6421057411 30 0.0 11 533992.9384218304 21 184471.8205937969 31 0.0 0 LINE 5 24A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533994.1138412768 20 184391.8322897049 30 0.0 11 534055.3825240914 21 184443.5071977732 31 0.0 0 LINE 5 24B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534157.3418682092 20 184390.7032924748 30 0.0 11 534042.765346289 21 184443.0891605456 31 0.0 0 LINE 5 24C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533853.5262160742 20 183878.666833987 30 0.0 11 533991.7515888664 21 184110.0601416636 31 0.0 0 LINE 5 24D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533594.9929879234 20 184433.8733680887 30 0.0 11 533641.9945211472 21 184432.8906104638 31 0.0 0 LINE 5 24E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533628.7970039238 20 184370.4553949276 30 0.0 11 533641.0891594411 21 184434.5623412031 31 0.0 0 LINE 5 24F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533581.8488463905 20 184354.5986597329 30 0.0 11 533681.4286148493 21 184323.5050470813 31 0.0 0 LINE 5 250 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533617.7166827114 20 184186.5613695425 30 0.0 11 533738.3689006447 21 184459.6946220967 31 0.0 0 LINE 5 251 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533695.5576018551 20 184548.4468131368 30 0.0 11 533763.508888339 21 184537.3930166142 31 0.0 0 LINE 5 252 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533757.4336712046 20 184506.1353830579 30 0.0 11 533767.2617213808 21 184565.4310944234 31 0.0 0 LINE 5 253 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533751.6485887866 20 184512.5069747506 30 0.0 11 533821.8879345495 21 184500.0606811671 31 0.0 0 LINE 5 254 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533819.0115705354 20 184497.7057147594 30 0.0 11 533829.5801939202 21 184552.8409484534 31 0.0 0 LINE 5 255 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533759.0519903664 20 184561.6574805929 30 0.0 11 533835.5076655954 21 184548.9839836887 31 0.0 0 LINE 5 256 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.0284085987 20 184006.7612202365 30 0.0 11 533824.5753432083 21 184113.0382085496 31 0.0 0 LINE 5 257 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533411.2768640178 20 184499.9072411442 30 0.0 11 533424.7221364126 21 184764.1665350379 31 0.0 0 LINE 5 258 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534079.0438751079 20 184492.5166948246 30 0.0 11 534641.721189493 21 184610.5719340789 31 0.0 0 LINE 5 25A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534078.581459301 20 184263.7540395752 30 0.0 11 534244.6175290031 21 184228.1883089295 31 0.0 0 LINE 5 25B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534001.2095466687 20 183814.2563075048 30 0.0 11 534167.6424192837 21 184551.2581387564 31 0.0 0 LINE 5 25C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534184.6430945557 20 184315.7129436011 30 0.0 11 534623.810301958 21 184321.8368213024 31 0.0 0 LINE 5 25D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534195.8955435099 20 184384.2914345422 30 0.0 11 534171.5481171157 21 184191.8941348217 31 0.0 0 LINE 5 25E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534267.7865448688 20 184374.0893695216 30 0.0 11 534259.1867207302 21 184310.3579900692 31 0.0 0 LINE 5 25F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534221.0297037694 20 184401.8573877923 30 0.0 11 534276.0859439502 21 184360.5528367094 31 0.0 0 LINE 5 260 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.3117883924 20 184365.7534653767 30 0.0 11 534658.9839601197 21 184387.0189272303 31 0.0 0 LINE 5 261 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534340.2964578094 20 184554.9790199963 30 0.0 11 534388.795247378 21 184150.5540434503 31 0.0 0 LINE 5 262 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534375.5833000987 20 184152.2097741889 30 0.0 11 534613.971169032 21 184166.5971171824 31 0.0 0 LINE 5 263 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534292.9527107281 20 183980.5182296566 30 0.0 11 534389.5250794471 21 184163.7684943256 31 0.0 0 LINE 5 264 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534243.591734117 20 184052.3894925513 30 0.0 11 534326.4617765393 21 184031.8012475966 31 0.0 0 LINE 5 265 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534523.6546636549 20 184592.9361776223 30 0.0 11 534529.6593127575 21 184503.01379338 31 0.0 0 LINE 5 267 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534200.4451829229 20 184234.3143184903 30 0.0 11 534624.4909197793 21 184238.8353143359 31 0.0 0 LINE 5 268 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534471.5327107409 20 183786.0600145884 30 0.0 11 534606.9904846774 21 184209.2224334297 31 0.0 0 LINE 5 269 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534421.2657241103 20 183576.3330352236 30 0.0 11 534556.4776611428 21 184059.4846922112 31 0.0 0 LINE 5 26A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534379.2230397164 20 183793.2446136424 30 0.0 11 534494.6738051587 21 183814.7073368633 31 0.0 0 LINE 5 26B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534398.2709077693 20 183852.3393541769 30 0.0 11 534483.5028377962 21 183783.049246773 31 0.0 0 LINE 5 26C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534444.3820505485 20 184036.6679774855 30 0.0 11 534413.1406446979 21 183837.0904088021 31 0.0 0 LINE 5 26D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534231.8313058096 20 183993.0367155942 30 0.0 11 534531.3403140241 21 183964.3680914949 31 0.0 0 LINE 5 26E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534172.5775135222 20 183923.7014562585 30 0.0 11 534215.9402417578 21 184037.1348698833 31 0.0 0 LINE 5 26F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534115.2587862785 20 184054.0831760169 30 0.0 11 534123.8030832675 21 183933.6060995451 31 0.0 0 LINE 5 270 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.0293094167 20 183939.744568014 30 0.0 11 534174.6763040911 21 183924.2648762933 31 0.0 0 LINE 5 271 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.5991600926 20 184073.5153000436 30 0.0 11 533810.6114064545 21 184073.5131405614 31 0.0 0 LINE 5 272 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533954.7380145801 20 184048.098338197 30 0.0 11 534364.6500434818 21 183975.815826753 31 0.0 0 LINE 5 273 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534375.5265551551 20 183983.0774559717 30 0.0 11 534371.123204419 21 183959.1951387822 31 0.0 0 LINE 5 274 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534530.9589212817 20 184092.5949168104 30 0.0 11 534574.5465687242 21 184080.1750068405 31 0.0 0 LINE 5 275 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534520.7335404321 20 184104.2896708572 30 0.0 11 534537.9608515989 21 184087.4859158428 31 0.0 0 LINE 5 276 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534527.3546613447 20 184168.0441267445 30 0.0 11 534522.0020775037 21 184096.3976877718 31 0.0 0 LINE 5 277 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534312.6897586476 20 184027.1174682027 30 0.0 11 534268.715040369 21 183678.6121619755 31 0.0 0 LINE 5 278 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534178.0924395927 20 183721.0298699493 30 0.0 11 534286.6169309787 21 183992.7609886244 31 0.0 0 LINE 5 279 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534160.0049395611 20 184014.8357883496 30 0.0 11 534154.1430236581 21 183979.7982132065 31 0.0 0 LINE 5 27A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534283.0554192325 20 183845.4622028715 30 0.0 11 534373.3845904289 21 183821.9572878209 31 0.0 0 LINE 5 27B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534338.5613499616 20 183826.740385397 30 0.0 11 534417.4375952255 21 183853.7796193919 31 0.0 0 LINE 5 27C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534338.6600611481 20 183839.8652194019 30 0.0 11 534399.4430551205 21 183787.6198821797 31 0.0 0 LINE 5 27D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534353.3950801142 20 183626.8977659865 30 0.0 11 534397.018575538 21 183800.0089834212 31 0.0 0 LINE 5 27E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534316.5240373919 20 184240.583205404 30 0.0 11 534323.0481789416 21 184194.0262992032 31 0.0 0 LINE 5 27F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534259.3074196166 20 184197.0997663956 30 0.0 11 534324.5541633551 21 184195.1866329612 31 0.0 0 LINE 5 280 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534236.1677363386 20 184240.9189471798 30 0.0 11 534221.3497769108 21 184137.6553470467 31 0.0 0 LINE 5 281 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534075.9993490205 20 184178.7166941591 30 0.0 11 534364.8760209383 21 184103.158770916 31 0.0 0 LINE 5 282 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534445.6665385903 20 184159.5737598459 30 0.0 11 534445.5888953305 21 184090.7293139994 31 0.0 0 LINE 5 283 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534413.7624798858 20 184091.7428221283 30 0.0 11 534473.8666444875 21 184091.4951244661 31 0.0 0 LINE 5 284 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534419.1301320043 20 184098.4698326099 30 0.0 11 534418.0426346745 21 184027.1445687356 31 0.0 0 LINE 5 285 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534415.2591650874 20 184029.6086372781 30 0.0 11 534471.3741634863 21 184027.9664590178 31 0.0 0 LINE 5 286 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534468.8322797114 20 184098.9981249308 30 0.0 11 534468.5116705245 21 184021.4998345739 31 0.0 0 LINE 5 287 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534352.4198206242 20 184432.4779143455 30 0.0 11 534615.4420738622 21 184461.3404170194 31 0.0 0 LINE 5 288 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533532.7624275796 20 183279.5203883841 30 0.0 11 532822.6282750719 21 183060.5581778998 31 0.0 0 LINE 5 289 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533342.1028701529 20 183213.5023917251 30 0.0 11 533311.0032423039 21 183772.1392497893 31 0.0 0 LINE 5 28A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533339.6295991045 20 183351.3335597998 30 0.0 11 533194.7893030568 21 183321.6859065113 31 0.0 0 LINE 5 28B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533278.6891237384 20 183198.401309585 30 0.0 11 533234.487352922 21 184185.8116573112 31 0.0 0 LINE 5 28C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533227.3181130724 20 183318.9206275791 30 0.0 11 533150.504528331 21 183347.5697367062 31 0.0 0 LINE 5 28D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533192.6831632028 20 183247.1171745893 30 0.0 11 533222.2627044432 21 183329.8364542056 31 0.0 0 LINE 5 28E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533206.543120186 20 183260.1410566229 30 0.0 11 533016.016412499 21 183203.0987351212 31 0.0 0 LINE 5 28F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533218.3705491292 20 183138.1125505508 30 0.0 11 533031.596680065 21 183528.7207214253 31 0.0 0 LINE 5 290 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532993.44798064 20 183254.429505146 30 0.0 11 533154.7660373612 21 183348.3247837068 31 0.0 0 LINE 5 291 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533020.7270185264 20 183200.3049458331 30 0.0 11 532993.7175981719 21 183255.2331889633 31 0.0 0 LINE 5 292 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532740.2254147077 20 183101.4565594727 30 0.0 11 533004.5635047808 21 183237.3658685307 31 0.0 0 LINE 5 293 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532802.6632449139 20 183129.4420001883 30 0.0 11 532757.924443903 21 183233.3469615745 31 0.0 0 LINE 5 294 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.720654224 20 183195.6187514277 30 0.0 11 533412.4422479266 21 183553.0579135474 31 0.0 0 LINE 5 295 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533130.6806038581 20 183490.7750957559 30 0.0 11 533024.5381114682 21 183916.9411888579 31 0.0 0 LINE 5 296 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533194.7538784246 20 183517.6868499452 30 0.0 11 533013.3144771753 21 183449.2086651994 31 0.0 0 LINE 5 297 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533168.0923122618 20 183585.2261651385 30 0.0 11 533108.1152453137 21 183562.0227786959 31 0.0 0 LINE 5 298 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533205.9844550757 20 183546.2203893963 30 0.0 11 533152.9953396826 21 183590.1454297818 31 0.0 0 LINE 5 299 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533162.6574581374 20 183572.125795115 30 0.0 11 533089.5755333646 21 183968.6811254574 31 0.0 0 LINE 5 29A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533327.1256725953 20 183697.8633855617 30 0.0 11 532922.5243948965 21 183650.8580632188 31 0.0 0 LINE 5 29B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532927.2110360585 20 183638.3948216737 30 0.0 11 532885.6939141481 21 183873.5800684076 31 0.0 0 LINE 5 29C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532779.4795621642 20 183518.0569124989 30 0.0 11 532935.2056681788 21 183654.6448395154 31 0.0 0 LINE 5 29D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532860.8690292618 20 183486.7880927641 30 0.0 11 532821.5502885538 21 183562.5862219661 31 0.0 0 LINE 5 29F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533293.6322814212 20 183952.7605173787 30 0.0 11 532883.8273047613 21 183871.1016442716 31 0.0 0 LINE 5 2A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533047.8398997946 20 183487.189023119 30 0.0 11 532953.4969078967 21 183900.6314329289 31 0.0 0 LINE 5 2A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532548.7839254298 20 183646.44825568 30 0.0 11 532960.4479911811 21 183900.052022287 31 0.0 0 LINE 5 2A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532323.5859293173 20 183530.3935634832 30 0.0 11 532794.9132185243 21 183792.7256292301 31 0.0 0 LINE 5 2A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532577.2654881728 20 183558.3489116874 30 0.0 11 532571.2553581126 21 183675.6238282977 31 0.0 0 LINE 5 2A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.3005233718 20 183590.633500544 30 0.0 11 532543.0686538527 21 183657.3882892886 31 0.0 0 LINE 5 2A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532798.8253221348 20 183678.3983628817 30 0.0 11 532612.008295049 21 183601.5437615102 31 0.0 0 LINE 5 2A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532817.6548659477 20 183429.3920899996 30 0.0 11 532708.2644265074 21 183746.131200443 31 0.0 0 LINE 5 2A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532982.2371375846 20 183070.6166723318 30 0.0 11 532758.2115810167 21 183586.6884875571 31 0.0 0 LINE 5 2A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532762.7409918191 20 183598.9569105556 30 0.0 11 532740.5404720749 21 183589.1135627954 31 0.0 0 LINE 5 2A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.0553973926 20 183775.6181090037 30 0.0 11 532810.8274301857 21 183815.1156361047 31 0.0 0 LINE 5 2AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532846.8096853747 20 183768.3969423502 30 0.0 11 532826.4564207106 21 183781.2379333611 31 0.0 0 LINE 5 2AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532907.2699385936 20 183789.6813889798 30 0.0 11 532838.8392540151 21 183767.7929495795 31 0.0 0 LINE 5 2AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532820.202091548 20 183548.1021399771 30 0.0 11 532411.6965931075 21 183400.5198149712 31 0.0 0 LINE 5 2AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532705.5512352485 20 183195.8969469713 30 0.0 11 532420.1445797267 21 183419.7888982393 31 0.0 0 LINE 5 2AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532468.0705552294 20 183288.5226947296 30 0.0 11 532792.8610919387 21 183514.7460345087 31 0.0 0 LINE 5 2B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532650.440516718 20 183476.9836669457 30 0.0 11 532606.5484086562 21 183559.3567393084 31 0.0 0 LINE 5 2B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532619.308676055 20 183526.6044619072 30 0.0 11 532627.2382057076 21 183609.6087075904 31 0.0 0 LINE 5 2B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532632.0497533188 20 183529.7565979628 30 0.0 11 532567.0871053734 21 183576.7033975304 31 0.0 0 LINE 5 2B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532319.1054598828 20 183440.943242896 30 0.0 11 532579.7002024197 21 183577.2303830341 31 0.0 0 LINE 5 2B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532691.0044244704 20 182972.7019742909 30 0.0 11 532839.9141442266 21 183067.6876560392 31 0.0 0 LINE 5 2B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532793.2164716504 20 183024.5212818305 30 0.0 11 532655.4838754236 21 183248.9506764272 31 0.0 0 LINE 5 2B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533026.9073257411 20 183601.5368553743 30 0.0 11 532980.1110058652 21 183597.0408144468 31 0.0 0 LINE 5 2B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532997.9421264003 20 183535.767804562 30 0.0 11 532980.888773864 21 183598.7755883294 31 0.0 0 LINE 5 2B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533045.9449296638 20 183523.46754336 30 0.0 11 532948.9701949887 21 183485.011804273 31 0.0 0 LINE 5 2B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533022.747934971 20 183353.2179265787 30 0.0 11 532882.0015395169 21 183616.5602579835 31 0.0 0 LINE 5 2BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532918.0536104154 20 183708.2663477616 30 0.0 11 532851.1196203771 21 183692.1603013838 31 0.0 0 LINE 5 2BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532859.5161003121 20 183661.4447183113 30 0.0 11 532845.2798621558 21 183719.8390800234 31 0.0 0 LINE 5 2BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532864.808334425 20 183668.2312208995 30 0.0 11 532795.6968644821 21 183650.5654166575 31 0.0 0 LINE 5 2BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532798.7413366781 20 183648.4322205175 30 0.0 11 532784.0778326244 21 183702.6223620896 31 0.0 0 LINE 5 2BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532853.7488820336 20 183716.6901838713 30 0.0 11 532778.4554968875 21 183698.3327888569 31 0.0 0 LINE 5 2C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533236.9410300952 20 184128.2527506047 30 0.0 11 533126.981531269 21 184343.3517983396 31 0.0 0 LINE 5 2C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532835.6102659117 20 183916.0876363871 30 0.0 11 533298.5518772549 21 184154.1088557825 31 0.0 0 LINE 5 2C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532781.1055054279 20 184010.2498283422 30 0.0 11 533459.0946851481 21 184343.719875779 31 0.0 0 LINE 5 2C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533226.0654550621 20 184305.4061726703 30 0.0 11 533119.9229626722 21 184731.5722657724 31 0.0 0 LINE 5 2C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533290.1387296285 20 184332.3179268596 30 0.0 11 533108.6993283793 21 184263.8397421138 31 0.0 0 LINE 5 2C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533263.4771634658 20 184399.8572420528 30 0.0 11 533203.5000965176 21 184376.6538556104 31 0.0 0 LINE 5 2CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533301.3693062795 20 184360.8514663108 30 0.0 11 533248.3801908866 21 184404.7765066962 31 0.0 0 LINE 5 2CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533258.0423093414 20 184386.7568720294 30 0.0 11 533184.9603845684 21 184783.3122023718 31 0.0 0 LINE 5 2CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533313.2245827507 20 184499.6854179535 30 0.0 11 533017.9092461005 21 184465.4891401333 31 0.0 0 LINE 5 2CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533022.5958872625 20 184453.0258985883 30 0.0 11 532981.0787653521 21 184688.211145322 31 0.0 0 LINE 5 2CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532874.8644133681 20 184332.6879894133 30 0.0 11 533030.5905193828 21 184469.2759164299 31 0.0 0 LINE 5 2CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532956.2538804658 20 184301.4191696784 30 0.0 11 532916.9351397578 21 184377.2172988805 31 0.0 0 LINE 5 2D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533312.5190293062 20 184749.7419374041 30 0.0 11 532979.2121559653 21 184685.7327211861 31 0.0 0 LINE 5 2D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533143.2247509987 20 184301.8201000335 30 0.0 11 533048.8817591007 21 184715.2625098432 31 0.0 0 LINE 5 2D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532593.9135947571 20 184428.0269791083 30 0.0 11 533055.8328423851 21 184714.6830992013 31 0.0 0 LINE 5 2D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532672.6503393768 20 184372.9799886018 30 0.0 11 532666.6402093166 21 184490.254905212 31 0.0 0 LINE 5 2D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532725.6853745756 20 184405.2645774584 30 0.0 11 532638.4535050566 21 184472.0193662031 31 0.0 0 LINE 5 2D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532894.2101733388 20 184493.0294397962 30 0.0 11 532707.3931462529 21 184416.1748384246 31 0.0 0 LINE 5 2D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532913.0397171517 20 184244.0231669139 30 0.0 11 532803.6492777113 21 184560.7622773574 31 0.0 0 LINE 5 2D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533002.9879995437 20 184269.8284089141 30 0.0 11 532884.4483571425 21 184243.4500331875 31 0.0 0 LINE 5 2D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533018.0305508438 20 184217.9793931889 30 0.0 11 533001.3606235288 21 184271.2685517172 31 0.0 0 LINE 5 2D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533077.6219887886 20 183885.2477492463 30 0.0 11 532853.5964322206 21 184401.3195644716 31 0.0 0 LINE 5 2DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532858.125843023 20 184413.5879874701 30 0.0 11 532835.9253232789 21 184403.7446397097 31 0.0 0 LINE 5 2DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532928.4402485964 20 184590.2491859182 30 0.0 11 532906.2122813897 21 184629.7467130191 31 0.0 0 LINE 5 2DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532942.1945365787 20 184583.0280192646 30 0.0 11 532921.8412719146 21 184595.8690102754 31 0.0 0 LINE 5 2DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533002.6547897976 20 184604.3124658941 30 0.0 11 532934.2241052192 21 184582.424026494 31 0.0 0 LINE 5 2DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532915.586942752 20 184362.7332168916 30 0.0 11 532579.4868776007 21 184248.3190809244 31 0.0 0 LINE 5 2DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532800.9360864524 20 184010.5280238858 30 0.0 11 532637.6889675159 21 184132.908686197 31 0.0 0 LINE 5 2E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532627.4102219 20 184103.5541580553 30 0.0 11 532888.2459431427 21 184329.3771114232 31 0.0 0 LINE 5 2E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532939.1957581605 20 184211.3855460326 30 0.0 11 532906.4862421954 21 184197.5262063909 31 0.0 0 LINE 5 2E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532745.825367922 20 184291.6147438601 30 0.0 11 532701.9332598602 21 184373.9878162229 31 0.0 0 LINE 5 2E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532714.693527259 20 184341.2355388216 30 0.0 11 532722.6230569117 21 184424.2397845048 31 0.0 0 LINE 5 2E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532727.4346045227 20 184344.3876748772 30 0.0 11 532662.4719565772 21 184391.3344744447 31 0.0 0 LINE 5 2E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532564.7483924605 20 184331.0512654725 30 0.0 11 532675.0850536236 21 184391.8614599485 31 0.0 0 LINE 5 2E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532906.0166036281 20 183843.1770056994 30 0.0 11 532750.8687266275 21 184063.5817533417 31 0.0 0 LINE 5 2E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533122.292176945 20 184416.1679322887 30 0.0 11 533075.4958570691 21 184411.6718913614 31 0.0 0 LINE 5 2E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533093.3269776042 20 184350.3988814763 30 0.0 11 533076.273625068 21 184413.4066652438 31 0.0 0 LINE 5 2E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533141.3297808676 20 184338.0986202742 30 0.0 11 533044.3550461925 21 184299.6428811874 31 0.0 0 LINE 5 2EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533118.132786175 20 184167.8490034932 30 0.0 11 532977.3863907207 21 184431.1913348979 31 0.0 0 LINE 5 2EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533013.4384616195 20 184522.897424676 30 0.0 11 532946.5044715811 21 184506.7913782983 31 0.0 0 LINE 5 2EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532954.9009515162 20 184476.0757952258 30 0.0 11 532940.6647133597 21 184534.470156938 31 0.0 0 LINE 5 2ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532960.1931856289 20 184482.8622978139 30 0.0 11 532891.0817156861 21 184465.196493572 31 0.0 0 LINE 5 2EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532894.1261878821 20 184463.0632974319 30 0.0 11 532879.4626838282 21 184517.2534390039 31 0.0 0 LINE 5 2EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532949.1337332375 20 184531.3212607857 30 0.0 11 532873.8403480914 21 184512.9638657713 31 0.0 0 LINE 5 2F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532962.7457486525 20 183975.8869687485 30 0.0 11 532917.3537715828 21 184079.0574052173 31 0.0 0 LINE 5 2F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532635.2106572713 20 184438.4366176368 30 0.0 11 532065.2785999623 21 184514.0689499459 31 0.0 0 LINE 5 2F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532590.2300880724 20 184386.4198395649 30 0.0 11 532364.6295972854 21 184414.239316967 31 0.0 0 LINE 5 2F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532652.7847925186 20 184210.3495376971 30 0.0 11 532489.8745094784 21 184162.4628243181 31 0.0 0 LINE 5 2F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532763.5654245859 20 183767.8992291204 30 0.0 11 532542.4660997646 21 184490.3856919131 31 0.0 0 LINE 5 2F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532543.1334552761 20 184254.2287175145 30 0.0 11 532030.3823403245 21 184165.1226977185 31 0.0 0 LINE 5 2F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532526.7823938887 20 184321.7732940453 30 0.0 11 532565.4542369875 21 184131.7364379803 31 0.0 0 LINE 5 2F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532455.8560125364 20 184306.2218749684 30 0.0 11 532469.1992844791 21 184243.3123939978 31 0.0 0 LINE 5 2F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532500.404604757 20 184337.4098207074 30 0.0 11 532448.5924934925 21 184292.102419002 31 0.0 0 LINE 5 2F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532467.9222000074 20 184298.7677181402 30 0.0 11 532151.5594281791 21 184344.7377033163 31 0.0 0 LINE 5 2FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532546.3727587354 20 184062.6106464354 30 0.0 11 532126.1632264118 21 184073.4140238009 31 0.0 0 LINE 5 307 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532584.4903761105 20 183864.2182182287 30 0.0 11 532532.7635513458 21 183974.0899667647 31 0.0 0 LINE 5 308 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532631.8950520743 20 183998.5224476362 30 0.0 11 532632.3872072136 21 183877.743770919 31 0.0 0 LINE 5 309 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532634.6940095361 20 183884.0725369571 30 0.0 11 532582.3553185839 21 183864.6230556592 31 0.0 0 LINE 5 30A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532934.2473785581 20 184040.6907525797 30 0.0 11 532934.235328054 21 184040.6876830364 31 0.0 0 LINE 5 30B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532792.4137581562 20 184004.5624334069 30 0.0 11 532167.9345982127 21 183901.8182242516 31 0.0 0 LINE 5 310 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532368.508547977 20 184092.6775787239 30 0.0 11 532506.9565822644 21 183612.623907776 31 0.0 0 LINE 5 311 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532594.1521268948 20 183661.7019549843 30 0.0 11 532478.1241977714 21 183964.5209857737 31 0.0 0 LINE 5 312 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532590.2102493452 20 183956.0377104505 30 0.0 11 532598.6767912577 21 183921.5368206355 31 0.0 0 LINE 5 317 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532306.0587504182 20 184266.992331815 30 0.0 11 532414.2191715132 21 184122.5293847503 31 0.0 0 LINE 5 318 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532477.551415465 20 184130.3624860479 30 0.0 11 532412.6306058845 21 184123.5738093414 31 0.0 0 LINE 5 319 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532661.721044324 20 184125.7436229359 30 0.0 11 532439.6824280089 21 184049.5153294456 31 0.0 0 LINE 5 31C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532847.7714891928 20 183350.8987513204 30 0.0 11 532995.8222172223 21 183426.7421009539 31 0.0 0 LINE 5 31D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532774.0262611856 20 183284.1426261447 30 0.0 11 532909.8188335092 21 183159.1966094306 31 0.0 0 LINE 5 31E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532709.4902750977 20 183812.8863756505 30 0.0 11 532835.4314276548 21 183979.9680373762 31 0.0 0 LINE 5 31F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532463.9437321764 20 184141.8423292799 30 0.0 11 532481.318514892 21 184025.9617418272 31 0.0 0 LINE 5 320 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533323.0645174747 20 183697.3915731477 30 0.0 11 533469.8168568623 21 183830.5378952181 31 0.0 0 LINE 5 322 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529846.7918439317 20 185094.6275250928 30 0.0 11 532736.3514167985 21 185388.7767557458 31 0.0 0 LINE 5 323 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530632.5473901829 20 185377.7313809267 30 0.0 11 530347.847156352 21 185292.772304566 31 0.0 0 LINE 5 324 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530537.8475188888 20 185421.3935488612 30 0.0 11 530918.4513398055 21 185724.2180642567 31 0.0 0 LINE 5 325 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530524.4682282156 20 184838.4117535552 30 0.0 11 530539.0027126899 21 185369.0524173398 31 0.0 0 LINE 5 326 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530335.1690853607 20 184982.8667579243 30 0.0 11 530559.2802786548 21 185043.4543895813 31 0.0 0 LINE 5 327 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530707.0247008471 20 184994.505863614 30 0.0 11 530707.477024887 21 185313.5574728215 31 0.0 0 LINE 5 332 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531131.4314460383 20 185132.7716499767 30 0.0 11 531131.4314460383 21 185359.3560314326 31 0.0 0 LINE 5 333 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530501.6760625543 20 185036.5091148205 30 0.0 11 530743.4035747344 21 185005.6828851596 31 0.0 0 LINE 5 334 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530485.4823504736 20 185236.4996961124 30 0.0 11 530775.1816292018 21 185251.6757933341 31 0.0 0 LINE 5 335 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532544.9929155681 20 185376.4324141973 30 0.0 11 536042.6124124007 21 185481.9872221566 31 0.0 0 LINE 5 358 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532320.5649707108 20 184501.5680036159 30 0.0 11 532310.185466446 21 184245.5571047196 31 0.0 0 LINE 5 366 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532121.1286102474 20 185156.5429902478 30 0.0 11 532552.7822942475 21 185237.5298082478 31 0.0 0 LINE 5 367 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532107.1836522989 20 185396.4993852853 30 0.0 11 532132.2182172474 21 185032.5284892478 31 0.0 0 LINE 5 368 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532191.4177562475 20 185229.8919942478 30 0.0 11 532195.3011802475 21 185165.7003692478 31 0.0 0 LINE 5 36B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532227.5888392475 20 185421.3871792478 30 0.0 11 532353.3590012474 21 185033.9680772478 31 0.0 0 LINE 5 36C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532340.0762082474 20 185033.0383432478 30 0.0 11 532571.1852702475 21 185093.2411102478 31 0.0 0 LINE 5 36D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532292.1971382474 20 184848.6111342478 30 0.0 11 532351.5203522474 21 185047.0743252478 31 0.0 0 LINE 5 36E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532229.8727212474 20 184909.5836812478 30 0.0 11 532315.1596332476 21 184905.4048772478 31 0.0 0 LINE 5 36F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532325.041593953 20 185475.0242132333 30 0.0 11 532348.3174009531 21 185387.9591352333 31 0.0 0 LINE 5 370 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532458.4917752475 20 185549.4005362478 30 0.0 11 532569.7094042475 21 185090.5118912478 31 0.0 0 LINE 5 371 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532152.3691472474 20 185079.7349762478 30 0.0 11 532567.5409532475 21 185166.1502402478 31 0.0 0 LINE 5 372 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532505.0021652475 20 184692.3458652478 30 0.0 11 532564.1192532476 21 185172.2285002478 31 0.0 0 LINE 5 373 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532493.2797917234 20 184439.2739090913 30 0.0 11 532535.4841562475 21 184977.0343742478 31 0.0 0 LINE 5 374 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532413.0449982474 20 184681.5489552478 30 0.0 11 532522.1683822475 21 184724.9265392478 31 0.0 0 LINE 5 375 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532420.3088972474 20 184743.2113052478 30 0.0 11 532517.3285312475 21 184691.7060482478 31 0.0 0 LINE 5 376 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532429.9143932474 20 184932.9769852478 30 0.0 11 532437.8461422474 21 184731.1247652478 31 0.0 0 LINE 5 377 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532009.6784914184 20 184830.2079244615 30 0.0 11 532529.2096642474 21 184878.8524782478 31 0.0 0 LINE 5 37C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532372.7184052475 20 184867.0858462478 30 0.0 11 532373.0152272474 21 184842.8027972478 31 0.0 0 LINE 5 37D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532504.0457382474 20 185004.5864872478 30 0.0 11 532549.2121822474 21 185000.8275632478 31 0.0 0 LINE 5 37E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532491.7523522475 20 185014.0837682478 30 0.0 11 532511.9032812475 21 185000.9275342478 31 0.0 0 LINE 5 37F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532485.9230932474 20 185077.9154972478 30 0.0 11 532494.5226922474 21 185006.5859152478 31 0.0 0 LINE 5 380 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532302.5529352474 20 184898.1469552478 30 0.0 11 532338.5096462474 21 184465.2908592478 31 0.0 0 LINE 5 381 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532317.2044082475 20 184488.8441172478 30 0.0 11 532511.6971542474 21 184540.6792792478 31 0.0 0 LINE 5 383 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532213.2094522475 20 184469.8995392478 30 0.0 11 532283.6140292475 21 184859.3980472478 31 0.0 0 LINE 5 385 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532308.5965642474 20 184714.1896122478 30 0.0 11 532401.7657552475 21 184708.5912152478 31 0.0 0 LINE 5 386 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532366.6747752475 20 184706.5517982478 30 0.0 11 532438.8355502475 21 184748.3298402478 31 0.0 0 LINE 5 387 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532364.2342372475 20 184719.4481072478 30 0.0 11 532433.9709632473 21 184679.9394162478 31 0.0 0 LINE 5 388 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532419.8636642474 20 184513.3471032478 30 0.0 11 532429.1970732474 21 184691.6260712478 31 0.0 0 LINE 5 38B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532265.0461522474 20 185108.3267922478 30 0.0 11 532280.4479262474 21 185063.9095062478 31 0.0 0 LINE 5 38C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532217.3154932475 20 185054.6021702478 30 0.0 11 532281.7011752476 21 185065.3390972478 31 0.0 0 LINE 5 38D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532186.1409172473 20 185093.1211442478 30 0.0 11 532191.5661672473 21 184988.9409652478 31 0.0 0 LINE 5 38E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532041.0195962473 20 185001.1274772478 30 0.0 11 532339.0538202476 21 184982.8427112478 31 0.0 0 LINE 5 38F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532407.4136222474 20 185053.8123962478 30 0.0 11 532420.6469452474 21 184986.2517352478 31 0.0 0 LINE 5 390 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532389.2250172473 20 184981.0932122478 30 0.0 11 532448.2431642476 21 184992.4699552478 31 0.0 0 LINE 5 391 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532393.1908912475 20 184988.7310262478 30 0.0 11 532405.9130212474 21 184918.5411172478 31 0.0 0 LINE 5 392 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532402.7056922474 20 184920.4205792478 30 0.0 11 532458.0795222474 21 184929.6579352478 31 0.0 0 LINE 5 393 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532441.8532422473 20 184998.8581272478 30 0.0 11 532456.5212062474 21 184922.7599102478 31 0.0 0 LINE 5 396 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532481.8907751978 20 185659.2708376926 30 0.0 11 533213.4750461979 21 185960.1946986926 31 0.0 0 LINE 5 397 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532608.229846198 20 185714.4250496926 30 0.0 11 532641.5976081978 21 185570.3962776926 31 0.0 0 LINE 5 398 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532494.571678198 20 185595.3291406926 30 0.0 11 532951.4964751979 21 185784.2850526926 31 0.0 0 LINE 5 399 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532625.5362291979 20 185598.8181416926 30 0.0 11 532683.5732141979 21 185540.9147166926 31 0.0 0 LINE 5 39A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532574.6806921979 20 185537.4257156926 30 0.0 11 532637.5657731979 21 185598.7681566926 31 0.0 0 LINE 5 39C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532379.7822005875 20 185516.783209897 30 0.0 11 532897.7881471978 21 185508.2540656925 31 0.0 0 LINE 5 3A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.1287281979 20 185133.8312426926 30 0.0 11 532743.2262311979 21 185136.4304986926 31 0.0 0 LINE 5 3A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532738.9965151979 20 185055.0737866926 30 0.0 11 532759.8070491979 21 185810.3475926926 31 0.0 0 LINE 5 3A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532822.0242801978 20 185582.5328036926 30 0.0 11 533308.048428696 21 185701.9470633644 31 0.0 0 LINE 5 3A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532819.8063591979 20 185651.9929206926 30 0.0 11 532833.1138871978 21 185458.5183026926 31 0.0 0 LINE 5 3A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532892.3134261978 20 185655.8818076926 30 0.0 11 532896.1968501978 21 185591.6901826926 31 0.0 0 LINE 5 3A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532841.0703711978 20 185674.0865966926 30 0.0 11 532903.0732311979 21 185644.2051496926 31 0.0 0 LINE 5 3A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532882.6667051979 20 185645.4847836926 30 0.0 11 533018.964367091 21 185679.8975924009 31 0.0 0 LINE 5 3A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532928.4845091979 20 185847.3769926925 30 0.0 11 533171.7912461943 21 185088.6905515849 31 0.0 0 LINE 5 3A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533040.9718781979 20 185459.0281566926 30 0.0 11 533342.0861666041 21 185539.2294065369 31 0.0 0 LINE 5 3AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533040.8696871645 20 185902.6867872737 30 0.0 11 533064.1454941645 21 185815.6217092737 31 0.0 0 LINE 5 3AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532853.2648171979 20 185505.7247896926 30 0.0 11 533314.949234796 21 185601.8213459973 31 0.0 0 LINE 5 3B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532896.5843681978 20 185272.3815836926 30 0.0 11 533323.6153840747 21 185304.8422916926 31 0.0 0 LINE 5 3B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532501.8603121979 20 185272.5915236926 30 0.0 11 533064.3466261978 21 185283.8483006926 31 0.0 0 LINE 5 3B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533003.4486051978 20 185324.1367686926 30 0.0 11 533056.9763947938 21 184798.3148205676 31 0.0 0 LINE 5 3BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532730.9905601978 20 185073.2185936926 30 0.0 11 532910.2405847092 21 184975.7707765721 31 0.0 0 LINE 5 3BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532887.8337612262 20 184954.2005379262 30 0.0 11 532984.509699198 21 185285.3878606926 31 0.0 0 LINE 5 3BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533009.4922341978 20 185140.1794256926 30 0.0 11 533223.8406176101 21 185128.4247817856 31 0.0 0 LINE 5 3C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533120.7593341979 20 184991.9777295595 30 0.0 11 533164.6698493871 21 185152.1929908819 31 0.0 0 LINE 5 3C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532535.0805407667 20 185099.0554407228 30 0.0 11 532800.0759271978 21 185049.7952976926 31 0.0 0 LINE 5 3C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532965.9418221979 20 185534.3166056926 30 0.0 11 532981.3435961978 21 185489.8993196926 31 0.0 0 LINE 5 3C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532918.2111631979 20 185480.5919836926 30 0.0 11 532982.596845198 21 185491.3289106925 31 0.0 0 LINE 5 3C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532887.0365871978 20 185519.1109576926 30 0.0 11 532892.4618371978 21 185414.9307786926 31 0.0 0 LINE 5 3CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532632.1075431978 20 185205.9006136926 30 0.0 11 532744.8092831978 21 185207.6001266926 31 0.0 0 LINE 5 3CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532964.0619481979 20 185729.5307256926 30 0.0 11 533287.3999608604 21 185848.0166997513 31 0.0 0 LINE 5 3CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533160.4851943644 20 185038.2038243795 30 0.0 11 533312.3771077996 21 184720.5496568575 31 0.0 0 LINE 5 3D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532525.9687370664 20 184938.1950755283 30 0.0 11 533310.1590899808 21 185042.7807927709 31 0.0 0 LINE 5 3D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532783.2026042486 20 184722.3529153568 30 0.0 11 533016.3547312031 21 184679.6358716281 31 0.0 0 LINE 5 3D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.4575456594 20 184793.6019525844 30 0.0 11 532842.931078161 21 184708.7398765826 31 0.0 0 LINE 5 3DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532637.5467937776 20 184576.4133326699 30 0.0 11 532697.7689800461 21 184475.6025395458 31 0.0 0 LINE 5 3DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532699.5784686391 20 184579.0743381345 30 0.0 11 532664.2017968141 21 184475.0835117567 31 0.0 0 LINE 5 3E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532790.6590954802 20 184784.0174906387 30 0.0 11 532807.618670413 21 184536.4242881813 31 0.0 0 LINE 5 3E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532688.1167109437 20 184815.5033675087 30 0.0 11 532809.5492248077 21 184814.234469069 31 0.0 0 LINE 5 3E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532790.4765161498 20 184914.5351786511 30 0.0 11 532680.4657737823 21 184864.6817180896 31 0.0 0 LINE 5 3E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.2588451061 20 184869.4146964122 30 0.0 11 532689.3739594284 21 184813.7308861308 31 0.0 0 LINE 5 3E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532702.8925823753 20 185206.9803013947 30 0.0 11 532702.8948103981 21 185206.968067317 31 0.0 0 LINE 5 3E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532729.11626022 20 185062.9860305268 30 0.0 11 532803.6929663337 21 184653.4851785078 31 0.0 0 LINE 5 3EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.7558926337 20 184720.028022434 30 0.0 11 532491.6707096186 21 184640.2317074956 31 0.0 0 LINE 5 3EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532499.9754730116 20 184739.9450397345 30 0.0 11 532792.482947854 21 184732.5461716932 31 0.0 0 LINE 5 3ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532769.2121150372 20 184858.9438041617 30 0.0 11 532734.3196016032 21 184852.2725047208 31 0.0 0 LINE 5 3EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532653.1157034118 20 184684.7299837778 30 0.0 11 532662.4446227496 21 184591.8601207191 31 0.0 0 LINE 5 3EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532654.8360919118 20 184626.1769731031 30 0.0 11 532707.5855661702 21 184561.6008536206 31 0.0 0 LINE 5 3F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532667.1782684115 20 184630.6425851331 30 0.0 11 532639.2944614704 21 184555.4984507766 31 0.0 0 LINE 5 3F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532472.5841021194 20 184542.862362741 30 0.0 11 532650.0704104144 21 184562.0746848949 31 0.0 0 LINE 5 3F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532893.7177966846 20 184994.6354611215 30 0.0 11 532923.1880844782 21 184697.4987358915 31 0.0 0 LINE 5 3FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531861.8278255367 20 185191.7735766143 30 0.0 11 531538.5384386285 21 185607.8478836246 31 0.0 0 LINE 5 3FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531733.7040754842 20 185347.6380927605 30 0.0 11 532464.1482035561 21 185651.3189967688 31 0.0 0 LINE 5 3FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531862.0971573802 20 185397.8253868076 30 0.0 11 531783.9926877962 21 185523.3538160008 31 0.0 0 LINE 5 3FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531697.5197138976 20 185401.8602090297 30 0.0 11 532154.4445108975 21 185590.8161210297 31 0.0 0 LINE 5 400 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531792.6965981642 20 185491.8893567981 30 0.0 11 531792.885563927 21 185573.87144354 31 0.0 0 LINE 5 401 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531713.3339456926 20 185499.4315717521 30 0.0 11 531801.1772682144 21 185500.4211012181 31 0.0 0 LINE 5 402 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.3606550528 20 185490.9574299569 30 0.0 11 531610.7000381212 21 185649.8145655847 31 0.0 0 LINE 5 403 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531620.0352627024 20 185437.4863894554 30 0.0 11 531921.4650168662 21 185748.2907083182 31 0.0 0 LINE 5 404 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531650.9979007346 20 185688.8051328634 30 0.0 11 531795.0736114228 21 185570.1374104197 31 0.0 0 LINE 5 405 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531609.7161111208 20 185644.4268986138 30 0.0 11 531651.8451968421 21 185688.8314120956 31 0.0 0 LINE 5 406 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531419.6038351391 20 185873.1395474812 30 0.0 11 531638.8567267734 21 185672.4553785438 31 0.0 0 LINE 5 407 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531467.5316540079 20 185824.3072660336 30 0.0 11 531549.4316502019 21 185902.346947863 31 0.0 0 LINE 5 408 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531488.9758274058 20 185956.9537109508 30 0.0 11 532119.1862890298 21 185356.9691234335 31 0.0 0 LINE 5 409 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531920.2925450763 20 185642.1958461826 30 0.0 11 532283.0697733463 21 185889.7366514033 31 0.0 0 LINE 5 40A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531967.7814881132 20 185591.4570314894 30 0.0 11 531840.5527883868 21 185737.8208797502 31 0.0 0 LINE 5 40B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532021.8574928066 20 185639.9150950438 30 0.0 11 531979.268683928 21 185688.1005602838 31 0.0 0 LINE 5 40C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531998.4393065221 20 185590.8350219038 30 0.0 11 532021.2274724078 21 185655.7808071295 31 0.0 0 LINE 5 40D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532007.6850459294 20 185640.4619804239 30 0.0 11 532354.1763415755 21 185846.7163859356 31 0.0 0 LINE 5 40E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532182.715114118 20 185529.8988290208 30 0.0 11 531998.1198935781 21 185892.9915152565 31 0.0 0 LINE 5 40F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.0600547571 20 185884.2681765558 30 0.0 11 532194.1878251483 21 186004.8795937868 31 0.0 0 LINE 5 410 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531823.9061445957 20 185981.011623581 30 0.0 11 532006.0750995708 21 185882.4146979472 31 0.0 0 LINE 5 411 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531822.8497064442 20 185893.8286643487 30 0.0 11 531880.2747016837 21 185957.0243104261 31 0.0 0 LINE 5 412 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532356.2144154167 20 185600.3187829731 30 0.0 11 532311.1985787343 21 185678.3935256651 31 0.0 0 LINE 5 413 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532436.5909745613 20 185602.3600801 30 0.0 11 532191.2154048476 21 186005.769275952 31 0.0 0 LINE 5 414 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531888.1595850235 20 185718.6348090544 30 0.0 11 532243.1029985761 21 185950.691697608 31 0.0 0 LINE 5 415 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531983.707795175 20 186179.1651187459 30 0.0 11 532196.6318225811 21 185988.747421823 31 0.0 0 LINE 5 416 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531651.9676286941 20 186274.3789995667 30 0.0 11 531834.7205437863 21 186117.8592350517 31 0.0 0 LINE 5 417 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531474.7328130902 20 185635.481035244 30 0.0 11 531880.879583697 21 186024.7911548033 31 0.0 0 LINE 5 419 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532084.0423358651 20 186020.2200672802 30 0.0 11 532125.4763841526 21 186066.8963861565 31 0.0 0 LINE 5 41A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532082.0474267376 20 186004.8140287462 30 0.0 11 532087.0205745952 21 186028.360031231 31 0.0 0 LINE 5 41B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532123.0045456797 20 185955.5090158614 30 0.0 11 532078.7129439776 21 186012.0785870981 31 0.0 0 LINE 5 41C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531418.7788685433 20 186104.3451573058 30 0.0 11 531495.3612063181 21 186318.6540757437 31 0.0 0 LINE 5 41D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531496.1237532815 20 185938.45407603 30 0.0 11 531405.175342562 21 186133.5223115784 31 0.0 0 LINE 5 41F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.1202134396 20 185777.976802319 30 0.0 11 531967.6519314506 21 185820.2988931271 31 0.0 0 LINE 5 420 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531916.3854307389 20 185782.2978865 30 0.0 11 531969.5488407774 21 185820.1720133031 31 0.0 0 LINE 5 421 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531921.5218807102 20 185733.0111496584 30 0.0 11 531851.7810069742 21 185810.5943537981 31 0.0 0 LINE 5 422 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531753.8130619647 20 185695.637566851 30 0.0 11 531951.8835598481 21 185919.0806450864 31 0.0 0 LINE 5 423 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532050.4021916367 20 185917.1215869044 30 0.0 11 532012.0528583068 21 185974.2958152379 31 0.0 0 LINE 5 424 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531986.1651783409 20 185955.7546193549 30 0.0 11 532035.9806907252 21 185989.3847647976 31 0.0 0 LINE 5 425 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531994.3672256759 20 185953.1487070773 30 0.0 11 531953.7989935165 21 186011.8231858276 31 0.0 0 LINE 5 426 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531952.8559031887 20 186008.2273663998 30 0.0 11 531998.5804950235 21 186040.7980817171 31 0.0 0 LINE 5 427 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532035.9690354825 20 185980.3492953121 30 0.0 11 531992.6053163253 21 186044.5807179909 31 0.0 0 LINE 5 428 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532589.7485624646 20 185685.3582884609 30 0.0 11 532589.9375282275 21 185767.3403752028 31 0.0 0 LINE 5 429 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532510.3859099931 20 185692.900503415 30 0.0 11 532598.2292325149 21 185693.8900328809 31 0.0 0 LINE 5 42A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532526.4656307082 20 185685.9832563354 30 0.0 11 532406.8050137765 21 185844.8403919632 31 0.0 0 LINE 5 42B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532357.8334418678 20 185569.8587237367 30 0.0 11 532718.5169811667 21 185941.7596399811 31 0.0 0 LINE 5 42C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532448.049865035 20 185882.2740645263 30 0.0 11 532592.1255757233 21 185763.6063420826 31 0.0 0 LINE 5 42D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.7680754211 20 185837.8958302767 30 0.0 11 532448.8971611424 21 185882.3003437585 31 0.0 0 LINE 5 42E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532216.6557994395 20 186066.608479144 30 0.0 11 532435.9086910738 21 185865.9243102067 31 0.0 0 LINE 5 42F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532360.5330683786 20 186075.9173659413 30 0.0 11 532834.2031285817 21 185630.4462966165 31 0.0 0 LINE 5 430 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532717.3445093768 20 185835.6647778455 30 0.0 11 532936.5865712611 21 185985.2644558515 31 0.0 0 LINE 5 431 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532764.8334524136 20 185784.9259631524 30 0.0 11 532637.6047526871 21 185931.289811413 31 0.0 0 LINE 5 432 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532818.909457107 20 185833.3840267067 30 0.0 11 532776.3206482284 21 185881.5694919468 31 0.0 0 LINE 5 433 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532795.4912708226 20 185784.3039535667 30 0.0 11 532818.2794367084 21 185849.2497387923 31 0.0 0 LINE 5 434 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532804.7370102297 20 185833.9309120868 30 0.0 11 533151.2283058758 21 186040.1853175985 31 0.0 0 LINE 5 435 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532929.8009410545 20 185821.4028240506 30 0.0 11 532795.1718578784 21 186086.4604469193 31 0.0 0 LINE 5 436 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532785.1120190575 20 186077.7371082186 30 0.0 11 532991.2397894489 21 186198.3485254497 31 0.0 0 LINE 5 437 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532620.9581088962 20 186174.4805552439 30 0.0 11 532803.1270638713 21 186075.88362961 31 0.0 0 LINE 5 438 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532487.8955622168 20 185923.2211543541 30 0.0 11 532677.3266659841 21 186150.4932420889 31 0.0 0 LINE 5 439 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.2115493238 20 185912.1037407173 30 0.0 11 533069.5807117685 21 186166.970324897 31 0.0 0 LINE 5 43A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532596.3237212511 20 186341.3319926437 30 0.0 11 532783.9267616241 21 186029.3305871086 31 0.0 0 LINE 5 43B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532563.3363404315 20 186239.6670789878 30 0.0 11 532671.2243390242 21 186286.0320171303 31 0.0 0 LINE 5 43C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532612.0301757858 20 186201.1453963313 30 0.0 11 532644.3347693412 21 186306.1311768702 31 0.0 0 LINE 5 43D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532271.7847773906 20 185828.9499669069 30 0.0 11 532505.4397367133 21 186045.7682751822 31 0.0 0 LINE 5 43E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532456.1709398957 20 185958.2385074901 30 0.0 11 532414.07966705 21 186283.737681027 31 0.0 0 LINE 5 43F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.7909252194 20 186170.6980676144 30 0.0 11 532571.9985347014 21 186193.8794666497 31 0.0 0 LINE 5 440 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532548.1691416875 20 186189.2161541062 30 0.0 11 532628.7607689065 21 186210.607083589 31 0.0 0 LINE 5 441 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532555.5499794265 20 186178.3628483507 30 0.0 11 532577.0134800563 21 186255.5863276716 31 0.0 0 LINE 5 442 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532486.5436966105 20 186326.2911970296 30 0.0 11 532581.8881197563 21 186243.9413365331 31 0.0 0 LINE 5 443 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532172.7351168023 20 185975.263057285 30 0.0 11 532257.3461442857 21 186098.2095402245 31 0.0 0 LINE 5 444 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532785.17217774 20 185971.4457339819 30 0.0 11 532764.7038957511 21 186013.76782479 31 0.0 0 LINE 5 445 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532713.4373950393 20 185975.7668181629 30 0.0 11 532766.6008050778 21 186013.640944966 31 0.0 0 LINE 5 446 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532718.5738450106 20 185926.4800813213 30 0.0 11 532648.8329712746 21 186004.063285461 31 0.0 0 LINE 5 447 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532550.8650262651 20 185889.1064985139 30 0.0 11 532748.9355241485 21 186112.5495767493 31 0.0 0 LINE 5 448 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532847.4541559371 20 186110.5905185672 30 0.0 11 532809.1048226073 21 186167.7647469007 31 0.0 0 LINE 5 449 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532783.2171426415 20 186149.2235510178 30 0.0 11 532833.0326550258 21 186182.8536964605 31 0.0 0 LINE 5 44A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532316.8864140805 20 185968.1543527131 30 0.0 11 532397.8707606938 21 186046.5514581896 31 0.0 0 LINE 5 44B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532611.7161158065 20 186297.5090828903 30 0.0 11 532484.7066932243 21 186858.233084708 31 0.0 0 LINE 5 44C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532547.3155668865 20 186321.6247646187 30 0.0 11 532495.053707063 21 186542.8445710875 31 0.0 0 LINE 5 44D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532403.9294344441 20 186201.8155025754 30 0.0 11 532302.4455707475 21 186337.9548541522 31 0.0 0 LINE 5 44E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532279.8671234338 20 186136.1577846746 30 0.0 11 533301.9646360159 21 186916.6816373291 31 0.0 0 LINE 5 44F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.9961318524 20 186319.8807114539 30 0.0 11 532220.4666046975 21 186717.4866760719 31 0.0 0 LINE 5 450 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532464.6578491668 20 186358.671862295 30 0.0 11 532299.8801138759 21 186256.40839832 31 0.0 0 LINE 5 451 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532425.4420865872 20 186419.7825992595 30 0.0 11 532371.082371042 21 186385.4217635892 31 0.0 0 LINE 5 452 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532470.1602454009 20 186388.8382734374 30 0.0 11 532409.6789007655 21 186421.6904038722 31 0.0 0 LINE 5 453 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532422.6424219159 20 186405.8786713312 30 0.0 11 532274.2743179815 21 186780.8240053286 31 0.0 0 LINE 5 454 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532559.6993444154 20 186561.0403135408 30 0.0 11 532171.8185395161 21 186436.7013597309 31 0.0 0 LINE 5 455 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532178.8262472758 20 186425.3793004152 30 0.0 11 532092.6246762097 21 186648.1012365569 31 0.0 0 LINE 5 456 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532057.1464107401 20 186278.7511375533 30 0.0 11 532183.5284855804 21 186442.8683306205 31 0.0 0 LINE 5 457 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532143.045524667 20 186263.8070193578 30 0.0 11 532089.8147203099 21 186330.5737867565 31 0.0 0 LINE 5 458 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532517.844537266 20 186743.5482656535 30 0.0 11 532433.5909544371 21 186711.5572547416 31 0.0 0 LINE 5 459 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532528.6452812824 20 186823.2219883138 30 0.0 11 532091.2724283363 21 186645.3087032108 31 0.0 0 LINE 5 45A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532326.4115569843 20 186300.3469340414 30 0.0 11 532153.9187586503 21 186687.7504199219 31 0.0 0 LINE 5 45B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531805.9814634882 20 186360.1205610736 30 0.0 11 532160.8507210284 21 186688.5257734576 31 0.0 0 LINE 5 45C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531638.584156153 20 186248.3972793169 30 0.0 11 532019.1879770698 21 186551.2217947124 31 0.0 0 LINE 5 45D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531850.9576992834 20 186279.1895284476 30 0.0 11 531822.388527218 21 186393.0900558247 31 0.0 0 LINE 5 45E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531896.7507059305 20 186321.1181604121 30 0.0 11 531798.2590085679 21 186369.7492865638 31 0.0 0 LINE 5 45F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532045.128842458 20 186439.807702748 30 0.0 11 531876.6943226217 21 186328.2862075614 31 0.0 0 LINE 5 460 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532093.9829120121 20 186228.3962886964 30 0.0 11 531943.1818398332 21 186488.7548350109 31 0.0 0 LINE 5 461 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532011.4998620817 20 186166.3447629878 30 0.0 11 531995.1789584217 21 186015.2308868018 31 0.0 0 LINE 5 462 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532367.7592458358 20 186017.384856327 30 0.0 11 532367.7521822822 21 186017.3950907273 31 0.0 0 LINE 5 463 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532159.4363386244 20 186124.1371738739 30 0.0 11 532023.0113161725 21 186341.976254682 31 0.0 0 LINE 5 464 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532025.08345726 20 186354.8888840192 30 0.0 11 532005.2047513148 21 186340.9392739177 31 0.0 0 LINE 5 465 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532059.9179272102 20 186541.8109382867 30 0.0 11 532030.473360213 21 186576.266048903 31 0.0 0 LINE 5 466 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532074.8087792434 20 186537.3850811423 30 0.0 11 532052.356979825 21 186546.0489795433 31 0.0 0 LINE 5 467 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532130.0135486268 20 186569.9565920827 30 0.0 11 532067.1054834822 21 186535.2515821992 31 0.0 0 LINE 5 468 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532091.2921244136 20 186316.102313323 30 0.0 11 531792.7632140843 21 186130.9801536181 31 0.0 0 LINE 5 469 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531936.6804172387 20 186133.8679621811 30 0.0 11 532070.9155718749 21 186278.0897346377 31 0.0 0 LINE 5 46A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532468.8458028386 20 186177.5755427393 30 0.0 11 531769.5162369404 21 186138.5166020882 31 0.0 0 LINE 5 46B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531938.4823451721 20 186213.5060128864 30 0.0 11 531879.4933379066 21 186285.8395267122 31 0.0 0 LINE 5 46C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531898.3447794365 20 186256.1720487052 30 0.0 11 531890.077737924 21 186339.1433586055 31 0.0 0 LINE 5 46D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531910.2360944391 20 186261.7279139901 30 0.0 11 531837.4229176238 21 186295.2299870572 31 0.0 0 LINE 5 46E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531710.4802981255 20 186186.4293161462 30 0.0 11 531849.6961797504 21 186298.185484916 31 0.0 0 LINE 5 46F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532283.7673474868 20 186408.4906846435 30 0.0 11 532238.7230775654 21 186395.0324646574 31 0.0 0 LINE 5 470 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532268.0635396029 20 186338.3626500527 30 0.0 11 532239.1507935487 21 186396.88487458 31 0.0 0 LINE 5 471 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532327.6932205972 20 186164.0523312674 30 0.0 11 532138.6908716636 21 186395.2164362678 31 0.0 0 LINE 5 472 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532156.333518464 20 186492.1622754376 30 0.0 11 532006.4397393707 21 186419.1755808819 31 0.0 0 LINE 5 473 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532443.2785890483 20 186521.0440070698 30 0.0 11 532359.9775658928 21 186772.1907556058 31 0.0 0 LINE 5 474 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531690.8699317568 20 185858.9173803943 30 0.0 11 531813.4096672386 21 185746.4218472305 31 0.0 0 LINE 5 475 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531602.6576685688 20 185904.8884095925 30 0.0 11 531532.6487409198 21 185734.1550506949 31 0.0 0 LINE 5 476 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532274.1029641282 20 186355.1102229073 30 0.0 11 532171.4693846109 21 186298.5722535568 31 0.0 0 LINE 5 477 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532180.8622533723 20 185533.5433447531 30 0.0 11 532356.6872845859 21 185442.1663750327 31 0.0 0 LINE 5 478 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534574.6571852977 20 184195.4021252921 30 0.0 11 535121.1408465514 21 184069.916780534 31 0.0 0 LINE 5 479 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534591.6805218133 20 184183.5721895806 30 0.0 11 534563.5622932388 21 184974.1290065872 31 0.0 0 LINE 5 47A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534583.8361464561 20 184321.2021780923 30 0.0 11 534730.4884537673 21 184302.4726435274 31 0.0 0 LINE 5 47C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534698.2576499472 20 184297.2817347705 30 0.0 11 534772.7128564283 21 184331.596753093 31 0.0 0 LINE 5 47D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534738.1669447289 20 184228.2704037896 30 0.0 11 534702.4823148565 21 184308.5451549328 31 0.0 0 LINE 5 47E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534723.3715470947 20 184240.2209736357 30 0.0 11 534917.6315636337 21 184197.5911864141 31 0.0 0 LINE 5 47F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534720.7058270503 20 184117.6496135786 30 0.0 11 534877.7361941457 21 184521.135282629 31 0.0 0 LINE 5 480 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.296866142 20 184250.4664032003 30 0.0 11 534768.4068052764 21 184332.030894389 31 0.0 0 LINE 5 481 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534913.1431511226 20 184194.4528395784 30 0.0 11 534935.9678830072 21 184251.2476658892 31 0.0 0 LINE 5 482 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535200.2533381722 20 184116.8648654899 30 0.0 11 534926.4889642517 21 184232.6190607658 31 0.0 0 LINE 5 483 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535135.8969533211 20 184140.101114365 30 0.0 11 535172.7375945441 21 184247.0617074395 31 0.0 0 LINE 5 484 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535247.5614010104 20 184214.8405486959 30 0.0 11 534562.2605079586 21 184461.1649807091 31 0.0 0 LINE 5 485 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534781.7684923542 20 184475.8838221603 30 0.0 11 534855.7334321526 21 184908.796001801 31 0.0 0 LINE 5 486 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534715.8615647035 20 184497.9270504825 30 0.0 11 534901.9152180392 21 184443.2136500017 31 0.0 0 LINE 5 487 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534737.396022412 20 184567.2715912787 30 0.0 11 534798.940808514 21 184548.6199155959 31 0.0 0 LINE 5 488 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534702.5279512712 20 184525.5405160086 30 0.0 11 534752.0826991785 21 184573.3064294077 31 0.0 0 LINE 5 489 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534743.7956458011 20 184554.6144922988 30 0.0 11 534787.0077403957 21 184955.5257201689 31 0.0 0 LINE 5 48A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534570.3822305559 20 184667.6964211436 30 0.0 11 534977.3661527182 21 184651.0897554535 31 0.0 0 LINE 5 48B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534973.6249792506 20 184638.3108424999 30 0.0 11 534997.4323029246 21 184875.9428753415 31 0.0 0 LINE 5 48C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535129.9446164009 20 184529.3614422962 30 0.0 11 534964.4371350048 21 184653.9172751708 31 0.0 0 LINE 5 48D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535051.122321311 20 184492.0917463117 30 0.0 11 535084.6606727746 21 184570.6188037027 31 0.0 0 LINE 5 48E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534553.9285474718 20 184777.7111798236 30 0.0 11 534643.6579189425 21 184769.3010137052 31 0.0 0 LINE 5 48F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534530.5281655633 20 184928.6853843727 30 0.0 11 534999.4790852679 21 184873.6110308273 31 0.0 0 LINE 5 490 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534864.6453430343 20 184478.5048502061 30 0.0 11 534927.7956627994 21 184897.846314246 31 0.0 0 LINE 5 491 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535350.3893007875 20 184674.6506536572 30 0.0 11 534920.9074000498 21 184896.7485383992 31 0.0 0 LINE 5 492 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535583.6379881881 20 184575.7674960427 30 0.0 11 535094.0071012423 21 184802.1060054018 31 0.0 0 LINE 5 493 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535328.5779771762 20 184584.6675441836 30 0.0 11 535325.7982992511 21 184702.0634602962 31 0.0 0 LINE 5 494 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535273.2764353342 20 184612.8942887018 30 0.0 11 535355.2701688879 21 184685.9875752475 31 0.0 0 LINE 5 495 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535098.6584225843 20 184687.8064271212 30 0.0 11 535290.7012472688 21 184625.1423636691 31 0.0 0 LINE 5 496 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535098.5090148775 20 184438.0892804688 30 0.0 11 535183.8986896964 21 184762.1240560096 31 0.0 0 LINE 5 497 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535006.8823547946 20 184457.0934690072 30 0.0 11 535127.0631374186 21 184439.6565824029 31 0.0 0 LINE 5 498 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535092.7796099318 20 184343.4867310913 30 0.0 11 534991.7531499059 21 184409.6787649087 31 0.0 0 LINE 5 499 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534995.7606139729 20 184404.26444609 30 0.0 11 535008.3974384137 21 184458.6513154741 31 0.0 0 LINE 5 49A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534961.226757078 20 184068.0072542187 30 0.0 11 535146.0188931681 21 184599.3917053508 31 0.0 0 LINE 5 49B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535140.5844114282 20 184611.286921755 30 0.0 11 535163.459076143 21 184603.1319057388 31 0.0 0 LINE 5 49C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535057.2515549811 20 184782.193123236 30 0.0 11 535076.4625545096 21 184823.2427842622 31 0.0 0 LINE 5 49D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535044.0759987184 20 184773.9632749442 30 0.0 11 535063.411640211 21 184788.2908497806 31 0.0 0 LINE 5 49E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534982.1929300688 20 184790.6652419575 30 0.0 11 535052.0692800617 21 184773.9572174507 31 0.0 0 LINE 5 49F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535087.0886008305 20 184556.2761598885 30 0.0 11 535505.4896536701 21 184439.6663665903 31 0.0 0 LINE 5 4A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535476.0032534414 20 184427.86715771 30 0.0 11 535494.9407156182 21 184628.2559917115 31 0.0 0 LINE 5 4A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535227.7655735143 20 184213.6345013193 30 0.0 11 535495.623878412 21 184458.2494913671 31 0.0 0 LINE 5 4A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535457.6518015389 20 184323.7658987257 30 0.0 11 535116.8482574903 21 184525.0588110716 31 0.0 0 LINE 5 4A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535074.8677798265 20 184403.5864576378 30 0.0 11 535108.5224187205 21 184392.2128473538 31 0.0 0 LINE 5 4A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535261.6946601973 20 184498.0562876151 30 0.0 11 535299.3017138007 21 184583.481984685 31 0.0 0 LINE 5 4A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535289.0272950536 20 184549.86692231 30 0.0 11 535274.9106969223 21 184632.0454103658 31 0.0 0 LINE 5 4A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535276.0861163686 20 184552.0571062738 30 0.0 11 535337.3547991832 21 184603.7320143421 31 0.0 0 LINE 5 4A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535488.6783927928 20 184532.6462587168 30 0.0 11 535324.7376213809 21 184603.3139771145 31 0.0 0 LINE 5 4A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535258.9681390138 20 183992.1531128462 30 0.0 11 535103.3700778348 21 184075.7331806402 31 0.0 0 LINE 5 4A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535153.1660462351 20 184036.1810629035 30 0.0 11 535273.7238639583 21 184270.2849582326 31 0.0 0 LINE 5 4AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534876.9652630151 20 184594.0981846576 30 0.0 11 534923.966796239 21 184593.1154270327 31 0.0 0 LINE 5 4AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534910.7692790155 20 184530.6802114966 30 0.0 11 534923.0614345329 21 184594.787157772 31 0.0 0 LINE 5 4AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534863.8211214823 20 184514.823476302 30 0.0 11 534963.400889941 21 184483.7298636502 31 0.0 0 LINE 5 4AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534899.6889578032 20 184346.7861861114 30 0.0 11 535020.3411757364 21 184619.9194386656 31 0.0 0 LINE 5 4AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534977.5298769468 20 184708.6716297057 30 0.0 11 535045.4811634307 21 184697.6178331832 31 0.0 0 LINE 5 4AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535039.4059462963 20 184666.3601996268 30 0.0 11 535049.2339964726 21 184725.6559109923 31 0.0 0 LINE 5 4B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535033.6208638784 20 184672.7317913196 30 0.0 11 535103.8602096413 21 184660.2854977361 31 0.0 0 LINE 5 4B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535100.9838456271 20 184657.9305313283 30 0.0 11 535111.5524690118 21 184713.0657650223 31 0.0 0 LINE 5 4B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535041.0242654582 20 184721.8822971619 30 0.0 11 535117.4799406871 21 184709.2088002577 31 0.0 0 LINE 5 4B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535069.0006836904 20 184166.9860368055 30 0.0 11 535106.5476183001 21 184273.2630251185 31 0.0 0 LINE 5 4B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534693.2491391094 20 184660.1320577132 30 0.0 11 534706.6944115045 21 184924.3913516068 31 0.0 0 LINE 5 4B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534453.6923026645 20 184480.7570328502 30 0.0 11 534407.5047163943 21 185779.3420802661 31 0.0 0 LINE 5 4B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534427.7785696117 20 185126.4152517712 30 0.0 11 534574.430876923 21 185107.6857172062 31 0.0 0 LINE 5 4B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534499.9886731898 20 184978.4702767471 30 0.0 11 534481.4814355449 21 185472.5776425573 31 0.0 0 LINE 5 4B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534542.2000731028 20 185102.4948084494 30 0.0 11 534616.655279584 21 185136.8098267719 31 0.0 0 LINE 5 4B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534582.1093678846 20 185033.4834774686 30 0.0 11 534546.4247380123 21 185113.7582286117 31 0.0 0 LINE 5 4BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534569.1238130012 20 185045.2214964583 30 0.0 11 534763.3838295403 21 185002.5917092368 31 0.0 0 LINE 5 4BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534533.7798853447 20 184843.5471823721 30 0.0 11 534721.6786173013 21 185326.3483563077 31 0.0 0 LINE 5 4BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534780.2392892977 20 185055.6794768792 30 0.0 11 534612.3492284322 21 185137.243968068 31 0.0 0 LINE 5 4BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534757.0855742783 20 184999.6659132573 30 0.0 11 534779.9103061629 21 185056.4607395681 31 0.0 0 LINE 5 4BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535044.1957613281 20 184922.0779391688 30 0.0 11 534770.4313874075 21 185037.8321344448 31 0.0 0 LINE 5 4BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534979.8393764768 20 184945.3141880438 30 0.0 11 535016.6800176997 21 185052.2747811184 31 0.0 0 LINE 5 4C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535091.5038241661 20 185020.0536223748 30 0.0 11 534390.4684959374 21 185301.8710613853 31 0.0 0 LINE 5 4C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534625.7109155098 20 185281.0968958392 30 0.0 11 534699.6758553083 21 185714.0090754798 31 0.0 0 LINE 5 4C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534559.8039878591 20 185303.1401241614 30 0.0 11 534745.8576411948 21 185248.4267236806 31 0.0 0 LINE 5 4C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534581.3384455677 20 185372.4846649576 30 0.0 11 534642.8832316696 21 185353.8329892748 31 0.0 0 LINE 5 4C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534546.4703744269 20 185330.7535896875 30 0.0 11 534596.0251223342 21 185378.5195030866 31 0.0 0 LINE 5 4C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534587.7380689568 20 185359.8275659777 30 0.0 11 534630.9501635513 21 185760.7387938477 31 0.0 0 LINE 5 4C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534157.7326287101 20 185538.9153082807 30 0.0 11 534848.8426457485 21 185522.3086425906 31 0.0 0 LINE 5 4C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534817.5674024062 20 185443.5239161787 30 0.0 11 534841.3747260803 21 185681.1559490204 31 0.0 0 LINE 5 4C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534973.8870395568 20 185334.5745159751 30 0.0 11 534808.3795581605 21 185459.1303488497 31 0.0 0 LINE 5 4C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534895.0647444666 20 185297.3048199906 30 0.0 11 534928.6030959303 21 185375.8318773816 31 0.0 0 LINE 5 4CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534406.089309661 20 185659.9740734423 30 0.0 11 534495.8186811316 21 185651.5639073239 31 0.0 0 LINE 5 4CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534374.470588719 20 185733.8984580516 30 0.0 11 534843.4215084236 21 185678.8241045062 31 0.0 0 LINE 5 4CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534708.5877661901 20 185283.717923885 30 0.0 11 534771.7380859552 21 185703.0593879249 31 0.0 0 LINE 5 4CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535078.9923763787 20 185538.2018863312 30 0.0 11 534764.8498232055 21 185701.9616120782 31 0.0 0 LINE 5 4D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534942.4514380332 20 185243.3023541477 30 0.0 11 535027.841112852 21 185567.3371296885 31 0.0 0 LINE 5 4D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534850.8247779503 20 185262.3065426861 30 0.0 11 534971.0055605743 21 185244.8696560818 31 0.0 0 LINE 5 4D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.7220330874 20 185148.6998047703 30 0.0 11 534835.6955730616 21 185214.8918385876 31 0.0 0 LINE 5 4D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534839.7030371286 20 185209.4775197689 30 0.0 11 534852.3398615693 21 185263.864389153 31 0.0 0 LINE 5 4D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534805.1691802337 20 184873.2203278976 30 0.0 11 534989.9613163239 21 185404.6047790297 31 0.0 0 LINE 5 4D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534984.5268345839 20 185416.4999954338 30 0.0 11 535007.4014992987 21 185408.3449794178 31 0.0 0 LINE 5 4D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534901.1939781368 20 185587.4061969149 30 0.0 11 534920.4049776653 21 185628.4558579411 31 0.0 0 LINE 5 4D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534888.0184218741 20 185579.1763486232 30 0.0 11 534907.3540633668 21 185593.5039234594 31 0.0 0 LINE 5 4D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534826.1353532244 20 185595.8783156365 30 0.0 11 534896.0117032174 21 185579.1702911296 31 0.0 0 LINE 5 4DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534931.0310239862 20 185361.4892335674 30 0.0 11 535274.7483125908 21 185272.5382705694 31 0.0 0 LINE 5 4DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535071.7079966699 20 185018.8475749982 30 0.0 11 535225.3427913389 21 185153.0973355788 31 0.0 0 LINE 5 4DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535237.7886563097 20 185124.5939782508 30 0.0 11 534960.7906806459 21 185330.2718847505 31 0.0 0 LINE 5 4DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534918.8102029823 20 185208.7995313166 30 0.0 11 534952.4648418761 21 185197.4259210327 31 0.0 0 LINE 5 4E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534979.4409143216 20 184844.1047242348 30 0.0 11 535117.6662871139 21 185075.4980319115 31 0.0 0 LINE 5 4E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534720.9076861708 20 185399.3112583365 30 0.0 11 534767.9092193946 21 185398.3285007116 31 0.0 0 LINE 5 4E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534754.7117021712 20 185335.8932851755 30 0.0 11 534767.0038576885 21 185400.0002314509 31 0.0 0 LINE 5 4E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534707.7635446379 20 185320.0365499808 30 0.0 11 534807.3433130968 21 185288.9429373291 31 0.0 0 LINE 5 4E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534743.6313809589 20 185151.9992597903 30 0.0 11 534864.2835988922 21 185425.1325123446 31 0.0 0 LINE 5 4EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534912.9431068461 20 184972.1991104843 30 0.0 11 534950.4900414558 21 185078.4760987974 31 0.0 0 LINE 5 4ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534537.1915622652 20 185503.4776332377 30 0.0 11 534550.6368346601 21 185729.6044252857 31 0.0 0 LINE 5 4F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535204.4961575484 20 185229.1919298231 30 0.0 11 535370.5322272506 21 185193.6261991774 31 0.0 0 LINE 5 4F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535127.1242449161 20 184779.6941977527 30 0.0 11 535293.5571175311 21 185516.6960290042 31 0.0 0 LINE 5 4F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535310.5577928031 20 185281.1508338489 30 0.0 11 535749.7250002055 21 185277.1594001404 31 0.0 0 LINE 5 4F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535321.8102417574 20 185349.72932479 30 0.0 11 535297.4628153631 21 185157.3320250695 31 0.0 0 LINE 5 4F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535393.7012431163 20 185339.5272597694 30 0.0 11 535385.1014189776 21 185275.795880317 31 0.0 0 LINE 5 4F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535346.9444020168 20 185367.2952780401 30 0.0 11 535402.0006421976 21 185325.9907269572 31 0.0 0 LINE 5 4F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535382.2264866398 20 185331.1913556245 30 0.0 11 535784.8986583672 21 185352.4568174781 31 0.0 0 LINE 5 4F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535466.2111560569 20 185520.4169102442 30 0.0 11 535514.7099456254 21 185115.9919336981 31 0.0 0 LINE 5 4F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535501.4979983462 20 185117.6476644367 30 0.0 11 535739.8858672794 21 185132.0350074303 31 0.0 0 LINE 5 4F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535418.8674089755 20 184945.9561199044 30 0.0 11 535515.4397776946 21 185129.2063845734 31 0.0 0 LINE 5 4FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535369.5064323645 20 185017.8273827992 30 0.0 11 535452.3764747868 21 184997.2391378445 31 0.0 0 LINE 5 4FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535717.5064167423 20 185601.3754019604 30 0.0 11 535737.9102122855 21 185129.6426019159 31 0.0 0 LINE 5 4FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535326.3598811704 20 185199.7522087382 30 0.0 11 535750.4056180268 21 185204.2732045837 31 0.0 0 LINE 5 4FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535597.4474089884 20 184751.4979048362 30 0.0 11 535748.2235633978 21 185210.8983017991 31 0.0 0 LINE 5 4FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535547.1804223578 20 184541.7709254714 30 0.0 11 535682.3923593902 21 185024.9225824591 31 0.0 0 LINE 5 500 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535505.1377379638 20 184758.6825038902 30 0.0 11 535620.5885034062 21 184780.1452271111 31 0.0 0 LINE 5 501 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535524.1856060168 20 184817.7772444247 30 0.0 11 535609.4175360436 21 184748.4871370208 31 0.0 0 LINE 5 502 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535570.296748796 20 185002.1058677334 30 0.0 11 535539.0553429453 21 184802.52829905 31 0.0 0 LINE 5 503 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535357.746004057 20 184958.474605842 30 0.0 11 535657.2550122715 21 184929.8059817427 31 0.0 0 LINE 5 504 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535298.4922117697 20 184889.1393465063 30 0.0 11 535341.8549400053 21 185002.5727601311 31 0.0 0 LINE 5 505 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535241.1734845259 20 185019.5210662647 30 0.0 11 535249.717781515 21 184899.043989793 31 0.0 0 LINE 5 506 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535246.9440076642 20 184905.1824582619 30 0.0 11 535300.5910023385 21 184889.7027665412 31 0.0 0 LINE 5 507 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.51385834 20 185038.9531902914 30 0.0 11 534936.5261047019 21 185038.9510308092 31 0.0 0 LINE 5 508 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535080.6527128276 20 185013.5362284448 30 0.0 11 535490.5647417293 21 184941.2537170008 31 0.0 0 LINE 5 509 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535501.4412534025 20 184948.5153462196 30 0.0 11 535497.0379026665 21 184924.6330290301 31 0.0 0 LINE 5 50A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535656.8736195291 20 185058.0328070582 30 0.0 11 535700.4612669717 21 185045.6128970883 31 0.0 0 LINE 5 50B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535646.6482386795 20 185069.727561105 30 0.0 11 535663.8755498464 21 185052.9238060906 31 0.0 0 LINE 5 50C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535653.2693595921 20 185133.4820169923 30 0.0 11 535647.9167757512 21 185061.8355780196 31 0.0 0 LINE 5 50D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535438.6044568951 20 184992.5553584505 30 0.0 11 535394.6297386165 21 184644.0500522233 31 0.0 0 LINE 5 50E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535304.0071378401 20 184686.4677601972 30 0.0 11 535412.5316292262 21 184958.1988788722 31 0.0 0 LINE 5 50F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535285.9196378086 20 184980.2736785974 30 0.0 11 535280.0577219055 21 184945.2361034543 31 0.0 0 LINE 5 510 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535408.97011748 20 184810.9000931193 30 0.0 11 535499.2992886763 21 184787.3951780687 31 0.0 0 LINE 5 511 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535464.4760482091 20 184792.1782756448 30 0.0 11 535543.352293473 21 184819.2175096397 31 0.0 0 LINE 5 512 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535464.5747593956 20 184805.3031096497 30 0.0 11 535525.357753368 21 184753.0577724275 31 0.0 0 LINE 5 513 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535479.3097783617 20 184592.3356562343 30 0.0 11 535522.9332737854 21 184765.446873669 31 0.0 0 LINE 5 514 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535442.4387356393 20 185206.0210956518 30 0.0 11 535448.962877189 21 185159.464189451 31 0.0 0 LINE 5 515 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535385.2221178641 20 185162.5376566434 30 0.0 11 535450.4688616026 21 185160.624523209 31 0.0 0 LINE 5 516 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535362.082434586 20 185206.3568374276 30 0.0 11 535347.2644751583 21 185103.0932372945 31 0.0 0 LINE 5 517 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535201.914047268 20 185144.1545844069 30 0.0 11 535490.7907191858 21 185068.5966611639 31 0.0 0 LINE 5 518 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535571.5812368377 20 185125.0116500937 30 0.0 11 535571.5035935779 21 185056.1672042472 31 0.0 0 LINE 5 519 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535539.6771781332 20 185057.1807123762 30 0.0 11 535599.7813427349 21 185056.9330147139 31 0.0 0 LINE 5 51A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535545.0448302518 20 185063.9077228577 30 0.0 11 535543.957332922 21 184992.5824589834 31 0.0 0 LINE 5 51B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535541.1738633348 20 184995.0465275259 30 0.0 11 535597.2888617337 21 184993.4043492656 31 0.0 0 LINE 5 51C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535594.7469779589 20 185064.4360151786 30 0.0 11 535594.4263687719 21 184986.9377248218 31 0.0 0 LINE 5 51D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535478.3345188717 20 185397.9158045933 30 0.0 11 535741.3567721097 21 185426.7783072673 31 0.0 0 LINE 5 521 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534391.2765926995 20 184519.6503847673 30 0.0 11 534386.096584341 21 184657.946565643 31 0.0 0 LINE 5 52B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.5953021055 20 184456.2129860037 30 0.0 11 534150.4528097157 21 184882.3790791057 31 0.0 0 LINE 5 52F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534288.5721563849 20 184537.5636853628 30 0.0 11 534215.4902316121 21 184934.1190157052 31 0.0 0 LINE 5 530 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534453.0403708427 20 184663.3012758095 30 0.0 11 534104.3003871109 21 184622.7857454523 31 0.0 0 LINE 5 534 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534447.258926724 20 184850.4577674675 30 0.0 11 534358.4101113065 21 184835.3587940743 31 0.0 0 LINE 5 535 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534473.2590024992 20 184926.5403161469 30 0.0 11 534009.7420030087 21 184836.5395345194 31 0.0 0 LINE 5 536 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534173.7545980421 20 184452.6269133669 30 0.0 11 534079.4116061442 21 184866.0693231767 31 0.0 0 LINE 5 537 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533755.4398820817 20 184661.6264292207 30 0.0 11 534086.3626894285 21 184865.4899125348 31 0.0 0 LINE 5 54B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534152.8220239885 20 184566.9747456222 30 0.0 11 534106.0257041126 21 184562.4787046947 31 0.0 0 LINE 5 54C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534123.8568246477 20 184501.2056948098 30 0.0 11 534106.8034721114 21 184564.2134785772 31 0.0 0 LINE 5 557 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534476.3853151561 20 184841.3974169092 30 0.0 11 534252.8962295165 21 185308.7896885875 31 0.0 0 LINE 5 55A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533961.5249641592 20 184881.5255266349 30 0.0 11 534304.3350339336 21 185057.7811684468 31 0.0 0 LINE 5 55B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533907.0202036754 20 184975.68771859 30 0.0 11 534585.0093833956 21 185309.1577660268 31 0.0 0 LINE 5 55C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534351.9801533095 20 185270.8440629181 30 0.0 11 534245.8376609196 21 185697.0101560202 31 0.0 0 LINE 5 55D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534416.053427876 20 185297.7558171074 30 0.0 11 534234.6140266268 21 185229.2776323616 31 0.0 0 LINE 5 55E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534389.3918617133 20 185365.2951323006 30 0.0 11 534329.4147947651 21 185342.0917458582 31 0.0 0 LINE 5 55F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534427.284004527 20 185326.2893565586 30 0.0 11 534374.294889134 21 185370.214396944 31 0.0 0 LINE 5 560 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534354.0779169706 20 185514.3239438399 30 0.0 11 534310.8750828159 21 185748.7500926196 31 0.0 0 LINE 5 564 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534082.1685787133 20 185266.8570599263 30 0.0 11 534042.8498380052 21 185342.6551891283 31 0.0 0 LINE 5 565 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534438.4337275536 20 185715.179827652 30 0.0 11 534231.2455671621 21 185651.1706114339 31 0.0 0 LINE 5 566 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534269.1394492462 20 185267.2579902813 30 0.0 11 534174.7964573482 21 185680.700400091 31 0.0 0 LINE 5 56B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534038.9544153992 20 185209.4610571617 30 0.0 11 533929.5639759587 21 185526.2001676052 31 0.0 0 LINE 5 56C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534128.9026977911 20 185235.266299162 30 0.0 11 534010.36305539 21 185208.8879234353 31 0.0 0 LINE 5 56D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534143.9452490913 20 185183.4172834368 30 0.0 11 534127.2753217763 21 185236.706441965 31 0.0 0 LINE 5 56E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534203.536687036 20 184850.6856394941 30 0.0 11 533979.511130468 21 185366.7574547194 31 0.0 0 LINE 5 56F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533984.0405412705 20 185379.0258777179 30 0.0 11 533961.8400215264 21 185369.1825299575 31 0.0 0 LINE 5 573 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534041.5016409995 20 185328.1711071394 30 0.0 11 533705.4015758481 21 185213.7569711722 31 0.0 0 LINE 5 574 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533926.8507846999 20 184975.9659141336 30 0.0 11 533763.6036657633 21 185098.3465764448 31 0.0 0 LINE 5 575 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533753.3249201474 20 185068.9920483031 30 0.0 11 534014.1606413901 21 185294.815001671 31 0.0 0 LINE 5 57B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534031.9313018756 20 184808.6148959472 30 0.0 11 533876.783424875 21 185029.0196435895 31 0.0 0 LINE 5 57C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534248.2068751925 20 185381.6058225365 30 0.0 11 534201.4105553166 21 185377.1097816092 31 0.0 0 LINE 5 57D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534219.2416758517 20 185315.8367717241 30 0.0 11 534202.1883233154 21 185378.8445554916 31 0.0 0 LINE 5 57E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534267.2444791151 20 185303.536510522 30 0.0 11 534170.26974444 21 185265.0807714352 31 0.0 0 LINE 5 585 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534088.6604468999 20 184941.3248589964 30 0.0 11 534043.2684698303 21 185044.4952954651 31 0.0 0 LINE 5 588 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533778.699490766 20 185175.787427945 30 0.0 11 533615.7892077258 21 185127.9007145659 31 0.0 0 LINE 5 589 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533889.4801228333 20 184733.3371193682 30 0.0 11 533668.380798012 21 185455.8235821609 31 0.0 0 LINE 5 58A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533669.0481535236 20 185219.6666077623 30 0.0 11 533156.2970385719 21 185130.5605879663 31 0.0 0 LINE 5 58B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533652.6970921362 20 185287.2111842932 30 0.0 11 533691.368935235 21 185097.1743282281 31 0.0 0 LINE 5 58D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533726.3554435946 20 185312.8337458587 30 0.0 11 533574.5071917399 21 185257.5403092498 31 0.0 0 LINE 5 58E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533593.8368982549 20 185264.2056083881 30 0.0 11 533277.4741264265 21 185310.1755935641 31 0.0 0 LINE 5 58F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533672.2874569829 20 185028.0485366832 30 0.0 11 533252.0779246593 21 185038.8519140487 31 0.0 0 LINE 5 590 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533710.405074358 20 184829.6561084765 30 0.0 11 533658.6782495932 21 184939.5278570125 31 0.0 0 LINE 5 591 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533757.8097503218 20 184963.9603378841 30 0.0 11 533758.301905461 21 184843.1816611668 31 0.0 0 LINE 5 592 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533760.6087077835 20 184849.5104272049 30 0.0 11 533708.2700168314 21 184830.060945907 31 0.0 0 LINE 5 593 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534060.1620768055 20 185006.1286428275 30 0.0 11 534060.1500263014 21 185006.1255732843 31 0.0 0 LINE 5 594 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.3284564037 20 184970.0003236548 30 0.0 11 532885.2387837082 21 184800.028308228 31 0.0 0 LINE 5 595 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533494.4232462245 20 185058.1154689717 30 0.0 11 533576.3287827944 21 184703.1402534146 31 0.0 0 LINE 5 596 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533720.0668251423 20 184684.4216508722 30 0.0 11 533604.0388960189 21 184929.9588760215 31 0.0 0 LINE 5 597 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533716.1249475926 20 184921.4756006983 30 0.0 11 533724.5914895052 21 184886.9747108834 31 0.0 0 LINE 5 598 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533431.9734486657 20 185232.4302220629 30 0.0 11 533540.1338697607 21 185087.9672749981 31 0.0 0 LINE 5 599 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533603.4661137124 20 185095.8003762957 30 0.0 11 533538.5453041319 21 185089.0116995892 31 0.0 0 LINE 5 59A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.6357425715 20 185091.1815131837 30 0.0 11 533565.5971262563 21 185014.9532196935 31 0.0 0 LINE 5 59D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.4049733451 20 184778.3242658983 30 0.0 11 533961.3461259023 21 184945.405927624 31 0.0 0 LINE 5 59E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533589.8584304239 20 185107.2802195277 30 0.0 11 533607.2332131394 21 184991.399632075 31 0.0 0 LINE 5 59F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534448.9792157222 20 184662.8294633956 30 0.0 11 534595.7315551097 21 184795.9757854659 31 0.0 0 LINE 5 5A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531733.2840274471 20 186204.7351113824 30 0.0 11 531448.5837936163 21 186119.7760350217 31 0.0 0 LINE 5 5A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531632.4721077171 20 185930.7358159032 30 0.0 11 531639.7393499542 21 186196.0561477955 31 0.0 0 LINE 5 5A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531358.457913672 20 185930.1338576856 30 0.0 11 531685.1949769023 21 186008.8922798291 31 0.0 0 LINE 5 5A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531770.0292339276 20 185963.2831550198 30 0.0 11 531808.2136621512 21 186140.5612032772 31 0.0 0 LINE 5 5A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532232.1680833026 20 186022.1457130604 30 0.0 11 532232.1680833026 21 186186.3597618883 31 0.0 0 LINE 5 5A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531627.5907608017 20 186001.9470050684 30 0.0 11 531869.3182729818 21 185971.1207754074 31 0.0 0 LINE 5 5A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531611.397048721 20 186201.9375863602 30 0.0 11 531901.0963274493 21 186217.1136835819 31 0.0 0 LINE 5 5A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533414.1140397175 20 185165.5370379062 30 0.0 11 533424.4254015407 21 184724.7392205304 31 0.0 0 LINE 5 5A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533322.7171241251 20 184642.9320605513 30 0.0 11 532990.6437599907 21 184514.5291438661 31 0.0 0 LINE 5 5AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534153.2048046347 20 184752.2472177889 30 0.0 11 533885.0218290623 21 184579.4395168853 31 0.0 0 LINE 5 5AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531550.2442337178 20 185166.8802593773 30 0.0 11 531510.6297846931 21 185399.9897693373 31 0.0 0 LINE 5 5AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532988.2362401025 20 186147.3083667564 30 0.0 11 533381.9029377306 21 186201.5675327487 31 0.0 0 LINE 5 5C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532778.6411400246 20 187622.1886596294 30 0.0 11 533427.582290831 21 185080.1812356924 31 0.0 0 LINE 5 5D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534248.5818166204 20 185619.4487363936 30 0.0 11 534493.593518952 21 185630.1835954607 31 0.0 0 LINE 5 5DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534282.0183703715 20 185616.188519107 30 0.0 11 534172.0588715453 21 185831.2875668419 31 0.0 0 LINE 5 5DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533826.1828457042 20 185498.1855968445 30 0.0 11 534504.1720254244 21 185831.6556442813 31 0.0 0 LINE 5 5E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534271.1427953385 20 185793.3419411726 30 0.0 11 534165.0003029485 21 186219.5080342747 31 0.0 0 LINE 5 5E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534335.2160699049 20 185820.2536953619 30 0.0 11 534153.7766686557 21 185751.7755106161 31 0.0 0 LINE 5 5E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534308.5545037421 20 185887.7930105551 30 0.0 11 534248.577436794 21 185864.5896241127 31 0.0 0 LINE 5 5E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534303.1196496177 20 185874.6926405317 30 0.0 11 534230.0377248448 21 186271.2479708741 31 0.0 0 LINE 5 5E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534358.301923027 20 185987.6211864558 30 0.0 11 534062.9865863768 21 185953.4249086355 31 0.0 0 LINE 5 5E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534067.6732275388 20 185940.9616670905 30 0.0 11 534026.1561056284 21 186176.1469138242 31 0.0 0 LINE 5 5E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533919.9417536444 20 185820.6237579156 30 0.0 11 534075.6678596591 21 185957.2116849322 31 0.0 0 LINE 5 5E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534001.3312207422 20 185789.3549381808 30 0.0 11 533962.0124800341 21 185865.1530673827 31 0.0 0 LINE 5 5E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534357.5963695824 20 186237.6777059064 30 0.0 11 534024.2894962416 21 186173.6684896884 31 0.0 0 LINE 5 5E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534188.3020912749 20 185789.7558685358 30 0.0 11 534093.959099377 21 186203.1982783455 31 0.0 0 LINE 5 5EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533638.9909350334 20 185915.9627476106 30 0.0 11 534100.9101826614 21 186202.6188677036 31 0.0 0 LINE 5 5EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533717.7276796531 20 185860.915757104 30 0.0 11 533711.7175495929 21 185978.1906737143 31 0.0 0 LINE 5 5EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533770.762714852 20 185893.2003459607 30 0.0 11 533683.5308453329 21 185959.9551347054 31 0.0 0 LINE 5 5ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533939.2875136152 20 185980.9652082985 30 0.0 11 533752.4704865293 21 185904.110606927 31 0.0 0 LINE 5 5EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533958.117057428 20 185731.9589354162 30 0.0 11 533848.7266179877 21 186048.6980458597 31 0.0 0 LINE 5 5EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534048.06533982 20 185757.7641774165 30 0.0 11 533929.5256974189 21 185731.3858016898 31 0.0 0 LINE 5 5F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534063.1078911201 20 185705.9151616913 30 0.0 11 534046.4379638052 21 185759.2043202194 31 0.0 0 LINE 5 5F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534282.8840061187 20 185012.2849875451 30 0.0 11 533898.6737724969 21 185889.2553329739 31 0.0 0 LINE 5 5F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533903.2031832994 20 185901.5237559724 30 0.0 11 533881.0026635552 21 185891.680408212 31 0.0 0 LINE 5 5F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533973.5175888728 20 186078.1849544206 30 0.0 11 533951.289621666 21 186117.6824815214 31 0.0 0 LINE 5 5F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533987.2718768551 20 186070.9637877669 30 0.0 11 533966.918612191 21 186083.8047787778 31 0.0 0 LINE 5 5F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534047.7321300739 20 186092.2482343965 30 0.0 11 533979.3014454954 21 186070.3597949963 31 0.0 0 LINE 5 5F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533960.6642830283 20 185850.6689853939 30 0.0 11 533624.564217877 21 185736.2548494267 31 0.0 0 LINE 5 5F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533846.0134267288 20 185498.4637923881 30 0.0 11 533682.7663077922 21 185620.8444546993 31 0.0 0 LINE 5 5F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533672.4875621763 20 185591.4899265576 30 0.0 11 533933.323283419 21 185817.3128799255 31 0.0 0 LINE 5 5F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533984.2730984368 20 185699.3213145349 30 0.0 11 533951.5635824718 21 185685.4619748932 31 0.0 0 LINE 5 5FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533790.9027081983 20 185779.5505123624 30 0.0 11 533747.0106001366 21 185861.9235847253 31 0.0 0 LINE 5 5FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533759.7708675354 20 185829.171307324 30 0.0 11 533767.7003971879 21 185912.175553007 31 0.0 0 LINE 5 5FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533772.511944799 20 185832.3234433795 30 0.0 11 533707.5492968536 21 185879.270242947 31 0.0 0 LINE 5 5FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533609.8257327368 20 185818.9870339748 30 0.0 11 533720.1623939 21 185879.7972284508 31 0.0 0 LINE 5 5FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533892.3579233192 20 185253.3677321921 30 0.0 11 533795.9460669039 21 185551.517521844 31 0.0 0 LINE 5 5FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534167.3695172214 20 185904.103700791 30 0.0 11 534120.5731973455 21 185899.6076598636 31 0.0 0 LINE 5 600 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534138.4043178805 20 185838.3346499785 30 0.0 11 534121.3509653443 21 185901.3424337461 31 0.0 0 LINE 5 601 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534186.407121144 20 185826.0343887765 30 0.0 11 534089.4323864689 21 185787.5786496897 31 0.0 0 LINE 5 602 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534163.2101264513 20 185655.7847719955 30 0.0 11 534022.4637309971 21 185919.1271034002 31 0.0 0 LINE 5 603 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534058.5158018959 20 186010.8331931783 30 0.0 11 533991.5818118574 21 185994.7271468006 31 0.0 0 LINE 5 604 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533999.9782917924 20 185964.0115637281 30 0.0 11 533985.742053636 21 186022.4059254402 31 0.0 0 LINE 5 605 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534005.2705259052 20 185970.7980663162 30 0.0 11 533936.1590559625 21 185953.1322620743 31 0.0 0 LINE 5 606 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533939.2035281584 20 185950.9990659342 30 0.0 11 533924.5400241045 21 186005.1892075063 31 0.0 0 LINE 5 607 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533994.2110735139 20 186019.257029288 30 0.0 11 533918.9176883678 21 186000.8996342736 31 0.0 0 LINE 5 608 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534007.8230889289 20 185463.8227372508 30 0.0 11 533962.4311118591 21 185566.9931737196 31 0.0 0 LINE 5 609 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533680.2879975476 20 185926.3723861391 30 0.0 11 533183.0921970397 21 185960.4920697405 31 0.0 0 LINE 5 60A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533635.3074283488 20 185874.3556080672 30 0.0 11 533409.7069375618 21 185902.1750854693 31 0.0 0 LINE 5 60B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533697.862132795 20 185698.2853061994 30 0.0 11 533534.9518497547 21 185650.3985928204 31 0.0 0 LINE 5 60C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533771.9073970045 20 185375.8751922475 30 0.0 11 533587.5434400409 21 185978.3214604154 31 0.0 0 LINE 5 60E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533571.859734165 20 185809.7090625476 30 0.0 11 533610.5315772639 21 185619.6722064826 31 0.0 0 LINE 5 60F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533500.9333528127 20 185794.1576434707 30 0.0 11 533514.2766247555 21 185731.2481625001 31 0.0 0 LINE 5 610 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533545.4819450334 20 185825.3455892097 30 0.0 11 533493.6698337688 21 185780.0381875042 31 0.0 0 LINE 5 611 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533512.9995402838 20 185786.7034866426 30 0.0 11 533196.6367684554 21 185832.6734718186 31 0.0 0 LINE 5 612 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533591.4500990117 20 185550.5464149377 30 0.0 11 533281.9833857183 21 185528.8296416967 31 0.0 0 LINE 5 616 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533979.3247188343 20 185528.626521082 30 0.0 11 533979.3126683303 21 185528.6234515387 31 0.0 0 LINE 5 619 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533592.716804391 20 185246.1291783604 30 0.0 11 533497.5594804018 21 185639.2600493747 31 0.0 0 LINE 5 61B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533351.1360906946 20 185754.9281003174 30 0.0 11 533459.2965117895 21 185610.4651532526 31 0.0 0 LINE 5 61C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533522.6287557413 20 185618.2982545502 30 0.0 11 533457.7079461609 21 185611.5095778437 31 0.0 0 LINE 5 61D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533706.7983846004 20 185613.6793914381 30 0.0 11 533484.7597682852 21 185537.451097948 31 0.0 0 LINE 5 620 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533365.6423109871 20 185989.5037721182 30 0.0 11 533355.2628067224 21 185733.4928732219 31 0.0 0 LINE 5 621 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533337.2744785237 20 186336.5469027501 30 0.0 11 533396.5976925238 21 186535.0100937501 31 0.0 0 LINE 5 622 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533550.0795055239 20 186180.2816337501 30 0.0 11 533609.1965935239 21 186660.1642687501 31 0.0 0 LINE 5 623 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533538.3571319998 20 185927.2096775935 30 0.0 11 533580.5614965238 21 186464.9701427501 31 0.0 0 LINE 5 624 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533458.1223385238 20 186169.4847237501 30 0.0 11 533567.2457225238 21 186212.8623077501 31 0.0 0 LINE 5 625 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533465.3862375238 20 186231.1470737501 30 0.0 11 533562.4058715238 21 186179.6418167501 31 0.0 0 LINE 5 626 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533474.9917335238 20 186420.9127537501 30 0.0 11 533482.9234825238 21 186219.0605337501 31 0.0 0 LINE 5 627 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533054.7558316947 20 186318.1436929638 30 0.0 11 533574.2870045238 21 186366.7882467501 31 0.0 0 LINE 5 628 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533417.7957455238 20 186355.0216147501 30 0.0 11 533418.0925675238 21 186330.7385657501 31 0.0 0 LINE 5 629 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533347.6302755237 20 186386.0827237501 30 0.0 11 533383.5869865237 21 185953.2266277501 31 0.0 0 LINE 5 62A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533362.2817485238 20 185976.7798857501 30 0.0 11 533556.7744945238 21 186028.6150477501 31 0.0 0 LINE 5 62B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533258.2867925238 20 185940.5511634717 30 0.0 11 533328.6913695239 21 186347.3338157501 31 0.0 0 LINE 5 62C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533353.6739045237 20 186202.1253807501 30 0.0 11 533446.8430955237 21 186196.5269837501 31 0.0 0 LINE 5 62D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533411.7521155238 20 186194.4875667501 30 0.0 11 533483.9128905238 21 186236.2656087501 31 0.0 0 LINE 5 62E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533409.3115775239 20 186207.3838757501 30 0.0 11 533479.0483035237 21 186167.8751847501 31 0.0 0 LINE 5 62F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533464.9410045238 20 186001.2828717501 30 0.0 11 533474.2744135237 21 186179.5618397501 31 0.0 0 LINE 5 631 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533828.2799445249 20 186210.2886838591 30 0.0 11 534061.4320714794 21 186167.5716401304 31 0.0 0 LINE 5 632 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533878.5348859357 20 186281.5377210867 30 0.0 11 533888.0084184373 21 186196.6756450849 31 0.0 0 LINE 5 633 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533682.6241340539 20 186064.3491011722 30 0.0 11 533742.8463203225 21 185963.5383080481 31 0.0 0 LINE 5 634 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533744.6558089154 20 186067.0101066368 30 0.0 11 533709.2791370904 21 185963.019280259 31 0.0 0 LINE 5 635 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.7364357564 20 186271.9532591409 30 0.0 11 533852.6960106894 21 186024.3600566836 31 0.0 0 LINE 5 636 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533733.19405122 20 186303.439136011 30 0.0 11 533854.626565084 21 186302.1702375712 31 0.0 0 LINE 5 637 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.5538564261 20 186402.4709471534 30 0.0 11 533725.5431140586 21 186352.6174865919 31 0.0 0 LINE 5 638 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533730.3361853824 20 186357.3504649146 30 0.0 11 533734.4512997048 21 186301.6666546332 31 0.0 0 LINE 5 639 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533774.1936004964 20 186550.921799029 30 0.0 11 533848.7703066101 21 186141.4209470101 31 0.0 0 LINE 5 63A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533878.8332329101 20 186207.9637909363 30 0.0 11 533536.7480498949 21 186128.1674759979 31 0.0 0 LINE 5 63B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533545.052813288 20 186227.8808082367 30 0.0 11 533837.5602881303 21 186220.4819401955 31 0.0 0 LINE 5 63C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533814.2894553135 20 186346.879572664 30 0.0 11 533779.3969418796 21 186340.2082732231 31 0.0 0 LINE 5 63D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533698.1930436881 20 186172.6657522801 30 0.0 11 533707.521963026 21 186079.7958892214 31 0.0 0 LINE 5 63E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533699.9134321882 20 186114.1127416054 30 0.0 11 533752.6629064465 21 186049.5366221229 31 0.0 0 LINE 5 63F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533712.2556086878 20 186118.5783536354 30 0.0 11 533684.3718017468 21 186043.434219279 31 0.0 0 LINE 5 640 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533517.6614423957 20 186030.7981312433 30 0.0 11 533695.1477506907 21 186050.0104533972 31 0.0 0 LINE 5 641 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533938.7951369609 20 186482.5712296238 30 0.0 11 533968.2654247545 21 186185.4345043938 31 0.0 0 LINE 5 643 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534367.7944644015 20 186130.8678290536 30 0.0 11 534035.7211002671 21 186002.4649123684 31 0.0 0 LINE 5 64E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532380.4365915808 20 183829.5073398477 30 0.0 11 532354.2882743064 21 183002.9918967023 31 0.0 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 281 1 3 ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 B4 3 ACAD_COLOR 350 62 3 ACAD_DETAILVIEWSTYLE 350 69 3 ACAD_GROUP 350 D 3 ACAD_LAYOUT 350 61 3 ACAD_MATERIAL 350 10 3 ACAD_MLEADERSTYLE 350 65 3 ACAD_MLINESTYLE 350 5E 3 ACAD_PLOTSETTINGS 350 60 3 ACAD_PLOTSTYLENAME 350 E 3 ACAD_SCALELIST 350 42 3 ACAD_SECTIONVIEWSTYLE 350 67 3 ACAD_TABLESTYLE 350 63 3 ACAD_VISUALSTYLE 350 29 3 ACDB_RECOMPOSE_DATA 350 658 3 AcDbVariableDictionary 350 34B 0 DICTIONARY 5 345 330 2 100 AcDbDictionary 280 1 281 1 3 ACAD_LAYERSTATES 360 346 0 DICTIONARY 5 340 330 54 100 AcDbDictionary 280 1 281 1 3 ADSK_XREC_LAYER_RECONCILED 360 341 0 DICTIONARY 5 135 330 6F 100 AcDbDictionary 280 1 281 1 3 ACAD_SORTENTS 360 136 0 XRECORD 5 B4 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 300 ACDMAC 300 2018 300 ACDMAC_F_S 0 DICTIONARY 5 62 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 69 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Imperial24 350 6A 0 DICTIONARY 5 D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 61 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Layout1 350 6E 3 Model 350 72 0 DICTIONARY 5 10 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 ByBlock 350 19 3 ByLayer 350 11 3 Global 350 21 0 DICTIONARY 5 65 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 66 0 DICTIONARY 5 5E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 5F 0 DICTIONARY 5 60 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 ACDBDICTIONARYWDFLT 5 E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Normal 350 F 100 AcDbDictionaryWithDefault 340 F 0 DICTIONARY 5 42 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 A0 350 43 3 A1 350 44 3 A2 350 45 3 A3 350 46 3 A4 350 47 3 A5 350 48 3 A6 350 49 3 A7 350 4A 3 A8 350 4B 3 A9 350 4C 3 B0 350 4D 3 B1 350 4E 3 B2 350 4F 3 B3 350 50 3 B4 350 51 3 B5 350 52 3 B6 350 53 0 DICTIONARY 5 67 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Imperial24 350 68 0 DICTIONARY 5 63 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 64 0 DICTIONARY 5 29 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 2dWireframe 350 2F 3 Basic 350 2E 3 Brighten 350 35 3 ColorChange 350 39 3 Conceptual 350 32 3 Dim 350 34 3 EdgeColorOff 350 41 3 Facepattern 350 38 3 Flat 350 2A 3 FlatWithEdges 350 2B 3 Gouraud 350 2C 3 GouraudWithEdges 350 2D 3 Hidden 350 31 3 JitterOff 350 3F 3 Linepattern 350 37 3 OverhangOff 350 40 3 Realistic 350 33 3 Shaded 350 3E 3 Shaded with edges 350 3D 3 Shades of Gray 350 3A 3 Sketchy 350 3B 3 Thicken 350 36 3 Wireframe 350 30 3 X-Ray 350 3C 0 XRECORD 5 658 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 90 1 330 64 0 DICTIONARY 5 34B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 CANNOSCALE 350 351 3 CMLEADERSTYLE 350 34D 3 CTABLESTYLE 350 34C 3 CVIEWDETAILSTYLE 350 34E 3 CVIEWSECTIONSTYLE 350 34F 3 LAYEREVAL 350 353 3 LAYERNOTIFY 350 354 3 LIGHTINGUNITS 350 352 3 MSLTSCALE 350 350 0 DICTIONARY 5 346 102 {ACAD_REACTORS 330 345 102 } 330 345 100 AcDbDictionary 281 1 0 XRECORD 5 341 102 {ACAD_REACTORS 330 340 102 } 330 340 100 AcDbXrecord 280 1 290 1 0 SORTENTSTABLE 5 136 102 {ACAD_REACTORS 330 135 102 } 330 135 100 AcDbSortentsTable 330 6F 331 2D6 5 2D7 331 25E 5 25F 331 280 5 281 331 2F8 5 2F9 331 1F8 5 1F9 331 90 5 90 331 271 5 272 331 2E9 5 2EA 331 1E9 5 1EA 331 2A2 5 2A3 331 21A 5 21B 331 182 5 182 331 10A 5 10A 331 FB 5 FB 331 293 5 294 331 30B 5 30C 331 20B 5 20C 331 12C 5 12D 331 23C 5 23D 331 1A4 5 1A4 331 11D 5 11E 331 D4 5 D4 331 2B5 5 2B6 331 22D 5 22E 331 1C6 5 1C7 331 14E 5 14E 331 13F 5 13F 331 24F 5 250 331 1B7 5 1B7 331 E7 5 E7 331 C5 5 C5 331 A3 5 A3 331 81 5 81 331 76 5 76 331 160 5 160 331 1C9 5 1CA 331 151 5 151 331 270 5 271 331 2E8 5 2E9 331 1E8 5 1E9 331 2D9 5 2DA 331 261 5 262 331 292 5 293 331 30A 5 30B 331 20A 5 20B 331 A2 5 A2 331 283 5 284 331 2FB 5 2FC 331 1FB 5 1FC 331 11C 5 11D 331 2B4 5 2B5 331 22C 5 22D 331 194 5 194 331 2A5 5 2A6 331 31D 5 31E 331 21D 5 21E 331 185 5 185 331 13E 5 13E 331 10D 5 10D 331 24E 5 24F 331 1B6 5 1B6 331 12F 5 130 331 E6 5 E6 331 2C7 5 2C8 331 23F 5 240 331 1A7 5 1A7 331 D7 5 D7 331 C4 5 C4 331 93 5 93 331 80 5 80 331 1C8 5 1C9 331 150 5 150 331 141 5 141 331 251 5 252 331 2D8 5 2D9 331 260 5 261 331 1B9 5 1B9 331 E9 5 E9 331 282 5 283 331 1FA 5 1FB 331 92 5 92 331 273 5 274 331 2EB 5 2EC 331 1EB 5 1EC 331 2A4 5 2A5 331 31C 5 31D 331 21C 5 21D 331 184 5 184 331 10C 5 10C 331 295 5 296 331 20D 5 20E 331 12E 5 12F 331 2C6 5 2C7 331 23E 5 23F 331 1A6 5 1A6 331 11F 5 120 331 D6 5 D6 331 2B7 5 2B8 331 22F 5 230 331 C7 5 C7 331 A5 5 A5 331 83 5 83 331 140 5 140 331 250 5 251 331 1B8 5 1B8 331 131 5 132 331 E8 5 E8 331 2C9 5 2CA 331 241 5 242 331 1CB 5 1CC 331 D9 5 D9 331 272 5 273 331 2EA 5 2EB 331 1EA 5 1EB 331 2DB 5 2DC 331 263 5 264 331 294 5 295 331 20C 5 20D 331 A4 5 A4 331 285 5 286 331 1FD 5 1FE 331 11E 5 11F 331 2B6 5 2B7 331 22E 5 22F 331 10F 5 10F 331 C6 5 C6 331 2A7 5 2A8 331 31F 5 320 331 21F 5 220 331 187 5 187 331 B7 5 B7 331 95 5 95 331 82 5 82 331 130 5 131 331 2C8 5 2C9 331 240 5 241 331 D8 5 D8 331 2B9 5 2BA 331 231 5 232 331 1CA 5 1CB 331 199 5 199 331 143 5 143 331 253 5 254 331 2DA 5 2DB 331 262 5 263 331 1DD 5 1DE 331 1BB 5 1BB 331 EB 5 EB 331 C9 5 C9 331 284 5 285 331 1FC 5 1FD 331 94 5 94 331 275 5 276 331 2ED 5 2EE 331 1ED 5 1EE 331 2A6 5 2A7 331 31E 5 31F 331 21E 5 21F 331 186 5 186 331 FF 5 FF 331 297 5 298 331 20F 5 210 331 A7 5 A7 331 85 5 85 331 2B8 5 2B9 331 230 5 231 331 111 5 111 331 C8 5 C8 331 2A9 5 2AA 331 221 5 222 331 142 5 142 331 252 5 253 331 133 5 134 331 EA 5 EA 331 2CB 5 2CC 331 243 5 244 331 1DC 5 1DD 331 1AB 5 1AB 331 1CD 5 1CE 331 DB 5 DB 331 B9 5 B9 331 274 5 275 331 2EC 5 2ED 331 1EC 5 1ED 331 2DD 5 2DE 331 265 5 266 331 296 5 297 331 20E 5 20F 331 A6 5 A6 331 287 5 288 331 1FF 5 200 331 97 5 97 331 84 5 84 331 110 5 110 331 2A8 5 2A9 331 320 5 321 331 220 5 221 331 188 5 188 331 B8 5 B8 331 299 5 29A 331 311 5 312 331 211 5 212 331 179 5 179 331 2CA 5 2CB 331 242 5 243 331 123 5 124 331 DA 5 DA 331 2BB 5 2BC 331 233 5 234 331 1CC 5 1CD 331 145 5 145 331 255 5 256 331 1BD 5 1BD 331 2DC 5 2DD 331 264 5 265 331 167 5 167 331 ED 5 ED 331 CB 5 CB 331 A9 5 A9 331 286 5 287 331 1FE 5 1FF 331 96 5 96 331 277 5 278 331 2EF 5 2F0 331 1EF 5 1F0 331 87 5 87 331 298 5 299 331 310 5 311 331 210 5 211 331 F1 5 F1 331 A8 5 A8 331 289 5 28A 331 201 5 202 331 169 5 169 331 122 5 123 331 2BA 5 2BB 331 232 5 233 331 113 5 113 331 CA 5 CA 331 2AB 5 2AC 331 323 5 324 331 223 5 224 331 18B 5 18B 331 144 5 144 331 254 5 255 331 2CD 5 2CE 331 245 5 246 331 1BC 5 1BC 331 1DE 5 1DF 331 1CF 5 1D0 331 1AD 5 1AD 331 EC 5 EC 331 BB 5 BB 331 99 5 99 331 276 5 277 331 2EE 5 2EF 331 1EE 5 1EF 331 2DF 5 2E0 331 267 5 268 331 86 5 86 331 F0 5 F0 331 288 5 289 331 200 5 201 331 168 5 168 331 98 5 98 331 279 5 27A 331 2F1 5 2F2 331 1F1 5 1F2 331 112 5 112 331 2AA 5 2AB 331 322 5 323 331 222 5 223 331 BA 5 BA 331 29B 5 29C 331 213 5 214 331 17B 5 17B 331 134 5 11B 331 2CC 5 2CD 331 244 5 245 331 125 5 126 331 DC 5 DC 331 2BD 5 2BE 331 235 5 236 331 1CE 5 1CF 331 19D 5 19D 331 147 5 147 331 257 5 258 331 2DE 5 2DF 331 1BF 5 1C0 331 EF 5 EF 331 CD 5 CD 331 AB 5 AB 331 89 5 89 331 278 5 279 331 2F0 5 2F1 331 1F0 5 1F1 331 88 5 88 331 269 5 26A 331 2E1 5 2E2 331 1E1 5 1E2 331 29A 5 29B 331 312 5 313 331 212 5 213 331 17A 5 17A 331 AA 5 AA 331 28B 5 28C 331 203 5 204 331 16B 5 16B 331 124 5 125 331 2BC 5 2BD 331 234 5 235 331 115 5 115 331 225 5 226 331 18D 5 18D 331 146 5 146 331 256 5 257 331 137 5 137 331 EE 5 EE 331 2CF 5 2D0 331 247 5 248 331 1AF 5 1AF 331 1D1 5 1D2 331 159 5 159 331 DF 5 DF 331 BD 5 BD 331 9B 5 9B 331 79 5 79 331 268 5 269 331 2E0 5 2E1 331 1E0 5 1E1 331 2D1 5 2D2 331 28A 5 28B 331 202 5 203 331 16A 5 16A 331 9A 5 9A 331 27B 5 27C 331 2F3 5 2F4 331 1F3 5 1F4 331 114 5 114 331 2AC 5 2AD 331 224 5 225 331 324 5 1BF 331 18C 5 18C 331 105 5 105 331 BC 5 BC 331 29D 5 29E 331 215 5 216 331 17D 5 17D 331 2CE 5 2CF 331 246 5 247 331 1AE 5 1AE 331 237 5 238 331 1D0 5 1D1 331 19F 5 19F 331 1C1 5 1C2 331 149 5 149 331 127 5 128 331 DE 5 DE 331 AD 5 AD 331 8B 5 8B 331 78 5 78 331 2D0 5 2D1 331 258 5 259 331 27A 5 27B 331 2F2 5 2F3 331 1F2 5 1F3 331 8A 5 8A 331 26B 5 26C 331 2E3 5 2E4 331 104 5 104 331 29C 5 29D 331 214 5 215 331 17C 5 17C 331 AC 5 AC 331 28D 5 28E 331 205 5 206 331 16D 5 16D 331 126 5 127 331 2BE 5 2BF 331 236 5 237 331 19E 5 19E 331 117 5 117 331 2AF 5 2B0 331 227 5 228 331 1C0 5 1C1 331 148 5 148 331 139 5 139 331 249 5 24A 331 1B1 5 1B1 331 1D3 5 1D4 331 15B 5 15B 331 E1 5 E1 331 BF 5 BF 331 9D 5 9D 331 7B 5 7B 331 26A 5 26B 331 2E2 5 2E3 331 1E2 5 1E3 331 7A 5 7A 331 2D3 5 2D4 331 25B 5 25C 331 28C 5 28D 331 204 5 205 331 16C 5 16C 331 9C 5 9C 331 27D 5 27E 331 2F5 5 2F6 331 1F5 5 1F6 331 116 5 116 331 2AE 5 2AF 331 226 5 227 331 18E 5 18E 331 107 5 107 331 BE 5 BE 331 29F 5 2A0 331 317 5 318 331 217 5 218 331 17F 5 17F 331 138 5 138 331 248 5 249 331 1B0 5 1B0 331 129 5 12A 331 E0 5 E0 331 239 5 23A 331 1A1 5 1A1 331 1D2 5 1D3 331 15A 5 15A 331 1C3 5 1C4 331 14B 5 14B 331 D1 5 D1 331 AF 5 AF 331 8D 5 8D 331 73 5 73 331 2D2 5 2D3 331 25A 5 25B 331 27C 5 27D 331 2F4 5 2F5 331 1F4 5 1F5 331 8C 5 8C 331 26D 5 26E 331 2E5 5 2E6 331 1E5 5 1E6 331 106 5 106 331 216 5 217 331 AE 5 AE 331 28F 5 290 331 307 5 308 331 207 5 208 331 16F 5 16F 331 238 5 239 331 1A0 5 1A0 331 119 5 119 331 D0 5 D0 331 2B1 5 2B2 331 229 5 22A 331 1C2 5 1C3 331 14A 5 14A 331 13B 5 13B 331 24B 5 24C 331 1B3 5 1B3 331 15D 5 15D 331 E3 5 E3 331 C1 5 C1 331 9F 5 9F 331 7D 5 7D 331 26C 5 26D 331 2E4 5 2E5 331 1E4 5 1E5 331 7C 5 7C 331 2D5 5 2D6 331 25D 5 25E 331 28E 5 28F 331 206 5 207 331 16E 5 16E 331 9E 5 9E 331 27F 5 280 331 2F7 5 2F8 331 1F7 5 1F8 331 118 5 118 331 2B0 5 2B1 331 228 5 229 331 2A1 5 2A2 331 319 5 31A 331 219 5 21A 331 181 5 181 331 13A 5 13A 331 109 5 109 331 24A 5 24B 331 1B2 5 1B2 331 12B 5 12C 331 E2 5 E2 331 23B 5 23C 331 1A3 5 1A3 331 1D4 5 1D6 331 15C 5 15C 331 14D 5 14D 331 D3 5 D3 331 C0 5 C0 331 8F 5 8F 331 75 5 75 331 2D4 5 2D5 331 25C 5 25D 331 27E 5 27F 331 2F6 5 2F7 331 1F6 5 1F7 331 8E 5 8E 331 26F 5 270 331 2E7 5 2E8 331 1E7 5 1E8 331 2A0 5 2A1 331 318 5 319 331 218 5 219 331 180 5 180 331 108 5 108 331 F9 5 F9 331 291 5 292 331 309 5 30A 331 209 5 20A 331 171 5 171 331 12A 5 12B 331 2C2 5 2C3 331 23A 5 23B 331 1A2 5 1A2 331 11B 5 11C 331 D2 5 D2 331 2B3 5 2B4 331 22B 5 22C 331 14C 5 14C 331 24D 5 24E 331 1D7 5 1DC 331 1B5 5 1B5 331 13D 5 13D 331 C3 5 C3 331 A1 5 A1 331 7F 5 7F 331 74 5 74 331 26E 5 26F 331 2E6 5 2E7 331 1E6 5 1E7 331 7E 5 7E 331 2D7 5 2D8 331 25F 5 260 331 290 5 291 331 308 5 309 331 208 5 209 331 170 5 170 331 A0 5 A0 331 281 5 282 331 2F9 5 2FA 331 1F9 5 1FA 331 11A 5 11A 331 2B2 5 2B3 331 22A 5 22B 331 2A3 5 2A4 331 21B 5 21C 331 183 5 183 331 13C 5 13C 331 10B 5 10B 331 24C 5 24D 331 1B4 5 1B4 331 12D 5 12E 331 E4 5 E4 331 2C5 5 2C6 331 23D 5 23E 331 1A5 5 1A5 331 1D6 5 1D7 331 15E 5 15E 331 1C7 5 1C8 331 14F 5 14F 331 D5 5 D5 331 C2 5 C2 331 91 5 91 331 77 5 77 0 ACDBDETAILVIEWSTYLE 5 6A 102 {ACAD_REACTORS 330 69 102 } 330 69 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 300 Imperial24 90 0 100 AcDbDetailViewStyle 70 0 71 0 90 3 71 1 340 55 62 256 40 0.24 340 0 62 256 40 0.24 300 40 0.36 280 3 71 2 340 5C 90 25 62 256 71 3 340 55 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewDetailId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 340 5C 90 25 62 256 340 5C 90 25 62 256 280 0 0 LAYOUT 5 6E 102 {ACAD_REACTORS 330 61 102 } 330 61 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout1 70 1 71 1 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 1.000000000000000E+20 24 1.000000000000000E+20 34 1.000000000000000E+20 15 -1.000000000000000E+20 25 -1.000000000000000E+20 35 -1.000000000000000E+20 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 6B 0 LAYOUT 5 72 102 {ACAD_REACTORS 330 61 102 } 330 61 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 1712 72 0 73 0 74 0 7 75 0 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Model 70 1 71 0 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 6F 331 B3 0 MATERIAL 5 19 102 {ACAD_XDICTIONARY 360 1A 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 ByBlock 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 11 102 {ACAD_XDICTIONARY 360 12 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 ByLayer 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 21 102 {ACAD_XDICTIONARY 360 22 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 Global 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MLEADERSTYLE 5 66 102 {ACAD_REACTORS 330 65 102 } 330 65 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 5A 92 -2 290 1 42 0.09 291 1 43 0.36 3 Standard 44 0.18 300 342 55 174 1 178 6 175 1 176 0 93 -1056964608 45 0.18 292 0 297 0 46 0.18 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 0 143 0.125 271 0 272 9 273 9 298 0 0 MLINESTYLE 5 5F 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 AcDbMlineStyle 2 STANDARD 70 0 3 62 256 51 90.0 52 90.0 71 2 49 0.5 62 256 6 BYLAYER 49 -0.5 62 256 6 BYLAYER 0 ACDBPLACEHOLDER 5 F 102 {ACAD_REACTORS 330 E 102 } 330 E 0 SCALE 5 43 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1:1 140 1.0 141 1.0 290 1 0 SCALE 5 44 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/128" = 1'-0" 140 0.0078125 141 12.0 290 0 0 SCALE 5 45 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/64" = 1'-0" 140 0.015625 141 12.0 290 0 0 SCALE 5 46 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/32" = 1'-0" 140 0.03125 141 12.0 290 0 0 SCALE 5 47 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/16" = 1'-0" 140 0.0625 141 12.0 290 0 0 SCALE 5 48 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/32" = 1'-0" 140 0.09375 141 12.0 290 0 0 SCALE 5 49 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/8" = 1'-0" 140 0.125 141 12.0 290 0 0 SCALE 5 4A 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/16" = 1'-0" 140 0.1875 141 12.0 290 0 0 SCALE 5 4B 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/4" = 1'-0" 140 0.25 141 12.0 290 0 0 SCALE 5 4C 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/8" = 1'-0" 140 0.375 141 12.0 290 0 0 SCALE 5 4D 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/2" = 1'-0" 140 0.5 141 12.0 290 0 0 SCALE 5 4E 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/4" = 1'-0" 140 0.75 141 12.0 290 0 0 SCALE 5 4F 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1" = 1'-0" 140 1.0 141 12.0 290 0 0 SCALE 5 50 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1-1/2" = 1'-0" 140 1.5 141 12.0 290 0 0 SCALE 5 51 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3" = 1'-0" 140 3.0 141 12.0 290 0 0 SCALE 5 52 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 6" = 1'-0" 140 6.0 141 12.0 290 0 0 SCALE 5 53 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1'-0" = 1'-0" 140 12.0 141 12.0 290 0 0 ACDBSECTIONVIEWSTYLE 5 68 102 {ACAD_REACTORS 330 67 102 } 330 67 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 300 Imperial24 90 0 100 AcDbSectionViewStyle 70 0 71 0 90 78 71 1 340 55 62 256 40 0.24 340 0 340 0 62 256 40 0.24 300 I, O, Q, S, X, Z 40 0.48 90 3 40 0.18 90 1 71 2 340 5C 90 25 62 256 340 5C 90 50 62 256 40 0.24 40 0.0 40 0.24 71 3 340 55 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewSectionStartId>%-%<\AcVar ViewSectionEndId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 62 256 62 257 300 ANSI31 40 1.0 90 0 290 0 290 0 90 6 40 0.0 40 1.570796326794896 40 0.2617993877991494 40 1.308996938995747 40 -0.2617993877991494 40 1.832595714594046 0 TABLESTYLE 5 64 102 {ACAD_XDICTIONARY 360 656 102 } 102 {ACAD_REACTORS 330 63 102 } 330 63 100 AcDbTableStyle 280 0 3 Standard 70 0 71 0 40 0.06 41 0.06 280 0 281 0 7 Standard 140 0.18 170 2 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.25 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.18 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 0 VISUALSTYLE 5 2F 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 2dWireframe 70 4 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2E 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Basic 70 7 177 3 291 1 70 58 90 1 176 1 90 0 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 35 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Brighten 70 12 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 39 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 ColorChange 70 16 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 8 420 8421504 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 8 420 8421504 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 32 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Conceptual 70 9 177 3 291 0 70 58 90 3 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 179.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 34 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Dim 70 11 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 -50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 41 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 EdgeColorOff 70 22 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 8 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 420 0 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 38 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Facepattern 70 15 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2A 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Flat 70 0 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2B 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 FlatWithEdges 70 1 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2C 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Gouraud 70 2 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2D 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 GouraudWithEdges 70 3 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 31 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Hidden 70 6 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 40.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3F 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 JitterOff 70 20 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 10 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 420 0 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 37 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Linepattern 70 14 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 7 176 1 90 7 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 40 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 OverhangOff 70 21 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 9 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 420 0 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 33 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Realistic 70 8 177 3 291 0 70 58 90 2 176 1 90 3 176 1 90 0 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3E 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shaded 70 27 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 8 420 7895160 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3D 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shaded with edges 70 26 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3A 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shades of Gray 70 23 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3B 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Sketchy 70 24 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 11 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 6 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 36 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Thicken 70 13 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 12 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 30 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Wireframe 70 5 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3C 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 X-Ray 70 25 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 1 176 1 40 0.5 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 DICTIONARYVAR 5 351 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 1:1 0 DICTIONARYVAR 5 34D 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 34C 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 34E 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 34F 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 353 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 1 0 DICTIONARYVAR 5 354 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 15 0 DICTIONARYVAR 5 352 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 0 0 DICTIONARYVAR 5 350 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 0 0 DICTIONARY 5 1A 330 19 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 1C 3 DIFFUSETILE 360 1B 3 OPACITYTILE 360 1F 3 REFLECTIONTILE 360 1E 3 REFRACTIONTILE 360 20 3 SPECULARTILE 360 1D 0 DICTIONARY 5 12 330 11 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 14 3 DIFFUSETILE 360 13 3 OPACITYTILE 360 17 3 REFLECTIONTILE 360 16 3 REFRACTIONTILE 360 18 3 SPECULARTILE 360 15 0 DICTIONARY 5 22 330 21 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 24 3 DIFFUSETILE 360 23 3 OPACITYTILE 360 27 3 REFLECTIONTILE 360 26 3 REFRACTIONTILE 360 28 3 SPECULARTILE 360 25 0 DICTIONARY 5 656 330 64 100 AcDbDictionary 280 1 281 1 3 ACAD_ROUNDTRIP_2008_TABLESTYLE_CELLSTYLEMAP 360 657 0 XRECORD 5 1C 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1B 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1F 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1E 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 20 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1D 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 14 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 13 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 17 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 16 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 18 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 15 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 24 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 23 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 27 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 26 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 28 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 25 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 CELLSTYLEMAP 5 657 102 {ACAD_REACTORS 330 656 102 } 330 656 100 AcDbCellStyleMap 90 3 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 32768 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 55 144 0.25 309 CONTENTFORMAT_END 171 0 94 0 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 1 91 1 300 _TITLE 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 55 144 0.18 309 CONTENTFORMAT_END 171 0 94 0 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 2 91 1 300 _HEADER 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 2 62 0 340 55 144 0.18 309 CONTENTFORMAT_END 171 0 94 0 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 3 91 2 300 _DATA 309 CELLSTYLE_END 0 ENDSEC 0 SECTION 2 ACDSDATA 70 2 71 8 0 ACDSSCHEMA 90 0 1 AcDb_Thumbnail_Schema 2 AcDbDs::ID 280 10 91 8 2 Thumbnail_Data 280 15 91 0 101 ACDSRECORD 95 0 90 1 2 AcDbDs::TreatedAsObjectData 280 1 291 1 101 ACDSRECORD 95 0 90 2 2 AcDbDs::Legacy 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 3 2 AcDs:Indexable 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 4 2 AcDbDs::HandleAttribute 280 7 282 1 0 ACDSSCHEMA 90 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 ACDSSCHEMA 90 2 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 ACDSSCHEMA 90 3 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 ACDSSCHEMA 90 4 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 72 2 Thumbnail_Data 280 15 94 3606 310 89504E470D0A1A0A0000000D4948445200000100000000A50803000000840AD3BD00000300504C5445212830FFFFFF2128300000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF0000000000000000000000000000000000000000000000000000000000002E4550F100000AD14944415478DAED9DDB7ADC360C84F1FEEF3BF7BDC8AE38FF80B29D7E962269C98BA475DCD404411C6606DCAACB2CD587AF8F37C0B2803EDD16FAB8FD6BFEAFFA98F3D7D402FA94A3 310 573B697D8CFBEB75FA9A7FF9F9DBD79FD3EF57E053B6FFE7ACFB7E3F62FFAFED57BF029AF8BF9EB7FF3203607F9A6D57CFDBFF6BA3D2A4F87BBC01F4B2C0F68BA224D0B30DA03FD1FFB57D8F82DA6907F428336C5EAF9729D436F86803684481F7E1BF7ED56E3FA4079588DBA51F8960FB7D72E79F6680D7C15B22788743D5 310 9E01C4D8A0DB5F7FDBBF4624DC6F8935AECDDD0DA057D0F3F4B7D5C33303E8BD46F2BCA301D48FDF9CE09508D52D355284BC44D43D0D206BFE6D677AF584E903329B8DFFF65D3FDC37EF6DF9DFCBA0DABD03304045BAD0CD6E40855B3BF2A1392CF476125F23336ADA375EF706680BE21AFBDBDCDF6B21310C9875861124DD 310 0635D2386179DC6788DF22A17DF59D2A84AF6E15E43D0C6027EFBB6EADB0467E18DF3F5A86F1553652374A82F867CDCA5CA1D25179A10C03DC69FB3303A81C1016F76F113F0DB021881A8E7593E6072E4DFF15E12101342B868B6133E936D8B150C5BCEFF9D60D72FF16EEB7BCB07D55EFD487107283ED63EB722C00D591B7 310 C7621F60FDC2D8FEE56FC1EB902546F50CEB6E82D7D1E3775A0239F1E27760347106FFCBB76806F01A007DAFD74F337FB972E78F90A7490EE4F75863A8C81BD62E5900B8F205F03656F2F86EED8DF7054114F856C7DF4803086DF645B7AF2A5CFB8101A01218DF3F921F4A6245916CAE724537B052D532FDD6F8D7C87F7619 310 46681C6E63D71DC160408B57BC069EB98AF1CB8F8D1192316E04018DCE77DC046D7C8AAE481990F679C76B1C19208E11D0B69AC9AA4801064101AD51175D28273AEDE355CB56F3A180B16A6F34C4E34FE580B0125B9398232F51178D3374DAC7C980F45CC97D7F739871A8EDBA6FE5B4A282BC407F280F79A47D46F873AA63 310 14C706110BBC90C6252A7A0620B62B9820690FD23E2A730877E4F2E8E7B0AF5544C4C51C20F5303A01D83B3479F4FE9DF0F0A377436CF1CBCD52CE121BFEE9B97FD8766200014B3EDF00F2D6B6D13E02BE9F6DB2E11C88916269CCDA71BA1C82208FA2B3DCDFDB9A0DF2F568874EB03CCE032F0404EEDD83125D01A852492D 310 EF63CC4740DF35A17DBC700F61A0F28C06645295189A5037B9FB4F0984DCB20E8EFE5B8E6BB40F2D529EDF4877AAB92D00D2E147BBBBE44E15B4C4C1C89F00654D681F5E7D23FBE53FE1CF8E12A039551715EE53A778806CFF4EFB94036216C23BE03961BFE6776060A98AE6389976F2E93AF0ECADBF99D03E860CB423AE59 310 9CD6D48DDD5980A7A8106D81A21E1EFCEA47B48FE23B2AC42EEA0668996D800756368ECA19D5A42591C3D964049ABE9B06EFCE62DD5E3EA7310A10A2E10BA3F35009ADF3090E10675F13325CD1D9E73F55C5558850EE95A3D14284898A8DF6E82F8EAE84B45F71F0CF334D894AC922FF81EB8124C11A93F120AEDE191EA089 310 13F7BB41984BD006740F50444113D6421D11F51F0AEC405F8EF3800C546E13F88654510008B9B27AEC0E5110F2A380BCAB100A81238B78F4AFEF5B931A8E91DF51020081CE050611E03CA11389C5146FA56175A911F414BF7705E26FA2EF9A08B6931FEE9EAE08A9D843E4C81990686201D3DE0B15D9B0085BED23BBA0F26A 310 043805986F737AF77D870012F0291E22EA696B3A70A7786487B502AD139110B706B4AF6008AD7740CD509440A9A019823F089C79BB157E81EAB8FD23E9D86938004A329C45E3D00A96CBC09A52260BC24E427A99E824E2910668999D20A7835FAE8AF44E824A08A9FA90442265BC5056845AB71D94C171AD50B017EE1168E0 310 90FF58F56380320B656EC65914DC419F372530775815E4618711DCF7AF11F445F2B38A6532549213A8AC3CBE9277710B39E14E00ED8846B8A0DA7422B7880218D8A9FA5E0DDF0493211614CB48E60082003A7016D95D0D3AA7860238F759DFAAE15BEFC8B0E215EE88B48EC27B8516E2B3034280F8B314128F6747EBE9F6D5 310 F0ADE225D217C88B438BAA2E9E22C9769C053CD99722B17BA062A7E0DC61658F4CEC03F87761CA4806BB3615FEF19A4AA7EA0BDBB7E41CCC664B9C5FA8E1A3ED909AA984BA93D07A33F1818488B3F55EC11837D0045073357CC570915D6CEA4891F4CA61D1D11BBB1CB78E0C84A87CCB8FC67E8A718EC00E77D5F0AEAB055D 310 A2E050C46A802D918E2745C07023CB95E7AE4C5354C3430BE089DE815F844E20EED1358CE2E1F83123FA80C880C44F9CE8463C21209CBFC79542CD986D2E206097E344DD7C6439EC099BC894C8FA89B478BAB247EEBDD84603C02812A090D219AA89361393D32F3302FB276AF81EDB3CAE5A928751440EF60CFDD450BE5BA8 310 4E4C203090E0CD70ED2115989E7509B9DF47CC2CDA9CA40C495D405292A99B54277A29064536534C5125E75621ADB53B70A67C6E3800077C2C034EAF8232FD830A8202A89470A21AF52DAFB689B99FA48FB1C8D3AAF40AD6BC122B6A9DEC8ECCA2DD3397E62B84D9670928A34AA93851474A03FEFD420D3FA7BEC97E26F718 310 22A3B36E8072FC0F92A8F8D1BCA70D070292C7D16AD451A5404BED7F550D3F3F2906FA152D0F465FAA3EECBB34A1BE890729439C729E26C42027CC97B2F776A14A8C3E29F1390EBF886A7182F9E2F015E4F4C416831D3AE9F00392953B63FEA44AD904026891F42F4E0CC5CCD9BCBB0E51D239812FE8BA06E8A53C9CDA078C 310 96841ABE280D7628BA89A75C28A2130A604D1A63F93381D10D00A30BF82349DC16DD425E18D85FFAC909B324D25E472062BEE6C8D1B256A310C890A954A12E0C40A0F7BDE68A3A77FB0DE49023C0217E5012AB5D0D4F42201E9EF420CBD92429F431272E35051CB8DD89FA2388601AD7F37D506C22E292028D9322E00E3E5A 310 5358122C6AED68237D77224B50607E434114E16EE799CE935C80905C6A9BD42B810A892CC4D0D5F875A06A21C4FEEE929E668050252803C477CC6FC5E86C8F6DC8217BA7AD7F1004C8D21AB09F7DF10EF38B71A3E87571417E3600A0F33DC047E4F8469604C01339CC107CBC1E33D11E63DA96D2C07FBFBA845D2168F0915F 310 777947892805E8738813CEF03223933DB687A4C5A442F1B6000EBB1044013C03E4BA9801F27D1455F87A390DD4FE13BCAC01569CF45045C577A5D77438F518C783C93E95A274A83E0112F3507307B9D4FC78F062D6F5785914FD820D7C021129529E2D354C5EDEB99607B497C27CB681D46ED33D16F8D47D76E45A2160E201 310 C6EAF9CC200D10121A1A804F08B559B46B3DC59FF296E87330E5132C09852431171D89C5BBECAB3900B27B8AC4BD36267096F0A14702C602CA108F9580FEBF34E828B9F80E6A84B8D0C756BCB335354010AF357D8AF20A06988A3551C8CCB0644B1C7DF07EC68EE8626FEAA953251487A97A4F3F796CD6C135C57C503C9671 310 DDE7B4829BDD1D5F8A2701E403103153E5D335B841573540E9275A657F56D00B65764DDE4E4A670D44FFFEBDD8A7D5F28925E5749CFBC7E9DCF7C1D44A80E4B17D3EA50A16FE091FB880FDF0F1B5AAD600544D3E8FE4EE06C81931A2E83E0E10BCCBFDFDBFAA7FDC9A889EA1F46DEF6C3DE10ECCC61DB726A9BD3618EFF2D5 310 E3AE00E66B85F767DB8353F51C03B48A08A2378C57DEED51E9BF2A131C2C76DD77710AF24EEFAAFFAD01381E335308B89CFC710600D1998C5F3CA2F09C8F1E532F8A82EEEEA0D3931CA07FBCD4D70D8E1E5300ED18E0874F3E3DC8049AB486BFD265DE32067CF8A7AE7FFC87CEAFB5D65A6BADB5D65A6BADB5D65A6BADB5D6 310 5A6BADB5D65A6BADB5D65A6BADB5D65A6BADB5D65A6BADB5D65A07AEFF00554FE27454DCB1F00000000049454E44AE426082 0 ENDSEC 0 EOF ================================================ FILE: testdata/barnsbury_extended1_axial.csv ================================================ Ref,x1,y1,x2,y2,Connectivity,Line Length 0,530635.696268,184468.675646,530732.377854,183731.866556,8,743.12512 1,530655.080407,184267.843134,531386.664678,184568.766995,9,791.0567 2,530781.419478,184322.997346,530814.78724,184178.968574,4,147.84348 3,530667.76131,184203.901437,531124.686107,184392.857349,5,494.45386 4,530798.725861,184207.390438,530856.762846,184149.487013,3,81.982307 5,530747.870324,184145.998012,530810.755405,184207.340453,3,87.848892 6,530753.938689,184164.022852,530781.427723,183967.049235,3,198.88251 7,530638.070845,184123.954322,531070.977779,184116.826362,7,432.96561 8,530837.494138,183967.908989,530855.674498,184153.675814,3,186.65433 9,530776.925919,183970.168342,530838.112518,183968.488823,3,61.209644 10,530803.879024,183673.983124,530817.351454,183970.908131,5,297.2305 11,530803.31836,183742.403539,530916.415863,183745.002795,2,113.12737 12,530912.186147,183663.646083,530932.996681,184479.606956,10,816.2262 13,530995.213912,184191.1051,531426.867596,184272.091918,4,439.18533 14,530992.995991,184260.565217,531006.303519,184067.090599,2,193.93173 15,531065.503058,184264.454104,531069.386482,184200.262479,3,64.308983 16,531014.260003,184282.658893,531076.262863,184252.777446,2,68.827721 17,531055.856337,184254.05708,531446.820644,184352.768824,4,403.23331 18,531101.674141,184455.949289,531227.444303,184068.530187,8,407.3226 19,531214.16151,184067.600453,531445.270572,184127.80322,7,238.82162 20,531166.28244,183883.173244,531225.605654,184081.636435,7,207.13977 21,531103.958023,183944.145791,531189.244935,183939.966987,1,85.389229 22,531199.126896,184509.586323,531222.402703,184422.521245,2,90.122643 23,531332.577077,184583.962646,531443.794706,184125.074001,10,472.17386 24,531026.454449,184114.297086,531441.626255,184200.71235,6,424.06982 25,531379.087467,183726.907975,531438.204555,184206.79061,11,483.51025 26,531367.365093,183473.836019,531409.569458,184011.596484,10,539.41406 27,531287.1303,183716.111065,531396.253684,183759.488649,5,117.42882 28,531294.394199,183777.773415,531391.413833,183726.268158,5,109.84353 29,531303.999695,183967.539095,531311.931444,183765.686875,4,202.008 30,531069.774,183880.95388,531403.294966,183913.414588,9,335.09689 31,531055.773886,183973.477395,531081.160429,183854.721389,3,121.43914 32,530979.070082,183853.471746,531006.056167,183971.198048,2,120.77968 33,531002.370625,183965.559662,531057.760946,183972.597647,2,55.835659 34,530675.049944,183881.16382,531237.536258,183892.420597,10,562.59894 35,531246.803707,183901.647956,531247.100529,183877.364907,1,24.284863 36,531378.13104,184039.148597,531423.297484,184035.389673,2,45.32259 37,531365.837654,184048.645878,531385.988583,184035.489644,2,24.065462 38,531360.008395,184112.477607,531368.607994,184041.148025,2,71.8461 39,531176.638237,183932.709065,531212.594948,183499.852969,6,434.34695 40,531191.28971,183523.406227,531385.782456,183575.241389,4,201.28168 41,530904.180192,183681.79089,531226.595062,183515.558473,5,362.74588 42,531087.294754,183504.461649,531157.699331,183893.960157,3,395.81042 43,531029.208299,183891.140964,531030.230687,183855.631128,1,35.524551 44,531182.681866,183748.751722,531275.851057,183743.153325,3,93.337242 45,531240.760077,183741.113908,531312.920852,183782.89195,4,83.382149 46,531238.319539,183754.010217,531308.056265,183714.501526,4,80.15078 47,531293.948966,183547.909213,531303.282375,183726.188181,3,178.52312 48,530707.321114,183575.611283,530731.660534,183750.551207,2,176.62498 49,530711.864142,183690.118506,530973.265559,183658.367594,4,263.32266 50,531139.131454,184142.888902,531154.533228,184098.471616,2,47.011806 51,531091.400795,184089.16428,531155.786477,184099.901207,1,65.274788 52,531060.226219,184127.683254,531065.651469,184023.503075,3,104.32134 53,530915.104898,184035.689587,531213.139122,184017.404821,3,298.5946 54,531281.498924,184088.374506,531294.732247,184020.813845,2,68.84449 55,531263.310319,184015.655322,531322.328466,184027.032065,3,60.104675 56,531267.276193,184023.293136,531279.998323,183953.103227,2,71.333557 57,531276.790994,183954.982689,531332.164824,183964.220045,3,56.139023 58,531315.938544,184033.420237,531330.606508,183957.32202,2,77.498955 59,530805.297175,183814.47291,530917.998915,183816.172423,2,112.71455 60,531137.25158,184338.103022,531389.731841,184417.270361,2,264.6011 61,531482.315148,184748.987159,531515.68291,184604.958387,3,147.84348 62,531368.65698,184629.89125,531825.581777,184818.847162,4,494.45386 63,531499.621531,184633.380251,531557.658516,184575.476826,3,81.982307 64,531448.765994,184571.987825,531511.651075,184633.330266,3,87.848892 65,531455.263586,184588.241656,531482.75262,184391.268039,3,198.88251 66,531253.867502,184551.34532,531771.873449,184542.816175,8,518.07617 67,531538.389808,184393.898802,531556.570168,184579.665627,3,186.65433 68,531477.821589,184396.158155,531539.008188,184394.478636,3,61.209644 69,531504.774694,184099.972937,531518.247124,184396.897944,5,297.2305 70,531504.21403,184168.393352,531617.311533,184170.992608,2,113.12737 71,531613.081817,184089.635896,531633.892351,184844.909702,11,755.56042 72,531696.109582,184617.094913,532336.825597,184713.631764,7,647.94781 73,531693.891661,184686.55503,531707.199189,184493.080412,3,193.93173 74,531766.398728,184690.443917,531770.282152,184626.252292,3,64.308983 75,531715.155673,184708.648706,531777.158533,184678.767259,2,68.827721 76,531756.752007,184680.046893,531893.049669,184714.459702,3,140.57487 77,531802.569811,184881.939102,531928.339973,184494.52,7,407.3226 78,531915.05718,184493.590266,532146.166242,184553.793033,5,238.82162 79,531867.17811,184309.163057,531926.501324,184507.626248,7,207.13977 80,531804.853693,184370.135604,531890.140605,184365.9568,1,85.389229 81,531914.954989,184937.248897,531938.230796,184850.183819,1,90.122643 82,531727.350119,184540.286899,532142.521925,184626.702163,5,424.06982 83,531988.02597,184142.100878,532097.149354,184185.478462,4,117.42882 84,531995.289869,184203.763228,532092.309503,184152.257971,4,109.84353 85,532004.895365,184393.528908,532012.827114,184191.676688,4,202.008 86,531770.66967,184306.943693,532197.700686,184339.404401,9,428.263 87,531756.669556,184399.467208,531782.056099,184280.711202,3,121.43914 88,531679.965752,184279.461559,531706.951837,184397.187861,2,120.77968 89,531703.266295,184391.549475,531758.656616,184398.58746,2,55.835659 90,531375.945614,184307.153633,531938.431928,184318.41041,10,562.59894 91,531947.699377,184327.637769,531947.996199,184303.35472,1,24.284863 92,532079.02671,184465.13841,532156.350838,184461.379486,1,77.415443 93,532066.733324,184474.635691,532086.884253,184461.479457,2,24.065462 94,532060.904065,184538.46742,532069.503664,184467.137838,2,71.8461 95,531877.533907,184358.698878,531913.490618,184005.483699,5,355.04062 96,531605.075862,184107.780703,531784.325886,184010.332886,5,204.02609 97,531761.919063,183988.762648,531858.595001,184319.94997,5,345.00909 98,531730.103969,184317.130777,531731.126357,184281.620941,1,35.524551 99,531883.577536,184174.741535,531976.746727,184169.143138,3,93.337242 100,531941.655747,184167.103721,532013.816522,184208.881763,4,83.382149 101,531939.215209,184180.00003,532008.951935,184140.491339,4,80.15078 102,531994.844636,184026.539839,532004.178045,184152.177994,3,125.98436 103,531409.165843,184133.61755,531674.161229,184084.357407,7,269.535 104,531840.027124,184568.878715,531855.428898,184524.461429,2,47.011806 105,531792.296465,184515.154093,531856.682147,184525.89102,1,65.274788 106,531761.121889,184553.673067,531766.547139,184449.492888,3,104.32134 107,531616.000568,184461.6794,531914.034792,184443.394634,3,298.5946 108,531982.394594,184514.364319,531995.627917,184446.803658,2,68.84449 109,531964.205989,184441.645135,532023.224136,184453.021878,3,60.104675 110,531968.171863,184449.282949,531980.893993,184379.09304,2,71.333557 111,531977.686664,184380.972502,532033.060494,184390.209858,3,56.139023 112,532016.834214,184459.41005,532031.502178,184383.311833,2,77.498955 113,531506.192845,184240.462723,531618.894585,184242.162236,2,112.71455 114,531838.14725,184764.092835,532090.627511,184843.260174,3,264.6011 115,531898.14101,185489.577346,532384.945646,183588.377395,18,1962.5341 116,532034.570496,184072.765934,532153.818761,183879.247573,2,227.30927 117,531848.44415,184056.30916,531872.755533,183888.256031,4,169.80252 118,531400.054039,183972.757185,532184.244392,184077.342903,11,791.13379 119,531934.003528,183974.894229,532082.780772,183561.676249,4,439.18533 120,531813.343861,183944.172569,532002.221345,183988.159089,2,193.93173 121,531954.870458,183903.130736,532017.621625,183917.199738,3,64.308983 122,532007.80999,183904.715765,532027.422876,183970.689929,2,68.827721 123,532005.819462,183925.065251,532165.607001,183554.842291,4,403.23331 124,531850.025607,183726.090547,532215.340633,183914.50679,8,411.04227 125,531846.989846,183739.055158,531943.272396,183520.502093,6,238.82162 126,531657.287906,183756.915025,531862.671007,183729.995445,7,207.13977 127,531707.542847,183828.164062,531717.01638,183743.301986,1,85.389229 128,531940.34277,183521.523908,532612.061879,183803.786692,10,728.61432 129,531863.159436,183931.80645,532014.667663,183535.72504,6,424.06982 130,531536.953309,183521.916305,532020.122575,183540.072134,8,483.51025 131,531322.823096,183496.217515,531822.859891,183537.217461,5,501.71484 132,531511.632096,183610.975442,531571.854282,183510.164649,5,117.42882 133,531538.287099,183509.645622,531573.66377,183613.636448,5,109.84353 134,531564.528151,183594.396389,531762.533216,183634.411704,4,202.008 135,531647.800083,183818.5796,531724.933652,183527.756719,8,300.87793 136,531562.202013,183850.065477,531683.634527,183848.796579,2,121.43914 137,531554.551076,183899.243828,531664.561818,183949.097288,2,120.77968 138,531559.344147,183903.976806,531563.459261,183848.292996,2,55.835659 139,531576.977884,184241.542411,531576.980112,184241.530177,1,0.012435302 140,531664.440206,183676.204772,531688.365256,183680.369694,1,24.284863 141,531845.046699,183572.646808,531848.537589,183527.458858,2,45.32259 142,531842.687431,183564.306378,531852.462311,183586.297243,2,24.065462 143,531845.502111,183582.366824,531914.547926,183602.2298,2,71.8461 144,531365.756011,183674.793817,531707.841194,183754.590132,5,351.26874 145,531374.060775,183774.507149,531666.56825,183767.108281,4,292.60104 146,531608.404903,183886.834614,531643.297417,183893.505914,1,35.524551 147,531527.201005,183719.292094,531536.529925,183626.42223,3,93.337242 148,531528.921394,183660.739083,531581.670868,183596.162963,4,83.382149 149,531513.379763,183590.060561,531541.26357,183665.204695,4,80.15078 150,531346.669404,183577.424472,531524.155712,183596.636795,3,178.52312 151,531867.958408,183802.842932,531909.351639,183825.129931,2,47.011806 152,531848.703773,183863.683623,531869.569538,183801.833663,1,65.274788 153,531779.776929,183878.633935,531881.759204,183900.601153,3,104.32134 154,531767.803098,184029.197571,531797.273386,183732.060846,5,298.5946 155,531813.648701,183652.055167,531878.234973,183675.891635,2,68.84449 156,531803.545994,183682.252572,531824.187543,183625.803494,3,60.104675 157,531744.455054,183655.80423,531811.718445,183679.555275,2,71.333557 158,531745.799066,183659.270202,531763.747518,183606.077695,3,56.139023 159,531756.689274,183606.516194,531829.475123,183633.130249,2,77.498955 160,532101.768494,183858.112362,532220.180595,183621.485389,2,264.6011 161,531603.201562,184097.54814,531677.778268,183688.047288,9,416.23627 162,530283.954463,184816.224091,530735.913127,184226.335686,8,743.12512 163,530031.188827,184139.955564,532155.727239,185032.528489,15,2304.4197 164,530658.07799,184557.915926,530736.182459,184432.387497,4,147.84348 165,530571.605016,184436.422319,531028.529813,184625.378231,5,494.45386 166,530666.7819,184526.451467,530666.970866,184608.433553,3,81.982307 167,530587.419247,184533.993682,530675.26257,184534.983211,3,87.848892 168,530484.78534,184684.376675,530604.445957,184525.51954,3,198.88251 169,530494.120564,184472.048499,530795.550319,184782.852818,7,432.96561 170,530525.083202,184723.367243,530669.158913,184604.69952,3,186.65433 171,530483.801413,184678.989008,530525.930499,184723.393522,3,61.209644 172,530293.689137,184907.701657,530512.942029,184707.017488,5,297.2305 173,530341.616956,184858.869376,530423.516952,184936.909058,2,113.12737 174,530363.061129,184991.515821,530950.638138,184434.164686,10,809.86853 175,530794.377847,184676.757956,531157.155075,184924.298761,4,439.18533 176,530714.63809,184772.38299,530841.86679,184626.019141,2,193.93173 177,530853.353986,184722.66267,530895.942795,184674.477205,3,64.308983 178,530872.524608,184625.397132,530895.312774,184690.342917,2,68.827721 179,530881.770348,184675.02409,531228.261643,184881.278496,4,403.23331 180,530872.205195,184927.553625,531056.800416,184564.460939,8,407.3226 181,530862.145357,184918.830286,531068.273127,185039.441704,7,238.82162 182,530697.991446,185015.573733,530880.160401,184916.976808,7,207.13977 183,530696.935008,184928.390774,530754.360003,184991.58642,1,85.389229 184,531185.28388,184712.955635,531230.299717,184634.880893,1,90.122643 185,531065.300707,185040.331386,531310.676276,184636.92219,8,472.17386 186,530762.244887,184753.196919,531117.1883,184985.253807,6,424.06982 187,530857.793097,185213.727228,531119.059025,184978.53416,7,351.53329 188,530551.230991,185447.375269,530733.983907,185290.855505,6,240.61809 189,530348.818115,184670.043145,530754.964885,185059.353265,7,562.59894 190,530751.101941,185076.766671,530768.042714,185059.366534,0,24.284863 191,530958.127638,185054.782177,530999.561686,185101.458496,2,62.413612 192,530956.132728,185039.376138,530961.105876,185062.922141,2,24.065462 193,530952.798246,185046.640697,530997.089847,184990.071126,2,71.8461 194,530292.86417,185138.907267,530369.446508,185353.216185,2,227.58112 195,530279.260644,185168.084421,530370.209055,184973.016186,4,215.22832 196,530155.854559,184909.143223,530296.643458,184802.490186,2,176.62498 197,530239.94609,184831.289787,530402.572415,185038.392418,5,263.32266 198,530841.737233,184854.861003,530862.205515,184812.538912,2,47.011806 199,530790.470732,184816.859996,530843.634143,184854.734123,1,65.274788 200,530725.866309,184845.156464,530795.607182,184767.573259,3,104.32134 201,530627.898364,184730.199677,530825.968862,184953.642755,4,298.5946 202,530886.13816,185008.857925,530924.487493,184951.683697,2,68.84449 203,530860.25048,184990.316729,530910.065992,185023.946875,3,60.104675 204,530827.884295,185046.385296,530868.452527,184987.710817,2,71.333557 205,530826.941205,185042.789476,530872.665797,185075.360191,3,56.139023 206,530866.690618,185079.142828,530910.054337,185014.911405,3,77.498955 207,531280.890316,184879.402502,531418.783795,184696.340072,3,229.18652 208,531365.823685,184738.325775,531592.602283,184976.32175,6,328.74097 209,531322.135167,184916.836174,531466.210877,184798.168452,2,186.65433 210,531280.853377,184872.45794,531322.982463,184916.862454,3,61.209644 211,531090.741101,185101.170589,531309.993993,184900.48642,4,297.2305 212,531234.61837,185110.479476,531708.28843,184665.008406,9,650.23676 213,531591.429811,184870.226888,531810.671873,185019.826566,3,265.41882 214,531511.690054,184965.851921,531638.918754,184819.488073,3,193.93173 215,531650.40595,184916.131602,531692.994759,184867.946136,3,64.308983 216,531669.576573,184818.866063,531692.364738,184883.811849,3,68.827721 217,531678.822312,184868.493022,532025.313608,185074.747427,4,403.23331 218,531669.25716,185121.022557,531803.886243,184855.964934,6,297.28864 219,531659.197321,185112.299218,531865.325091,185232.910635,4,238.82162 220,531525.017578,185192.81948,531677.212366,185110.445739,6,173.05688 221,531361.980864,184957.783264,531551.411968,185185.055352,4,295.86609 222,531559.296851,184946.66585,531914.240265,185178.722739,4,424.06982 223,531495.587084,185514.328262,531683.190124,185202.326857,6,364.06012 224,531462.599703,185412.663349,531570.487702,185459.028287,4,117.42882 225,531511.293539,185374.141666,531543.598132,185479.127446,4,109.84353 226,531145.870079,184863.512077,531379.525038,185080.330385,4,318.7551 227,531313.34303,185456.733951,531364.882898,185058.167136,5,401.88538 228,531306.054288,185343.694337,531471.261897,185366.875736,4,166.82605 229,531447.432504,185362.212424,531528.024132,185383.603353,4,83.382149 230,531454.813342,185351.359118,531476.276843,185428.582597,4,80.15078 231,531385.807059,185499.287467,531481.151482,185416.937606,3,125.98436 232,531046.820419,185009.825167,531131.431446,185132.77165,5,149.24767 233,531638.789198,185048.329935,531659.257479,185006.007844,2,47.011806 234,531587.522697,185010.328928,531640.686107,185048.203055,1,65.274788 235,531522.918273,185038.625395,531592.659147,184961.042191,3,104.32134 236,531424.950328,184923.668608,531623.020826,185147.111687,3,298.5946 237,531683.190124,185202.326857,531721.539458,185145.152628,2,68.84449 238,531522.475126,185175.01268,531707.117957,185217.415806,4,189.4492 239,531190.971716,185002.716462,531271.956062,185081.113568,2,112.71455 240,531383.970056,186031.229354,531510.979479,185470.505352,6,574.92853 241,531394.31707,185715.840841,531446.57893,185494.621034,2,227.30927 242,531201.708933,185510.951124,531303.192797,185374.811772,3,169.80252 243,531179.130486,185309.154054,531945.523583,185894.409458,13,964.30402 244,531119.729967,185890.482946,531306.259495,185492.876981,4,439.18533 245,531199.143477,185429.404668,531363.921212,185531.668132,2,193.93173 246,531270.345734,185558.418033,531324.705449,185592.778869,3,64.308983 247,531308.942264,185594.686673,531369.423608,185561.834543,2,68.827721 248,531173.537681,185953.820275,531321.905785,185578.874941,4,403.23331 249,531071.081902,185609.697629,531458.962707,185734.036583,8,407.3226 250,530991.888039,185821.097506,531078.08961,185598.37557,6,238.82162 251,530956.409773,185451.747407,531082.791848,185615.8646,7,207.13977 252,530989.078083,185503.570056,531042.308887,185436.803289,1,85.389229 253,530990.535791,185818.304973,531427.908644,185996.218258,7,472.17386 254,531053.182121,185860.746689,531225.67492,185473.343204,5,424.06982 255,530705.244826,185533.116831,531060.114084,185861.522043,8,483.51025 256,530721.65189,185566.086325,530750.221062,185452.185798,4,117.42882 257,530697.522371,185542.745556,530796.014069,185494.11443,4,109.84353 258,530775.957685,185501.282477,530944.392205,185612.803972,4,202.008 259,530842.445203,185661.751105,530993.246275,185401.392558,7,300.87793 260,530866.53772,185054.496792,530910.763225,185339.341033,5,288.25708 261,531241.837484,185051.9572,531241.844548,185051.946966,1,0.012435302 262,530922.274679,185514.972524,531058.699701,185297.133443,5,257.03241 263,530904.468114,185513.935543,530924.34682,185527.885154,1,24.284863 264,530929.736723,185749.262318,530959.18129,185714.807208,2,45.32259 265,530951.620343,185719.045249,530974.072142,185710.381351,2,24.065462 266,530966.368846,185708.247852,531029.276911,185742.952862,2,71.8461 267,530692.026577,185303.976423,530990.555487,185489.098583,6,351.26874 268,530835.94378,185306.864232,530970.178935,185451.086004,3,197.02538 269,530668.7796,185311.512872,531368.109166,185350.571812,10,700.41949 270,530778.756701,185458.835796,530837.745708,185386.502282,3,93.337242 271,530789.341101,185512.139628,530797.608142,185429.168318,4,83.382149 272,530736.68628,185468.226257,530809.499457,185434.724184,4,80.15078 273,530609.743661,185359.425586,530748.959542,185471.181754,4,178.52312 274,531137.98644,185568.028734,531183.03071,185581.486954,2,47.011806 275,531138.414156,185569.881144,531167.326902,185511.35892,2,65.274788 276,531037.954234,185568.212706,531226.956583,185337.048601,4,298.5946 277,530905.703102,185592.17185,531055.596881,185665.158545,2,166.71893 278,531259.240929,185945.187025,531342.541952,185694.040277,2,264.6011 279,530564.955234,184893.47949,530687.494969,184780.983957,2,166.34673 280,530406.734043,184768.71716,530476.74297,184939.450519,2,184.52948 281,531070.732747,185471.568523,531173.366327,185528.106492,2,117.17591 282,531054.947555,184568.105455,531230.772586,184476.728485,3,198.15195 283,533270.701887,183269.704674,533995.226148,183104.47889,8,743.12512 284,533457.921448,183355.764288,533604.573756,183337.034753,3,147.84348 285,533511.624314,183701.926679,533530.131552,183207.819313,5,494.45386 286,533572.342952,183331.843845,533646.798158,183366.158863,3,81.982307 287,533576.567617,183343.107265,533612.252246,183262.832514,3,87.848892 288,533597.456849,183274.783083,533791.716865,183232.153296,3,198.88251 289,533594.791129,183152.211723,533751.821496,183555.697392,7,432.96561 290,533642.492107,183366.593004,533810.382168,183285.028513,3,186.65433 291,533787.228453,183229.014949,533810.053185,183285.809776,3,61.209644 292,533800.574266,183267.181171,534074.33864,183151.426975,5,297.2305 293,534009.982255,183174.663224,534046.822896,183281.623817,2,113.12737 294,533363.7017,183552.296365,534121.646703,183249.402658,10,816.2262 295,533655.853794,183510.445932,533729.818734,183943.358112,4,439.18533 296,533589.946866,183532.48916,533776.00052,183477.77576,2,193.93173 297,533611.481324,183601.833701,533673.02611,183583.182025,3,64.308983 298,533576.613253,183560.102626,533626.168001,183607.868539,2,68.827721 299,533617.880948,183589.176602,533661.093042,183990.08783,4,403.23331 300,533444.467532,183702.258531,533851.451454,183685.651865,7,407.3226 301,533847.710281,183672.872952,533871.517605,183910.504985,7,238.82162 302,533838.522437,183688.479385,534004.029918,183563.923552,7,207.13977 303,533925.207623,183526.653856,533958.745975,183605.180913,1,85.389229 304,533207.325575,183960.304964,533517.743221,183803.863123,4,347.61066 305,533404.613467,183963.247494,533873.564387,183908.173141,9,472.17386 306,533738.730645,183513.06696,533801.880965,183932.408424,6,424.06982 307,533794.992702,183931.310648,534224.474603,183709.212763,11,483.51025 308,533968.092403,183836.668115,534457.72329,183610.329606,10,539.41406 309,534199.883601,183736.62557,534202.663279,183619.229654,5,117.42882 310,534147.361737,183647.456398,534229.355471,183720.549685,5,109.84353 311,533972.743724,183722.368537,534164.786549,183659.704473,4,202.008 312,533972.594317,183472.65139,534057.983991,183796.686166,9,335.09689 313,533880.967657,183491.655579,534001.148439,183474.218692,3,121.43914 314,533865.838452,183444.240875,533966.864912,183378.048841,2,120.77968 315,533869.845916,183438.826556,533882.48274,183493.213425,2,55.835659 316,533835.312059,183102.569364,534020.104195,183633.953815,10,562.59894 317,534014.669713,183645.849032,534037.544378,183637.694015,1,24.284863 318,533931.336857,183816.755233,533950.547856,183857.804894,2,45.32259 319,533918.1613,183808.525385,533937.496942,183822.85296,2,24.065462 320,533856.278232,183825.227352,533926.154582,183808.519327,2,71.8461 321,533961.173903,183590.83827,534379.574955,183474.228476,6,434.34695 322,534350.088555,183462.429267,534369.026017,183662.818101,4,201.28168 323,534101.850875,183248.196611,534369.70918,183492.811601,5,362.74588 324,533990.933559,183559.620921,534331.737103,183358.328008,3,395.81042 325,533948.953082,183438.148567,533982.60772,183426.774957,1,35.524551 326,534135.779962,183532.618397,534173.387016,183618.044094,3,93.337242 327,534148.995999,183666.60752,534163.112597,183584.429032,4,83.382149 328,534150.171418,183586.619216,534211.440101,183638.294124,4,80.15078 329,534198.822923,183637.876087,534362.763695,183567.208368,3,178.52312 330,533977.45538,183110.29529,534133.053441,183026.715223,2,176.62498 331,534027.251348,183070.743173,534147.809166,183304.847068,4,263.32266 332,533751.050565,183628.660294,533798.052098,183627.677537,2,47.011806 333,533784.854581,183565.242321,533797.146736,183629.349268,1,65.274788 334,533737.906423,183549.385586,533837.486192,183518.291973,3,104.32134 335,533773.77426,183381.348296,533894.426477,183654.481548,3,298.5946 336,533851.615179,183743.233739,533919.566465,183732.179943,2,68.84449 337,533913.491248,183700.922309,533923.319298,183760.218021,3,60.104675 338,533907.706166,183707.293901,533977.945511,183694.847607,2,71.333557 339,533975.069147,183692.492641,533985.637771,183747.627875,3,56.139023 340,533915.109567,183756.444407,533991.565242,183743.77091,2,77.498955 341,533943.085985,183201.548147,533980.63292,183307.825135,2,112.71455 342,533567.334441,183694.694167,533580.779713,183958.953461,2,264.6011 343,533281.590018,184813.90419,533299.34,184222.454929,10,591.71558 344,533203.504476,184131.512968,533448.516179,184142.247827,6,245.24675 345,533355.566737,184507.139752,533425.55373,183189.45307,10,1319.5439 346,533416.285375,184137.056918,533490.740581,184171.371937,3,81.982307 347,533420.51004,184148.320338,533456.19467,184068.045587,3,87.848892 348,533443.209115,184079.783606,533637.469131,184037.153819,3,198.88251 349,533407.865187,183878.109292,533595.763919,184360.910466,7,518.07617 350,533486.43453,184171.806078,533654.324591,184090.241587,3,186.65433 351,533631.170876,184034.228023,533653.995608,184091.022849,3,61.209644 352,533644.516689,184072.394244,533918.281063,183956.640049,5,297.2305 353,533853.924678,183979.876298,533890.765319,184086.836891,2,113.12737 354,533264.553798,184336.433171,533965.589126,184054.615732,11,755.56042 355,533499.796217,184315.659006,533573.761157,184748.571185,5,439.18533 356,533433.88929,184337.702234,533619.942943,184282.988833,3,193.93173 357,533455.423747,184407.046775,533516.968533,184388.395099,3,64.308983 358,533420.555676,184365.315699,533470.110424,184413.081613,2,68.827721 359,533461.823371,184394.389676,533505.035465,184795.300904,4,403.23331 360,533288.409955,184507.471605,533695.393878,184490.864939,8,407.3226 361,533691.652704,184478.086026,533715.460028,184715.718059,7,238.82162 362,533682.46486,184493.692459,533847.972341,184369.136626,7,207.13977 363,533769.150046,184331.86693,533802.688398,184410.393987,1,85.389229 364,533280.174611,184638.111522,533369.903983,184629.701356,2,90.122643 365,533248.55589,184768.460568,533717.50681,184713.386214,11,472.17386 366,533582.673068,184318.280034,533645.823388,184737.621498,6,424.06982 367,533638.935125,184736.523722,534121.003937,184485.225527,11,543.63696 368,534043.826024,184541.838644,534046.605702,184424.442728,4,117.42882 369,533991.30416,184452.669472,534073.297894,184525.762759,4,109.84353 370,533816.686147,184527.581611,534008.728972,184464.917547,4,202.008 371,533816.53674,184277.864464,533901.926415,184601.899239,9,335.09689 372,533724.91008,184296.868652,533845.090862,184279.431766,3,121.43914 373,533709.780875,184249.453948,533810.807335,184183.261915,2,120.77968 374,533713.788339,184244.03963,533726.425163,184298.426499,2,55.835659 375,533679.254482,183907.782438,533864.046618,184439.166889,10,562.59894 376,533858.612136,184451.062105,533881.486801,184442.907089,1,24.284863 377,533775.27928,184621.968307,533794.490279,184663.017968,2,45.32259 378,533762.103724,184613.738458,533781.439365,184628.066033,2,24.065462 379,533700.220655,184630.440425,533770.097005,184613.732401,2,71.8461 380,533805.116326,184396.051343,534148.833614,184307.10038,5,355.04062 381,533945.793298,184053.409685,534099.428093,184187.659445,5,204.02609 382,533834.875982,184364.833995,534111.873958,184159.156088,5,345.00909 383,533792.895505,184243.361641,533826.550144,184231.988031,1,35.524551 384,533979.722385,184337.831471,534017.329439,184423.257168,3,93.337242 385,533992.938422,184471.820594,534007.05502,184389.642106,4,83.382149 386,533994.113841,184391.83229,534055.382524,184443.507198,4,80.15078 387,534042.765346,184443.089161,534157.341868,184390.703292,3,125.98436 388,533853.526216,183878.666834,533991.751589,184110.060142,6,269.535 389,533594.992988,184433.873368,533641.994521,184432.89061,2,47.011806 390,533628.797004,184370.455395,533641.089159,184434.562341,1,65.274788 391,533581.848846,184354.59866,533681.428615,184323.505047,3,104.32134 392,533617.716683,184186.56137,533738.368901,184459.694622,3,298.5946 393,533695.557602,184548.446813,533763.508888,184537.393017,2,68.84449 394,533757.433671,184506.135383,533767.261721,184565.431094,3,60.104675 395,533751.648589,184512.506975,533821.887935,184500.060681,2,71.333557 396,533819.011571,184497.705715,533829.580194,184552.840948,3,56.139023 397,533759.05199,184561.657481,533835.507666,184548.983984,2,77.498955 398,533787.028409,184006.76122,533824.575343,184113.038209,3,112.71455 399,533411.276864,184499.907241,533424.722136,184764.166535,3,264.6011 400,534079.043875,184492.516695,534641.721189,184610.571934,10,574.92853 401,534078.581459,184263.75404,534244.617529,184228.188309,4,169.80252 402,534001.209547,183814.256308,534167.642419,184551.258139,11,755.56042 403,534184.643095,184315.712944,534623.810302,184321.836821,4,439.2099 404,534171.548117,184191.894135,534195.895544,184384.291435,2,193.93173 405,534259.186721,184310.35799,534267.786545,184374.08937,3,64.308983 406,534221.029704,184401.857388,534276.085944,184360.552837,2,68.827721 407,534256.311788,184365.753465,534658.98396,184387.018927,4,403.23331 408,534340.296458,184554.97902,534388.795247,184150.554043,7,407.3226 409,534375.5833,184152.209774,534613.971169,184166.597117,5,238.82162 410,534292.952711,183980.51823,534389.525079,184163.768494,7,207.13977 411,534243.591734,184052.389493,534326.461777,184031.801248,1,85.389229 412,534523.654664,184592.936178,534529.659313,184503.013793,1,90.122643 413,534200.445183,184234.314318,534624.49092,184238.835314,5,424.06982 414,534471.532711,183786.060015,534606.990485,184209.222433,7,444.31436 415,534421.265724,183576.333035,534556.477661,184059.484692,5,501.71484 416,534379.22304,183793.244614,534494.673805,183814.707337,5,117.42882 417,534398.270908,183852.339354,534483.502838,183783.049247,5,109.84353 418,534413.140645,183837.090409,534444.382051,184036.667977,4,202.008 419,534231.831306,183993.036716,534531.340314,183964.368091,8,300.87793 420,534172.577514,183923.701456,534215.940242,184037.13487,2,121.43914 421,534115.258786,184054.083176,534123.803083,183933.6061,2,120.77968 422,534121.029309,183939.744568,534174.676304,183924.264876,2,55.835659 423,533810.59916,184073.5153,533810.611406,184073.513141,1,0.012435302 424,533954.738015,184048.098338,534364.650043,183975.815827,8,416.23627 425,534371.123204,183959.195139,534375.526555,183983.077456,1,24.284863 426,534530.958921,184092.594917,534574.546569,184080.175007,2,45.32259 427,534520.73354,184104.289671,534537.960852,184087.485916,2,24.065462 428,534522.002078,184096.397688,534527.354661,184168.044127,2,71.8461 429,534268.71504,183678.612162,534312.689759,184027.117468,5,351.26874 430,534178.09244,183721.02987,534286.616931,183992.760989,4,292.60104 431,534154.143024,183979.798213,534160.00494,184014.835788,1,35.524551 432,534283.055419,183845.462203,534373.38459,183821.957288,3,93.337242 433,534338.56135,183826.740385,534417.437595,183853.779619,4,83.382149 434,534338.660061,183839.865219,534399.443055,183787.619882,4,80.15078 435,534353.39508,183626.897766,534397.018576,183800.008983,3,178.52312 436,534316.524037,184240.583205,534323.048179,184194.026299,2,47.011806 437,534259.30742,184197.099766,534324.554163,184195.186633,1,65.274788 438,534221.349777,184137.655347,534236.167736,184240.918947,3,104.32134 439,534075.999349,184178.716694,534364.876021,184103.158771,5,298.5946 440,534445.588895,184090.729314,534445.666539,184159.57376,2,68.84449 441,534413.76248,184091.742822,534473.866644,184091.495124,3,60.104675 442,534418.042635,184027.144569,534419.130132,184098.469833,2,71.333557 443,534415.259165,184029.608637,534471.374163,184027.966459,3,56.139023 444,534468.511671,184021.499835,534468.83228,184098.998125,2,77.498955 445,534352.419821,184432.477914,534615.442074,184461.340417,3,264.6011 446,532822.628275,183060.558178,533532.762428,183279.520388,8,743.12512 447,533311.003242,183772.13925,533342.10287,183213.502392,5,559.50183 448,533194.789303,183321.685907,533339.629599,183351.33356,4,147.84348 449,533234.487353,184185.811657,533278.689124,183198.40131,9,988.39923 450,533150.504528,183347.569737,533227.318113,183318.920628,3,81.982307 451,533192.683163,183247.117175,533222.262704,183329.836454,3,87.848892 452,533016.016412,183203.098735,533206.54312,183260.141057,3,198.88251 453,533031.59668,183528.720721,533218.370549,183138.112551,7,432.96561 454,532993.447981,183254.429505,533154.766037,183348.324784,3,186.65433 455,532993.717598,183255.233189,533020.727019,183200.304946,3,61.209644 456,532740.225415,183101.456559,533004.563505,183237.365869,5,297.2305 457,532757.924444,183233.346962,532802.663245,183129.442,2,113.12737 458,532685.720654,183195.618751,533412.442248,183553.057914,11,809.86853 459,533024.538111,183916.941189,533130.680604,183490.775096,4,439.18533 460,533013.314477,183449.208665,533194.753878,183517.68685,2,193.93173 461,533108.115245,183562.022779,533168.092312,183585.226165,3,64.308983 462,533152.99534,183590.14543,533205.984455,183546.220389,2,68.827721 463,533089.575533,183968.681125,533162.657458,183572.125795,4,403.23331 464,532922.524395,183650.858063,533327.125673,183697.863386,8,407.3226 465,532885.693914,183873.580068,532927.211036,183638.394822,7,238.82162 466,532779.479562,183518.056912,532935.205668,183654.64484,7,207.13977 467,532821.550289,183562.586222,532860.869029,183486.788093,1,85.389229 468,532883.827305,183871.101644,533293.632281,183952.760517,9,417.86157 469,532953.496908,183900.631433,533047.8399,183487.189023,6,424.06982 470,532548.783925,183646.448256,532960.447991,183900.052022,11,483.51025 471,532323.585929,183530.393563,532794.913219,183792.725629,8,539.41406 472,532571.255358,183675.623828,532577.265488,183558.348912,5,117.42882 473,532543.068654,183657.388289,532630.300523,183590.633501,5,109.84353 474,532612.008295,183601.543762,532798.825322,183678.398363,4,202.008 475,532708.264427,183746.1312,532817.654866,183429.39209,8,335.09689 476,532758.211581,183586.688488,532982.237138,183070.616672,8,562.59894 477,532740.540472,183589.113563,532762.740992,183598.956911,1,24.284863 478,532810.82743,183815.115636,532833.055397,183775.618109,2,45.32259 479,532826.456421,183781.237933,532846.809685,183768.396942,2,24.065462 480,532838.839254,183767.79295,532907.269939,183789.681389,2,71.8461 481,532411.696593,183400.519815,532820.202092,183548.10214,5,434.34695 482,532420.14458,183419.788898,532705.551235,183195.896947,4,362.74588 483,532468.070555,183288.522695,532792.861092,183514.746035,3,395.81042 484,532606.548409,183559.356739,532650.440517,183476.983667,3,93.337242 485,532619.308676,183526.604462,532627.238206,183609.608708,4,83.382149 486,532567.087105,183576.703398,532632.049753,183529.756598,4,80.15078 487,532319.10546,183440.943243,532579.700202,183577.230383,3,294.0813 488,532691.004424,182972.701974,532839.914144,183067.687656,2,176.62498 489,532655.483875,183248.950676,532793.216472,183024.521282,4,263.32266 490,532980.111006,183597.040814,533026.907326,183601.536855,2,47.011806 491,532980.888774,183598.775588,532997.942126,183535.767805,1,65.274788 492,532948.970195,183485.011804,533045.94493,183523.467543,3,104.32134 493,532882.00154,183616.560258,533022.747935,183353.217927,4,298.5946 494,532851.11962,183692.160301,532918.05361,183708.266348,2,68.84449 495,532845.279862,183719.83908,532859.5161,183661.444718,3,60.104675 496,532795.696864,183650.565417,532864.808334,183668.231221,2,71.333557 497,532784.077833,183702.622362,532798.741337,183648.432221,3,56.139023 498,532778.455497,183698.332789,532853.748882,183716.690184,2,77.498955 499,533126.981531,184343.351798,533236.94103,184128.252751,5,241.57544 500,532835.610266,183916.087636,533298.551877,184154.108856,5,520.54688 501,532781.105505,184010.249828,533459.094685,184343.719876,10,755.56042 502,533119.922963,184731.572266,533226.065455,184305.406173,5,439.18533 503,533108.699328,184263.839742,533290.13873,184332.317927,3,193.93173 504,533203.500097,184376.653856,533263.477163,184399.857242,3,64.308983 505,533248.380191,184404.776507,533301.369306,184360.851466,3,68.827721 506,533184.960385,184783.312202,533258.042309,184386.756872,5,403.23331 507,533017.909246,184465.48914,533313.224583,184499.685418,6,297.28864 508,532981.078765,184688.211145,533022.595887,184453.025899,8,238.82162 509,532874.864413,184332.687989,533030.590519,184469.275916,7,207.13977 510,532916.93514,184377.217299,532956.25388,184301.41917,1,85.389229 511,532979.212156,184685.732721,533312.519029,184749.741937,8,339.39749 512,533048.881759,184715.26251,533143.224751,184301.8201,7,424.06982 513,532593.913595,184428.026979,533055.832842,184714.683099,11,543.63696 514,532666.640209,184490.254905,532672.650339,184372.979989,5,117.42882 515,532638.453505,184472.019366,532725.685375,184405.264577,4,109.84353 516,532707.393146,184416.174838,532894.210173,184493.02944,4,202.008 517,532803.649278,184560.762277,532913.039717,184244.023167,9,335.09689 518,532884.448357,184243.450033,533002.988,184269.828409,3,121.43914 519,533001.360624,184271.268552,533018.030551,184217.979393,1,55.835659 520,532853.596432,184401.319564,533077.621989,183885.247749,9,562.59894 521,532835.925323,184403.74464,532858.125843,184413.587987,1,24.284863 522,532906.212281,184629.746713,532928.440249,184590.249186,2,45.32259 523,532921.841272,184595.86901,532942.194537,184583.028019,2,24.065462 524,532934.224105,184582.424026,533002.65479,184604.312466,2,71.8461 525,532579.486878,184248.319081,532915.586943,184362.733217,5,355.04062 526,532637.688968,184132.908686,532800.936086,184010.528024,5,204.02609 527,532627.410222,184103.554158,532888.245943,184329.377111,5,345.00909 528,532906.486242,184197.526206,532939.195758,184211.385546,1,35.524551 529,532701.93326,184373.987816,532745.825368,184291.614744,3,93.337242 530,532714.693527,184341.235539,532722.623057,184424.239785,4,83.382149 531,532662.471957,184391.334474,532727.434605,184344.387675,4,80.15078 532,532564.748392,184331.051265,532675.085054,184391.86146,3,125.98436 533,532750.868727,184063.581753,532906.016604,183843.177006,7,269.535 534,533075.495857,184411.671891,533122.292177,184416.167932,2,47.011806 535,533076.273625,184413.406665,533093.326978,184350.398881,1,65.274788 536,533044.355046,184299.642881,533141.329781,184338.09862,3,104.32134 537,532977.386391,184431.191335,533118.132786,184167.849003,3,298.5946 538,532946.504472,184506.791378,533013.438462,184522.897425,3,68.84449 539,532940.664713,184534.470157,532954.900952,184476.075795,3,60.104675 540,532891.081716,184465.196494,532960.193186,184482.862298,2,71.333557 541,532879.462684,184517.253439,532894.126188,184463.063297,3,56.139023 542,532873.840348,184512.963866,532949.133733,184531.321261,2,77.498955 543,532917.353772,184079.057405,532962.745749,183975.886969,2,112.71455 544,532065.2786,184514.06895,532635.210657,184438.436618,7,574.92853 545,532364.629597,184414.239317,532590.230088,184386.41984,1,227.30927 546,532489.874509,184162.462824,532652.784793,184210.349538,2,169.80252 547,532542.4661,184490.385692,532763.565425,183767.899229,12,755.56042 548,532030.38234,184165.122698,532543.133455,184254.228718,5,520.43597 549,532526.782394,184321.773294,532565.454237,184131.736438,2,193.93173 550,532455.856013,184306.221875,532469.199284,184243.312394,2,64.308983 551,532448.592493,184292.102419,532500.404605,184337.409821,2,68.827721 552,532151.559428,184344.737703,532467.9222,184298.767718,5,319.68521 553,532126.163226,184073.414024,532546.372759,184062.610646,5,420.34839 554,532532.763551,183974.089967,532584.490376,183864.218218,2,121.43914 555,532631.895052,183998.522448,532632.387207,183877.743771,2,120.77968 556,532582.355319,183864.623056,532634.69401,183884.072537,2,55.835659 557,532934.235328,184040.687683,532934.247379,184040.690753,1,0.012435302 558,532167.934598,183901.818224,532792.413758,184004.562433,7,632.87488 559,532368.508548,184092.677579,532506.956582,183612.623908,4,499.61923 560,532478.124198,183964.520986,532594.152127,183661.701955,4,324.28668 561,532590.210249,183956.03771,532598.676791,183921.536821,0,35.524551 562,532306.05875,184266.992332,532414.219172,184122.529385,3,180.46667 563,532412.630606,184123.573809,532477.551415,184130.362486,2,65.274788 564,532439.682428,184049.515329,532661.721044,184125.743623,5,234.75923 565,532847.771489,183350.898751,532995.822217,183426.742101,2,166.34673 566,532774.026261,183284.142626,532909.818834,183159.196609,2,184.52948 567,532709.490275,183812.886376,532835.431428,183979.968037,2,209.23062 568,532463.943732,184141.842329,532481.318515,184025.961742,3,117.17591 569,533323.064517,183697.391573,533469.816857,183830.537895,3,198.15195 570,529846.791844,185094.627525,532736.351417,185388.776756,16,2904.4927 571,530347.847156,185292.772305,530632.54739,185377.731381,3,297.10651 572,530537.847519,185421.393549,530918.45134,185724.218064,2,486.37634 573,530524.468228,184838.411754,530539.002713,185369.052417,5,530.83966 574,530335.169085,184982.866758,530559.280279,185043.45439,5,232.1566 575,530707.024701,184994.505864,530707.477025,185313.557473,6,319.05194 576,531131.431446,185132.77165,531131.431446,185359.356031,3,226.58438 577,530501.676063,185036.509115,530743.403575,185005.682885,5,243.68513 578,530485.48235,185236.499696,530775.181629,185251.675793,2,290.0965 579,532544.992916,185376.432414,536042.612412,185481.987222,23,3499.2119 580,532310.185466,184245.557105,532320.564971,184501.568004,4,256.22122 581,532121.12861,185156.54299,532552.782294,185237.529808,4,439.18533 582,532107.183652,185396.499385,532132.218217,185032.528489,3,364.83084 583,532191.417756,185229.891994,532195.30118,185165.700369,1,64.308983 584,532227.588839,185421.387179,532353.359001,185033.968077,5,407.3226 585,532340.076208,185033.038343,532571.18527,185093.24111,7,238.82162 586,532292.197138,184848.611134,532351.520352,185047.074325,6,207.13977 587,532229.872721,184909.583681,532315.159633,184905.404877,1,85.389229 588,532325.041594,185475.024213,532348.317401,185387.959135,1,90.122643 589,532458.491775,185549.400536,532569.709404,185090.511891,8,472.17386 590,532152.369147,185079.734976,532567.540953,185166.15024,5,424.06982 591,532505.002165,184692.345865,532564.119253,185172.2285,11,483.51025 592,532493.279792,184439.273909,532535.484156,184977.034374,10,539.41406 593,532413.044998,184681.548955,532522.168382,184724.926539,5,117.42882 594,532420.308897,184743.211305,532517.328531,184691.706048,5,109.84353 595,532429.914393,184932.976985,532437.846142,184731.124765,4,202.008 596,532009.678491,184830.207924,532529.209664,184878.852478,9,521.80353 597,532372.718405,184867.085846,532373.015227,184842.802797,1,24.284863 598,532504.045738,185004.586487,532549.212182,185000.827563,2,45.32259 599,532491.752352,185014.083768,532511.903281,185000.927534,2,24.065462 600,532485.923093,185077.915497,532494.522692,185006.585915,2,71.8461 601,532302.552935,184898.146955,532338.509646,184465.290859,6,434.34695 602,532317.204408,184488.844117,532511.697154,184540.679279,4,201.28168 603,532213.209452,184469.899539,532283.614029,184859.398047,3,395.81042 604,532308.596564,184714.189612,532401.765755,184708.591215,4,93.337242 605,532366.674775,184706.551798,532438.83555,184748.32984,4,83.382149 606,532364.234237,184719.448107,532433.970963,184679.939416,4,80.15078 607,532419.863664,184513.347103,532429.197073,184691.626071,3,178.52312 608,532265.046152,185108.326792,532280.447926,185063.909506,2,47.011806 609,532217.315493,185054.60217,532281.701175,185065.339097,1,65.274788 610,532186.140917,185093.121144,532191.566167,184988.940965,2,104.32134 611,532041.019596,185001.127477,532339.05382,184982.842711,3,298.5946 612,532407.413622,185053.812396,532420.646945,184986.251735,2,68.84449 613,532389.225017,184981.093212,532448.243164,184992.469955,3,60.104675 614,532393.190891,184988.731026,532405.913021,184918.541117,2,71.333557 615,532402.705692,184920.420579,532458.079522,184929.657935,3,56.139023 616,532441.853242,184998.858127,532456.521206,184922.75991,2,77.498955 617,532481.890775,185659.270838,533213.475046,185960.194699,11,791.0567 618,532608.229846,185714.42505,532641.597608,185570.396278,4,147.84348 619,532494.571678,185595.329141,532951.496475,185784.285053,4,494.45386 620,532625.536229,185598.818142,532683.573214,185540.914717,2,81.982307 621,532574.680692,185537.425716,532637.565773,185598.768157,2,87.848892 622,532379.782201,185516.78321,532897.788147,185508.254066,5,518.07617 623,532630.128728,185133.831243,532743.226231,185136.430499,1,113.12737 624,532738.996515,185055.073787,532759.807049,185810.347593,11,755.56042 625,532822.02428,185582.532804,533308.048429,185701.947063,4,500.479 626,532819.806359,185651.992921,532833.113887,185458.518303,3,193.93173 627,532892.313426,185655.881808,532896.19685,185591.690183,3,64.308983 628,532841.070371,185674.086597,532903.073231,185644.20515,2,68.827721 629,532882.666705,185645.484784,533018.964367,185679.897592,3,140.57487 630,532928.484509,185847.376993,533171.791246,185088.690552,12,796.74542 631,533040.971878,185459.028157,533342.086167,185539.229407,3,311.61203 632,533040.869687,185902.686787,533064.145494,185815.621709,1,90.122643 633,532853.264817,185505.72479,533314.949235,185601.821346,5,471.57932 634,532896.584368,185272.381584,533323.615384,185304.842292,5,428.263 635,532501.860312,185272.591524,533064.346626,185283.848301,5,562.59894 636,533003.448605,185324.136769,533056.976395,184798.314821,5,528.53943 637,532730.99056,185073.218594,532910.240585,184975.770777,5,204.02609 638,532887.833761,184954.200538,532984.509699,185285.387861,5,345.00909 639,533009.492234,185140.179426,533223.840618,185128.424782,4,214.67044 640,533120.759334,184991.97773,533164.669849,185152.192991,4,166.12364 641,532535.080541,185099.055441,532800.075927,185049.795298,6,269.535 642,532965.941822,185534.316606,532981.343596,185489.89932,2,47.011806 643,532918.211163,185480.591984,532982.596845,185491.328911,1,65.274788 644,532887.036587,185519.110958,532892.461837,185414.930779,2,104.32134 645,532632.107543,185205.900614,532744.809283,185207.600127,2,112.71455 646,532964.061948,185729.530726,533287.399961,185848.0167,3,344.36377 647,533160.485194,185038.203824,533312.377108,184720.549657,5,352.10129 648,532525.968737,184938.195076,533310.15909,185042.780793,10,791.13379 649,532783.202604,184722.352915,533016.354731,184679.635872,7,237.03304 650,532833.457546,184793.601953,532842.931078,184708.739877,1,85.389229 651,532637.546794,184576.413333,532697.76898,184475.60254,4,117.42882 652,532664.201797,184475.083512,532699.578469,184579.074338,3,109.84353 653,532790.659095,184784.017491,532807.61867,184536.424288,5,248.17337 654,532688.116711,184815.503368,532809.549225,184814.234469,2,121.43914 655,532680.465774,184864.681718,532790.476516,184914.535179,2,120.77968 656,532685.258845,184869.414696,532689.373959,184813.730886,2,55.835659 657,532702.892582,185206.980301,532702.89481,185206.968067,1,0.012435302 658,532729.11626,185062.986031,532803.692966,184653.485179,9,416.23627 659,532491.67071,184640.231707,532833.755893,184720.028022,5,351.26874 660,532499.975473,184739.94504,532792.482948,184732.546172,3,292.60104 661,532734.319602,184852.272505,532769.212115,184858.943804,1,35.524551 662,532653.115703,184684.729984,532662.444623,184591.860121,3,93.337242 663,532654.836092,184626.176973,532707.585566,184561.600854,3,83.382149 664,532639.294461,184555.498451,532667.178268,184630.642585,4,80.15078 665,532472.584102,184542.862363,532650.07041,184562.074685,3,178.52312 666,532893.717797,184994.635461,532923.188084,184697.498736,4,298.5946 667,531538.538439,185607.847884,531861.827826,185191.773577,6,526.90973 668,531733.704075,185347.638093,532464.148204,185651.318997,8,791.0567 669,531783.992688,185523.353816,531862.097157,185397.825387,4,147.84348 670,531697.519714,185401.860209,532154.444511,185590.816121,5,494.45386 671,531792.696598,185491.889357,531792.885564,185573.871444,3,81.982307 672,531713.333946,185499.431572,531801.177268,185500.421101,3,87.848892 673,531610.700038,185649.814566,531730.360655,185490.95743,4,198.88251 674,531620.035263,185437.486389,531921.465017,185748.290708,7,432.96561 675,531650.997901,185688.805133,531795.073611,185570.13741,4,186.65433 676,531609.716111,185644.426899,531651.845197,185688.831412,3,61.209644 677,531419.603835,185873.139547,531638.856727,185672.455379,5,297.2305 678,531467.531654,185824.307266,531549.43165,185902.346948,2,113.12737 679,531488.975827,185956.953711,532119.186289,185356.969123,9,870.14178 680,531920.292545,185642.195846,532283.069773,185889.736651,4,439.18533 681,531840.552788,185737.82088,531967.781488,185591.457031,2,193.93173 682,531979.268684,185688.10056,532021.857493,185639.915095,3,64.308983 683,531998.439307,185590.835022,532021.227472,185655.780807,2,68.827721 684,532007.685046,185640.46198,532354.176342,185846.716386,4,403.23331 685,531998.119894,185892.991515,532182.715114,185529.898829,7,407.3226 686,531988.060055,185884.268177,532194.187825,186004.879594,7,238.82162 687,531823.906145,185981.011624,532006.0751,185882.414698,6,207.13977 688,531822.849706,185893.828664,531880.274702,185957.02431,1,85.389229 689,532311.198579,185678.393526,532356.214415,185600.318783,1,90.122643 690,532191.215405,186005.769276,532436.590975,185602.36008,8,472.17386 691,531888.159585,185718.634809,532243.102999,185950.691698,5,424.06982 692,531983.707795,186179.165119,532196.631823,185988.747422,5,285.64932 693,531651.967629,186274.379,531834.720544,186117.859235,5,240.61809 694,531474.732813,185635.481035,531880.879584,186024.791155,5,562.59894 695,532084.042336,186020.220067,532125.476384,186066.896386,2,62.413612 696,532082.047427,186004.814029,532087.020575,186028.360031,2,24.065462 697,532078.712944,186012.078587,532123.004546,185955.509016,2,71.8461 698,531418.778869,186104.345157,531495.361206,186318.654076,1,227.58112 699,531405.175343,186133.522312,531496.123753,185938.454076,2,215.22832 700,531967.651931,185820.298893,531988.120213,185777.976802,2,47.011806 701,531916.385431,185782.297886,531969.548841,185820.172013,1,65.274788 702,531851.781007,185810.594354,531921.521881,185733.01115,3,104.32134 703,531753.813062,185695.637567,531951.88356,185919.080645,5,298.5946 704,532012.052858,185974.295815,532050.402192,185917.121587,2,68.84449 705,531986.165178,185955.754619,532035.980691,185989.384765,3,60.104675 706,531953.798994,186011.823186,531994.367226,185953.148707,2,71.333557 707,531952.855903,186008.227366,531998.580495,186040.798082,3,56.139023 708,531992.605316,186044.580718,532035.969035,185980.349295,3,77.498955 709,532589.748562,185685.358288,532589.937528,185767.340375,3,81.982307 710,532510.38591,185692.900503,532598.229233,185693.890033,3,87.848892 711,532406.805014,185844.840392,532526.465631,185685.983256,3,198.88251 712,532357.833442,185569.858724,532718.516981,185941.75964,8,518.07617 713,532448.049865,185882.274065,532592.125576,185763.606342,3,186.65433 714,532406.768075,185837.89583,532448.897161,185882.300344,3,61.209644 715,532216.655799,186066.608479,532435.908691,185865.92431,5,297.2305 716,532360.533068,186075.917366,532834.203129,185630.446297,10,650.23676 717,532717.344509,185835.664778,532936.586571,185985.264456,3,265.41882 718,532637.604753,185931.289811,532764.833452,185784.925963,3,193.93173 719,532776.320648,185881.569492,532818.909457,185833.384027,3,64.308983 720,532795.491271,185784.303954,532818.279437,185849.249739,3,68.827721 721,532804.73701,185833.930912,533151.228306,186040.185318,3,403.23331 722,532795.171858,186086.460447,532929.800941,185821.402824,6,297.28864 723,532785.112019,186077.737108,532991.239789,186198.348525,3,238.82162 724,532620.958109,186174.480555,532803.127064,186075.88363,5,207.13977 725,532487.895562,185923.221154,532677.326666,186150.493242,2,295.86609 726,532685.211549,185912.103741,533069.580712,186166.970325,5,461.19046 727,532596.323721,186341.331993,532783.926762,186029.330587,5,364.06012 728,532563.33634,186239.667079,532671.224339,186286.032017,4,117.42882 729,532612.030176,186201.145396,532644.334769,186306.131177,3,109.84353 730,532271.784777,185828.949967,532505.439737,186045.768275,4,318.7551 731,532414.079667,186283.737681,532456.17094,185958.238507,5,328.20935 732,532406.790925,186170.698068,532571.998535,186193.879467,4,166.82605 733,532548.169142,186189.216154,532628.760769,186210.607084,3,83.382149 734,532555.549979,186178.362848,532577.01348,186255.586328,4,80.15078 735,532486.543697,186326.291197,532581.88812,186243.941337,3,125.98436 736,532172.735117,185975.263057,532257.346144,186098.20954,5,149.24767 737,532764.703896,186013.767825,532785.172178,185971.445734,2,47.011806 738,532713.437395,185975.766818,532766.600805,186013.640945,1,65.274788 739,532648.832971,186004.063285,532718.573845,185926.480081,3,104.32134 740,532550.865026,185889.106499,532748.935524,186112.549577,4,298.5946 741,532809.104823,186167.764747,532847.454156,186110.590519,2,68.84449 742,532783.217143,186149.223551,532833.032655,186182.853696,1,60.104675 743,532316.886414,185968.154353,532397.870761,186046.551458,2,112.71455 744,532484.706693,186858.233085,532611.716116,186297.509083,5,574.92853 745,532495.053707,186542.844571,532547.315567,186321.624765,2,227.30927 746,532302.445571,186337.954854,532403.929434,186201.815503,3,169.80252 747,532279.867123,186136.157785,533301.964636,186916.681637,8,1286.0408 748,532220.466605,186717.486676,532406.996132,186319.880711,4,439.18533 749,532299.880114,186256.408398,532464.657849,186358.671862,2,193.93173 750,532371.082371,186385.421764,532425.442087,186419.782599,3,64.308983 751,532409.678901,186421.690404,532470.160245,186388.838273,2,68.827721 752,532274.274318,186780.824005,532422.642422,186405.878671,4,403.23331 753,532171.81854,186436.70136,532559.699344,186561.040314,8,407.3226 754,532092.624676,186648.101237,532178.826247,186425.3793,6,238.82162 755,532057.146411,186278.751138,532183.528486,186442.868331,7,207.13977 756,532089.81472,186330.573787,532143.045525,186263.807019,1,85.389229 757,532433.590954,186711.557255,532517.844537,186743.548266,1,90.122643 758,532091.272428,186645.308703,532528.645281,186823.221988,7,472.17386 759,532153.918759,186687.75042,532326.411557,186300.346934,5,424.06982 760,531805.981463,186360.120561,532160.850721,186688.525773,8,483.51025 761,531638.584156,186248.397279,532019.187977,186551.221795,2,486.37634 762,531822.388527,186393.090056,531850.957699,186279.189528,4,117.42882 763,531798.259009,186369.749287,531896.750706,186321.11816,4,109.84353 764,531876.694323,186328.286208,532045.128842,186439.807703,4,202.008 765,531943.18184,186488.754835,532093.982912,186228.396289,7,300.87793 766,531995.178958,186015.230887,532011.499862,186166.344763,4,151.99268 767,532367.752182,186017.395091,532367.759246,186017.384856,1,0.012435302 768,532023.011316,186341.976255,532159.436339,186124.137174,5,257.03241 769,532005.204751,186340.939274,532025.083457,186354.888884,1,24.284863 770,532030.47336,186576.266049,532059.917927,186541.810938,2,45.32259 771,532052.35698,186546.04898,532074.808779,186537.385081,2,24.065462 772,532067.105483,186535.251582,532130.013549,186569.956592,2,71.8461 773,531792.763214,186130.980154,532091.292124,186316.102313,6,351.26874 774,531936.680417,186133.867962,532070.915572,186278.089735,3,197.02538 775,531769.516237,186138.516602,532468.845803,186177.575543,11,700.41949 776,531879.493338,186285.839527,531938.482345,186213.506013,3,93.337242 777,531890.077738,186339.143359,531898.344779,186256.172049,4,83.382149 778,531837.422918,186295.229987,531910.236094,186261.727914,4,80.15078 779,531710.480298,186186.429316,531849.69618,186298.185485,4,178.52312 780,532238.723078,186395.032465,532283.767347,186408.490685,2,47.011806 781,532239.150794,186396.884875,532268.06354,186338.36265,2,65.274788 782,532138.690872,186395.216436,532327.693221,186164.052331,4,298.5946 783,532006.439739,186419.175581,532156.333518,186492.162275,2,166.71893 784,532359.977566,186772.190756,532443.278589,186521.044007,2,264.6011 785,531690.869932,185858.91738,531813.409667,185746.421847,3,166.34673 786,531532.648741,185734.155051,531602.657669,185904.88841,2,184.52948 787,532171.469385,186298.572254,532274.102964,186355.110223,2,117.17591 788,532180.862253,185533.543345,532356.687285,185442.166375,1,198.15195 789,534574.657185,184195.402125,535121.140847,184069.916781,5,560.70575 790,534563.562293,184974.129007,534591.680522,184183.57219,13,791.0567 791,534583.836146,184321.202178,534730.488454,184302.472644,3,147.84348 792,534698.25765,184297.281735,534772.712856,184331.596753,3,81.982307 793,534702.482315,184308.545155,534738.166945,184228.270404,3,87.848892 794,534723.371547,184240.220974,534917.631564,184197.591186,3,198.88251 795,534720.705827,184117.649614,534877.736194,184521.135283,7,432.96561 796,534768.406805,184332.030894,534936.296866,184250.466403,3,186.65433 797,534913.143151,184194.45284,534935.967883,184251.247666,3,61.209644 798,534926.488964,184232.619061,535200.253338,184116.864865,5,297.2305 799,535135.896953,184140.101114,535172.737595,184247.061707,2,113.12737 800,534562.260508,184461.164981,535247.561401,184214.840549,8,728.22595 801,534781.768492,184475.883822,534855.733432,184908.796002,4,439.18533 802,534715.861565,184497.92705,534901.915218,184443.21365,2,193.93173 803,534737.396022,184567.271591,534798.940809,184548.619916,3,64.308983 804,534702.527951,184525.540516,534752.082699,184573.306429,2,68.827721 805,534743.795646,184554.614492,534787.00774,184955.52572,4,403.23331 806,534570.382231,184667.696421,534977.366153,184651.089755,7,407.3226 807,534973.624979,184638.310842,534997.432303,184875.942875,7,238.82162 808,534964.437135,184653.917275,535129.944616,184529.361442,7,207.13977 809,535051.122321,184492.091746,535084.660673,184570.618804,1,85.389229 810,534553.928547,184777.71118,534643.657919,184769.301014,2,90.122643 811,534530.528166,184928.685384,534999.479085,184873.611031,10,472.17386 812,534864.645343,184478.50485,534927.795663,184897.846314,6,424.06982 813,534920.9074,184896.748538,535350.389301,184674.650654,11,483.51025 814,535094.007101,184802.106005,535583.637988,184575.767496,10,539.41406 815,535325.798299,184702.06346,535328.577977,184584.667544,5,117.42882 816,535273.276435,184612.894289,535355.270169,184685.987575,5,109.84353 817,535098.658423,184687.806427,535290.701247,184625.142364,4,202.008 818,535098.509015,184438.08928,535183.89869,184762.124056,9,335.09689 819,535006.882355,184457.093469,535127.063137,184439.656582,3,121.43914 820,534991.75315,184409.678765,535092.77961,184343.486731,2,120.77968 821,534995.760614,184404.264446,535008.397438,184458.651315,2,55.835659 822,534961.226757,184068.007254,535146.018893,184599.391705,10,562.59894 823,535140.584411,184611.286922,535163.459076,184603.131906,1,24.284863 824,535057.251555,184782.193123,535076.462555,184823.242784,2,45.32259 825,535044.075999,184773.963275,535063.41164,184788.29085,2,24.065462 826,534982.19293,184790.665242,535052.06928,184773.957217,2,71.8461 827,535087.088601,184556.27616,535505.489654,184439.666367,6,434.34695 828,535476.003253,184427.867158,535494.940716,184628.255992,4,201.28168 829,535227.765574,184213.634501,535495.623878,184458.249491,5,362.74588 830,535116.848257,184525.058811,535457.651802,184323.765899,3,395.81042 831,535074.86778,184403.586458,535108.522419,184392.212847,1,35.524551 832,535261.69466,184498.056288,535299.301714,184583.481985,3,93.337242 833,535274.910697,184632.04541,535289.027295,184549.866922,4,83.382149 834,535276.086116,184552.057106,535337.354799,184603.732014,4,80.15078 835,535324.737621,184603.313977,535488.678393,184532.646259,3,178.52312 836,535103.370078,184075.733181,535258.968139,183992.153113,2,176.62498 837,535153.166046,184036.181063,535273.723864,184270.284958,4,263.32266 838,534876.965263,184594.098185,534923.966796,184593.115427,2,47.011806 839,534910.769279,184530.680211,534923.061435,184594.787158,1,65.274788 840,534863.821121,184514.823476,534963.40089,184483.729864,3,104.32134 841,534899.688958,184346.786186,535020.341176,184619.919439,2,298.5946 842,534977.529877,184708.67163,535045.481163,184697.617833,2,68.84449 843,535039.405946,184666.3602,535049.233996,184725.655911,3,60.104675 844,535033.620864,184672.731791,535103.86021,184660.285498,2,71.333557 845,535100.983846,184657.930531,535111.552469,184713.065765,3,56.139023 846,535041.024265,184721.882297,535117.479941,184709.2088,2,77.498955 847,535069.000684,184166.986037,535106.547618,184273.263025,2,112.71455 848,534693.249139,184660.132058,534706.694412,184924.391352,2,264.6011 849,534407.504716,185779.34208,534453.692303,184480.757033,15,1299.4061 850,534427.77857,185126.415252,534574.430877,185107.685717,4,147.84348 851,534481.481436,185472.577643,534499.988673,184978.470277,4,494.45386 852,534542.200073,185102.494808,534616.65528,185136.809827,3,81.982307 853,534546.424738,185113.758229,534582.109368,185033.483477,3,87.848892 854,534569.123813,185045.221496,534763.38383,185002.591709,3,198.88251 855,534533.779885,184843.547182,534721.678617,185326.348356,8,518.07617 856,534612.349228,185137.243968,534780.239289,185055.679477,3,186.65433 857,534757.085574,184999.665913,534779.910306,185056.46074,3,61.209644 858,534770.431387,185037.832134,535044.195761,184922.077939,5,297.2305 859,534979.839376,184945.314188,535016.680018,185052.274781,2,113.12737 860,534390.468496,185301.871061,535091.503824,185020.053622,11,755.56042 861,534625.710916,185281.096896,534699.675855,185714.009075,5,439.18533 862,534559.803988,185303.140124,534745.857641,185248.426724,3,193.93173 863,534581.338446,185372.484665,534642.883232,185353.832989,3,64.308983 864,534546.470374,185330.75359,534596.025122,185378.519503,2,68.827721 865,534587.738069,185359.827566,534630.950164,185760.738794,5,403.23331 866,534157.732629,185538.915308,534848.842646,185522.308643,9,691.30951 867,534817.567402,185443.523916,534841.374726,185681.155949,6,238.82162 868,534808.379558,185459.130349,534973.88704,185334.574516,7,207.13977 869,534895.064744,185297.30482,534928.603096,185375.831877,1,85.389229 870,534406.08931,185659.974073,534495.818681,185651.563907,1,90.122643 871,534374.470589,185733.898458,534843.421508,185678.824105,7,472.17386 872,534708.587766,185283.717924,534771.738086,185703.059388,7,424.06982 873,534764.849823,185701.961612,535078.992376,185538.201886,5,354.26373 874,534942.451438,185243.302354,535027.841113,185567.33713,8,335.09689 875,534850.824778,185262.306543,534971.005561,185244.869656,3,121.43914 876,534835.695573,185214.891839,534936.722033,185148.699805,2,120.77968 877,534839.703037,185209.47752,534852.339862,185263.864389,2,55.835659 878,534805.16918,184873.220328,534989.961316,185404.604779,10,562.59894 879,534984.526835,185416.499995,535007.401499,185408.344979,1,24.284863 880,534901.193978,185587.406197,534920.404978,185628.455858,2,45.32259 881,534888.018422,185579.176349,534907.354063,185593.503923,2,24.065462 882,534826.135353,185595.878316,534896.011703,185579.170291,2,71.8461 883,534931.031024,185361.489234,535274.748313,185272.538271,4,355.04062 884,535071.707997,185018.847575,535225.342791,185153.097336,5,204.02609 885,534960.790681,185330.271885,535237.788656,185124.593978,5,345.00909 886,534918.810203,185208.799531,534952.464842,185197.425921,1,35.524551 887,534979.440914,184844.104724,535117.666287,185075.498032,6,269.535 888,534720.907686,185399.311258,534767.909219,185398.328501,2,47.011806 889,534754.711702,185335.893285,534767.003858,185400.000231,1,65.274788 890,534707.763545,185320.03655,534807.343313,185288.942937,3,104.32134 891,534743.631381,185151.99926,534864.283599,185425.132512,3,298.5946 892,534912.943107,184972.19911,534950.490041,185078.476099,2,112.71455 893,534537.191562,185503.477633,534550.636835,185729.604425,2,226.52615 894,535204.496158,185229.19193,535370.532227,185193.626199,4,169.80252 895,535127.124245,184779.694198,535293.557118,185516.696029,9,755.56042 896,535310.557793,185281.150834,535749.725,185277.1594,4,439.18533 897,535297.462815,185157.332025,535321.810242,185349.729325,2,193.93173 898,535385.101419,185275.79588,535393.701243,185339.52726,3,64.308983 899,535346.944402,185367.295278,535402.000642,185325.990727,2,68.827721 900,535382.226487,185331.191356,535784.898658,185352.456817,4,403.23331 901,535466.211156,185520.41691,535514.709946,185115.991934,7,407.3226 902,535501.497998,185117.647664,535739.885867,185132.035007,6,238.82162 903,535418.867409,184945.95612,535515.439778,185129.206385,7,207.13977 904,535369.506432,185017.827383,535452.376475,184997.239138,1,85.389229 905,535717.506417,185601.375402,535737.910212,185129.642602,7,472.17386 906,535326.359881,185199.752209,535750.405618,185204.273205,6,424.06982 907,535597.447409,184751.497905,535748.223563,185210.898302,8,483.51025 908,535547.180422,184541.770925,535682.392359,185024.922582,5,501.71484 909,535505.137738,184758.682504,535620.588503,184780.145227,5,117.42882 910,535524.185606,184817.777244,535609.417536,184748.487137,5,109.84353 911,535539.055343,184802.528299,535570.296749,185002.105868,4,202.008 912,535357.746004,184958.474606,535657.255012,184929.805982,8,300.87793 913,535298.492212,184889.139347,535341.85494,185002.57276,2,121.43914 914,535241.173485,185019.521066,535249.717782,184899.04399,2,120.77968 915,535246.944008,184905.182458,535300.591002,184889.702767,2,55.835659 916,534936.513858,185038.95319,534936.526105,185038.951031,1,0.012435302 917,535080.652713,185013.536228,535490.564742,184941.253717,8,416.23627 918,535497.037903,184924.633029,535501.441253,184948.515346,1,24.284863 919,535656.87362,185058.032807,535700.461267,185045.612897,2,45.32259 920,535646.648239,185069.727561,535663.87555,185052.923806,2,24.065462 921,535647.916776,185061.835578,535653.26936,185133.482017,2,71.8461 922,535394.629739,184644.050052,535438.604457,184992.555358,5,351.26874 923,535304.007138,184686.46776,535412.531629,184958.198879,4,292.60104 924,535280.057722,184945.236103,535285.919638,184980.273679,1,35.524551 925,535408.970117,184810.900093,535499.299289,184787.395178,3,93.337242 926,535464.476048,184792.178276,535543.352293,184819.21751,4,83.382149 927,535464.574759,184805.30311,535525.357753,184753.057772,4,80.15078 928,535479.309778,184592.335656,535522.933274,184765.446874,3,178.52312 929,535442.438736,185206.021096,535448.962877,185159.464189,2,47.011806 930,535385.222118,185162.537657,535450.468862,185160.624523,1,65.274788 931,535347.264475,185103.093237,535362.082435,185206.356837,3,104.32134 932,535201.914047,185144.154584,535490.790719,185068.596661,5,298.5946 933,535571.503594,185056.167204,535571.581237,185125.01165,2,68.84449 934,535539.677178,185057.180712,535599.781343,185056.933015,3,60.104675 935,535543.957333,184992.582459,535545.04483,185063.907723,2,71.333557 936,535541.173863,184995.046528,535597.288862,184993.404349,3,56.139023 937,535594.426369,184986.937725,535594.746978,185064.436015,2,77.498955 938,535478.334519,185397.915805,535741.356772,185426.778307,2,264.6011 939,534386.096584,184657.946566,534391.276593,184519.650385,2,138.39316 940,534150.45281,184882.379079,534256.595302,184456.212986,3,439.18533 941,534215.490232,184934.119016,534288.572156,184537.563685,2,403.23331 942,534104.300387,184622.785745,534453.040371,184663.301276,5,351.08557 943,534358.410111,184835.358794,534447.258927,184850.457767,1,90.122643 944,534009.742003,184836.539535,534473.259002,184926.540316,8,472.17386 945,534079.411606,184866.069323,534173.754598,184452.626913,7,424.06982 946,533755.439882,184661.626429,534086.362689,184865.489913,5,388.67752 947,534106.025704,184562.478705,534152.822024,184566.974746,2,47.011806 948,534106.803472,184564.213479,534123.856825,184501.205695,2,65.274788 949,534252.89623,185308.789689,534476.385315,184841.397417,6,518.07617 950,533961.524964,184881.525527,534304.335034,185057.781168,4,385.46698 951,533907.020204,184975.687719,534585.009383,185309.157766,10,755.56042 952,534245.837661,185697.010156,534351.980153,185270.844063,7,439.18533 953,534234.614027,185229.277632,534416.053428,185297.755817,3,193.93173 954,534329.414795,185342.091746,534389.391862,185365.295132,2,64.308983 955,534374.294889,185370.214397,534427.284005,185326.289357,2,68.827721 956,534310.875083,185748.750093,534354.077917,185514.323944,4,238.37387 957,534042.849838,185342.655189,534082.168579,185266.85706,0,85.389229 958,534231.245567,185651.170611,534438.433728,185715.179828,4,216.85043 959,534174.796457,185680.7004,534269.139449,185267.25799,6,424.06982 960,533929.563976,185526.200168,534038.954415,185209.461057,6,335.09689 961,534010.363055,185208.887923,534128.902698,185235.266299,3,121.43914 962,534127.275322,185236.706442,534143.945249,185183.417283,1,55.835659 963,533979.51113,185366.757455,534203.536687,184850.685639,7,562.59894 964,533961.840022,185369.18253,533984.040541,185379.025878,1,24.284863 965,533705.401576,185213.756971,534041.501641,185328.171107,4,355.04062 966,533763.603666,185098.346576,533926.850785,184975.965914,5,204.02609 967,533753.32492,185068.992048,534014.160641,185294.815002,5,345.00909 968,533876.783425,185029.019644,534031.931302,184808.614896,6,269.535 969,534201.410555,185377.109782,534248.206875,185381.605823,2,47.011806 970,534202.188323,185378.844555,534219.241676,185315.836772,1,65.274788 971,534170.269744,185265.080771,534267.244479,185303.536511,3,104.32134 972,534043.26847,185044.495295,534088.660447,184941.324859,3,112.71455 973,533615.789208,185127.900715,533778.699491,185175.787428,2,169.80252 974,533668.380798,185455.823582,533889.480123,184733.337119,10,755.56042 975,533156.297039,185130.560588,533669.048154,185219.666608,6,520.43597 976,533652.697092,185287.211184,533691.368935,185097.174328,3,193.93173 977,533574.507192,185257.540309,533726.355444,185312.833746,4,161.60216 978,533277.474126,185310.175594,533593.836898,185264.205608,4,319.68521 979,533252.077925,185038.851914,533672.287457,185028.048537,5,420.34839 980,533658.67825,184939.527857,533710.405074,184829.656108,2,121.43914 981,533757.80975,184963.960338,533758.301905,184843.181661,2,120.77968 982,533708.270017,184830.060946,533760.608708,184849.510427,2,55.835659 983,534060.150026,185006.125573,534060.162077,185006.128643,1,0.012435302 984,532885.238784,184800.028308,533918.328456,184970.000324,9,1046.9789 985,533494.423246,185058.115469,533576.328783,184703.140253,4,364.30197 986,533604.038896,184929.958876,533720.066825,184684.421651,4,271.57138 987,533716.124948,184921.475601,533724.59149,184886.974711,0,35.524551 988,533431.973449,185232.430222,533540.13387,185087.967275,2,180.46667 989,533538.545304,185089.0117,533603.466114,185095.800376,2,65.274788 990,533565.597126,185014.95322,533787.635743,185091.181513,5,234.75923 991,533835.404973,184778.324266,533961.346126,184945.405928,2,209.23062 992,533589.85843,185107.28022,533607.233213,184991.399632,3,117.17591 993,534448.979216,184662.829463,534595.731555,184795.975785,2,198.15195 994,531448.583794,186119.776035,531733.284027,186204.735111,1,297.10651 995,531632.472108,185930.735816,531639.73935,186196.056148,3,265.41983 996,531358.457914,185930.133858,531685.194977,186008.89228,4,336.09521 997,531770.029234,185963.283155,531808.213662,186140.561203,1,181.34375 998,532232.168083,186022.145713,532232.168083,186186.359762,3,164.21405 999,531627.590761,186001.947005,531869.318273,185971.120775,5,243.68513 1000,531611.397049,186201.937586,531901.096327,186217.113684,2,290.0965 1001,533414.11404,185165.537038,533424.425402,184724.739221,5,440.9184 1002,532990.64376,184514.529144,533322.717124,184642.932061,7,356.03375 1003,533885.021829,184579.439517,534153.204805,184752.247218,3,319.03702 1004,531510.629785,185399.989769,531550.244234,185166.880259,6,236.45158 1005,532988.23624,186147.308367,533381.902938,186201.567533,5,397.38837 1006,532778.64114,187622.18866,533427.582291,185080.181236,15,2623.5332 1007,534248.581817,185619.448736,534493.593519,185630.183595,4,245.24675 1008,534172.058872,185831.287567,534282.01837,185616.188519,7,241.57544 1009,533826.182846,185498.185597,534504.172025,185831.655644,7,755.56042 1010,534165.000303,186219.508034,534271.142795,185793.341941,5,439.18533 1011,534153.776669,185751.775511,534335.21607,185820.253695,2,193.93173 1012,534248.577437,185864.589624,534308.554504,185887.793011,2,64.308983 1013,534230.037725,186271.247971,534303.11965,185874.692641,4,403.23331 1014,534062.986586,185953.424909,534358.301923,185987.621186,5,297.28864 1015,534026.156106,186176.146914,534067.673228,185940.961667,8,238.82162 1016,533919.941754,185820.623758,534075.66786,185957.211685,7,207.13977 1017,533962.01248,185865.153067,534001.331221,185789.354938,1,85.389229 1018,534024.289496,186173.66849,534357.59637,186237.677706,6,339.39749 1019,534093.959099,186203.198278,534188.302091,185789.755869,7,424.06982 1020,533638.990935,185915.962748,534100.910183,186202.618868,11,543.63696 1021,533711.71755,185978.190674,533717.72768,185860.915757,5,117.42882 1022,533683.530845,185959.955135,533770.762715,185893.200346,4,109.84353 1023,533752.470487,185904.110607,533939.287514,185980.965208,4,202.008 1024,533848.726618,186048.698046,533958.117057,185731.958935,9,335.09689 1025,533929.525697,185731.385802,534048.06534,185757.764177,3,121.43914 1026,534046.437964,185759.20432,534063.107891,185705.915162,1,55.835659 1027,533898.673772,185889.255333,534282.884006,185012.284988,11,957.44165 1028,533881.002664,185891.680408,533903.203183,185901.523756,1,24.284863 1029,533951.289622,186117.682482,533973.517589,186078.184954,2,45.32259 1030,533966.918612,186083.804779,533987.271877,186070.963788,2,24.065462 1031,533979.301445,186070.359795,534047.73213,186092.248234,2,71.8461 1032,533624.564218,185736.254849,533960.664283,185850.668985,5,355.04062 1033,533682.766308,185620.844455,533846.013427,185498.463792,5,204.02609 1034,533672.487562,185591.489927,533933.323283,185817.31288,5,345.00909 1035,533951.563582,185685.461975,533984.273098,185699.321315,1,35.524551 1036,533747.0106,185861.923585,533790.902708,185779.550512,3,93.337242 1037,533759.770868,185829.171307,533767.700397,185912.175553,4,83.382149 1038,533707.549297,185879.270243,533772.511945,185832.323443,4,80.15078 1039,533609.825733,185818.987034,533720.162394,185879.797228,3,125.98436 1040,533795.946067,185551.517522,533892.357923,185253.367732,3,313.35052 1041,534120.573197,185899.60766,534167.369517,185904.103701,2,47.011806 1042,534121.350965,185901.342434,534138.404318,185838.33465,1,65.274788 1043,534089.432386,185787.57865,534186.407121,185826.034389,3,104.32134 1044,534022.463731,185919.127103,534163.210126,185655.784772,3,298.5946 1045,533991.581812,185994.727147,534058.515802,186010.833193,3,68.84449 1046,533985.742054,186022.405925,533999.978292,185964.011564,3,60.104675 1047,533936.159056,185953.132262,534005.270526,185970.798066,2,71.333557 1048,533924.540024,186005.189208,533939.203528,185950.999066,3,56.139023 1049,533918.917688,186000.899634,533994.211074,186019.257029,2,77.498955 1050,533962.431112,185566.993174,534007.823089,185463.822737,2,112.71455 1051,533183.092197,185960.49207,533680.287998,185926.372386,7,498.36514 1052,533409.706938,185902.175085,533635.307428,185874.355608,1,227.30927 1053,533534.95185,185650.398593,533697.862133,185698.285306,2,169.80252 1054,533587.54344,185978.32146,533771.907397,185375.875192,9,630.02509 1055,533571.859734,185809.709063,533610.531577,185619.672206,1,193.93173 1056,533500.933353,185794.157643,533514.276625,185731.248163,2,64.308983 1057,533493.669834,185780.038188,533545.481945,185825.345589,2,68.827721 1058,533196.636768,185832.673472,533512.99954,185786.703487,5,319.68521 1059,533281.983386,185528.829642,533591.450099,185550.546415,4,310.22775 1060,533979.312668,185528.623452,533979.324719,185528.626521,1,0.012435302 1061,533497.55948,185639.260049,533592.716804,185246.129178,6,404.48337 1062,533351.136091,185754.9281,533459.296512,185610.465153,2,180.46667 1063,533457.707946,185611.509578,533522.628756,185618.298255,2,65.274788 1064,533484.759768,185537.451098,533706.798385,185613.679391,5,234.75923 1065,533355.262807,185733.492873,533365.642311,185989.503772,4,256.22122 1066,533337.274479,186336.546903,533396.597693,186535.010094,2,207.13977 1067,533550.079506,186180.281634,533609.196594,186660.164269,5,483.51025 1068,533538.357132,185927.209678,533580.561497,186464.970143,9,539.41406 1069,533458.122339,186169.484724,533567.245723,186212.862308,5,117.42882 1070,533465.386238,186231.147074,533562.405872,186179.641817,5,109.84353 1071,533474.991734,186420.912754,533482.923483,186219.060534,3,202.008 1072,533054.755832,186318.143693,533574.287005,186366.788247,8,521.80353 1073,533417.795746,186355.021615,533418.092568,186330.738566,1,24.284863 1074,533347.630276,186386.082724,533383.586987,185953.226628,5,434.34695 1075,533362.281749,185976.779886,533556.774495,186028.615048,4,201.28168 1076,533258.286793,185940.551163,533328.69137,186347.333816,3,412.83038 1077,533353.673905,186202.125381,533446.843096,186196.526984,4,93.337242 1078,533411.752116,186194.487567,533483.912891,186236.265609,4,83.382149 1079,533409.311578,186207.383876,533479.048304,186167.875185,4,80.15078 1080,533464.941005,186001.282872,533474.274414,186179.56184,3,178.52312 1081,533828.279945,186210.288684,534061.432071,186167.57164,7,237.03304 1082,533878.534886,186281.537721,533888.008418,186196.675645,1,85.389229 1083,533682.624134,186064.349101,533742.84632,185963.538308,4,117.42882 1084,533709.279137,185963.01928,533744.655809,186067.010107,3,109.84353 1085,533835.736436,186271.953259,533852.696011,186024.360057,5,248.17337 1086,533733.194051,186303.439136,533854.626565,186302.170238,2,121.43914 1087,533725.543114,186352.617487,533835.553856,186402.470947,2,120.77968 1088,533730.336185,186357.350465,533734.4513,186301.666655,2,55.835659 1089,533774.1936,186550.921799,533848.770307,186141.420947,7,416.23627 1090,533536.74805,186128.167476,533878.833233,186207.963791,5,351.26874 1091,533545.052813,186227.880808,533837.560288,186220.48194,3,292.60104 1092,533779.396942,186340.208273,533814.289455,186346.879573,1,35.524551 1093,533698.193044,186172.665752,533707.521963,186079.795889,3,93.337242 1094,533699.913432,186114.112742,533752.662906,186049.536622,3,83.382149 1095,533684.371802,186043.434219,533712.255609,186118.578354,4,80.15078 1096,533517.661442,186030.798131,533695.147751,186050.010453,3,178.52312 1097,533938.795137,186482.57123,533968.265425,186185.434504,0,298.5946 1098,534035.7211,186002.464912,534367.794464,186130.867829,5,356.03375 1099,532354.288274,183002.991897,532380.436592,183829.50734,4,826.92896 ================================================ FILE: testdata/barnsbury_extended1_axial.tsv ================================================ Ref x1 y1 x2 y2 Connectivity Line Length 0 530635.696268 184468.675646 530732.377854 183731.866556 8 743.12512 1 530655.080407 184267.843134 531386.664678 184568.766995 9 791.0567 2 530781.419478 184322.997346 530814.78724 184178.968574 4 147.84348 3 530667.76131 184203.901437 531124.686107 184392.857349 5 494.45386 4 530798.725861 184207.390438 530856.762846 184149.487013 3 81.982307 5 530747.870324 184145.998012 530810.755405 184207.340453 3 87.848892 6 530753.938689 184164.022852 530781.427723 183967.049235 3 198.88251 7 530638.070845 184123.954322 531070.977779 184116.826362 7 432.96561 8 530837.494138 183967.908989 530855.674498 184153.675814 3 186.65433 9 530776.925919 183970.168342 530838.112518 183968.488823 3 61.209644 10 530803.879024 183673.983124 530817.351454 183970.908131 5 297.2305 11 530803.31836 183742.403539 530916.415863 183745.002795 2 113.12737 12 530912.186147 183663.646083 530932.996681 184479.606956 10 816.2262 13 530995.213912 184191.1051 531426.867596 184272.091918 4 439.18533 14 530992.995991 184260.565217 531006.303519 184067.090599 2 193.93173 15 531065.503058 184264.454104 531069.386482 184200.262479 3 64.308983 16 531014.260003 184282.658893 531076.262863 184252.777446 2 68.827721 17 531055.856337 184254.05708 531446.820644 184352.768824 4 403.23331 18 531101.674141 184455.949289 531227.444303 184068.530187 8 407.3226 19 531214.16151 184067.600453 531445.270572 184127.80322 7 238.82162 20 531166.28244 183883.173244 531225.605654 184081.636435 7 207.13977 21 531103.958023 183944.145791 531189.244935 183939.966987 1 85.389229 22 531199.126896 184509.586323 531222.402703 184422.521245 2 90.122643 23 531332.577077 184583.962646 531443.794706 184125.074001 10 472.17386 24 531026.454449 184114.297086 531441.626255 184200.71235 6 424.06982 25 531379.087467 183726.907975 531438.204555 184206.79061 11 483.51025 26 531367.365093 183473.836019 531409.569458 184011.596484 10 539.41406 27 531287.1303 183716.111065 531396.253684 183759.488649 5 117.42882 28 531294.394199 183777.773415 531391.413833 183726.268158 5 109.84353 29 531303.999695 183967.539095 531311.931444 183765.686875 4 202.008 30 531069.774 183880.95388 531403.294966 183913.414588 9 335.09689 31 531055.773886 183973.477395 531081.160429 183854.721389 3 121.43914 32 530979.070082 183853.471746 531006.056167 183971.198048 2 120.77968 33 531002.370625 183965.559662 531057.760946 183972.597647 2 55.835659 34 530675.049944 183881.16382 531237.536258 183892.420597 10 562.59894 35 531246.803707 183901.647956 531247.100529 183877.364907 1 24.284863 36 531378.13104 184039.148597 531423.297484 184035.389673 2 45.32259 37 531365.837654 184048.645878 531385.988583 184035.489644 2 24.065462 38 531360.008395 184112.477607 531368.607994 184041.148025 2 71.8461 39 531176.638237 183932.709065 531212.594948 183499.852969 6 434.34695 40 531191.28971 183523.406227 531385.782456 183575.241389 4 201.28168 41 530904.180192 183681.79089 531226.595062 183515.558473 5 362.74588 42 531087.294754 183504.461649 531157.699331 183893.960157 3 395.81042 43 531029.208299 183891.140964 531030.230687 183855.631128 1 35.524551 44 531182.681866 183748.751722 531275.851057 183743.153325 3 93.337242 45 531240.760077 183741.113908 531312.920852 183782.89195 4 83.382149 46 531238.319539 183754.010217 531308.056265 183714.501526 4 80.15078 47 531293.948966 183547.909213 531303.282375 183726.188181 3 178.52312 48 530707.321114 183575.611283 530731.660534 183750.551207 2 176.62498 49 530711.864142 183690.118506 530973.265559 183658.367594 4 263.32266 50 531139.131454 184142.888902 531154.533228 184098.471616 2 47.011806 51 531091.400795 184089.16428 531155.786477 184099.901207 1 65.274788 52 531060.226219 184127.683254 531065.651469 184023.503075 3 104.32134 53 530915.104898 184035.689587 531213.139122 184017.404821 3 298.5946 54 531281.498924 184088.374506 531294.732247 184020.813845 2 68.84449 55 531263.310319 184015.655322 531322.328466 184027.032065 3 60.104675 56 531267.276193 184023.293136 531279.998323 183953.103227 2 71.333557 57 531276.790994 183954.982689 531332.164824 183964.220045 3 56.139023 58 531315.938544 184033.420237 531330.606508 183957.32202 2 77.498955 59 530805.297175 183814.47291 530917.998915 183816.172423 2 112.71455 60 531137.25158 184338.103022 531389.731841 184417.270361 2 264.6011 61 531482.315148 184748.987159 531515.68291 184604.958387 3 147.84348 62 531368.65698 184629.89125 531825.581777 184818.847162 4 494.45386 63 531499.621531 184633.380251 531557.658516 184575.476826 3 81.982307 64 531448.765994 184571.987825 531511.651075 184633.330266 3 87.848892 65 531455.263586 184588.241656 531482.75262 184391.268039 3 198.88251 66 531253.867502 184551.34532 531771.873449 184542.816175 8 518.07617 67 531538.389808 184393.898802 531556.570168 184579.665627 3 186.65433 68 531477.821589 184396.158155 531539.008188 184394.478636 3 61.209644 69 531504.774694 184099.972937 531518.247124 184396.897944 5 297.2305 70 531504.21403 184168.393352 531617.311533 184170.992608 2 113.12737 71 531613.081817 184089.635896 531633.892351 184844.909702 11 755.56042 72 531696.109582 184617.094913 532336.825597 184713.631764 7 647.94781 73 531693.891661 184686.55503 531707.199189 184493.080412 3 193.93173 74 531766.398728 184690.443917 531770.282152 184626.252292 3 64.308983 75 531715.155673 184708.648706 531777.158533 184678.767259 2 68.827721 76 531756.752007 184680.046893 531893.049669 184714.459702 3 140.57487 77 531802.569811 184881.939102 531928.339973 184494.52 7 407.3226 78 531915.05718 184493.590266 532146.166242 184553.793033 5 238.82162 79 531867.17811 184309.163057 531926.501324 184507.626248 7 207.13977 80 531804.853693 184370.135604 531890.140605 184365.9568 1 85.389229 81 531914.954989 184937.248897 531938.230796 184850.183819 1 90.122643 82 531727.350119 184540.286899 532142.521925 184626.702163 5 424.06982 83 531988.02597 184142.100878 532097.149354 184185.478462 4 117.42882 84 531995.289869 184203.763228 532092.309503 184152.257971 4 109.84353 85 532004.895365 184393.528908 532012.827114 184191.676688 4 202.008 86 531770.66967 184306.943693 532197.700686 184339.404401 9 428.263 87 531756.669556 184399.467208 531782.056099 184280.711202 3 121.43914 88 531679.965752 184279.461559 531706.951837 184397.187861 2 120.77968 89 531703.266295 184391.549475 531758.656616 184398.58746 2 55.835659 90 531375.945614 184307.153633 531938.431928 184318.41041 10 562.59894 91 531947.699377 184327.637769 531947.996199 184303.35472 1 24.284863 92 532079.02671 184465.13841 532156.350838 184461.379486 1 77.415443 93 532066.733324 184474.635691 532086.884253 184461.479457 2 24.065462 94 532060.904065 184538.46742 532069.503664 184467.137838 2 71.8461 95 531877.533907 184358.698878 531913.490618 184005.483699 5 355.04062 96 531605.075862 184107.780703 531784.325886 184010.332886 5 204.02609 97 531761.919063 183988.762648 531858.595001 184319.94997 5 345.00909 98 531730.103969 184317.130777 531731.126357 184281.620941 1 35.524551 99 531883.577536 184174.741535 531976.746727 184169.143138 3 93.337242 100 531941.655747 184167.103721 532013.816522 184208.881763 4 83.382149 101 531939.215209 184180.00003 532008.951935 184140.491339 4 80.15078 102 531994.844636 184026.539839 532004.178045 184152.177994 3 125.98436 103 531409.165843 184133.61755 531674.161229 184084.357407 7 269.535 104 531840.027124 184568.878715 531855.428898 184524.461429 2 47.011806 105 531792.296465 184515.154093 531856.682147 184525.89102 1 65.274788 106 531761.121889 184553.673067 531766.547139 184449.492888 3 104.32134 107 531616.000568 184461.6794 531914.034792 184443.394634 3 298.5946 108 531982.394594 184514.364319 531995.627917 184446.803658 2 68.84449 109 531964.205989 184441.645135 532023.224136 184453.021878 3 60.104675 110 531968.171863 184449.282949 531980.893993 184379.09304 2 71.333557 111 531977.686664 184380.972502 532033.060494 184390.209858 3 56.139023 112 532016.834214 184459.41005 532031.502178 184383.311833 2 77.498955 113 531506.192845 184240.462723 531618.894585 184242.162236 2 112.71455 114 531838.14725 184764.092835 532090.627511 184843.260174 3 264.6011 115 531898.14101 185489.577346 532384.945646 183588.377395 18 1962.5341 116 532034.570496 184072.765934 532153.818761 183879.247573 2 227.30927 117 531848.44415 184056.30916 531872.755533 183888.256031 4 169.80252 118 531400.054039 183972.757185 532184.244392 184077.342903 11 791.13379 119 531934.003528 183974.894229 532082.780772 183561.676249 4 439.18533 120 531813.343861 183944.172569 532002.221345 183988.159089 2 193.93173 121 531954.870458 183903.130736 532017.621625 183917.199738 3 64.308983 122 532007.80999 183904.715765 532027.422876 183970.689929 2 68.827721 123 532005.819462 183925.065251 532165.607001 183554.842291 4 403.23331 124 531850.025607 183726.090547 532215.340633 183914.50679 8 411.04227 125 531846.989846 183739.055158 531943.272396 183520.502093 6 238.82162 126 531657.287906 183756.915025 531862.671007 183729.995445 7 207.13977 127 531707.542847 183828.164062 531717.01638 183743.301986 1 85.389229 128 531940.34277 183521.523908 532612.061879 183803.786692 10 728.61432 129 531863.159436 183931.80645 532014.667663 183535.72504 6 424.06982 130 531536.953309 183521.916305 532020.122575 183540.072134 8 483.51025 131 531322.823096 183496.217515 531822.859891 183537.217461 5 501.71484 132 531511.632096 183610.975442 531571.854282 183510.164649 5 117.42882 133 531538.287099 183509.645622 531573.66377 183613.636448 5 109.84353 134 531564.528151 183594.396389 531762.533216 183634.411704 4 202.008 135 531647.800083 183818.5796 531724.933652 183527.756719 8 300.87793 136 531562.202013 183850.065477 531683.634527 183848.796579 2 121.43914 137 531554.551076 183899.243828 531664.561818 183949.097288 2 120.77968 138 531559.344147 183903.976806 531563.459261 183848.292996 2 55.835659 139 531576.977884 184241.542411 531576.980112 184241.530177 1 0.012435302 140 531664.440206 183676.204772 531688.365256 183680.369694 1 24.284863 141 531845.046699 183572.646808 531848.537589 183527.458858 2 45.32259 142 531842.687431 183564.306378 531852.462311 183586.297243 2 24.065462 143 531845.502111 183582.366824 531914.547926 183602.2298 2 71.8461 144 531365.756011 183674.793817 531707.841194 183754.590132 5 351.26874 145 531374.060775 183774.507149 531666.56825 183767.108281 4 292.60104 146 531608.404903 183886.834614 531643.297417 183893.505914 1 35.524551 147 531527.201005 183719.292094 531536.529925 183626.42223 3 93.337242 148 531528.921394 183660.739083 531581.670868 183596.162963 4 83.382149 149 531513.379763 183590.060561 531541.26357 183665.204695 4 80.15078 150 531346.669404 183577.424472 531524.155712 183596.636795 3 178.52312 151 531867.958408 183802.842932 531909.351639 183825.129931 2 47.011806 152 531848.703773 183863.683623 531869.569538 183801.833663 1 65.274788 153 531779.776929 183878.633935 531881.759204 183900.601153 3 104.32134 154 531767.803098 184029.197571 531797.273386 183732.060846 5 298.5946 155 531813.648701 183652.055167 531878.234973 183675.891635 2 68.84449 156 531803.545994 183682.252572 531824.187543 183625.803494 3 60.104675 157 531744.455054 183655.80423 531811.718445 183679.555275 2 71.333557 158 531745.799066 183659.270202 531763.747518 183606.077695 3 56.139023 159 531756.689274 183606.516194 531829.475123 183633.130249 2 77.498955 160 532101.768494 183858.112362 532220.180595 183621.485389 2 264.6011 161 531603.201562 184097.54814 531677.778268 183688.047288 9 416.23627 162 530283.954463 184816.224091 530735.913127 184226.335686 8 743.12512 163 530031.188827 184139.955564 532155.727239 185032.528489 15 2304.4197 164 530658.07799 184557.915926 530736.182459 184432.387497 4 147.84348 165 530571.605016 184436.422319 531028.529813 184625.378231 5 494.45386 166 530666.7819 184526.451467 530666.970866 184608.433553 3 81.982307 167 530587.419247 184533.993682 530675.26257 184534.983211 3 87.848892 168 530484.78534 184684.376675 530604.445957 184525.51954 3 198.88251 169 530494.120564 184472.048499 530795.550319 184782.852818 7 432.96561 170 530525.083202 184723.367243 530669.158913 184604.69952 3 186.65433 171 530483.801413 184678.989008 530525.930499 184723.393522 3 61.209644 172 530293.689137 184907.701657 530512.942029 184707.017488 5 297.2305 173 530341.616956 184858.869376 530423.516952 184936.909058 2 113.12737 174 530363.061129 184991.515821 530950.638138 184434.164686 10 809.86853 175 530794.377847 184676.757956 531157.155075 184924.298761 4 439.18533 176 530714.63809 184772.38299 530841.86679 184626.019141 2 193.93173 177 530853.353986 184722.66267 530895.942795 184674.477205 3 64.308983 178 530872.524608 184625.397132 530895.312774 184690.342917 2 68.827721 179 530881.770348 184675.02409 531228.261643 184881.278496 4 403.23331 180 530872.205195 184927.553625 531056.800416 184564.460939 8 407.3226 181 530862.145357 184918.830286 531068.273127 185039.441704 7 238.82162 182 530697.991446 185015.573733 530880.160401 184916.976808 7 207.13977 183 530696.935008 184928.390774 530754.360003 184991.58642 1 85.389229 184 531185.28388 184712.955635 531230.299717 184634.880893 1 90.122643 185 531065.300707 185040.331386 531310.676276 184636.92219 8 472.17386 186 530762.244887 184753.196919 531117.1883 184985.253807 6 424.06982 187 530857.793097 185213.727228 531119.059025 184978.53416 7 351.53329 188 530551.230991 185447.375269 530733.983907 185290.855505 6 240.61809 189 530348.818115 184670.043145 530754.964885 185059.353265 7 562.59894 190 530751.101941 185076.766671 530768.042714 185059.366534 0 24.284863 191 530958.127638 185054.782177 530999.561686 185101.458496 2 62.413612 192 530956.132728 185039.376138 530961.105876 185062.922141 2 24.065462 193 530952.798246 185046.640697 530997.089847 184990.071126 2 71.8461 194 530292.86417 185138.907267 530369.446508 185353.216185 2 227.58112 195 530279.260644 185168.084421 530370.209055 184973.016186 4 215.22832 196 530155.854559 184909.143223 530296.643458 184802.490186 2 176.62498 197 530239.94609 184831.289787 530402.572415 185038.392418 5 263.32266 198 530841.737233 184854.861003 530862.205515 184812.538912 2 47.011806 199 530790.470732 184816.859996 530843.634143 184854.734123 1 65.274788 200 530725.866309 184845.156464 530795.607182 184767.573259 3 104.32134 201 530627.898364 184730.199677 530825.968862 184953.642755 4 298.5946 202 530886.13816 185008.857925 530924.487493 184951.683697 2 68.84449 203 530860.25048 184990.316729 530910.065992 185023.946875 3 60.104675 204 530827.884295 185046.385296 530868.452527 184987.710817 2 71.333557 205 530826.941205 185042.789476 530872.665797 185075.360191 3 56.139023 206 530866.690618 185079.142828 530910.054337 185014.911405 3 77.498955 207 531280.890316 184879.402502 531418.783795 184696.340072 3 229.18652 208 531365.823685 184738.325775 531592.602283 184976.32175 6 328.74097 209 531322.135167 184916.836174 531466.210877 184798.168452 2 186.65433 210 531280.853377 184872.45794 531322.982463 184916.862454 3 61.209644 211 531090.741101 185101.170589 531309.993993 184900.48642 4 297.2305 212 531234.61837 185110.479476 531708.28843 184665.008406 9 650.23676 213 531591.429811 184870.226888 531810.671873 185019.826566 3 265.41882 214 531511.690054 184965.851921 531638.918754 184819.488073 3 193.93173 215 531650.40595 184916.131602 531692.994759 184867.946136 3 64.308983 216 531669.576573 184818.866063 531692.364738 184883.811849 3 68.827721 217 531678.822312 184868.493022 532025.313608 185074.747427 4 403.23331 218 531669.25716 185121.022557 531803.886243 184855.964934 6 297.28864 219 531659.197321 185112.299218 531865.325091 185232.910635 4 238.82162 220 531525.017578 185192.81948 531677.212366 185110.445739 6 173.05688 221 531361.980864 184957.783264 531551.411968 185185.055352 4 295.86609 222 531559.296851 184946.66585 531914.240265 185178.722739 4 424.06982 223 531495.587084 185514.328262 531683.190124 185202.326857 6 364.06012 224 531462.599703 185412.663349 531570.487702 185459.028287 4 117.42882 225 531511.293539 185374.141666 531543.598132 185479.127446 4 109.84353 226 531145.870079 184863.512077 531379.525038 185080.330385 4 318.7551 227 531313.34303 185456.733951 531364.882898 185058.167136 5 401.88538 228 531306.054288 185343.694337 531471.261897 185366.875736 4 166.82605 229 531447.432504 185362.212424 531528.024132 185383.603353 4 83.382149 230 531454.813342 185351.359118 531476.276843 185428.582597 4 80.15078 231 531385.807059 185499.287467 531481.151482 185416.937606 3 125.98436 232 531046.820419 185009.825167 531131.431446 185132.77165 5 149.24767 233 531638.789198 185048.329935 531659.257479 185006.007844 2 47.011806 234 531587.522697 185010.328928 531640.686107 185048.203055 1 65.274788 235 531522.918273 185038.625395 531592.659147 184961.042191 3 104.32134 236 531424.950328 184923.668608 531623.020826 185147.111687 3 298.5946 237 531683.190124 185202.326857 531721.539458 185145.152628 2 68.84449 238 531522.475126 185175.01268 531707.117957 185217.415806 4 189.4492 239 531190.971716 185002.716462 531271.956062 185081.113568 2 112.71455 240 531383.970056 186031.229354 531510.979479 185470.505352 6 574.92853 241 531394.31707 185715.840841 531446.57893 185494.621034 2 227.30927 242 531201.708933 185510.951124 531303.192797 185374.811772 3 169.80252 243 531179.130486 185309.154054 531945.523583 185894.409458 13 964.30402 244 531119.729967 185890.482946 531306.259495 185492.876981 4 439.18533 245 531199.143477 185429.404668 531363.921212 185531.668132 2 193.93173 246 531270.345734 185558.418033 531324.705449 185592.778869 3 64.308983 247 531308.942264 185594.686673 531369.423608 185561.834543 2 68.827721 248 531173.537681 185953.820275 531321.905785 185578.874941 4 403.23331 249 531071.081902 185609.697629 531458.962707 185734.036583 8 407.3226 250 530991.888039 185821.097506 531078.08961 185598.37557 6 238.82162 251 530956.409773 185451.747407 531082.791848 185615.8646 7 207.13977 252 530989.078083 185503.570056 531042.308887 185436.803289 1 85.389229 253 530990.535791 185818.304973 531427.908644 185996.218258 7 472.17386 254 531053.182121 185860.746689 531225.67492 185473.343204 5 424.06982 255 530705.244826 185533.116831 531060.114084 185861.522043 8 483.51025 256 530721.65189 185566.086325 530750.221062 185452.185798 4 117.42882 257 530697.522371 185542.745556 530796.014069 185494.11443 4 109.84353 258 530775.957685 185501.282477 530944.392205 185612.803972 4 202.008 259 530842.445203 185661.751105 530993.246275 185401.392558 7 300.87793 260 530866.53772 185054.496792 530910.763225 185339.341033 5 288.25708 261 531241.837484 185051.9572 531241.844548 185051.946966 1 0.012435302 262 530922.274679 185514.972524 531058.699701 185297.133443 5 257.03241 263 530904.468114 185513.935543 530924.34682 185527.885154 1 24.284863 264 530929.736723 185749.262318 530959.18129 185714.807208 2 45.32259 265 530951.620343 185719.045249 530974.072142 185710.381351 2 24.065462 266 530966.368846 185708.247852 531029.276911 185742.952862 2 71.8461 267 530692.026577 185303.976423 530990.555487 185489.098583 6 351.26874 268 530835.94378 185306.864232 530970.178935 185451.086004 3 197.02538 269 530668.7796 185311.512872 531368.109166 185350.571812 10 700.41949 270 530778.756701 185458.835796 530837.745708 185386.502282 3 93.337242 271 530789.341101 185512.139628 530797.608142 185429.168318 4 83.382149 272 530736.68628 185468.226257 530809.499457 185434.724184 4 80.15078 273 530609.743661 185359.425586 530748.959542 185471.181754 4 178.52312 274 531137.98644 185568.028734 531183.03071 185581.486954 2 47.011806 275 531138.414156 185569.881144 531167.326902 185511.35892 2 65.274788 276 531037.954234 185568.212706 531226.956583 185337.048601 4 298.5946 277 530905.703102 185592.17185 531055.596881 185665.158545 2 166.71893 278 531259.240929 185945.187025 531342.541952 185694.040277 2 264.6011 279 530564.955234 184893.47949 530687.494969 184780.983957 2 166.34673 280 530406.734043 184768.71716 530476.74297 184939.450519 2 184.52948 281 531070.732747 185471.568523 531173.366327 185528.106492 2 117.17591 282 531054.947555 184568.105455 531230.772586 184476.728485 3 198.15195 283 533270.701887 183269.704674 533995.226148 183104.47889 8 743.12512 284 533457.921448 183355.764288 533604.573756 183337.034753 3 147.84348 285 533511.624314 183701.926679 533530.131552 183207.819313 5 494.45386 286 533572.342952 183331.843845 533646.798158 183366.158863 3 81.982307 287 533576.567617 183343.107265 533612.252246 183262.832514 3 87.848892 288 533597.456849 183274.783083 533791.716865 183232.153296 3 198.88251 289 533594.791129 183152.211723 533751.821496 183555.697392 7 432.96561 290 533642.492107 183366.593004 533810.382168 183285.028513 3 186.65433 291 533787.228453 183229.014949 533810.053185 183285.809776 3 61.209644 292 533800.574266 183267.181171 534074.33864 183151.426975 5 297.2305 293 534009.982255 183174.663224 534046.822896 183281.623817 2 113.12737 294 533363.7017 183552.296365 534121.646703 183249.402658 10 816.2262 295 533655.853794 183510.445932 533729.818734 183943.358112 4 439.18533 296 533589.946866 183532.48916 533776.00052 183477.77576 2 193.93173 297 533611.481324 183601.833701 533673.02611 183583.182025 3 64.308983 298 533576.613253 183560.102626 533626.168001 183607.868539 2 68.827721 299 533617.880948 183589.176602 533661.093042 183990.08783 4 403.23331 300 533444.467532 183702.258531 533851.451454 183685.651865 7 407.3226 301 533847.710281 183672.872952 533871.517605 183910.504985 7 238.82162 302 533838.522437 183688.479385 534004.029918 183563.923552 7 207.13977 303 533925.207623 183526.653856 533958.745975 183605.180913 1 85.389229 304 533207.325575 183960.304964 533517.743221 183803.863123 4 347.61066 305 533404.613467 183963.247494 533873.564387 183908.173141 9 472.17386 306 533738.730645 183513.06696 533801.880965 183932.408424 6 424.06982 307 533794.992702 183931.310648 534224.474603 183709.212763 11 483.51025 308 533968.092403 183836.668115 534457.72329 183610.329606 10 539.41406 309 534199.883601 183736.62557 534202.663279 183619.229654 5 117.42882 310 534147.361737 183647.456398 534229.355471 183720.549685 5 109.84353 311 533972.743724 183722.368537 534164.786549 183659.704473 4 202.008 312 533972.594317 183472.65139 534057.983991 183796.686166 9 335.09689 313 533880.967657 183491.655579 534001.148439 183474.218692 3 121.43914 314 533865.838452 183444.240875 533966.864912 183378.048841 2 120.77968 315 533869.845916 183438.826556 533882.48274 183493.213425 2 55.835659 316 533835.312059 183102.569364 534020.104195 183633.953815 10 562.59894 317 534014.669713 183645.849032 534037.544378 183637.694015 1 24.284863 318 533931.336857 183816.755233 533950.547856 183857.804894 2 45.32259 319 533918.1613 183808.525385 533937.496942 183822.85296 2 24.065462 320 533856.278232 183825.227352 533926.154582 183808.519327 2 71.8461 321 533961.173903 183590.83827 534379.574955 183474.228476 6 434.34695 322 534350.088555 183462.429267 534369.026017 183662.818101 4 201.28168 323 534101.850875 183248.196611 534369.70918 183492.811601 5 362.74588 324 533990.933559 183559.620921 534331.737103 183358.328008 3 395.81042 325 533948.953082 183438.148567 533982.60772 183426.774957 1 35.524551 326 534135.779962 183532.618397 534173.387016 183618.044094 3 93.337242 327 534148.995999 183666.60752 534163.112597 183584.429032 4 83.382149 328 534150.171418 183586.619216 534211.440101 183638.294124 4 80.15078 329 534198.822923 183637.876087 534362.763695 183567.208368 3 178.52312 330 533977.45538 183110.29529 534133.053441 183026.715223 2 176.62498 331 534027.251348 183070.743173 534147.809166 183304.847068 4 263.32266 332 533751.050565 183628.660294 533798.052098 183627.677537 2 47.011806 333 533784.854581 183565.242321 533797.146736 183629.349268 1 65.274788 334 533737.906423 183549.385586 533837.486192 183518.291973 3 104.32134 335 533773.77426 183381.348296 533894.426477 183654.481548 3 298.5946 336 533851.615179 183743.233739 533919.566465 183732.179943 2 68.84449 337 533913.491248 183700.922309 533923.319298 183760.218021 3 60.104675 338 533907.706166 183707.293901 533977.945511 183694.847607 2 71.333557 339 533975.069147 183692.492641 533985.637771 183747.627875 3 56.139023 340 533915.109567 183756.444407 533991.565242 183743.77091 2 77.498955 341 533943.085985 183201.548147 533980.63292 183307.825135 2 112.71455 342 533567.334441 183694.694167 533580.779713 183958.953461 2 264.6011 343 533281.590018 184813.90419 533299.34 184222.454929 10 591.71558 344 533203.504476 184131.512968 533448.516179 184142.247827 6 245.24675 345 533355.566737 184507.139752 533425.55373 183189.45307 10 1319.5439 346 533416.285375 184137.056918 533490.740581 184171.371937 3 81.982307 347 533420.51004 184148.320338 533456.19467 184068.045587 3 87.848892 348 533443.209115 184079.783606 533637.469131 184037.153819 3 198.88251 349 533407.865187 183878.109292 533595.763919 184360.910466 7 518.07617 350 533486.43453 184171.806078 533654.324591 184090.241587 3 186.65433 351 533631.170876 184034.228023 533653.995608 184091.022849 3 61.209644 352 533644.516689 184072.394244 533918.281063 183956.640049 5 297.2305 353 533853.924678 183979.876298 533890.765319 184086.836891 2 113.12737 354 533264.553798 184336.433171 533965.589126 184054.615732 11 755.56042 355 533499.796217 184315.659006 533573.761157 184748.571185 5 439.18533 356 533433.88929 184337.702234 533619.942943 184282.988833 3 193.93173 357 533455.423747 184407.046775 533516.968533 184388.395099 3 64.308983 358 533420.555676 184365.315699 533470.110424 184413.081613 2 68.827721 359 533461.823371 184394.389676 533505.035465 184795.300904 4 403.23331 360 533288.409955 184507.471605 533695.393878 184490.864939 8 407.3226 361 533691.652704 184478.086026 533715.460028 184715.718059 7 238.82162 362 533682.46486 184493.692459 533847.972341 184369.136626 7 207.13977 363 533769.150046 184331.86693 533802.688398 184410.393987 1 85.389229 364 533280.174611 184638.111522 533369.903983 184629.701356 2 90.122643 365 533248.55589 184768.460568 533717.50681 184713.386214 11 472.17386 366 533582.673068 184318.280034 533645.823388 184737.621498 6 424.06982 367 533638.935125 184736.523722 534121.003937 184485.225527 11 543.63696 368 534043.826024 184541.838644 534046.605702 184424.442728 4 117.42882 369 533991.30416 184452.669472 534073.297894 184525.762759 4 109.84353 370 533816.686147 184527.581611 534008.728972 184464.917547 4 202.008 371 533816.53674 184277.864464 533901.926415 184601.899239 9 335.09689 372 533724.91008 184296.868652 533845.090862 184279.431766 3 121.43914 373 533709.780875 184249.453948 533810.807335 184183.261915 2 120.77968 374 533713.788339 184244.03963 533726.425163 184298.426499 2 55.835659 375 533679.254482 183907.782438 533864.046618 184439.166889 10 562.59894 376 533858.612136 184451.062105 533881.486801 184442.907089 1 24.284863 377 533775.27928 184621.968307 533794.490279 184663.017968 2 45.32259 378 533762.103724 184613.738458 533781.439365 184628.066033 2 24.065462 379 533700.220655 184630.440425 533770.097005 184613.732401 2 71.8461 380 533805.116326 184396.051343 534148.833614 184307.10038 5 355.04062 381 533945.793298 184053.409685 534099.428093 184187.659445 5 204.02609 382 533834.875982 184364.833995 534111.873958 184159.156088 5 345.00909 383 533792.895505 184243.361641 533826.550144 184231.988031 1 35.524551 384 533979.722385 184337.831471 534017.329439 184423.257168 3 93.337242 385 533992.938422 184471.820594 534007.05502 184389.642106 4 83.382149 386 533994.113841 184391.83229 534055.382524 184443.507198 4 80.15078 387 534042.765346 184443.089161 534157.341868 184390.703292 3 125.98436 388 533853.526216 183878.666834 533991.751589 184110.060142 6 269.535 389 533594.992988 184433.873368 533641.994521 184432.89061 2 47.011806 390 533628.797004 184370.455395 533641.089159 184434.562341 1 65.274788 391 533581.848846 184354.59866 533681.428615 184323.505047 3 104.32134 392 533617.716683 184186.56137 533738.368901 184459.694622 3 298.5946 393 533695.557602 184548.446813 533763.508888 184537.393017 2 68.84449 394 533757.433671 184506.135383 533767.261721 184565.431094 3 60.104675 395 533751.648589 184512.506975 533821.887935 184500.060681 2 71.333557 396 533819.011571 184497.705715 533829.580194 184552.840948 3 56.139023 397 533759.05199 184561.657481 533835.507666 184548.983984 2 77.498955 398 533787.028409 184006.76122 533824.575343 184113.038209 3 112.71455 399 533411.276864 184499.907241 533424.722136 184764.166535 3 264.6011 400 534079.043875 184492.516695 534641.721189 184610.571934 10 574.92853 401 534078.581459 184263.75404 534244.617529 184228.188309 4 169.80252 402 534001.209547 183814.256308 534167.642419 184551.258139 11 755.56042 403 534184.643095 184315.712944 534623.810302 184321.836821 4 439.2099 404 534171.548117 184191.894135 534195.895544 184384.291435 2 193.93173 405 534259.186721 184310.35799 534267.786545 184374.08937 3 64.308983 406 534221.029704 184401.857388 534276.085944 184360.552837 2 68.827721 407 534256.311788 184365.753465 534658.98396 184387.018927 4 403.23331 408 534340.296458 184554.97902 534388.795247 184150.554043 7 407.3226 409 534375.5833 184152.209774 534613.971169 184166.597117 5 238.82162 410 534292.952711 183980.51823 534389.525079 184163.768494 7 207.13977 411 534243.591734 184052.389493 534326.461777 184031.801248 1 85.389229 412 534523.654664 184592.936178 534529.659313 184503.013793 1 90.122643 413 534200.445183 184234.314318 534624.49092 184238.835314 5 424.06982 414 534471.532711 183786.060015 534606.990485 184209.222433 7 444.31436 415 534421.265724 183576.333035 534556.477661 184059.484692 5 501.71484 416 534379.22304 183793.244614 534494.673805 183814.707337 5 117.42882 417 534398.270908 183852.339354 534483.502838 183783.049247 5 109.84353 418 534413.140645 183837.090409 534444.382051 184036.667977 4 202.008 419 534231.831306 183993.036716 534531.340314 183964.368091 8 300.87793 420 534172.577514 183923.701456 534215.940242 184037.13487 2 121.43914 421 534115.258786 184054.083176 534123.803083 183933.6061 2 120.77968 422 534121.029309 183939.744568 534174.676304 183924.264876 2 55.835659 423 533810.59916 184073.5153 533810.611406 184073.513141 1 0.012435302 424 533954.738015 184048.098338 534364.650043 183975.815827 8 416.23627 425 534371.123204 183959.195139 534375.526555 183983.077456 1 24.284863 426 534530.958921 184092.594917 534574.546569 184080.175007 2 45.32259 427 534520.73354 184104.289671 534537.960852 184087.485916 2 24.065462 428 534522.002078 184096.397688 534527.354661 184168.044127 2 71.8461 429 534268.71504 183678.612162 534312.689759 184027.117468 5 351.26874 430 534178.09244 183721.02987 534286.616931 183992.760989 4 292.60104 431 534154.143024 183979.798213 534160.00494 184014.835788 1 35.524551 432 534283.055419 183845.462203 534373.38459 183821.957288 3 93.337242 433 534338.56135 183826.740385 534417.437595 183853.779619 4 83.382149 434 534338.660061 183839.865219 534399.443055 183787.619882 4 80.15078 435 534353.39508 183626.897766 534397.018576 183800.008983 3 178.52312 436 534316.524037 184240.583205 534323.048179 184194.026299 2 47.011806 437 534259.30742 184197.099766 534324.554163 184195.186633 1 65.274788 438 534221.349777 184137.655347 534236.167736 184240.918947 3 104.32134 439 534075.999349 184178.716694 534364.876021 184103.158771 5 298.5946 440 534445.588895 184090.729314 534445.666539 184159.57376 2 68.84449 441 534413.76248 184091.742822 534473.866644 184091.495124 3 60.104675 442 534418.042635 184027.144569 534419.130132 184098.469833 2 71.333557 443 534415.259165 184029.608637 534471.374163 184027.966459 3 56.139023 444 534468.511671 184021.499835 534468.83228 184098.998125 2 77.498955 445 534352.419821 184432.477914 534615.442074 184461.340417 3 264.6011 446 532822.628275 183060.558178 533532.762428 183279.520388 8 743.12512 447 533311.003242 183772.13925 533342.10287 183213.502392 5 559.50183 448 533194.789303 183321.685907 533339.629599 183351.33356 4 147.84348 449 533234.487353 184185.811657 533278.689124 183198.40131 9 988.39923 450 533150.504528 183347.569737 533227.318113 183318.920628 3 81.982307 451 533192.683163 183247.117175 533222.262704 183329.836454 3 87.848892 452 533016.016412 183203.098735 533206.54312 183260.141057 3 198.88251 453 533031.59668 183528.720721 533218.370549 183138.112551 7 432.96561 454 532993.447981 183254.429505 533154.766037 183348.324784 3 186.65433 455 532993.717598 183255.233189 533020.727019 183200.304946 3 61.209644 456 532740.225415 183101.456559 533004.563505 183237.365869 5 297.2305 457 532757.924444 183233.346962 532802.663245 183129.442 2 113.12737 458 532685.720654 183195.618751 533412.442248 183553.057914 11 809.86853 459 533024.538111 183916.941189 533130.680604 183490.775096 4 439.18533 460 533013.314477 183449.208665 533194.753878 183517.68685 2 193.93173 461 533108.115245 183562.022779 533168.092312 183585.226165 3 64.308983 462 533152.99534 183590.14543 533205.984455 183546.220389 2 68.827721 463 533089.575533 183968.681125 533162.657458 183572.125795 4 403.23331 464 532922.524395 183650.858063 533327.125673 183697.863386 8 407.3226 465 532885.693914 183873.580068 532927.211036 183638.394822 7 238.82162 466 532779.479562 183518.056912 532935.205668 183654.64484 7 207.13977 467 532821.550289 183562.586222 532860.869029 183486.788093 1 85.389229 468 532883.827305 183871.101644 533293.632281 183952.760517 9 417.86157 469 532953.496908 183900.631433 533047.8399 183487.189023 6 424.06982 470 532548.783925 183646.448256 532960.447991 183900.052022 11 483.51025 471 532323.585929 183530.393563 532794.913219 183792.725629 8 539.41406 472 532571.255358 183675.623828 532577.265488 183558.348912 5 117.42882 473 532543.068654 183657.388289 532630.300523 183590.633501 5 109.84353 474 532612.008295 183601.543762 532798.825322 183678.398363 4 202.008 475 532708.264427 183746.1312 532817.654866 183429.39209 8 335.09689 476 532758.211581 183586.688488 532982.237138 183070.616672 8 562.59894 477 532740.540472 183589.113563 532762.740992 183598.956911 1 24.284863 478 532810.82743 183815.115636 532833.055397 183775.618109 2 45.32259 479 532826.456421 183781.237933 532846.809685 183768.396942 2 24.065462 480 532838.839254 183767.79295 532907.269939 183789.681389 2 71.8461 481 532411.696593 183400.519815 532820.202092 183548.10214 5 434.34695 482 532420.14458 183419.788898 532705.551235 183195.896947 4 362.74588 483 532468.070555 183288.522695 532792.861092 183514.746035 3 395.81042 484 532606.548409 183559.356739 532650.440517 183476.983667 3 93.337242 485 532619.308676 183526.604462 532627.238206 183609.608708 4 83.382149 486 532567.087105 183576.703398 532632.049753 183529.756598 4 80.15078 487 532319.10546 183440.943243 532579.700202 183577.230383 3 294.0813 488 532691.004424 182972.701974 532839.914144 183067.687656 2 176.62498 489 532655.483875 183248.950676 532793.216472 183024.521282 4 263.32266 490 532980.111006 183597.040814 533026.907326 183601.536855 2 47.011806 491 532980.888774 183598.775588 532997.942126 183535.767805 1 65.274788 492 532948.970195 183485.011804 533045.94493 183523.467543 3 104.32134 493 532882.00154 183616.560258 533022.747935 183353.217927 4 298.5946 494 532851.11962 183692.160301 532918.05361 183708.266348 2 68.84449 495 532845.279862 183719.83908 532859.5161 183661.444718 3 60.104675 496 532795.696864 183650.565417 532864.808334 183668.231221 2 71.333557 497 532784.077833 183702.622362 532798.741337 183648.432221 3 56.139023 498 532778.455497 183698.332789 532853.748882 183716.690184 2 77.498955 499 533126.981531 184343.351798 533236.94103 184128.252751 5 241.57544 500 532835.610266 183916.087636 533298.551877 184154.108856 5 520.54688 501 532781.105505 184010.249828 533459.094685 184343.719876 10 755.56042 502 533119.922963 184731.572266 533226.065455 184305.406173 5 439.18533 503 533108.699328 184263.839742 533290.13873 184332.317927 3 193.93173 504 533203.500097 184376.653856 533263.477163 184399.857242 3 64.308983 505 533248.380191 184404.776507 533301.369306 184360.851466 3 68.827721 506 533184.960385 184783.312202 533258.042309 184386.756872 5 403.23331 507 533017.909246 184465.48914 533313.224583 184499.685418 6 297.28864 508 532981.078765 184688.211145 533022.595887 184453.025899 8 238.82162 509 532874.864413 184332.687989 533030.590519 184469.275916 7 207.13977 510 532916.93514 184377.217299 532956.25388 184301.41917 1 85.389229 511 532979.212156 184685.732721 533312.519029 184749.741937 8 339.39749 512 533048.881759 184715.26251 533143.224751 184301.8201 7 424.06982 513 532593.913595 184428.026979 533055.832842 184714.683099 11 543.63696 514 532666.640209 184490.254905 532672.650339 184372.979989 5 117.42882 515 532638.453505 184472.019366 532725.685375 184405.264577 4 109.84353 516 532707.393146 184416.174838 532894.210173 184493.02944 4 202.008 517 532803.649278 184560.762277 532913.039717 184244.023167 9 335.09689 518 532884.448357 184243.450033 533002.988 184269.828409 3 121.43914 519 533001.360624 184271.268552 533018.030551 184217.979393 1 55.835659 520 532853.596432 184401.319564 533077.621989 183885.247749 9 562.59894 521 532835.925323 184403.74464 532858.125843 184413.587987 1 24.284863 522 532906.212281 184629.746713 532928.440249 184590.249186 2 45.32259 523 532921.841272 184595.86901 532942.194537 184583.028019 2 24.065462 524 532934.224105 184582.424026 533002.65479 184604.312466 2 71.8461 525 532579.486878 184248.319081 532915.586943 184362.733217 5 355.04062 526 532637.688968 184132.908686 532800.936086 184010.528024 5 204.02609 527 532627.410222 184103.554158 532888.245943 184329.377111 5 345.00909 528 532906.486242 184197.526206 532939.195758 184211.385546 1 35.524551 529 532701.93326 184373.987816 532745.825368 184291.614744 3 93.337242 530 532714.693527 184341.235539 532722.623057 184424.239785 4 83.382149 531 532662.471957 184391.334474 532727.434605 184344.387675 4 80.15078 532 532564.748392 184331.051265 532675.085054 184391.86146 3 125.98436 533 532750.868727 184063.581753 532906.016604 183843.177006 7 269.535 534 533075.495857 184411.671891 533122.292177 184416.167932 2 47.011806 535 533076.273625 184413.406665 533093.326978 184350.398881 1 65.274788 536 533044.355046 184299.642881 533141.329781 184338.09862 3 104.32134 537 532977.386391 184431.191335 533118.132786 184167.849003 3 298.5946 538 532946.504472 184506.791378 533013.438462 184522.897425 3 68.84449 539 532940.664713 184534.470157 532954.900952 184476.075795 3 60.104675 540 532891.081716 184465.196494 532960.193186 184482.862298 2 71.333557 541 532879.462684 184517.253439 532894.126188 184463.063297 3 56.139023 542 532873.840348 184512.963866 532949.133733 184531.321261 2 77.498955 543 532917.353772 184079.057405 532962.745749 183975.886969 2 112.71455 544 532065.2786 184514.06895 532635.210657 184438.436618 7 574.92853 545 532364.629597 184414.239317 532590.230088 184386.41984 1 227.30927 546 532489.874509 184162.462824 532652.784793 184210.349538 2 169.80252 547 532542.4661 184490.385692 532763.565425 183767.899229 12 755.56042 548 532030.38234 184165.122698 532543.133455 184254.228718 5 520.43597 549 532526.782394 184321.773294 532565.454237 184131.736438 2 193.93173 550 532455.856013 184306.221875 532469.199284 184243.312394 2 64.308983 551 532448.592493 184292.102419 532500.404605 184337.409821 2 68.827721 552 532151.559428 184344.737703 532467.9222 184298.767718 5 319.68521 553 532126.163226 184073.414024 532546.372759 184062.610646 5 420.34839 554 532532.763551 183974.089967 532584.490376 183864.218218 2 121.43914 555 532631.895052 183998.522448 532632.387207 183877.743771 2 120.77968 556 532582.355319 183864.623056 532634.69401 183884.072537 2 55.835659 557 532934.235328 184040.687683 532934.247379 184040.690753 1 0.012435302 558 532167.934598 183901.818224 532792.413758 184004.562433 7 632.87488 559 532368.508548 184092.677579 532506.956582 183612.623908 4 499.61923 560 532478.124198 183964.520986 532594.152127 183661.701955 4 324.28668 561 532590.210249 183956.03771 532598.676791 183921.536821 0 35.524551 562 532306.05875 184266.992332 532414.219172 184122.529385 3 180.46667 563 532412.630606 184123.573809 532477.551415 184130.362486 2 65.274788 564 532439.682428 184049.515329 532661.721044 184125.743623 5 234.75923 565 532847.771489 183350.898751 532995.822217 183426.742101 2 166.34673 566 532774.026261 183284.142626 532909.818834 183159.196609 2 184.52948 567 532709.490275 183812.886376 532835.431428 183979.968037 2 209.23062 568 532463.943732 184141.842329 532481.318515 184025.961742 3 117.17591 569 533323.064517 183697.391573 533469.816857 183830.537895 3 198.15195 570 529846.791844 185094.627525 532736.351417 185388.776756 16 2904.4927 571 530347.847156 185292.772305 530632.54739 185377.731381 3 297.10651 572 530537.847519 185421.393549 530918.45134 185724.218064 2 486.37634 573 530524.468228 184838.411754 530539.002713 185369.052417 5 530.83966 574 530335.169085 184982.866758 530559.280279 185043.45439 5 232.1566 575 530707.024701 184994.505864 530707.477025 185313.557473 6 319.05194 576 531131.431446 185132.77165 531131.431446 185359.356031 3 226.58438 577 530501.676063 185036.509115 530743.403575 185005.682885 5 243.68513 578 530485.48235 185236.499696 530775.181629 185251.675793 2 290.0965 579 532544.992916 185376.432414 536042.612412 185481.987222 23 3499.2119 580 532310.185466 184245.557105 532320.564971 184501.568004 4 256.22122 581 532121.12861 185156.54299 532552.782294 185237.529808 4 439.18533 582 532107.183652 185396.499385 532132.218217 185032.528489 3 364.83084 583 532191.417756 185229.891994 532195.30118 185165.700369 1 64.308983 584 532227.588839 185421.387179 532353.359001 185033.968077 5 407.3226 585 532340.076208 185033.038343 532571.18527 185093.24111 7 238.82162 586 532292.197138 184848.611134 532351.520352 185047.074325 6 207.13977 587 532229.872721 184909.583681 532315.159633 184905.404877 1 85.389229 588 532325.041594 185475.024213 532348.317401 185387.959135 1 90.122643 589 532458.491775 185549.400536 532569.709404 185090.511891 8 472.17386 590 532152.369147 185079.734976 532567.540953 185166.15024 5 424.06982 591 532505.002165 184692.345865 532564.119253 185172.2285 11 483.51025 592 532493.279792 184439.273909 532535.484156 184977.034374 10 539.41406 593 532413.044998 184681.548955 532522.168382 184724.926539 5 117.42882 594 532420.308897 184743.211305 532517.328531 184691.706048 5 109.84353 595 532429.914393 184932.976985 532437.846142 184731.124765 4 202.008 596 532009.678491 184830.207924 532529.209664 184878.852478 9 521.80353 597 532372.718405 184867.085846 532373.015227 184842.802797 1 24.284863 598 532504.045738 185004.586487 532549.212182 185000.827563 2 45.32259 599 532491.752352 185014.083768 532511.903281 185000.927534 2 24.065462 600 532485.923093 185077.915497 532494.522692 185006.585915 2 71.8461 601 532302.552935 184898.146955 532338.509646 184465.290859 6 434.34695 602 532317.204408 184488.844117 532511.697154 184540.679279 4 201.28168 603 532213.209452 184469.899539 532283.614029 184859.398047 3 395.81042 604 532308.596564 184714.189612 532401.765755 184708.591215 4 93.337242 605 532366.674775 184706.551798 532438.83555 184748.32984 4 83.382149 606 532364.234237 184719.448107 532433.970963 184679.939416 4 80.15078 607 532419.863664 184513.347103 532429.197073 184691.626071 3 178.52312 608 532265.046152 185108.326792 532280.447926 185063.909506 2 47.011806 609 532217.315493 185054.60217 532281.701175 185065.339097 1 65.274788 610 532186.140917 185093.121144 532191.566167 184988.940965 2 104.32134 611 532041.019596 185001.127477 532339.05382 184982.842711 3 298.5946 612 532407.413622 185053.812396 532420.646945 184986.251735 2 68.84449 613 532389.225017 184981.093212 532448.243164 184992.469955 3 60.104675 614 532393.190891 184988.731026 532405.913021 184918.541117 2 71.333557 615 532402.705692 184920.420579 532458.079522 184929.657935 3 56.139023 616 532441.853242 184998.858127 532456.521206 184922.75991 2 77.498955 617 532481.890775 185659.270838 533213.475046 185960.194699 11 791.0567 618 532608.229846 185714.42505 532641.597608 185570.396278 4 147.84348 619 532494.571678 185595.329141 532951.496475 185784.285053 4 494.45386 620 532625.536229 185598.818142 532683.573214 185540.914717 2 81.982307 621 532574.680692 185537.425716 532637.565773 185598.768157 2 87.848892 622 532379.782201 185516.78321 532897.788147 185508.254066 5 518.07617 623 532630.128728 185133.831243 532743.226231 185136.430499 1 113.12737 624 532738.996515 185055.073787 532759.807049 185810.347593 11 755.56042 625 532822.02428 185582.532804 533308.048429 185701.947063 4 500.479 626 532819.806359 185651.992921 532833.113887 185458.518303 3 193.93173 627 532892.313426 185655.881808 532896.19685 185591.690183 3 64.308983 628 532841.070371 185674.086597 532903.073231 185644.20515 2 68.827721 629 532882.666705 185645.484784 533018.964367 185679.897592 3 140.57487 630 532928.484509 185847.376993 533171.791246 185088.690552 12 796.74542 631 533040.971878 185459.028157 533342.086167 185539.229407 3 311.61203 632 533040.869687 185902.686787 533064.145494 185815.621709 1 90.122643 633 532853.264817 185505.72479 533314.949235 185601.821346 5 471.57932 634 532896.584368 185272.381584 533323.615384 185304.842292 5 428.263 635 532501.860312 185272.591524 533064.346626 185283.848301 5 562.59894 636 533003.448605 185324.136769 533056.976395 184798.314821 5 528.53943 637 532730.99056 185073.218594 532910.240585 184975.770777 5 204.02609 638 532887.833761 184954.200538 532984.509699 185285.387861 5 345.00909 639 533009.492234 185140.179426 533223.840618 185128.424782 4 214.67044 640 533120.759334 184991.97773 533164.669849 185152.192991 4 166.12364 641 532535.080541 185099.055441 532800.075927 185049.795298 6 269.535 642 532965.941822 185534.316606 532981.343596 185489.89932 2 47.011806 643 532918.211163 185480.591984 532982.596845 185491.328911 1 65.274788 644 532887.036587 185519.110958 532892.461837 185414.930779 2 104.32134 645 532632.107543 185205.900614 532744.809283 185207.600127 2 112.71455 646 532964.061948 185729.530726 533287.399961 185848.0167 3 344.36377 647 533160.485194 185038.203824 533312.377108 184720.549657 5 352.10129 648 532525.968737 184938.195076 533310.15909 185042.780793 10 791.13379 649 532783.202604 184722.352915 533016.354731 184679.635872 7 237.03304 650 532833.457546 184793.601953 532842.931078 184708.739877 1 85.389229 651 532637.546794 184576.413333 532697.76898 184475.60254 4 117.42882 652 532664.201797 184475.083512 532699.578469 184579.074338 3 109.84353 653 532790.659095 184784.017491 532807.61867 184536.424288 5 248.17337 654 532688.116711 184815.503368 532809.549225 184814.234469 2 121.43914 655 532680.465774 184864.681718 532790.476516 184914.535179 2 120.77968 656 532685.258845 184869.414696 532689.373959 184813.730886 2 55.835659 657 532702.892582 185206.980301 532702.89481 185206.968067 1 0.012435302 658 532729.11626 185062.986031 532803.692966 184653.485179 9 416.23627 659 532491.67071 184640.231707 532833.755893 184720.028022 5 351.26874 660 532499.975473 184739.94504 532792.482948 184732.546172 3 292.60104 661 532734.319602 184852.272505 532769.212115 184858.943804 1 35.524551 662 532653.115703 184684.729984 532662.444623 184591.860121 3 93.337242 663 532654.836092 184626.176973 532707.585566 184561.600854 3 83.382149 664 532639.294461 184555.498451 532667.178268 184630.642585 4 80.15078 665 532472.584102 184542.862363 532650.07041 184562.074685 3 178.52312 666 532893.717797 184994.635461 532923.188084 184697.498736 4 298.5946 667 531538.538439 185607.847884 531861.827826 185191.773577 6 526.90973 668 531733.704075 185347.638093 532464.148204 185651.318997 8 791.0567 669 531783.992688 185523.353816 531862.097157 185397.825387 4 147.84348 670 531697.519714 185401.860209 532154.444511 185590.816121 5 494.45386 671 531792.696598 185491.889357 531792.885564 185573.871444 3 81.982307 672 531713.333946 185499.431572 531801.177268 185500.421101 3 87.848892 673 531610.700038 185649.814566 531730.360655 185490.95743 4 198.88251 674 531620.035263 185437.486389 531921.465017 185748.290708 7 432.96561 675 531650.997901 185688.805133 531795.073611 185570.13741 4 186.65433 676 531609.716111 185644.426899 531651.845197 185688.831412 3 61.209644 677 531419.603835 185873.139547 531638.856727 185672.455379 5 297.2305 678 531467.531654 185824.307266 531549.43165 185902.346948 2 113.12737 679 531488.975827 185956.953711 532119.186289 185356.969123 9 870.14178 680 531920.292545 185642.195846 532283.069773 185889.736651 4 439.18533 681 531840.552788 185737.82088 531967.781488 185591.457031 2 193.93173 682 531979.268684 185688.10056 532021.857493 185639.915095 3 64.308983 683 531998.439307 185590.835022 532021.227472 185655.780807 2 68.827721 684 532007.685046 185640.46198 532354.176342 185846.716386 4 403.23331 685 531998.119894 185892.991515 532182.715114 185529.898829 7 407.3226 686 531988.060055 185884.268177 532194.187825 186004.879594 7 238.82162 687 531823.906145 185981.011624 532006.0751 185882.414698 6 207.13977 688 531822.849706 185893.828664 531880.274702 185957.02431 1 85.389229 689 532311.198579 185678.393526 532356.214415 185600.318783 1 90.122643 690 532191.215405 186005.769276 532436.590975 185602.36008 8 472.17386 691 531888.159585 185718.634809 532243.102999 185950.691698 5 424.06982 692 531983.707795 186179.165119 532196.631823 185988.747422 5 285.64932 693 531651.967629 186274.379 531834.720544 186117.859235 5 240.61809 694 531474.732813 185635.481035 531880.879584 186024.791155 5 562.59894 695 532084.042336 186020.220067 532125.476384 186066.896386 2 62.413612 696 532082.047427 186004.814029 532087.020575 186028.360031 2 24.065462 697 532078.712944 186012.078587 532123.004546 185955.509016 2 71.8461 698 531418.778869 186104.345157 531495.361206 186318.654076 1 227.58112 699 531405.175343 186133.522312 531496.123753 185938.454076 2 215.22832 700 531967.651931 185820.298893 531988.120213 185777.976802 2 47.011806 701 531916.385431 185782.297886 531969.548841 185820.172013 1 65.274788 702 531851.781007 185810.594354 531921.521881 185733.01115 3 104.32134 703 531753.813062 185695.637567 531951.88356 185919.080645 5 298.5946 704 532012.052858 185974.295815 532050.402192 185917.121587 2 68.84449 705 531986.165178 185955.754619 532035.980691 185989.384765 3 60.104675 706 531953.798994 186011.823186 531994.367226 185953.148707 2 71.333557 707 531952.855903 186008.227366 531998.580495 186040.798082 3 56.139023 708 531992.605316 186044.580718 532035.969035 185980.349295 3 77.498955 709 532589.748562 185685.358288 532589.937528 185767.340375 3 81.982307 710 532510.38591 185692.900503 532598.229233 185693.890033 3 87.848892 711 532406.805014 185844.840392 532526.465631 185685.983256 3 198.88251 712 532357.833442 185569.858724 532718.516981 185941.75964 8 518.07617 713 532448.049865 185882.274065 532592.125576 185763.606342 3 186.65433 714 532406.768075 185837.89583 532448.897161 185882.300344 3 61.209644 715 532216.655799 186066.608479 532435.908691 185865.92431 5 297.2305 716 532360.533068 186075.917366 532834.203129 185630.446297 10 650.23676 717 532717.344509 185835.664778 532936.586571 185985.264456 3 265.41882 718 532637.604753 185931.289811 532764.833452 185784.925963 3 193.93173 719 532776.320648 185881.569492 532818.909457 185833.384027 3 64.308983 720 532795.491271 185784.303954 532818.279437 185849.249739 3 68.827721 721 532804.73701 185833.930912 533151.228306 186040.185318 3 403.23331 722 532795.171858 186086.460447 532929.800941 185821.402824 6 297.28864 723 532785.112019 186077.737108 532991.239789 186198.348525 3 238.82162 724 532620.958109 186174.480555 532803.127064 186075.88363 5 207.13977 725 532487.895562 185923.221154 532677.326666 186150.493242 2 295.86609 726 532685.211549 185912.103741 533069.580712 186166.970325 5 461.19046 727 532596.323721 186341.331993 532783.926762 186029.330587 5 364.06012 728 532563.33634 186239.667079 532671.224339 186286.032017 4 117.42882 729 532612.030176 186201.145396 532644.334769 186306.131177 3 109.84353 730 532271.784777 185828.949967 532505.439737 186045.768275 4 318.7551 731 532414.079667 186283.737681 532456.17094 185958.238507 5 328.20935 732 532406.790925 186170.698068 532571.998535 186193.879467 4 166.82605 733 532548.169142 186189.216154 532628.760769 186210.607084 3 83.382149 734 532555.549979 186178.362848 532577.01348 186255.586328 4 80.15078 735 532486.543697 186326.291197 532581.88812 186243.941337 3 125.98436 736 532172.735117 185975.263057 532257.346144 186098.20954 5 149.24767 737 532764.703896 186013.767825 532785.172178 185971.445734 2 47.011806 738 532713.437395 185975.766818 532766.600805 186013.640945 1 65.274788 739 532648.832971 186004.063285 532718.573845 185926.480081 3 104.32134 740 532550.865026 185889.106499 532748.935524 186112.549577 4 298.5946 741 532809.104823 186167.764747 532847.454156 186110.590519 2 68.84449 742 532783.217143 186149.223551 532833.032655 186182.853696 1 60.104675 743 532316.886414 185968.154353 532397.870761 186046.551458 2 112.71455 744 532484.706693 186858.233085 532611.716116 186297.509083 5 574.92853 745 532495.053707 186542.844571 532547.315567 186321.624765 2 227.30927 746 532302.445571 186337.954854 532403.929434 186201.815503 3 169.80252 747 532279.867123 186136.157785 533301.964636 186916.681637 8 1286.0408 748 532220.466605 186717.486676 532406.996132 186319.880711 4 439.18533 749 532299.880114 186256.408398 532464.657849 186358.671862 2 193.93173 750 532371.082371 186385.421764 532425.442087 186419.782599 3 64.308983 751 532409.678901 186421.690404 532470.160245 186388.838273 2 68.827721 752 532274.274318 186780.824005 532422.642422 186405.878671 4 403.23331 753 532171.81854 186436.70136 532559.699344 186561.040314 8 407.3226 754 532092.624676 186648.101237 532178.826247 186425.3793 6 238.82162 755 532057.146411 186278.751138 532183.528486 186442.868331 7 207.13977 756 532089.81472 186330.573787 532143.045525 186263.807019 1 85.389229 757 532433.590954 186711.557255 532517.844537 186743.548266 1 90.122643 758 532091.272428 186645.308703 532528.645281 186823.221988 7 472.17386 759 532153.918759 186687.75042 532326.411557 186300.346934 5 424.06982 760 531805.981463 186360.120561 532160.850721 186688.525773 8 483.51025 761 531638.584156 186248.397279 532019.187977 186551.221795 2 486.37634 762 531822.388527 186393.090056 531850.957699 186279.189528 4 117.42882 763 531798.259009 186369.749287 531896.750706 186321.11816 4 109.84353 764 531876.694323 186328.286208 532045.128842 186439.807703 4 202.008 765 531943.18184 186488.754835 532093.982912 186228.396289 7 300.87793 766 531995.178958 186015.230887 532011.499862 186166.344763 4 151.99268 767 532367.752182 186017.395091 532367.759246 186017.384856 1 0.012435302 768 532023.011316 186341.976255 532159.436339 186124.137174 5 257.03241 769 532005.204751 186340.939274 532025.083457 186354.888884 1 24.284863 770 532030.47336 186576.266049 532059.917927 186541.810938 2 45.32259 771 532052.35698 186546.04898 532074.808779 186537.385081 2 24.065462 772 532067.105483 186535.251582 532130.013549 186569.956592 2 71.8461 773 531792.763214 186130.980154 532091.292124 186316.102313 6 351.26874 774 531936.680417 186133.867962 532070.915572 186278.089735 3 197.02538 775 531769.516237 186138.516602 532468.845803 186177.575543 11 700.41949 776 531879.493338 186285.839527 531938.482345 186213.506013 3 93.337242 777 531890.077738 186339.143359 531898.344779 186256.172049 4 83.382149 778 531837.422918 186295.229987 531910.236094 186261.727914 4 80.15078 779 531710.480298 186186.429316 531849.69618 186298.185485 4 178.52312 780 532238.723078 186395.032465 532283.767347 186408.490685 2 47.011806 781 532239.150794 186396.884875 532268.06354 186338.36265 2 65.274788 782 532138.690872 186395.216436 532327.693221 186164.052331 4 298.5946 783 532006.439739 186419.175581 532156.333518 186492.162275 2 166.71893 784 532359.977566 186772.190756 532443.278589 186521.044007 2 264.6011 785 531690.869932 185858.91738 531813.409667 185746.421847 3 166.34673 786 531532.648741 185734.155051 531602.657669 185904.88841 2 184.52948 787 532171.469385 186298.572254 532274.102964 186355.110223 2 117.17591 788 532180.862253 185533.543345 532356.687285 185442.166375 1 198.15195 789 534574.657185 184195.402125 535121.140847 184069.916781 5 560.70575 790 534563.562293 184974.129007 534591.680522 184183.57219 13 791.0567 791 534583.836146 184321.202178 534730.488454 184302.472644 3 147.84348 792 534698.25765 184297.281735 534772.712856 184331.596753 3 81.982307 793 534702.482315 184308.545155 534738.166945 184228.270404 3 87.848892 794 534723.371547 184240.220974 534917.631564 184197.591186 3 198.88251 795 534720.705827 184117.649614 534877.736194 184521.135283 7 432.96561 796 534768.406805 184332.030894 534936.296866 184250.466403 3 186.65433 797 534913.143151 184194.45284 534935.967883 184251.247666 3 61.209644 798 534926.488964 184232.619061 535200.253338 184116.864865 5 297.2305 799 535135.896953 184140.101114 535172.737595 184247.061707 2 113.12737 800 534562.260508 184461.164981 535247.561401 184214.840549 8 728.22595 801 534781.768492 184475.883822 534855.733432 184908.796002 4 439.18533 802 534715.861565 184497.92705 534901.915218 184443.21365 2 193.93173 803 534737.396022 184567.271591 534798.940809 184548.619916 3 64.308983 804 534702.527951 184525.540516 534752.082699 184573.306429 2 68.827721 805 534743.795646 184554.614492 534787.00774 184955.52572 4 403.23331 806 534570.382231 184667.696421 534977.366153 184651.089755 7 407.3226 807 534973.624979 184638.310842 534997.432303 184875.942875 7 238.82162 808 534964.437135 184653.917275 535129.944616 184529.361442 7 207.13977 809 535051.122321 184492.091746 535084.660673 184570.618804 1 85.389229 810 534553.928547 184777.71118 534643.657919 184769.301014 2 90.122643 811 534530.528166 184928.685384 534999.479085 184873.611031 10 472.17386 812 534864.645343 184478.50485 534927.795663 184897.846314 6 424.06982 813 534920.9074 184896.748538 535350.389301 184674.650654 11 483.51025 814 535094.007101 184802.106005 535583.637988 184575.767496 10 539.41406 815 535325.798299 184702.06346 535328.577977 184584.667544 5 117.42882 816 535273.276435 184612.894289 535355.270169 184685.987575 5 109.84353 817 535098.658423 184687.806427 535290.701247 184625.142364 4 202.008 818 535098.509015 184438.08928 535183.89869 184762.124056 9 335.09689 819 535006.882355 184457.093469 535127.063137 184439.656582 3 121.43914 820 534991.75315 184409.678765 535092.77961 184343.486731 2 120.77968 821 534995.760614 184404.264446 535008.397438 184458.651315 2 55.835659 822 534961.226757 184068.007254 535146.018893 184599.391705 10 562.59894 823 535140.584411 184611.286922 535163.459076 184603.131906 1 24.284863 824 535057.251555 184782.193123 535076.462555 184823.242784 2 45.32259 825 535044.075999 184773.963275 535063.41164 184788.29085 2 24.065462 826 534982.19293 184790.665242 535052.06928 184773.957217 2 71.8461 827 535087.088601 184556.27616 535505.489654 184439.666367 6 434.34695 828 535476.003253 184427.867158 535494.940716 184628.255992 4 201.28168 829 535227.765574 184213.634501 535495.623878 184458.249491 5 362.74588 830 535116.848257 184525.058811 535457.651802 184323.765899 3 395.81042 831 535074.86778 184403.586458 535108.522419 184392.212847 1 35.524551 832 535261.69466 184498.056288 535299.301714 184583.481985 3 93.337242 833 535274.910697 184632.04541 535289.027295 184549.866922 4 83.382149 834 535276.086116 184552.057106 535337.354799 184603.732014 4 80.15078 835 535324.737621 184603.313977 535488.678393 184532.646259 3 178.52312 836 535103.370078 184075.733181 535258.968139 183992.153113 2 176.62498 837 535153.166046 184036.181063 535273.723864 184270.284958 4 263.32266 838 534876.965263 184594.098185 534923.966796 184593.115427 2 47.011806 839 534910.769279 184530.680211 534923.061435 184594.787158 1 65.274788 840 534863.821121 184514.823476 534963.40089 184483.729864 3 104.32134 841 534899.688958 184346.786186 535020.341176 184619.919439 2 298.5946 842 534977.529877 184708.67163 535045.481163 184697.617833 2 68.84449 843 535039.405946 184666.3602 535049.233996 184725.655911 3 60.104675 844 535033.620864 184672.731791 535103.86021 184660.285498 2 71.333557 845 535100.983846 184657.930531 535111.552469 184713.065765 3 56.139023 846 535041.024265 184721.882297 535117.479941 184709.2088 2 77.498955 847 535069.000684 184166.986037 535106.547618 184273.263025 2 112.71455 848 534693.249139 184660.132058 534706.694412 184924.391352 2 264.6011 849 534407.504716 185779.34208 534453.692303 184480.757033 15 1299.4061 850 534427.77857 185126.415252 534574.430877 185107.685717 4 147.84348 851 534481.481436 185472.577643 534499.988673 184978.470277 4 494.45386 852 534542.200073 185102.494808 534616.65528 185136.809827 3 81.982307 853 534546.424738 185113.758229 534582.109368 185033.483477 3 87.848892 854 534569.123813 185045.221496 534763.38383 185002.591709 3 198.88251 855 534533.779885 184843.547182 534721.678617 185326.348356 8 518.07617 856 534612.349228 185137.243968 534780.239289 185055.679477 3 186.65433 857 534757.085574 184999.665913 534779.910306 185056.46074 3 61.209644 858 534770.431387 185037.832134 535044.195761 184922.077939 5 297.2305 859 534979.839376 184945.314188 535016.680018 185052.274781 2 113.12737 860 534390.468496 185301.871061 535091.503824 185020.053622 11 755.56042 861 534625.710916 185281.096896 534699.675855 185714.009075 5 439.18533 862 534559.803988 185303.140124 534745.857641 185248.426724 3 193.93173 863 534581.338446 185372.484665 534642.883232 185353.832989 3 64.308983 864 534546.470374 185330.75359 534596.025122 185378.519503 2 68.827721 865 534587.738069 185359.827566 534630.950164 185760.738794 5 403.23331 866 534157.732629 185538.915308 534848.842646 185522.308643 9 691.30951 867 534817.567402 185443.523916 534841.374726 185681.155949 6 238.82162 868 534808.379558 185459.130349 534973.88704 185334.574516 7 207.13977 869 534895.064744 185297.30482 534928.603096 185375.831877 1 85.389229 870 534406.08931 185659.974073 534495.818681 185651.563907 1 90.122643 871 534374.470589 185733.898458 534843.421508 185678.824105 7 472.17386 872 534708.587766 185283.717924 534771.738086 185703.059388 7 424.06982 873 534764.849823 185701.961612 535078.992376 185538.201886 5 354.26373 874 534942.451438 185243.302354 535027.841113 185567.33713 8 335.09689 875 534850.824778 185262.306543 534971.005561 185244.869656 3 121.43914 876 534835.695573 185214.891839 534936.722033 185148.699805 2 120.77968 877 534839.703037 185209.47752 534852.339862 185263.864389 2 55.835659 878 534805.16918 184873.220328 534989.961316 185404.604779 10 562.59894 879 534984.526835 185416.499995 535007.401499 185408.344979 1 24.284863 880 534901.193978 185587.406197 534920.404978 185628.455858 2 45.32259 881 534888.018422 185579.176349 534907.354063 185593.503923 2 24.065462 882 534826.135353 185595.878316 534896.011703 185579.170291 2 71.8461 883 534931.031024 185361.489234 535274.748313 185272.538271 4 355.04062 884 535071.707997 185018.847575 535225.342791 185153.097336 5 204.02609 885 534960.790681 185330.271885 535237.788656 185124.593978 5 345.00909 886 534918.810203 185208.799531 534952.464842 185197.425921 1 35.524551 887 534979.440914 184844.104724 535117.666287 185075.498032 6 269.535 888 534720.907686 185399.311258 534767.909219 185398.328501 2 47.011806 889 534754.711702 185335.893285 534767.003858 185400.000231 1 65.274788 890 534707.763545 185320.03655 534807.343313 185288.942937 3 104.32134 891 534743.631381 185151.99926 534864.283599 185425.132512 3 298.5946 892 534912.943107 184972.19911 534950.490041 185078.476099 2 112.71455 893 534537.191562 185503.477633 534550.636835 185729.604425 2 226.52615 894 535204.496158 185229.19193 535370.532227 185193.626199 4 169.80252 895 535127.124245 184779.694198 535293.557118 185516.696029 9 755.56042 896 535310.557793 185281.150834 535749.725 185277.1594 4 439.18533 897 535297.462815 185157.332025 535321.810242 185349.729325 2 193.93173 898 535385.101419 185275.79588 535393.701243 185339.52726 3 64.308983 899 535346.944402 185367.295278 535402.000642 185325.990727 2 68.827721 900 535382.226487 185331.191356 535784.898658 185352.456817 4 403.23331 901 535466.211156 185520.41691 535514.709946 185115.991934 7 407.3226 902 535501.497998 185117.647664 535739.885867 185132.035007 6 238.82162 903 535418.867409 184945.95612 535515.439778 185129.206385 7 207.13977 904 535369.506432 185017.827383 535452.376475 184997.239138 1 85.389229 905 535717.506417 185601.375402 535737.910212 185129.642602 7 472.17386 906 535326.359881 185199.752209 535750.405618 185204.273205 6 424.06982 907 535597.447409 184751.497905 535748.223563 185210.898302 8 483.51025 908 535547.180422 184541.770925 535682.392359 185024.922582 5 501.71484 909 535505.137738 184758.682504 535620.588503 184780.145227 5 117.42882 910 535524.185606 184817.777244 535609.417536 184748.487137 5 109.84353 911 535539.055343 184802.528299 535570.296749 185002.105868 4 202.008 912 535357.746004 184958.474606 535657.255012 184929.805982 8 300.87793 913 535298.492212 184889.139347 535341.85494 185002.57276 2 121.43914 914 535241.173485 185019.521066 535249.717782 184899.04399 2 120.77968 915 535246.944008 184905.182458 535300.591002 184889.702767 2 55.835659 916 534936.513858 185038.95319 534936.526105 185038.951031 1 0.012435302 917 535080.652713 185013.536228 535490.564742 184941.253717 8 416.23627 918 535497.037903 184924.633029 535501.441253 184948.515346 1 24.284863 919 535656.87362 185058.032807 535700.461267 185045.612897 2 45.32259 920 535646.648239 185069.727561 535663.87555 185052.923806 2 24.065462 921 535647.916776 185061.835578 535653.26936 185133.482017 2 71.8461 922 535394.629739 184644.050052 535438.604457 184992.555358 5 351.26874 923 535304.007138 184686.46776 535412.531629 184958.198879 4 292.60104 924 535280.057722 184945.236103 535285.919638 184980.273679 1 35.524551 925 535408.970117 184810.900093 535499.299289 184787.395178 3 93.337242 926 535464.476048 184792.178276 535543.352293 184819.21751 4 83.382149 927 535464.574759 184805.30311 535525.357753 184753.057772 4 80.15078 928 535479.309778 184592.335656 535522.933274 184765.446874 3 178.52312 929 535442.438736 185206.021096 535448.962877 185159.464189 2 47.011806 930 535385.222118 185162.537657 535450.468862 185160.624523 1 65.274788 931 535347.264475 185103.093237 535362.082435 185206.356837 3 104.32134 932 535201.914047 185144.154584 535490.790719 185068.596661 5 298.5946 933 535571.503594 185056.167204 535571.581237 185125.01165 2 68.84449 934 535539.677178 185057.180712 535599.781343 185056.933015 3 60.104675 935 535543.957333 184992.582459 535545.04483 185063.907723 2 71.333557 936 535541.173863 184995.046528 535597.288862 184993.404349 3 56.139023 937 535594.426369 184986.937725 535594.746978 185064.436015 2 77.498955 938 535478.334519 185397.915805 535741.356772 185426.778307 2 264.6011 939 534386.096584 184657.946566 534391.276593 184519.650385 2 138.39316 940 534150.45281 184882.379079 534256.595302 184456.212986 3 439.18533 941 534215.490232 184934.119016 534288.572156 184537.563685 2 403.23331 942 534104.300387 184622.785745 534453.040371 184663.301276 5 351.08557 943 534358.410111 184835.358794 534447.258927 184850.457767 1 90.122643 944 534009.742003 184836.539535 534473.259002 184926.540316 8 472.17386 945 534079.411606 184866.069323 534173.754598 184452.626913 7 424.06982 946 533755.439882 184661.626429 534086.362689 184865.489913 5 388.67752 947 534106.025704 184562.478705 534152.822024 184566.974746 2 47.011806 948 534106.803472 184564.213479 534123.856825 184501.205695 2 65.274788 949 534252.89623 185308.789689 534476.385315 184841.397417 6 518.07617 950 533961.524964 184881.525527 534304.335034 185057.781168 4 385.46698 951 533907.020204 184975.687719 534585.009383 185309.157766 10 755.56042 952 534245.837661 185697.010156 534351.980153 185270.844063 7 439.18533 953 534234.614027 185229.277632 534416.053428 185297.755817 3 193.93173 954 534329.414795 185342.091746 534389.391862 185365.295132 2 64.308983 955 534374.294889 185370.214397 534427.284005 185326.289357 2 68.827721 956 534310.875083 185748.750093 534354.077917 185514.323944 4 238.37387 957 534042.849838 185342.655189 534082.168579 185266.85706 0 85.389229 958 534231.245567 185651.170611 534438.433728 185715.179828 4 216.85043 959 534174.796457 185680.7004 534269.139449 185267.25799 6 424.06982 960 533929.563976 185526.200168 534038.954415 185209.461057 6 335.09689 961 534010.363055 185208.887923 534128.902698 185235.266299 3 121.43914 962 534127.275322 185236.706442 534143.945249 185183.417283 1 55.835659 963 533979.51113 185366.757455 534203.536687 184850.685639 7 562.59894 964 533961.840022 185369.18253 533984.040541 185379.025878 1 24.284863 965 533705.401576 185213.756971 534041.501641 185328.171107 4 355.04062 966 533763.603666 185098.346576 533926.850785 184975.965914 5 204.02609 967 533753.32492 185068.992048 534014.160641 185294.815002 5 345.00909 968 533876.783425 185029.019644 534031.931302 184808.614896 6 269.535 969 534201.410555 185377.109782 534248.206875 185381.605823 2 47.011806 970 534202.188323 185378.844555 534219.241676 185315.836772 1 65.274788 971 534170.269744 185265.080771 534267.244479 185303.536511 3 104.32134 972 534043.26847 185044.495295 534088.660447 184941.324859 3 112.71455 973 533615.789208 185127.900715 533778.699491 185175.787428 2 169.80252 974 533668.380798 185455.823582 533889.480123 184733.337119 10 755.56042 975 533156.297039 185130.560588 533669.048154 185219.666608 6 520.43597 976 533652.697092 185287.211184 533691.368935 185097.174328 3 193.93173 977 533574.507192 185257.540309 533726.355444 185312.833746 4 161.60216 978 533277.474126 185310.175594 533593.836898 185264.205608 4 319.68521 979 533252.077925 185038.851914 533672.287457 185028.048537 5 420.34839 980 533658.67825 184939.527857 533710.405074 184829.656108 2 121.43914 981 533757.80975 184963.960338 533758.301905 184843.181661 2 120.77968 982 533708.270017 184830.060946 533760.608708 184849.510427 2 55.835659 983 534060.150026 185006.125573 534060.162077 185006.128643 1 0.012435302 984 532885.238784 184800.028308 533918.328456 184970.000324 9 1046.9789 985 533494.423246 185058.115469 533576.328783 184703.140253 4 364.30197 986 533604.038896 184929.958876 533720.066825 184684.421651 4 271.57138 987 533716.124948 184921.475601 533724.59149 184886.974711 0 35.524551 988 533431.973449 185232.430222 533540.13387 185087.967275 2 180.46667 989 533538.545304 185089.0117 533603.466114 185095.800376 2 65.274788 990 533565.597126 185014.95322 533787.635743 185091.181513 5 234.75923 991 533835.404973 184778.324266 533961.346126 184945.405928 2 209.23062 992 533589.85843 185107.28022 533607.233213 184991.399632 3 117.17591 993 534448.979216 184662.829463 534595.731555 184795.975785 2 198.15195 994 531448.583794 186119.776035 531733.284027 186204.735111 1 297.10651 995 531632.472108 185930.735816 531639.73935 186196.056148 3 265.41983 996 531358.457914 185930.133858 531685.194977 186008.89228 4 336.09521 997 531770.029234 185963.283155 531808.213662 186140.561203 1 181.34375 998 532232.168083 186022.145713 532232.168083 186186.359762 3 164.21405 999 531627.590761 186001.947005 531869.318273 185971.120775 5 243.68513 1000 531611.397049 186201.937586 531901.096327 186217.113684 2 290.0965 1001 533414.11404 185165.537038 533424.425402 184724.739221 5 440.9184 1002 532990.64376 184514.529144 533322.717124 184642.932061 7 356.03375 1003 533885.021829 184579.439517 534153.204805 184752.247218 3 319.03702 1004 531510.629785 185399.989769 531550.244234 185166.880259 6 236.45158 1005 532988.23624 186147.308367 533381.902938 186201.567533 5 397.38837 1006 532778.64114 187622.18866 533427.582291 185080.181236 15 2623.5332 1007 534248.581817 185619.448736 534493.593519 185630.183595 4 245.24675 1008 534172.058872 185831.287567 534282.01837 185616.188519 7 241.57544 1009 533826.182846 185498.185597 534504.172025 185831.655644 7 755.56042 1010 534165.000303 186219.508034 534271.142795 185793.341941 5 439.18533 1011 534153.776669 185751.775511 534335.21607 185820.253695 2 193.93173 1012 534248.577437 185864.589624 534308.554504 185887.793011 2 64.308983 1013 534230.037725 186271.247971 534303.11965 185874.692641 4 403.23331 1014 534062.986586 185953.424909 534358.301923 185987.621186 5 297.28864 1015 534026.156106 186176.146914 534067.673228 185940.961667 8 238.82162 1016 533919.941754 185820.623758 534075.66786 185957.211685 7 207.13977 1017 533962.01248 185865.153067 534001.331221 185789.354938 1 85.389229 1018 534024.289496 186173.66849 534357.59637 186237.677706 6 339.39749 1019 534093.959099 186203.198278 534188.302091 185789.755869 7 424.06982 1020 533638.990935 185915.962748 534100.910183 186202.618868 11 543.63696 1021 533711.71755 185978.190674 533717.72768 185860.915757 5 117.42882 1022 533683.530845 185959.955135 533770.762715 185893.200346 4 109.84353 1023 533752.470487 185904.110607 533939.287514 185980.965208 4 202.008 1024 533848.726618 186048.698046 533958.117057 185731.958935 9 335.09689 1025 533929.525697 185731.385802 534048.06534 185757.764177 3 121.43914 1026 534046.437964 185759.20432 534063.107891 185705.915162 1 55.835659 1027 533898.673772 185889.255333 534282.884006 185012.284988 11 957.44165 1028 533881.002664 185891.680408 533903.203183 185901.523756 1 24.284863 1029 533951.289622 186117.682482 533973.517589 186078.184954 2 45.32259 1030 533966.918612 186083.804779 533987.271877 186070.963788 2 24.065462 1031 533979.301445 186070.359795 534047.73213 186092.248234 2 71.8461 1032 533624.564218 185736.254849 533960.664283 185850.668985 5 355.04062 1033 533682.766308 185620.844455 533846.013427 185498.463792 5 204.02609 1034 533672.487562 185591.489927 533933.323283 185817.31288 5 345.00909 1035 533951.563582 185685.461975 533984.273098 185699.321315 1 35.524551 1036 533747.0106 185861.923585 533790.902708 185779.550512 3 93.337242 1037 533759.770868 185829.171307 533767.700397 185912.175553 4 83.382149 1038 533707.549297 185879.270243 533772.511945 185832.323443 4 80.15078 1039 533609.825733 185818.987034 533720.162394 185879.797228 3 125.98436 1040 533795.946067 185551.517522 533892.357923 185253.367732 3 313.35052 1041 534120.573197 185899.60766 534167.369517 185904.103701 2 47.011806 1042 534121.350965 185901.342434 534138.404318 185838.33465 1 65.274788 1043 534089.432386 185787.57865 534186.407121 185826.034389 3 104.32134 1044 534022.463731 185919.127103 534163.210126 185655.784772 3 298.5946 1045 533991.581812 185994.727147 534058.515802 186010.833193 3 68.84449 1046 533985.742054 186022.405925 533999.978292 185964.011564 3 60.104675 1047 533936.159056 185953.132262 534005.270526 185970.798066 2 71.333557 1048 533924.540024 186005.189208 533939.203528 185950.999066 3 56.139023 1049 533918.917688 186000.899634 533994.211074 186019.257029 2 77.498955 1050 533962.431112 185566.993174 534007.823089 185463.822737 2 112.71455 1051 533183.092197 185960.49207 533680.287998 185926.372386 7 498.36514 1052 533409.706938 185902.175085 533635.307428 185874.355608 1 227.30927 1053 533534.95185 185650.398593 533697.862133 185698.285306 2 169.80252 1054 533587.54344 185978.32146 533771.907397 185375.875192 9 630.02509 1055 533571.859734 185809.709063 533610.531577 185619.672206 1 193.93173 1056 533500.933353 185794.157643 533514.276625 185731.248163 2 64.308983 1057 533493.669834 185780.038188 533545.481945 185825.345589 2 68.827721 1058 533196.636768 185832.673472 533512.99954 185786.703487 5 319.68521 1059 533281.983386 185528.829642 533591.450099 185550.546415 4 310.22775 1060 533979.312668 185528.623452 533979.324719 185528.626521 1 0.012435302 1061 533497.55948 185639.260049 533592.716804 185246.129178 6 404.48337 1062 533351.136091 185754.9281 533459.296512 185610.465153 2 180.46667 1063 533457.707946 185611.509578 533522.628756 185618.298255 2 65.274788 1064 533484.759768 185537.451098 533706.798385 185613.679391 5 234.75923 1065 533355.262807 185733.492873 533365.642311 185989.503772 4 256.22122 1066 533337.274479 186336.546903 533396.597693 186535.010094 2 207.13977 1067 533550.079506 186180.281634 533609.196594 186660.164269 5 483.51025 1068 533538.357132 185927.209678 533580.561497 186464.970143 9 539.41406 1069 533458.122339 186169.484724 533567.245723 186212.862308 5 117.42882 1070 533465.386238 186231.147074 533562.405872 186179.641817 5 109.84353 1071 533474.991734 186420.912754 533482.923483 186219.060534 3 202.008 1072 533054.755832 186318.143693 533574.287005 186366.788247 8 521.80353 1073 533417.795746 186355.021615 533418.092568 186330.738566 1 24.284863 1074 533347.630276 186386.082724 533383.586987 185953.226628 5 434.34695 1075 533362.281749 185976.779886 533556.774495 186028.615048 4 201.28168 1076 533258.286793 185940.551163 533328.69137 186347.333816 3 412.83038 1077 533353.673905 186202.125381 533446.843096 186196.526984 4 93.337242 1078 533411.752116 186194.487567 533483.912891 186236.265609 4 83.382149 1079 533409.311578 186207.383876 533479.048304 186167.875185 4 80.15078 1080 533464.941005 186001.282872 533474.274414 186179.56184 3 178.52312 1081 533828.279945 186210.288684 534061.432071 186167.57164 7 237.03304 1082 533878.534886 186281.537721 533888.008418 186196.675645 1 85.389229 1083 533682.624134 186064.349101 533742.84632 185963.538308 4 117.42882 1084 533709.279137 185963.01928 533744.655809 186067.010107 3 109.84353 1085 533835.736436 186271.953259 533852.696011 186024.360057 5 248.17337 1086 533733.194051 186303.439136 533854.626565 186302.170238 2 121.43914 1087 533725.543114 186352.617487 533835.553856 186402.470947 2 120.77968 1088 533730.336185 186357.350465 533734.4513 186301.666655 2 55.835659 1089 533774.1936 186550.921799 533848.770307 186141.420947 7 416.23627 1090 533536.74805 186128.167476 533878.833233 186207.963791 5 351.26874 1091 533545.052813 186227.880808 533837.560288 186220.48194 3 292.60104 1092 533779.396942 186340.208273 533814.289455 186346.879573 1 35.524551 1093 533698.193044 186172.665752 533707.521963 186079.795889 3 93.337242 1094 533699.913432 186114.112742 533752.662906 186049.536622 3 83.382149 1095 533684.371802 186043.434219 533712.255609 186118.578354 4 80.15078 1096 533517.661442 186030.798131 533695.147751 186050.010453 3 178.52312 1097 533938.795137 186482.57123 533968.265425 186185.434504 0 298.5946 1098 534035.7211 186002.464912 534367.794464 186130.867829 5 356.03375 1099 532354.288274 183002.991897 532380.436592 183829.50734 4 826.92896 ================================================ FILE: testdata/barnsbury_extended2.dxf ================================================ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1032 9 $ACADMAINTVER 90 29 9 $DWGCODEPAGE 3 ANSI_1252 9 $LASTSAVEDBY 1 petros 9 $REQUIREDVERSIONS 160 0 9 $INSBASE 10 0.0 20 0.0 30 0.0 9 $EXTMIN 10 519734.4698767327 20 175043.3191102119 30 0.0 9 $EXTMAX 10 553979.5277822344 20 197652.3201767497 30 0.0 9 $LIMMIN 10 0.0 20 0.0 9 $LIMMAX 10 12.0 20 9.0 9 $ORTHOMODE 70 0 9 $REGENMODE 70 1 9 $FILLMODE 70 1 9 $QTEXTMODE 70 0 9 $MIRRTEXT 70 0 9 $LTSCALE 40 1.0 9 $ATTMODE 70 1 9 $TEXTSIZE 40 0.2 9 $TRACEWID 40 0.05 9 $TEXTSTYLE 7 Standard 9 $CLAYER 8 0 9 $CELTYPE 6 ByLayer 9 $CECOLOR 62 256 9 $CELTSCALE 40 1.0 9 $DISPSILH 70 0 9 $DIMSCALE 40 1.0 9 $DIMASZ 40 0.18 9 $DIMEXO 40 0.0625 9 $DIMDLI 40 0.38 9 $DIMRND 40 0.0 9 $DIMDLE 40 0.0 9 $DIMEXE 40 0.18 9 $DIMTP 40 0.0 9 $DIMTM 40 0.0 9 $DIMTXT 40 0.18 9 $DIMCEN 40 0.09 9 $DIMTSZ 40 0.0 9 $DIMTOL 70 0 9 $DIMLIM 70 0 9 $DIMTIH 70 1 9 $DIMTOH 70 1 9 $DIMSE1 70 0 9 $DIMSE2 70 0 9 $DIMTAD 70 0 9 $DIMZIN 70 0 9 $DIMBLK 1 9 $DIMASO 70 1 9 $DIMSHO 70 1 9 $DIMPOST 1 9 $DIMAPOST 1 9 $DIMALT 70 0 9 $DIMALTD 70 2 9 $DIMALTF 40 25.4 9 $DIMLFAC 40 1.0 9 $DIMTOFL 70 0 9 $DIMTVP 40 0.0 9 $DIMTIX 70 0 9 $DIMSOXD 70 0 9 $DIMSAH 70 0 9 $DIMBLK1 1 9 $DIMBLK2 1 9 $DIMSTYLE 2 Standard 9 $DIMCLRD 70 0 9 $DIMCLRE 70 0 9 $DIMCLRT 70 0 9 $DIMTFAC 40 1.0 9 $DIMGAP 40 0.09 9 $DIMJUST 70 0 9 $DIMSD1 70 0 9 $DIMSD2 70 0 9 $DIMTOLJ 70 1 9 $DIMTZIN 70 0 9 $DIMALTZ 70 0 9 $DIMALTTZ 70 0 9 $DIMUPT 70 0 9 $DIMDEC 70 4 9 $DIMTDEC 70 4 9 $DIMALTU 70 2 9 $DIMALTTD 70 2 9 $DIMTXSTY 7 Standard 9 $DIMAUNIT 70 0 9 $DIMADEC 70 0 9 $DIMALTRND 40 0.0 9 $DIMAZIN 70 0 9 $DIMDSEP 70 46 9 $DIMATFIT 70 3 9 $DIMFRAC 70 0 9 $DIMLDRBLK 1 9 $DIMLUNIT 70 2 9 $DIMLWD 70 -2 9 $DIMLWE 70 -2 9 $DIMTMOVE 70 0 9 $DIMFXL 40 1.0 9 $DIMFXLON 70 0 9 $DIMJOGANG 40 0.7853981633974483 9 $DIMTFILL 70 0 9 $DIMTFILLCLR 70 0 9 $DIMARCSYM 70 0 9 $DIMLTYPE 6 9 $DIMLTEX1 6 9 $DIMLTEX2 6 9 $DIMTXTDIRECTION 70 0 9 $LUNITS 70 2 9 $LUPREC 70 4 9 $SKETCHINC 40 0.1 9 $FILLETRAD 40 0.0 9 $AUNITS 70 0 9 $AUPREC 70 0 9 $MENU 1 . 9 $ELEVATION 40 0.0 9 $PELEVATION 40 0.0 9 $THICKNESS 40 0.0 9 $LIMCHECK 70 0 9 $CHAMFERA 40 0.0 9 $CHAMFERB 40 0.0 9 $CHAMFERC 40 0.0 9 $CHAMFERD 40 0.0 9 $SKPOLY 70 0 9 $TDCREATE 40 2458404.565312500 9 $TDUCREATE 40 2458404.523645833 9 $TDUPDATE 40 2458404.657638889 9 $TDUUPDATE 40 2458404.615972222 9 $TDINDWG 40 0.0820949074 9 $TDUSRTIMER 40 0.0820949074 9 $USRTIMER 70 1 9 $ANGBASE 50 0.0 9 $ANGDIR 70 0 9 $PDMODE 70 0 9 $PDSIZE 40 0.0 9 $PLINEWID 40 0.0 9 $SPLFRAME 70 0 9 $SPLINETYPE 70 6 9 $SPLINESEGS 70 8 9 $HANDSEED 5 22F6 9 $SURFTAB1 70 6 9 $SURFTAB2 70 6 9 $SURFTYPE 70 6 9 $SURFU 70 6 9 $SURFV 70 6 9 $UCSBASE 2 9 $UCSNAME 2 9 $UCSORG 10 0.0 20 0.0 30 0.0 9 $UCSXDIR 10 1.0 20 0.0 30 0.0 9 $UCSYDIR 10 0.0 20 1.0 30 0.0 9 $UCSORTHOREF 2 9 $UCSORTHOVIEW 70 0 9 $UCSORGTOP 10 0.0 20 0.0 30 0.0 9 $UCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $UCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $UCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $UCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $UCSORGBACK 10 0.0 20 0.0 30 0.0 9 $PUCSBASE 2 9 $PUCSNAME 2 9 $PUCSORG 10 0.0 20 0.0 30 0.0 9 $PUCSXDIR 10 1.0 20 0.0 30 0.0 9 $PUCSYDIR 10 0.0 20 1.0 30 0.0 9 $PUCSORTHOREF 2 9 $PUCSORTHOVIEW 70 0 9 $PUCSORGTOP 10 0.0 20 0.0 30 0.0 9 $PUCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $PUCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $PUCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $PUCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $PUCSORGBACK 10 0.0 20 0.0 30 0.0 9 $USERI1 70 0 9 $USERI2 70 0 9 $USERI3 70 0 9 $USERI4 70 0 9 $USERI5 70 0 9 $USERR1 40 0.0 9 $USERR2 40 0.0 9 $USERR3 40 0.0 9 $USERR4 40 0.0 9 $USERR5 40 0.0 9 $WORLDVIEW 70 1 9 $SHADEDGE 70 3 9 $SHADEDIF 70 70 9 $TILEMODE 70 1 9 $MAXACTVP 70 64 9 $PINSBASE 10 0.0 20 0.0 30 0.0 9 $PLIMCHECK 70 0 9 $PEXTMIN 10 1.000000000000000E+20 20 1.000000000000000E+20 30 1.000000000000000E+20 9 $PEXTMAX 10 -1.000000000000000E+20 20 -1.000000000000000E+20 30 -1.000000000000000E+20 9 $PLIMMIN 10 0.0 20 0.0 9 $PLIMMAX 10 12.0 20 9.0 9 $UNITMODE 70 0 9 $VISRETAIN 70 1 9 $PLINEGEN 70 0 9 $PSLTSCALE 70 1 9 $TREEDEPTH 70 3020 9 $CMLSTYLE 2 Standard 9 $CMLJUST 70 0 9 $CMLSCALE 40 1.0 9 $PROXYGRAPHICS 70 1 9 $MEASUREMENT 70 0 9 $CELWEIGHT 370 -1 9 $ENDCAPS 280 0 9 $JOINSTYLE 280 0 9 $LWDISPLAY 290 0 9 $INSUNITS 70 0 9 $HYPERLINKBASE 1 9 $STYLESHEET 1 9 $XEDIT 290 1 9 $CEPSNTYPE 380 0 9 $PSTYLEMODE 290 1 9 $FINGERPRINTGUID 2 {2B8CF25F-82C1-5146-94DB-BDE3530BDA2A} 9 $VERSIONGUID 2 {58F8BA06-8073-9041-99B1-34838A46B6E6} 9 $EXTNAMES 290 1 9 $PSVPSCALE 40 0.0 9 $OLESTARTUP 290 0 9 $SORTENTS 280 127 9 $INDEXCTL 280 0 9 $HIDETEXT 280 0 9 $XCLIPFRAME 280 2 9 $HALOGAP 280 0 9 $OBSCOLOR 70 257 9 $OBSLTYPE 280 0 9 $INTERSECTIONDISPLAY 280 0 9 $INTERSECTIONCOLOR 70 257 9 $DIMASSOC 280 1 9 $PROJECTNAME 1 9 $CAMERADISPLAY 290 0 9 $LENSLENGTH 40 50.0 9 $CAMERAHEIGHT 40 0.0 9 $STEPSPERSEC 40 2.0 9 $STEPSIZE 40 6.0 9 $3DDWFPREC 40 2.0 9 $PSOLWIDTH 40 0.25 9 $PSOLHEIGHT 40 4.0 9 $LOFTANG1 40 1.570796326794896 9 $LOFTANG2 40 1.570796326794896 9 $LOFTMAG1 40 0.0 9 $LOFTMAG2 40 0.0 9 $LOFTPARAM 70 7 9 $LOFTNORMALS 280 1 9 $LATITUDE 40 37.795 9 $LONGITUDE 40 -122.394 9 $NORTHDIRECTION 40 0.0 9 $TIMEZONE 70 -8000 9 $LIGHTGLYPHDISPLAY 280 1 9 $TILEMODELIGHTSYNCH 280 1 9 $CMATERIAL 347 11 9 $SOLIDHIST 280 0 9 $SHOWHIST 280 1 9 $DWFFRAME 280 2 9 $DGNFRAME 280 0 9 $REALWORLDSCALE 290 1 9 $INTERFERECOLOR 62 1 9 $INTERFEREOBJVS 345 33 9 $INTERFEREVPVS 346 30 9 $CSHADOW 280 0 9 $SHADOWPLANELOCATION 40 0.0 0 ENDSEC 0 SECTION 2 CLASSES 0 CLASS 1 ACDBDICTIONARYWDFLT 2 AcDbDictionaryWithDefault 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 MATERIAL 2 AcDbMaterial 3 ObjectDBX Classes 90 1153 91 3 280 0 281 0 0 CLASS 1 VISUALSTYLE 2 AcDbVisualStyle 3 ObjectDBX Classes 90 4095 91 24 280 0 281 0 0 CLASS 1 SCALE 2 AcDbScale 3 ObjectDBX Classes 90 1153 91 17 280 0 281 0 0 CLASS 1 TABLESTYLE 2 AcDbTableStyle 3 ObjectDBX Classes 90 4095 91 1 280 0 281 0 0 CLASS 1 MLEADERSTYLE 2 AcDbMLeaderStyle 3 ACDB_MLEADERSTYLE_CLASS 90 4095 91 1 280 0 281 0 0 CLASS 1 ACDBSECTIONVIEWSTYLE 2 AcDbSectionViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 ACDBDETAILVIEWSTYLE 2 AcDbDetailViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 SORTENTSTABLE 2 AcDbSortentsTable 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 DICTIONARYVAR 2 AcDbDictionaryVar 3 ObjectDBX Classes 90 0 91 9 280 0 281 0 0 CLASS 1 CELLSTYLEMAP 2 AcDbCellStyleMap 3 ObjectDBX Classes 90 1152 91 3 280 0 281 0 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 8 330 0 100 AcDbSymbolTable 70 1 0 VPORT 5 B3 330 8 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *Active 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 530257.0980907157 22 182183.4473277476 13 0.0 23 0.0 14 1.0 24 1.0 15 0.0 25 0.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 22470.11987693544 41 1.512419503219871 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 1000 73 1 74 3 75 0 76 0 77 0 78 0 281 0 65 1 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 348 2F 60 3 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 1001 ACAD_NAV_VCDISPLAY 1070 1 0 ENDTAB 0 TABLE 2 LTYPE 5 5 330 0 100 AcDbSymbolTable 70 2 0 LTYPE 5 5A 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByBlock 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 5B 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByLayer 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 5C 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 Continuous 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 2 102 {ACAD_XDICTIONARY 360 345 102 } 330 0 100 AcDbSymbolTable 70 1 0 LAYER 5 54 102 {ACAD_XDICTIONARY 360 340 102 } 330 2 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 62 7 6 Continuous 370 -3 390 F 347 21 348 0 0 ENDTAB 0 TABLE 2 STYLE 5 3 330 0 100 AcDbSymbolTable 70 2 0 STYLE 5 55 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Standard 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 0 STYLE 5 59 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Annotative 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 0 ENDTAB 0 TABLE 2 VIEW 5 6 330 0 100 AcDbSymbolTable 70 2 0 ENDTAB 0 TABLE 2 UCS 5 7 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 9 330 0 100 AcDbSymbolTable 70 4 0 APPID 5 56 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 APPID 5 5D 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnotative 70 0 0 APPID 5 B2 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_NAV_VCDISPLAY 70 0 0 APPID 5 F2 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_EXEMPT_FROM_CAD_STANDARDS 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 A 330 0 100 AcDbSymbolTable 70 3 100 AcDbDimStyleTable 71 1 340 57 0 DIMSTYLE 105 57 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Standard 70 0 340 55 0 DIMSTYLE 105 58 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Annotative 70 0 340 55 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 1 330 0 100 AcDbSymbolTable 70 1 0 BLOCK_RECORD 5 6F 102 {ACAD_XDICTIONARY 360 135 102 } 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Model_Space 340 72 70 0 280 1 281 0 0 BLOCK_RECORD 5 6B 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space 340 6E 70 0 280 1 281 0 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 70 330 6F 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *Model_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Model_Space 1 0 ENDBLK 5 71 330 6F 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 6C 330 6B 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space 1 0 ENDBLK 5 6D 330 6B 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LINE 5 73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530635.6962680001 20 184468.675646 30 0.0 11 530732.3778539999 21 183731.866556 31 0.0 0 LINE 5 74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530655.0804069999 20 184267.843134 30 0.0 11 531386.6646780001 21 184568.766995 31 0.0 0 LINE 5 75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530781.419478 20 184322.997346 30 0.0 11 530814.78724 21 184178.968574 31 0.0 0 LINE 5 76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530667.7613100001 20 184203.901437 30 0.0 11 531124.6861069999 21 184392.857349 31 0.0 0 LINE 5 77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530798.725861 20 184207.390438 30 0.0 11 530856.762846 21 184149.487013 31 0.0 0 LINE 5 78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530747.8703240001 20 184145.998012 30 0.0 11 530810.7554050001 21 184207.340453 31 0.0 0 LINE 5 79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530753.9386890001 20 184164.022852 30 0.0 11 530781.427723 21 183967.049235 31 0.0 0 LINE 5 7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530638.0708449999 20 184123.954322 30 0.0 11 531070.9777789999 21 184116.826362 31 0.0 0 LINE 5 7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530837.4941380001 20 183967.908989 30 0.0 11 530855.6744979999 21 184153.675814 31 0.0 0 LINE 5 7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530776.9259189999 20 183970.168342 30 0.0 11 530838.1125180001 21 183968.488823 31 0.0 0 LINE 5 7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530803.8790240001 20 183673.983124 30 0.0 11 530817.351454 21 183970.908131 31 0.0 0 LINE 5 7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530803.31836 20 183742.403539 30 0.0 11 530916.415863 21 183745.002795 31 0.0 0 LINE 5 7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530912.1861470001 20 183663.646083 30 0.0 11 530932.996681 21 184479.6069563149 31 0.0 0 LINE 5 80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530995.2139119999 20 184191.1051 30 0.0 11 531426.867596 21 184272.091918 31 0.0 0 LINE 5 81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530992.995991 20 184260.565217 30 0.0 11 531006.3035189999 21 184067.090599 31 0.0 0 LINE 5 82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531065.5030580001 20 184264.454104 30 0.0 11 531069.386482 21 184200.262479 31 0.0 0 LINE 5 83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531014.2600029999 20 184282.658893 30 0.0 11 531076.262863 21 184252.777446 31 0.0 0 LINE 5 84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.8563370001 20 184254.05708 30 0.0 11 531446.820644 21 184352.768824 31 0.0 0 LINE 5 85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531101.674141 20 184455.949289 30 0.0 11 531227.444303 21 184068.530187 31 0.0 0 LINE 5 86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531214.16151 20 184067.600453 30 0.0 11 531445.270572 21 184127.80322 31 0.0 0 LINE 5 87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531166.2824399999 20 183883.173244 30 0.0 11 531225.605654 21 184081.636435 31 0.0 0 LINE 5 88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531103.958023 20 183944.145791 30 0.0 11 531189.2449350001 21 183939.966987 31 0.0 0 LINE 5 89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531199.1268957056 20 184509.5863229855 30 0.0 11 531222.4027027056 21 184422.5212449855 31 0.0 0 LINE 5 8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531332.5770770001 20 184583.962646 30 0.0 11 531443.794706 21 184125.074001 31 0.0 0 LINE 5 8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531026.4544489999 20 184114.297086 30 0.0 11 531441.626255 21 184200.71235 31 0.0 0 LINE 5 8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531379.0874670001 20 183726.907975 30 0.0 11 531438.2045550001 21 184206.79061 31 0.0 0 LINE 5 8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531367.365093476 20 183473.8360188434 30 0.0 11 531409.569458 21 184011.596484 31 0.0 0 LINE 5 8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531287.1303 20 183716.111065 30 0.0 11 531396.253684 21 183759.488649 31 0.0 0 LINE 5 8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531294.394199 20 183777.773415 30 0.0 11 531391.413833 21 183726.268158 31 0.0 0 LINE 5 90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531303.999695 20 183967.539095 30 0.0 11 531311.931444 21 183765.686875 31 0.0 0 LINE 5 91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530639.1597319652 20 183843.3318650589 30 0.0 11 531403.294966 21 183913.414588 31 0.0 0 LINE 5 92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.773886 20 183973.477395 30 0.0 11 531081.1604290001 21 183854.721389 31 0.0 0 LINE 5 93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530979.070082 20 183853.471746 30 0.0 11 531006.056167 21 183971.198048 31 0.0 0 LINE 5 94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531002.3706249999 20 183965.559662 30 0.0 11 531057.7609460001 21 183972.597647 31 0.0 0 LINE 5 97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531378.13104 20 184039.148597 30 0.0 11 531423.297484 21 184035.389673 31 0.0 0 LINE 5 98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531365.8376540001 20 184048.645878 30 0.0 11 531385.9885830001 21 184035.489644 31 0.0 0 LINE 5 99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531360.008395 20 184112.477607 30 0.0 11 531368.607994 21 184041.148025 31 0.0 0 LINE 5 9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531176.638237 20 183932.709065 30 0.0 11 531212.5949479999 21 183499.852969 31 0.0 0 LINE 5 9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531191.28971 20 183523.406227 30 0.0 11 531385.782456 21 183575.241389 31 0.0 0 LINE 5 9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530904.180192 20 183681.79089 30 0.0 11 531226.595062 21 183515.558473 31 0.0 0 LINE 5 9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531087.294754 20 183504.461649 30 0.0 11 531157.6993310001 21 183893.960157 31 0.0 0 LINE 5 9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531029.2082989999 20 183891.140964 30 0.0 11 531030.2306869999 21 183855.631128 31 0.0 0 LINE 5 9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531182.681866 20 183748.751722 30 0.0 11 531275.851057 21 183743.153325 31 0.0 0 LINE 5 A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531240.7600770002 20 183741.113908 30 0.0 11 531312.920852 21 183782.89195 31 0.0 0 LINE 5 A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531238.3195390001 20 183754.010217 30 0.0 11 531308.0562649999 21 183714.501526 31 0.0 0 LINE 5 A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531293.948966 20 183547.909213 30 0.0 11 531303.2823749999 21 183726.188181 31 0.0 0 LINE 5 A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530707.321114 20 183575.611283 30 0.0 11 530731.6605340001 21 183750.551207 31 0.0 0 LINE 5 A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530711.864142 20 183690.118506 30 0.0 11 530973.265559 21 183658.367594 31 0.0 0 LINE 5 A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531139.131454 20 184142.888902 30 0.0 11 531154.5332279999 21 184098.471616 31 0.0 0 LINE 5 A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531091.4007950001 20 184089.16428 30 0.0 11 531155.7864770001 21 184099.901207 31 0.0 0 LINE 5 A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531060.2262189999 20 184127.683254 30 0.0 11 531065.6514689999 21 184023.503075 31 0.0 0 LINE 5 A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530915.1048979999 20 184035.689587 30 0.0 11 531213.1391220001 21 184017.404821 31 0.0 0 LINE 5 A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531281.4989239999 20 184088.374506 30 0.0 11 531294.732247 21 184020.813845 31 0.0 0 LINE 5 AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531263.3103189999 20 184015.655322 30 0.0 11 531322.3284660001 21 184027.032065 31 0.0 0 LINE 5 AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531267.276193 20 184023.293136 30 0.0 11 531279.9983229999 21 183953.103227 31 0.0 0 LINE 5 AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531276.7909939999 20 183954.982689 30 0.0 11 531332.164824 21 183964.220045 31 0.0 0 LINE 5 AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531315.9385439999 20 184033.420237 30 0.0 11 531330.6065079999 21 183957.32202 31 0.0 0 LINE 5 AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530805.297175 20 183814.47291 30 0.0 11 530917.998915 21 183816.172423 31 0.0 0 LINE 5 AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531137.2515800001 20 184338.103022 30 0.0 11 531389.731841 21 184417.270361 31 0.0 0 LINE 5 B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531482.3151479505 20 184748.9871594448 30 0.0 11 531515.6829099504 21 184604.9583874448 31 0.0 0 LINE 5 B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531368.6569799505 20 184629.8912504447 30 0.0 11 531825.5817769504 21 184818.8471624447 31 0.0 0 LINE 5 B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531499.6215309505 20 184633.3802514448 30 0.0 11 531557.6585159504 21 184575.4768264448 31 0.0 0 LINE 5 BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531448.7659939505 20 184571.9878254447 30 0.0 11 531511.6510749504 21 184633.3302664447 31 0.0 0 LINE 5 BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531455.263586 20 184588.2416564698 30 0.0 11 531482.7526199998 21 184391.2680394698 31 0.0 0 LINE 5 BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531253.86750234 20 184551.3453196492 30 0.0 11 531771.8734489504 21 184542.8161754447 31 0.0 0 LINE 5 BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531538.3898079505 20 184393.8988024447 30 0.0 11 531556.5701679504 21 184579.6656274448 31 0.0 0 LINE 5 BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531477.8215889504 20 184396.1581554448 30 0.0 11 531539.0081879505 21 184394.4786364447 31 0.0 0 LINE 5 BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531504.7746939504 20 184099.9729374447 30 0.0 11 531518.2471239504 21 184396.8979444447 31 0.0 0 LINE 5 C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531504.2140299504 20 184168.3933524448 30 0.0 11 531617.3115329505 21 184170.9926084448 31 0.0 0 LINE 5 C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531613.0818169503 20 184089.6358964447 30 0.0 11 531633.8923509504 21 184844.9097024448 31 0.0 0 LINE 5 C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531696.1095819504 20 184617.0949134447 30 0.0 11 532336.8255974543 21 184713.6317642464 31 0.0 0 LINE 5 C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531693.8916609504 20 184686.5550304448 30 0.0 11 531707.1991889504 21 184493.0804124447 31 0.0 0 LINE 5 C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531766.3987279504 20 184690.4439174447 30 0.0 11 531770.2821519504 21 184626.2522924448 31 0.0 0 LINE 5 C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531715.1556729503 20 184708.6487064448 30 0.0 11 531777.1585329505 21 184678.7672594447 31 0.0 0 LINE 5 C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531756.7520069505 20 184680.0468934447 30 0.0 11 531893.0496688435 21 184714.4597021531 31 0.0 0 LINE 5 C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531802.5698109504 20 184881.9391024447 30 0.0 11 531928.3399729504 21 184494.5200004447 31 0.0 0 LINE 5 C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531915.0571799504 20 184493.5902664447 30 0.0 11 532146.1662419505 21 184553.7930334447 31 0.0 0 LINE 5 C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531867.1781099504 20 184309.1630574448 30 0.0 11 531926.5013239504 21 184507.6262484447 31 0.0 0 LINE 5 CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531804.8536929503 20 184370.1356044448 30 0.0 11 531890.1406049505 21 184365.9568004447 31 0.0 0 LINE 5 CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531914.954988917 20 184937.2488970258 30 0.0 11 531938.230795917 21 184850.1838190259 31 0.0 0 LINE 5 CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531727.3501189504 20 184540.2868994447 30 0.0 11 532142.5219249505 21 184626.7021634447 31 0.0 0 LINE 5 D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.0259699504 20 184142.1008784448 30 0.0 11 532097.1493539504 21 184185.4784624447 31 0.0 0 LINE 5 D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531995.2898689503 20 184203.7632284447 30 0.0 11 532092.3095029504 21 184152.2579714447 31 0.0 0 LINE 5 D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532004.8953649504 20 184393.5289084448 30 0.0 11 532012.8271139505 21 184191.6766884448 31 0.0 0 LINE 5 D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531770.6696699504 20 184306.9436934447 30 0.0 11 532197.7006858273 21 184339.4044014448 31 0.0 0 LINE 5 D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531756.6695559503 20 184399.4672084447 30 0.0 11 531782.0560989504 21 184280.7112024448 31 0.0 0 LINE 5 D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531679.9657519504 20 184279.4615594447 30 0.0 11 531706.9518369503 21 184397.1878614447 31 0.0 0 LINE 5 D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531703.2662949504 20 184391.5494754448 30 0.0 11 531758.6566159504 21 184398.5874604448 31 0.0 0 LINE 5 D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531375.9456139504 20 184307.1536334448 30 0.0 11 531938.4319279503 21 184318.4104104447 31 0.0 0 LINE 5 D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531947.6993769504 20 184327.6377694447 30 0.0 11 531947.9961989505 21 184303.3547204447 31 0.0 0 LINE 5 D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532079.0267099504 20 184465.1384104447 30 0.0 11 532156.3508382652 21 184461.3794864448 31 0.0 0 LINE 5 DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532066.7333239505 20 184474.6356914448 30 0.0 11 532086.8842529504 21 184461.4794574448 31 0.0 0 LINE 5 DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532060.9040649504 20 184538.4674204447 30 0.0 11 532069.5036639504 21 184467.1378384447 31 0.0 0 LINE 5 DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531877.5339069504 20 184358.6988784447 30 0.0 11 531913.4906179503 21 184005.4836986493 31 0.0 0 LINE 5 DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531605.0758619504 20 184107.7807034448 30 0.0 11 531784.3258864618 21 184010.3328863243 31 0.0 0 LINE 5 DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531761.9190629788 20 183988.7626476783 30 0.0 11 531858.5950009506 21 184319.9499704448 31 0.0 0 LINE 5 E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.1039689503 20 184317.1307774448 30 0.0 11 531731.1263569504 21 184281.6209414447 31 0.0 0 LINE 5 E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531883.5775359503 20 184174.7415354448 30 0.0 11 531976.7467269504 21 184169.1431384447 31 0.0 0 LINE 5 E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531941.6557469504 20 184167.1037214447 30 0.0 11 532013.8165219504 21 184208.8817634447 31 0.0 0 LINE 5 E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531939.2152089505 20 184180.0000304447 30 0.0 11 532008.9519349505 21 184140.4913394448 31 0.0 0 LINE 5 E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531994.8446359504 20 184026.5398393117 30 0.0 11 532004.1780449503 21 184152.1779944448 31 0.0 0 LINE 5 E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531409.1658425192 20 184133.617550475 30 0.0 11 531674.1612289504 21 184084.3574074447 31 0.0 0 LINE 5 E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531840.0271239504 20 184568.8787154448 30 0.0 11 531855.4288979504 21 184524.4614294448 31 0.0 0 LINE 5 E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531792.2964649504 20 184515.1540934448 30 0.0 11 531856.6821469506 21 184525.8910204447 31 0.0 0 LINE 5 E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531761.1218889504 20 184553.6730674448 30 0.0 11 531766.5471389503 21 184449.4928884447 31 0.0 0 LINE 5 EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531616.0005679503 20 184461.6794004447 30 0.0 11 531914.0347919505 21 184443.3946344448 31 0.0 0 LINE 5 EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531982.3945939504 20 184514.3643194447 30 0.0 11 531995.6279169504 21 184446.8036584448 31 0.0 0 LINE 5 EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531964.2059889504 20 184441.6451354448 30 0.0 11 532023.2241359505 21 184453.0218784447 31 0.0 0 LINE 5 ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531968.1718629504 20 184449.2829494447 30 0.0 11 531980.8939929504 21 184379.0930404447 31 0.0 0 LINE 5 EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531977.6866639505 20 184380.9725024447 30 0.0 11 532033.0604939504 21 184390.2098584447 31 0.0 0 LINE 5 EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532016.8342139503 20 184459.4100504447 30 0.0 11 532031.5021779503 21 184383.3118334448 31 0.0 0 LINE 5 F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531506.1928449503 20 184240.4627234447 30 0.0 11 531618.8945849504 21 184242.1622364448 31 0.0 0 LINE 5 F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531838.1472499504 20 184764.0928354447 30 0.0 11 532090.6275109504 21 184843.2601744448 31 0.0 0 LINE 5 F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531898.1410099429 20 185489.5773460393 30 0.0 11 532384.9456462926 21 183588.3773949871 31 0.0 0 LINE 5 FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532034.5704961169 20 184072.7659341317 30 0.0 11 532153.81876062 21 183879.2475727824 31 0.0 0 LINE 5 FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531848.4441497004 20 184056.3091599104 30 0.0 11 531872.7555329124 21 183888.2560305589 31 0.0 0 LINE 5 104 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531400.0540388189 20 183972.7571852804 30 0.0 11 532184.2443917333 21 184077.3429025231 31 0.0 0 LINE 5 105 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531934.003528394 20 183974.8942294735 30 0.0 11 532082.7807717206 21 183561.6762489006 31 0.0 0 LINE 5 106 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532002.2213451149 20 183988.1590894068 30 0.0 11 531813.3438607319 21 183944.1725686889 31 0.0 0 LINE 5 107 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532017.6216248512 20 183917.199737725 30 0.0 11 531954.8704583398 21 183903.1307362112 31 0.0 0 LINE 5 108 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532027.4228756862 20 183970.6899285112 30 0.0 11 532007.8099904357 21 183904.7157649685 31 0.0 0 LINE 5 109 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532005.8194622598 20 183925.0652505675 30 0.0 11 532165.6070012576 21 183554.8422905387 31 0.0 0 LINE 5 10A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532215.3406327096 20 183914.506790095 30 0.0 11 531850.025606886 21 183726.0905468235 31 0.0 0 LINE 5 10B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531846.9898456826 20 183739.0551582372 30 0.0 11 531943.2723962862 21 183520.502093417 31 0.0 0 LINE 5 10C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531657.2879060011 20 183756.915025109 30 0.0 11 531862.6710068011 21 183729.9954447442 31 0.0 0 LINE 5 10D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531707.5428474121 20 183828.1640623365 30 0.0 11 531717.0163799135 21 183743.3019863348 31 0.0 0 LINE 5 10F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532612.0618786471 20 183803.7866919309 30 0.0 11 531940.3427695725 21 183521.5239075487 31 0.0 0 LINE 5 110 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531863.1594357444 20 183931.8064504249 30 0.0 11 532014.6676634007 21 183535.7250404825 31 0.0 0 LINE 5 111 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531536.9533087979 20 183521.91630484 30 0.0 11 532020.1225745254 21 183540.0721337803 31 0.0 0 LINE 5 112 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531322.8230960095 20 183496.2175151871 30 0.0 11 531822.8598906507 21 183537.2174611747 31 0.0 0 LINE 5 113 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531511.6320955303 20 183610.9754424221 30 0.0 11 531571.8542817987 21 183510.1646492979 31 0.0 0 LINE 5 114 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531573.6637703916 20 183613.6364478867 30 0.0 11 531538.2870985668 21 183509.6456215089 31 0.0 0 LINE 5 115 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531762.5332163358 20 183634.4117035529 30 0.0 11 531564.5281508437 21 183594.3963889772 31 0.0 0 LINE 5 116 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531647.8000830325 20 183818.5796003908 30 0.0 11 531724.9336515695 21 183527.7567185295 31 0.0 0 LINE 5 117 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531562.2020126962 20 183850.0654772609 30 0.0 11 531683.6345265603 21 183848.7965788212 31 0.0 0 LINE 5 118 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531664.5618179023 20 183949.0972884033 30 0.0 11 531554.5510755348 21 183899.2438278418 31 0.0 0 LINE 5 119 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531559.3441468585 20 183903.9768061644 30 0.0 11 531563.4592611811 21 183848.292995883 31 0.0 0 LINE 5 11A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531576.9778841278 20 184241.5424111468 30 0.0 11 531576.9801121507 21 184241.5301770692 31 0.0 0 LINE 5 11B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531688.3652557219 20 183680.3696937222 30 0.0 11 531664.4402060374 21 183676.2047723989 31 0.0 0 LINE 5 11C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531845.0466985964 20 183572.6468079129 30 0.0 11 531848.5375890713 21 183527.4588575618 31 0.0 0 LINE 5 11D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531852.4623111796 20 183586.2972429151 30 0.0 11 531842.6874311459 21 183564.3063776991 31 0.0 0 LINE 5 11E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531914.5479255571 20 183602.2297999917 30 0.0 11 531845.5021105826 21 183582.3668242385 31 0.0 0 LINE 5 11F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531707.8411943864 20 183754.5901321862 30 0.0 11 531365.7560113711 21 183674.7938172478 31 0.0 0 LINE 5 122 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531374.0607747642 20 183774.5071494866 30 0.0 11 531666.5682496065 21 183767.1082814454 31 0.0 0 LINE 5 123 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531643.2974167897 20 183893.5059139139 30 0.0 11 531608.4049033558 21 183886.834614473 31 0.0 0 LINE 5 124 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531527.2010051643 20 183719.29209353 30 0.0 11 531536.5299245022 21 183626.4222304713 31 0.0 0 LINE 5 125 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531528.9213936644 20 183660.7390828553 30 0.0 11 531581.6708679228 21 183596.1629633728 31 0.0 0 LINE 5 126 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531541.263570164 20 183665.2046948853 30 0.0 11 531513.379763223 21 183590.0605605288 31 0.0 0 LINE 5 127 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531346.6694038719 20 183577.4244724932 30 0.0 11 531524.155712167 21 183596.6367946471 31 0.0 0 LINE 5 129 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531909.3516392598 20 183825.1299313012 30 0.0 11 531867.9584077485 21 183802.8429323333 31 0.0 0 LINE 5 12A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531848.70377308 20 183863.6836230238 30 0.0 11 531869.5695376331 21 183801.8336633017 31 0.0 0 LINE 5 12B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531881.7592038701 20 183900.6011533052 30 0.0 11 531779.7769291967 21 183878.6339348538 31 0.0 0 LINE 5 12C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531767.8030984371 20 184029.1975708737 30 0.0 11 531797.2733862307 21 183732.0608456437 31 0.0 0 LINE 5 12D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531878.2349730312 20 183675.8916353841 30 0.0 11 531813.6487009317 21 183652.0551673432 31 0.0 0 LINE 5 12E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531803.5459941819 20 183682.2525717864 30 0.0 11 531824.1875434457 21 183625.8034938436 31 0.0 0 LINE 5 12F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531811.718444662 20 183679.5552745401 30 0.0 11 531744.4550535487 21 183655.8042296553 31 0.0 0 LINE 5 130 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531745.7990662274 20 183659.270202339 30 0.0 11 531763.7475182557 21 183606.0776947413 31 0.0 0 LINE 5 131 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531829.4751229565 20 183633.1302494412 30 0.0 11 531756.6892737099 21 183606.5161939831 31 0.0 0 LINE 5 133 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532101.7684936581 20 183858.112361732 30 0.0 11 532220.1805946465 21 183621.4853892659 31 0.0 0 LINE 5 134 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531603.2015619726 20 184097.5481402789 30 0.0 11 531677.7782680864 21 183688.04728826 31 0.0 0 LINE 5 137 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530735.9131272892 20 184226.3356863664 30 0.0 11 530283.9544628965 21 184816.224090947 31 0.0 0 LINE 5 138 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530031.1888274785 20 184139.9555640059 30 0.0 11 532155.7272385915 21 185032.5284892478 31 0.0 0 LINE 5 139 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530736.1824591328 20 184432.3874965597 30 0.0 11 530658.0779895487 21 184557.9159257529 31 0.0 0 LINE 5 13A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530571.6050156501 20 184436.4223187819 30 0.0 11 531028.5298126501 21 184625.3782307819 31 0.0 0 LINE 5 13B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530666.7818999167 20 184526.4514665502 30 0.0 11 530666.9708656795 21 184608.4335532921 31 0.0 0 LINE 5 13C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530587.4192474452 20 184533.9936815043 30 0.0 11 530675.2625699671 21 184534.9832109703 31 0.0 0 LINE 5 13D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530604.4459568052 20 184525.5195397091 30 0.0 11 530484.7853398737 21 184684.3766753369 31 0.0 0 LINE 5 13F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530525.0832024871 20 184723.3672426156 30 0.0 11 530669.1589131753 21 184604.6995201719 31 0.0 0 LINE 5 140 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530483.8014128733 20 184678.989008366 30 0.0 11 530525.9304985947 21 184723.3935218478 31 0.0 0 LINE 5 141 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530293.6891368918 20 184907.7016572334 30 0.0 11 530512.942028526 21 184707.017488296 31 0.0 0 LINE 5 142 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530341.6169557605 20 184858.8693757858 30 0.0 11 530423.5169519546 21 184936.9090576151 31 0.0 0 LINE 5 143 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530363.0611291585 20 184991.515820703 30 0.0 11 530950.6381382885 21 184434.1646856795 31 0.0 0 LINE 5 144 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530794.3778468289 20 184676.7579559348 30 0.0 11 531157.1550750989 21 184924.2987611555 31 0.0 0 LINE 5 146 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530895.9427945592 20 184674.477204796 30 0.0 11 530853.3539856806 21 184722.662670036 31 0.0 0 LINE 5 147 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530872.5246082747 20 184625.397131656 30 0.0 11 530895.3127741604 21 184690.3429168817 31 0.0 0 LINE 5 148 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530881.7703476819 20 184675.0240901761 30 0.0 11 531228.261643328 21 184881.2784956878 31 0.0 0 LINE 5 149 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531056.8004158705 20 184564.4609387729 30 0.0 11 530872.2051953306 21 184927.5536250086 31 0.0 0 LINE 5 14A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530862.1453565096 20 184918.8302863079 30 0.0 11 531068.2731269009 21 185039.441703539 31 0.0 0 LINE 5 14B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530697.9914463482 20 185015.5737333332 30 0.0 11 530880.1604013233 21 184916.9768076993 31 0.0 0 LINE 5 14C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530696.9350081967 20 184928.3907741009 30 0.0 11 530754.3600034362 21 184991.5864201783 31 0.0 0 LINE 5 14D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531230.2997171692 20 184634.8808927253 30 0.0 11 531185.2838804869 21 184712.9556354173 31 0.0 0 LINE 5 14E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531310.676276314 20 184636.9221898522 30 0.0 11 531065.3007066001 21 185040.3313857042 31 0.0 0 LINE 5 14F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530762.244886776 20 184753.1969188066 30 0.0 11 531117.1883003287 21 184985.2538073602 31 0.0 0 LINE 5 150 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530857.7930969276 20 185213.7272284981 30 0.0 11 531119.0590254821 21 184978.5341598309 31 0.0 0 LINE 5 151 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530551.2309914298 20 185447.3752691109 30 0.0 11 530733.9839065221 21 185290.855504596 31 0.0 0 LINE 5 159 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530348.8181148427 20 184670.0431449962 30 0.0 11 530754.9648854495 21 185059.3532645555 31 0.0 0 LINE 5 15A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530768.0427135953 20 185059.3665338815 30 0.0 11 530751.1019407378 21 185076.7666714392 31 0.0 0 LINE 5 15B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530958.1276376175 20 185054.7821770324 30 0.0 11 530999.5616859051 21 185101.4584959087 31 0.0 0 LINE 5 15C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530956.1327284903 20 185039.3761384984 30 0.0 11 530961.1058763477 21 185062.9221409832 31 0.0 0 LINE 5 15D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530997.0898474322 20 184990.0711256135 30 0.0 11 530952.7982457301 21 185046.6406968503 31 0.0 0 LINE 5 15E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530292.8641702958 20 185138.907267058 30 0.0 11 530369.4465080707 21 185353.2161854958 31 0.0 0 LINE 5 160 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530370.209055034 20 184973.0161857821 30 0.0 11 530279.2606443146 21 185168.0844213306 31 0.0 0 LINE 5 167 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530103.8172967549 20 184909.1432228739 30 0.0 11 530296.6434578779 21 184802.4901862823 31 0.0 0 LINE 5 168 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530239.946090109 20 184831.2897865306 30 0.0 11 530402.572414678 21 185038.3924175608 31 0.0 0 LINE 5 169 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530862.2055151921 20 184812.5389120712 30 0.0 11 530841.7372332033 21 184854.8610028793 31 0.0 0 LINE 5 16A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530790.4707324915 20 184816.8599962522 30 0.0 11 530843.6341425299 21 184854.7341230553 31 0.0 0 LINE 5 16B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530795.6071824628 20 184767.5732594106 30 0.0 11 530725.8663087268 21 184845.1564635503 31 0.0 0 LINE 5 16C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530627.8983637173 20 184730.1996766032 30 0.0 11 530825.9688616006 21 184953.6427548386 31 0.0 0 LINE 5 16D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530924.4874933892 20 184951.6836966566 30 0.0 11 530886.1381600594 21 185008.8579249901 31 0.0 0 LINE 5 16E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530860.2504800935 20 184990.3167291071 30 0.0 11 530910.0659924778 21 185023.9468745498 31 0.0 0 LINE 5 16F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530868.4525274285 20 184987.7108168294 30 0.0 11 530827.8842952691 21 185046.3852955798 31 0.0 0 LINE 5 170 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530826.9412049412 20 185042.7894761519 30 0.0 11 530872.6657967761 21 185075.3601914692 31 0.0 0 LINE 5 171 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530910.0543372351 20 185014.9114050643 30 0.0 11 530866.6906180778 21 185079.1428277431 31 0.0 0 LINE 5 179 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531418.7837954784 20 184696.3400722527 30 0.0 11 531280.8903155291 21 184879.4025017154 31 0.0 0 LINE 5 17A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531365.823685466 20 184738.3257753346 30 0.0 11 531592.6022829192 21 184976.3217497332 31 0.0 0 LINE 5 17B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531322.1351667875 20 184916.8361742784 30 0.0 11 531466.2108774758 21 184798.1684518348 31 0.0 0 LINE 5 17C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531280.8533771736 20 184872.4579400288 30 0.0 11 531322.982462895 21 184916.8624535107 31 0.0 0 LINE 5 17D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531090.7411011921 20 185101.1705888962 30 0.0 11 531309.9939928264 21 184900.4864199589 31 0.0 0 LINE 5 17F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531234.6183701311 20 185110.4794756935 30 0.0 11 531708.2884303343 21 184665.0084063687 31 0.0 0 LINE 5 180 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531591.4298111294 20 184870.2268875977 30 0.0 11 531810.6718730136 21 185019.8265656036 31 0.0 0 LINE 5 181 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531638.9187541661 20 184819.4880729046 30 0.0 11 531511.6900544397 21 184965.8519211652 31 0.0 0 LINE 5 182 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531692.9947588596 20 184867.9461364589 30 0.0 11 531650.4059499809 21 184916.131601699 31 0.0 0 LINE 5 183 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531669.5765725753 20 184818.8660633189 30 0.0 11 531692.3647384609 21 184883.8118485445 31 0.0 0 LINE 5 184 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531678.8223119822 20 184868.493021839 30 0.0 11 532025.3136076282 21 185074.7474273507 31 0.0 0 LINE 5 185 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531803.886242807 20 184855.9649338027 30 0.0 11 531669.257159631 21 185121.0225566715 31 0.0 0 LINE 5 186 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531659.1973208101 20 185112.2992179708 30 0.0 11 531865.3250912015 21 185232.9106352019 31 0.0 0 LINE 5 187 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531525.0175778789 20 185192.8194795596 30 0.0 11 531677.2123656238 21 185110.4457393622 31 0.0 0 LINE 5 188 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531361.9808639693 20 184957.7832641063 30 0.0 11 531551.4119677366 21 185185.0553518411 31 0.0 0 LINE 5 18B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531559.2968510764 20 184946.6658504695 30 0.0 11 531914.240264629 21 185178.722739023 31 0.0 0 LINE 5 18C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531495.5870839868 20 185514.328262188 30 0.0 11 531683.1901243598 21 185202.3268566529 31 0.0 0 LINE 5 18D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531462.5997031672 20 185412.663348532 30 0.0 11 531570.4877017599 21 185459.0282866746 31 0.0 0 LINE 5 18E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531511.2935385215 20 185374.1416658756 30 0.0 11 531543.5981320772 21 185479.1274464145 31 0.0 0 LINE 5 194 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531145.8700791432 20 184863.5120766591 30 0.0 11 531379.525038466 21 185080.3303849344 31 0.0 0 LINE 5 199 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531364.8828980397 20 185058.1671364388 30 0.0 11 531313.3430297857 21 185456.7339505713 31 0.0 0 LINE 5 19D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531306.0542879553 20 185343.6943371587 30 0.0 11 531471.2618974372 21 185366.875736194 31 0.0 0 LINE 5 19E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531447.4325044233 20 185362.2124236505 30 0.0 11 531528.0241316422 21 185383.6033531333 31 0.0 0 LINE 5 19F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531454.8133421622 20 185351.359117895 30 0.0 11 531476.2768427921 21 185428.5825972159 31 0.0 0 LINE 5 1A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531385.8070593464 20 185499.2874665739 30 0.0 11 531481.1514824921 21 185416.9376060774 31 0.0 0 LINE 5 1A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531046.8204185547 20 185009.8251670371 30 0.0 11 531131.4314460383 21 185132.7716499767 31 0.0 0 LINE 5 1A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531659.2574794926 20 185006.0078437341 30 0.0 11 531638.7891975036 21 185048.3299345422 31 0.0 0 LINE 5 1A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531587.5226967918 20 185010.328927915 30 0.0 11 531640.6861068304 21 185048.2030547182 31 0.0 0 LINE 5 1A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531592.6591467632 20 184961.0421910735 30 0.0 11 531522.9182730272 21 185038.625395213 31 0.0 0 LINE 5 1A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531424.9503280177 20 184923.6686082661 30 0.0 11 531623.020825901 21 185147.1116865014 31 0.0 0 LINE 5 1A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531721.5394576896 20 185145.1526283194 30 0.0 11 531683.1901243598 21 185202.3268566529 31 0.0 0 LINE 5 1A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531522.4751258036 20 185175.0126803835 30 0.0 11 531707.1179567783 21 185217.4158062127 31 0.0 0 LINE 5 1AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531190.971715833 20 185002.7164624653 30 0.0 11 531271.9560624464 21 185081.1135679418 31 0.0 0 LINE 5 1AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531510.9794785422 20 185470.5053524346 30 0.0 11 531383.9700559601 21 186031.2293542523 31 0.0 0 LINE 5 1AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531446.5789296222 20 185494.6210341629 30 0.0 11 531394.317069799 21 185715.8408406318 31 0.0 0 LINE 5 1AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531303.1927971798 20 185374.8117721197 30 0.0 11 531201.7089334832 21 185510.9511236965 31 0.0 0 LINE 5 1B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531179.1304861695 20 185309.1540542189 30 0.0 11 531945.5235833686 21 185894.4094584342 31 0.0 0 LINE 5 1B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531306.2594945883 20 185492.8769809982 30 0.0 11 531119.7299674333 21 185890.4829456162 31 0.0 0 LINE 5 1B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531363.9212119025 20 185531.6681318393 30 0.0 11 531199.1434766117 21 185429.4046678644 31 0.0 0 LINE 5 1B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531324.7054493229 20 185592.7788688038 30 0.0 11 531270.3457337779 21 185558.4180331335 31 0.0 0 LINE 5 1B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531369.4236081366 20 185561.8345429817 30 0.0 11 531308.9422635012 21 185594.6866734165 31 0.0 0 LINE 5 1B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531321.9057846517 20 185578.8749408755 30 0.0 11 531173.5376807172 21 185953.8202748729 31 0.0 0 LINE 5 1B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531458.9627071512 20 185734.036583085 30 0.0 11 531071.0819022518 21 185609.6976292752 31 0.0 0 LINE 5 1B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531078.0896100116 20 185598.3755699595 30 0.0 11 530991.8880389454 21 185821.0975061012 31 0.0 0 LINE 5 1B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530956.4097734758 20 185451.7474070975 30 0.0 11 531082.7918483163 21 185615.8646001648 31 0.0 0 LINE 5 1B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531042.3088874028 20 185436.8032889021 30 0.0 11 530989.0780830457 21 185503.5700563008 31 0.0 0 LINE 5 1BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531427.9086440181 20 185996.2182578582 30 0.0 11 530990.5357910721 21 185818.3049727551 31 0.0 0 LINE 5 1BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531225.67491972 20 185473.3432035857 30 0.0 11 531053.182121386 21 185860.7466894662 31 0.0 0 LINE 5 1BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530705.244826224 20 185533.1168306179 30 0.0 11 531060.1140837643 21 185861.5220430019 31 0.0 0 LINE 5 1BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530750.2210620191 20 185452.1857979919 30 0.0 11 530721.6518899537 21 185566.0863253691 31 0.0 0 LINE 5 1C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530796.0140686664 20 185494.1144299564 30 0.0 11 530697.5223713036 21 185542.7455561081 31 0.0 0 LINE 5 1C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530944.3922051936 20 185612.8039722922 30 0.0 11 530775.9576853574 21 185501.2824771057 31 0.0 0 LINE 5 1C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530993.2462747479 20 185401.3925582406 30 0.0 11 530842.445202569 21 185661.7511045552 31 0.0 0 LINE 5 1C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530910.7632248174 20 185339.3410325321 30 0.0 11 530866.5377199338 21 185054.4967921601 31 0.0 0 LINE 5 1C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531241.8445475885 20 185051.9469660791 30 0.0 11 531241.8374840348 21 185051.9572004795 31 0.0 0 LINE 5 1C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531058.6997013602 20 185297.1334434182 30 0.0 11 530922.2746789083 21 185514.9725242263 31 0.0 0 LINE 5 1C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530924.3468199957 20 185527.8851535635 30 0.0 11 530904.4681140504 21 185513.935543462 31 0.0 0 LINE 5 1C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530959.1812899459 20 185714.807207831 30 0.0 11 530929.7367229487 21 185749.2623184473 31 0.0 0 LINE 5 1CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530974.0721419792 20 185710.3813506865 30 0.0 11 530951.620342561 21 185719.0452490875 31 0.0 0 LINE 5 1CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531029.2769113626 20 185742.952861627 30 0.0 11 530966.368846218 21 185708.2478517434 31 0.0 0 LINE 5 1CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530990.5554871495 20 185489.0985828673 30 0.0 11 530692.0265768201 21 185303.9764231624 31 0.0 0 LINE 5 1CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530835.9437799745 20 185306.8642317253 30 0.0 11 530970.1789346107 21 185451.086004182 31 0.0 0 LINE 5 1CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531368.1091655745 20 185350.5718122836 30 0.0 11 530668.7795996761 21 185311.5128716326 31 0.0 0 LINE 5 1CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530837.7457079078 20 185386.5022824307 30 0.0 11 530778.7567006423 21 185458.8357962565 31 0.0 0 LINE 5 1D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530797.6081421722 20 185429.1683182495 30 0.0 11 530789.3411006597 21 185512.1396281498 31 0.0 0 LINE 5 1D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530809.4994571749 20 185434.7241835344 30 0.0 11 530736.6862803595 21 185468.2262566015 31 0.0 0 LINE 5 1D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530609.7436608612 20 185359.4255856905 30 0.0 11 530748.9595424861 21 185471.1817544603 31 0.0 0 LINE 5 1D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531183.0307102225 20 185581.4869541878 30 0.0 11 531137.9864403011 21 185568.0287342017 31 0.0 0 LINE 5 1D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531167.3269023387 20 185511.358919597 30 0.0 11 531138.4141562844 21 185569.8811441243 31 0.0 0 LINE 5 1D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531226.956583333 20 185337.0486008117 30 0.0 11 531037.9542343994 21 185568.2127058122 31 0.0 0 LINE 5 1D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531055.5968811997 20 185665.1585449819 30 0.0 11 530905.7031021065 21 185592.1718504262 31 0.0 0 LINE 5 1DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531342.5419517839 20 185694.0402766141 30 0.0 11 531259.2409286286 21 185945.1870251501 31 0.0 0 LINE 5 1DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530564.9552335094 20 184893.4794901465 30 0.0 11 530687.4949689912 21 184780.9839569827 31 0.0 0 LINE 5 1DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530476.7429703215 20 184939.4505193447 30 0.0 11 530406.7340426724 21 184768.7171604471 31 0.0 0 LINE 5 1E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531173.3663268639 20 185528.1064924517 30 0.0 11 531070.7327473465 21 185471.5685231011 31 0.0 0 LINE 5 1E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531054.9475551248 20 184568.1054545053 30 0.0 11 531230.7725863386 21 184476.7284847849 31 0.0 0 LINE 5 1E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533270.7018874835 20 183269.704674172 30 0.0 11 533995.2261483039 21 183104.4788902862 31 0.0 0 LINE 5 1E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533457.9214482086 20 183355.7642878445 30 0.0 11 533604.5737555198 21 183337.0347532795 31 0.0 0 LINE 5 1E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533530.1315517867 20 183207.8193128204 30 0.0 11 533511.6243141418 21 183701.9266786306 31 0.0 0 LINE 5 1E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533572.3429516997 20 183331.8438445227 30 0.0 11 533646.7981581808 21 183366.1588628451 31 0.0 0 LINE 5 1E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533612.2522464815 20 183262.8325135418 30 0.0 11 533576.567616609 21 183343.107264685 31 0.0 0 LINE 5 1E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533597.4568488472 20 183274.7830833879 30 0.0 11 533791.7168653864 21 183232.1532961663 31 0.0 0 LINE 5 1E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533594.7911288029 20 183152.2117233308 30 0.0 11 533751.8214958982 21 183555.6973923812 31 0.0 0 LINE 5 1EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.3821678945 20 183285.0285129525 30 0.0 11 533642.492107029 21 183366.5930041412 31 0.0 0 LINE 5 1EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.2284528753 20 183229.0149493306 30 0.0 11 533810.0531847598 21 183285.8097756414 31 0.0 0 LINE 5 1EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534074.3386399248 20 183151.4269752421 30 0.0 11 533800.5742660043 21 183267.181170518 31 0.0 0 LINE 5 1ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534009.9822550737 20 183174.6632241171 30 0.0 11 534046.8228962965 21 183281.6238171917 31 0.0 0 LINE 5 1EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.646702763 20 183249.4026584481 30 0.0 11 533363.7016999166 21 183552.296365491 31 0.0 0 LINE 5 1EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533655.8537941067 20 183510.4459319125 30 0.0 11 533729.8187339051 21 183943.3581115531 31 0.0 0 LINE 5 1F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533589.946866456 20 183532.4891602347 30 0.0 11 533776.0005197917 21 183477.7757597539 31 0.0 0 LINE 5 1F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533611.4813241646 20 183601.8337010309 30 0.0 11 533673.0261102665 21 183583.1820253481 31 0.0 0 LINE 5 1F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533576.6132530237 20 183560.1026257608 30 0.0 11 533626.1680009311 21 183607.8685391599 31 0.0 0 LINE 5 1F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533617.8809475537 20 183589.176602051 30 0.0 11 533661.0930421482 21 183990.087829921 31 0.0 0 LINE 5 1F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533444.4675323084 20 183702.2585308958 30 0.0 11 533851.4514544708 21 183685.6518652057 31 0.0 0 LINE 5 1F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533847.7102810031 20 183672.8729522521 30 0.0 11 533871.5176046772 21 183910.5049850937 31 0.0 0 LINE 5 1F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534004.0299181535 20 183563.9235520484 30 0.0 11 533838.5224367574 21 183688.479384923 31 0.0 0 LINE 5 1F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533925.2076230635 20 183526.6538560638 30 0.0 11 533958.7459745272 21 183605.1809134549 31 0.0 0 LINE 5 1F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533207.3255747524 20 183960.3049635265 30 0.0 11 533517.743220695 21 183803.8631234574 31 0.0 0 LINE 5 1F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533404.6134673158 20 183963.2474941249 30 0.0 11 533873.5643870204 21 183908.1731405794 31 0.0 0 LINE 5 1FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533738.7306447869 20 183513.0669599583 30 0.0 11 533801.8809645518 21 183932.4084239981 31 0.0 0 LINE 5 1FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534224.47460254 20 183709.2127634093 30 0.0 11 533794.9927018023 21 183931.3106481514 31 0.0 0 LINE 5 1FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534457.7232899407 20 183610.3296057948 30 0.0 11 533968.0924029948 21 183836.668115154 31 0.0 0 LINE 5 1FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534202.6632789289 20 183619.2296539358 30 0.0 11 534199.8836010037 21 183736.6255700483 31 0.0 0 LINE 5 1FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534147.3617370868 20 183647.456398454 30 0.0 11 534229.3554706404 21 183720.5496849997 31 0.0 0 LINE 5 1FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533972.7437243368 20 183722.3685368734 30 0.0 11 534164.7865490214 21 183659.7044734213 31 0.0 0 LINE 5 200 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533972.5943166301 20 183472.651390221 30 0.0 11 534057.9839914489 21 183796.6861657618 31 0.0 0 LINE 5 201 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533880.9676565471 20 183491.6555787594 30 0.0 11 534001.1484391712 21 183474.2186921551 31 0.0 0 LINE 5 202 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533966.8649116843 20 183378.0488408435 30 0.0 11 533865.8384516585 21 183444.2408746609 31 0.0 0 LINE 5 203 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533869.8459157255 20 183438.8265558422 30 0.0 11 533882.4827401662 21 183493.2134252263 31 0.0 0 LINE 5 204 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.3120588305 20 183102.5693639709 30 0.0 11 534020.1041949208 21 183633.953815103 31 0.0 0 LINE 5 205 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534014.6697131808 20 183645.8490315072 30 0.0 11 534037.5443778956 21 183637.6940154909 31 0.0 0 LINE 5 206 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533931.3368567337 20 183816.7552329881 30 0.0 11 533950.5478562621 21 183857.8048940144 31 0.0 0 LINE 5 207 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.1613004711 20 183808.5253846964 30 0.0 11 533937.4969419636 21 183822.8529595328 31 0.0 0 LINE 5 208 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533856.2782318214 20 183825.2273517097 30 0.0 11 533926.1545818143 21 183808.5193272029 31 0.0 0 LINE 5 209 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533961.1739025831 20 183590.8382696407 30 0.0 11 534379.5749554228 21 183474.2284763425 31 0.0 0 LINE 5 20A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534350.0885551939 20 183462.4292674622 30 0.0 11 534369.0260173707 21 183662.8181014637 31 0.0 0 LINE 5 20B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534101.8508752668 20 183248.1966110715 30 0.0 11 534369.7091801646 21 183492.8116011192 31 0.0 0 LINE 5 20C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534331.7371032914 20 183358.3280084779 30 0.0 11 533990.9335592428 21 183559.6209208238 31 0.0 0 LINE 5 20D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533948.9530815789 20 183438.1485673899 30 0.0 11 533982.607720473 21 183426.774957106 31 0.0 0 LINE 5 20E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534135.7799619498 20 183532.6183973673 30 0.0 11 534173.3870155533 21 183618.0440944372 31 0.0 0 LINE 5 20F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534163.1125968062 20 183584.4290320622 30 0.0 11 534148.9959986748 21 183666.607520118 31 0.0 0 LINE 5 210 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534150.1714181212 20 183586.619216026 30 0.0 11 534211.4401009357 21 183638.2941240943 31 0.0 0 LINE 5 211 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534362.7636945454 20 183567.208368469 30 0.0 11 534198.8229231334 21 183637.8760868667 31 0.0 0 LINE 5 212 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534133.0534407664 20 183026.7152225984 30 0.0 11 533977.4553795874 21 183110.2952903923 31 0.0 0 LINE 5 213 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534027.2513479877 20 183070.7431726557 30 0.0 11 534147.8091657108 21 183304.8470679847 31 0.0 0 LINE 5 214 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533751.0505647677 20 183628.6602944098 30 0.0 11 533798.0520979916 21 183627.6775367849 31 0.0 0 LINE 5 215 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533784.854580768 20 183565.2423212487 30 0.0 11 533797.1467362854 21 183629.3492675242 31 0.0 0 LINE 5 216 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533737.9064232347 20 183549.3855860542 30 0.0 11 533837.4861916935 21 183518.2919734023 31 0.0 0 LINE 5 217 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533773.7742595558 20 183381.3482958636 30 0.0 11 533894.426477489 21 183654.4815484178 31 0.0 0 LINE 5 218 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533851.6151786993 20 183743.2337394579 30 0.0 11 533919.5664651833 21 183732.1799429354 31 0.0 0 LINE 5 219 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533913.4912480489 20 183700.922309379 30 0.0 11 533923.3192982251 21 183760.2180207445 31 0.0 0 LINE 5 21A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533907.7061656309 20 183707.2939010718 30 0.0 11 533977.9455113938 21 183694.8476074883 31 0.0 0 LINE 5 21B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533975.0691473797 20 183692.4926410805 30 0.0 11 533985.6377707644 21 183747.6278747745 31 0.0 0 LINE 5 21C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533915.1095672107 20 183756.444406914 30 0.0 11 533991.5652424396 21 183743.7709100099 31 0.0 0 LINE 5 21D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533943.085985443 20 183201.5481465576 30 0.0 11 533980.6329200526 21 183307.8251348707 31 0.0 0 LINE 5 21E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533567.3344408618 20 183694.6941674654 30 0.0 11 533580.779713257 21 183958.953461359 31 0.0 0 LINE 5 21F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533299.3400004697 20 184222.45492858 30 0.0 11 533281.5900181469 21 184813.9041900183 31 0.0 0 LINE 5 220 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533203.5044763441 20 184131.5129678913 30 0.0 11 533448.5161786756 21 184142.2478269584 31 0.0 0 LINE 5 221 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533425.5537299617 20 183189.4530703633 30 0.0 11 533355.5667372975 21 184507.1397523095 31 0.0 0 LINE 5 222 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533416.2853748554 20 184137.0569182016 30 0.0 11 533490.7405813366 21 184171.371936524 31 0.0 0 LINE 5 223 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533456.1946696371 20 184068.0455872208 30 0.0 11 533420.510039765 21 184148.3203383639 31 0.0 0 LINE 5 224 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533443.2091147539 20 184079.7836062105 30 0.0 11 533637.4691312929 21 184037.1538189889 31 0.0 0 LINE 5 225 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533407.8651870973 20 183878.1092921243 30 0.0 11 533595.763919054 21 184360.9104660599 31 0.0 0 LINE 5 226 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533654.3245910503 20 184090.2415866314 30 0.0 11 533486.4345301848 21 184171.8060778201 31 0.0 0 LINE 5 227 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533631.1708760309 20 184034.2280230095 30 0.0 11 533653.9956079153 21 184091.0228493203 31 0.0 0 LINE 5 228 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.2810630807 20 183956.640048921 30 0.0 11 533644.51668916 21 184072.3942441969 31 0.0 0 LINE 5 229 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533853.9246782293 20 183979.876297796 30 0.0 11 533890.7653194523 21 184086.8368908706 31 0.0 0 LINE 5 22A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533965.5891259187 20 184054.615732127 30 0.0 11 533264.55379769 21 184336.4331711375 31 0.0 0 LINE 5 22B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533499.7962172624 20 184315.6590055914 30 0.0 11 533573.761157061 21 184748.571185232 31 0.0 0 LINE 5 22C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533433.8892896117 20 184337.7022339136 30 0.0 11 533619.9429429473 21 184282.9888334328 31 0.0 0 LINE 5 22D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533455.4237473202 20 184407.0467747098 30 0.0 11 533516.9685334222 21 184388.3950990269 31 0.0 0 LINE 5 22E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533420.5556761794 20 184365.3156994397 30 0.0 11 533470.1104240868 21 184413.0816128387 31 0.0 0 LINE 5 22F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533461.8233707093 20 184394.3896757299 30 0.0 11 533505.0354653038 21 184795.3009035999 31 0.0 0 LINE 5 230 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533288.409955464 20 184507.4716045747 30 0.0 11 533695.3938776265 21 184490.8649388846 31 0.0 0 LINE 5 231 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533691.6527041588 20 184478.0860259309 30 0.0 11 533715.4600278328 21 184715.7180587726 31 0.0 0 LINE 5 232 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533847.9723413094 20 184369.1366257273 30 0.0 11 533682.4648599131 21 184493.6924586019 31 0.0 0 LINE 5 233 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533769.1500462192 20 184331.8669297427 30 0.0 11 533802.6883976829 21 184410.3939871337 31 0.0 0 LINE 5 234 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533280.1746114135 20 184638.1115223118 30 0.0 11 533369.903982884 21 184629.7013561934 31 0.0 0 LINE 5 235 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533248.5558904716 20 184768.4605678038 30 0.0 11 533717.5068101762 21 184713.3862142584 31 0.0 0 LINE 5 236 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533582.6730679426 20 184318.2800336372 30 0.0 11 533645.8233877078 21 184737.6214976771 31 0.0 0 LINE 5 237 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.0039373072 20 184485.2255270968 30 0.0 11 533638.9351249582 21 184736.5237218303 31 0.0 0 LINE 5 238 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534046.6057020844 20 184424.4427276146 30 0.0 11 534043.8260241596 21 184541.8386437273 31 0.0 0 LINE 5 239 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533991.3041602425 20 184452.6694721329 30 0.0 11 534073.2978937961 21 184525.7627586786 31 0.0 0 LINE 5 23A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533816.6861474925 20 184527.5816105521 30 0.0 11 534008.728972177 21 184464.9175471002 31 0.0 0 LINE 5 23B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533816.5367397858 20 184277.8644638999 30 0.0 11 533901.9264146046 21 184601.8992394407 31 0.0 0 LINE 5 23C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533724.9100797029 20 184296.8686524383 30 0.0 11 533845.0908623268 21 184279.431765834 31 0.0 0 LINE 5 23D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.80733484 20 184183.2619145225 30 0.0 11 533709.7808748143 21 184249.4539483398 31 0.0 0 LINE 5 23E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533713.7883388813 20 184244.0396295211 30 0.0 11 533726.4251633219 21 184298.4264989052 31 0.0 0 LINE 5 23F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533679.2544819863 20 183907.7824376498 30 0.0 11 533864.0466180764 21 184439.1668887819 31 0.0 0 LINE 5 240 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533858.6121363364 20 184451.062105186 30 0.0 11 533881.4868010512 21 184442.9070891699 31 0.0 0 LINE 5 241 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533775.2792798895 20 184621.968306667 30 0.0 11 533794.4902794179 21 184663.0179676933 31 0.0 0 LINE 5 242 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533762.1037236266 20 184613.7384583753 30 0.0 11 533781.4393651193 21 184628.0660332116 31 0.0 0 LINE 5 243 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533700.2206549769 20 184630.4404253886 30 0.0 11 533770.09700497 21 184613.7324008818 31 0.0 0 LINE 5 244 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533805.1163257389 20 184396.0513433196 30 0.0 11 534148.8336143433 21 184307.1003803216 31 0.0 0 LINE 5 245 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533945.7932984225 20 184053.4096847504 30 0.0 11 534099.4280930914 21 184187.6594453309 31 0.0 0 LINE 5 246 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534111.8739580623 20 184159.1560880029 30 0.0 11 533834.8759823985 21 184364.8339945026 31 0.0 0 LINE 5 247 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533792.8955047349 20 184243.3616410688 30 0.0 11 533826.5501436286 21 184231.9880307849 31 0.0 0 LINE 5 248 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533979.7223851057 20 184337.8314710463 30 0.0 11 534017.3294387088 21 184423.2571681159 31 0.0 0 LINE 5 249 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534007.0550199618 20 184389.6421057411 30 0.0 11 533992.9384218304 21 184471.8205937969 31 0.0 0 LINE 5 24A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533994.1138412768 20 184391.8322897049 30 0.0 11 534055.3825240914 21 184443.5071977732 31 0.0 0 LINE 5 24B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534157.3418682092 20 184390.7032924748 30 0.0 11 534042.765346289 21 184443.0891605456 31 0.0 0 LINE 5 24C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533853.5262160743 20 183878.666833987 30 0.0 11 533991.7515888664 21 184110.0601416636 31 0.0 0 LINE 5 24D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533594.9929879234 20 184433.8733680887 30 0.0 11 533641.9945211472 21 184432.8906104638 31 0.0 0 LINE 5 24E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533628.7970039238 20 184370.4553949276 30 0.0 11 533641.0891594411 21 184434.5623412031 31 0.0 0 LINE 5 24F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533581.8488463905 20 184354.5986597329 30 0.0 11 533681.4286148493 21 184323.5050470813 31 0.0 0 LINE 5 250 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533617.7166827114 20 184186.5613695425 30 0.0 11 533738.3689006447 21 184459.6946220967 31 0.0 0 LINE 5 251 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533695.557601855 20 184548.4468131368 30 0.0 11 533763.508888339 21 184537.3930166142 31 0.0 0 LINE 5 252 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533757.4336712046 20 184506.1353830579 30 0.0 11 533767.2617213808 21 184565.4310944234 31 0.0 0 LINE 5 253 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533751.6485887866 20 184512.5069747506 30 0.0 11 533821.8879345495 21 184500.0606811671 31 0.0 0 LINE 5 254 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533819.0115705354 20 184497.7057147594 30 0.0 11 533829.5801939202 21 184552.8409484534 31 0.0 0 LINE 5 255 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533759.0519903664 20 184561.6574805929 30 0.0 11 533835.5076655954 21 184548.9839836887 31 0.0 0 LINE 5 256 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.0284085987 20 184006.7612202365 30 0.0 11 533824.5753432083 21 184113.0382085496 31 0.0 0 LINE 5 257 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533411.2768640178 20 184499.9072411442 30 0.0 11 533424.7221364126 21 184764.1665350379 31 0.0 0 LINE 5 258 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534079.0438751079 20 184492.5166948246 30 0.0 11 534641.721189493 21 184610.5719340789 31 0.0 0 LINE 5 25A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534078.5814593011 20 184263.7540395752 30 0.0 11 534244.6175290032 21 184228.1883089295 31 0.0 0 LINE 5 25B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534001.2095466687 20 183814.2563075048 30 0.0 11 534167.6424192836 21 184551.2581387564 31 0.0 0 LINE 5 25C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534184.6430945557 20 184315.7129436011 30 0.0 11 534623.810301958 21 184321.8368213024 31 0.0 0 LINE 5 25D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534195.8955435099 20 184384.2914345422 30 0.0 11 534171.5481171157 21 184191.8941348217 31 0.0 0 LINE 5 25E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534267.7865448688 20 184374.0893695216 30 0.0 11 534259.1867207303 21 184310.3579900692 31 0.0 0 LINE 5 25F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534221.0297037694 20 184401.8573877923 30 0.0 11 534276.0859439502 21 184360.5528367094 31 0.0 0 LINE 5 260 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.3117883924 20 184365.7534653767 30 0.0 11 534658.9839601197 21 184387.0189272303 31 0.0 0 LINE 5 261 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534340.2964578094 20 184554.9790199963 30 0.0 11 534388.795247378 21 184150.5540434503 31 0.0 0 LINE 5 262 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534375.5833000987 20 184152.2097741889 30 0.0 11 534613.971169032 21 184166.5971171824 31 0.0 0 LINE 5 263 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534292.9527107282 20 183980.5182296566 30 0.0 11 534389.5250794471 21 184163.7684943256 31 0.0 0 LINE 5 264 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534243.591734117 20 184052.3894925513 30 0.0 11 534326.4617765393 21 184031.8012475966 31 0.0 0 LINE 5 265 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534523.654663655 20 184592.9361776223 30 0.0 11 534529.6593127575 21 184503.01379338 31 0.0 0 LINE 5 267 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534200.4451829229 20 184234.3143184903 30 0.0 11 534624.4909197793 21 184238.8353143359 31 0.0 0 LINE 5 268 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534471.5327107409 20 183786.0600145884 30 0.0 11 534606.9904846774 21 184209.2224334297 31 0.0 0 LINE 5 269 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534421.2657241103 20 183576.3330352236 30 0.0 11 534556.4776611428 21 184059.4846922112 31 0.0 0 LINE 5 26A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534379.2230397164 20 183793.2446136424 30 0.0 11 534494.6738051587 21 183814.7073368633 31 0.0 0 LINE 5 26B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534398.2709077693 20 183852.3393541769 30 0.0 11 534483.5028377962 21 183783.049246773 31 0.0 0 LINE 5 26C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534444.3820505485 20 184036.6679774855 30 0.0 11 534413.140644698 21 183837.0904088021 31 0.0 0 LINE 5 26D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534231.8313058096 20 183993.0367155942 30 0.0 11 534531.3403140241 21 183964.3680914949 31 0.0 0 LINE 5 26E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534172.5775135222 20 183923.7014562585 30 0.0 11 534215.9402417578 21 184037.1348698832 31 0.0 0 LINE 5 26F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534115.2587862786 20 184054.0831760169 30 0.0 11 534123.8030832675 21 183933.6060995451 31 0.0 0 LINE 5 270 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.0293094167 20 183939.744568014 30 0.0 11 534174.6763040911 21 183924.2648762933 31 0.0 0 LINE 5 271 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533810.5991600926 20 184073.5153000436 30 0.0 11 533810.6114064546 21 184073.5131405614 31 0.0 0 LINE 5 272 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533954.7380145801 20 184048.098338197 30 0.0 11 534364.6500434818 21 183975.815826753 31 0.0 0 LINE 5 273 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534375.5265551551 20 183983.0774559717 30 0.0 11 534371.123204419 21 183959.1951387822 31 0.0 0 LINE 5 274 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534530.9589212817 20 184092.5949168104 30 0.0 11 534574.5465687242 21 184080.1750068405 31 0.0 0 LINE 5 275 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534520.7335404321 20 184104.2896708572 30 0.0 11 534537.9608515989 21 184087.4859158428 31 0.0 0 LINE 5 276 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534527.3546613447 20 184168.0441267445 30 0.0 11 534522.0020775037 21 184096.3976877718 31 0.0 0 LINE 5 277 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534312.6897586476 20 184027.1174682027 30 0.0 11 534268.715040369 21 183678.6121619755 31 0.0 0 LINE 5 278 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534178.0924395927 20 183721.0298699493 30 0.0 11 534286.6169309787 21 183992.7609886244 31 0.0 0 LINE 5 279 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534160.0049395611 20 184014.8357883496 30 0.0 11 534154.1430236581 21 183979.7982132065 31 0.0 0 LINE 5 27A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534283.0554192325 20 183845.4622028715 30 0.0 11 534373.3845904289 21 183821.9572878209 31 0.0 0 LINE 5 27B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534338.5613499616 20 183826.740385397 30 0.0 11 534417.4375952255 21 183853.7796193919 31 0.0 0 LINE 5 27C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534338.6600611481 20 183839.8652194019 30 0.0 11 534399.4430551204 21 183787.6198821797 31 0.0 0 LINE 5 27D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534353.3950801142 20 183626.8977659865 30 0.0 11 534397.018575538 21 183800.0089834212 31 0.0 0 LINE 5 27E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534316.5240373919 20 184240.583205404 30 0.0 11 534323.0481789416 21 184194.0262992032 31 0.0 0 LINE 5 27F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534259.3074196166 20 184197.0997663956 30 0.0 11 534324.554163355 21 184195.1866329612 31 0.0 0 LINE 5 280 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534236.1677363386 20 184240.9189471798 30 0.0 11 534221.3497769107 21 184137.6553470467 31 0.0 0 LINE 5 281 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534075.9993490205 20 184178.7166941591 30 0.0 11 534364.8760209383 21 184103.158770916 31 0.0 0 LINE 5 282 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534445.6665385903 20 184159.5737598459 30 0.0 11 534445.5888953305 21 184090.7293139994 31 0.0 0 LINE 5 283 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534413.7624798858 20 184091.7428221283 30 0.0 11 534473.8666444875 21 184091.4951244661 31 0.0 0 LINE 5 284 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534419.1301320043 20 184098.4698326099 30 0.0 11 534418.0426346746 21 184027.1445687356 31 0.0 0 LINE 5 285 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534415.2591650874 20 184029.6086372781 30 0.0 11 534471.3741634863 21 184027.9664590178 31 0.0 0 LINE 5 286 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534468.8322797114 20 184098.9981249308 30 0.0 11 534468.5116705245 21 184021.4998345739 31 0.0 0 LINE 5 287 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534352.4198206242 20 184432.4779143455 30 0.0 11 534615.4420738622 21 184461.3404170194 31 0.0 0 LINE 5 288 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533532.7624275796 20 183279.5203883841 30 0.0 11 532822.6282750719 21 183060.5581778998 31 0.0 0 LINE 5 289 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533342.1028701529 20 183213.5023917251 30 0.0 11 533311.0032423038 21 183772.1392497893 31 0.0 0 LINE 5 28A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533339.6295991045 20 183351.3335597998 30 0.0 11 533194.7893030568 21 183321.6859065113 31 0.0 0 LINE 5 28B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533278.6891237384 20 183198.401309585 30 0.0 11 533234.487352922 21 184185.8116573112 31 0.0 0 LINE 5 28C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533227.3181130724 20 183318.9206275791 30 0.0 11 533150.504528331 21 183347.5697367062 31 0.0 0 LINE 5 28D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533192.6831632028 20 183247.1171745893 30 0.0 11 533222.2627044432 21 183329.8364542056 31 0.0 0 LINE 5 28E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533206.543120186 20 183260.1410566229 30 0.0 11 533016.016412499 21 183203.0987351212 31 0.0 0 LINE 5 28F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533218.3705491292 20 183138.1125505508 30 0.0 11 533031.596680065 21 183528.7207214253 31 0.0 0 LINE 5 290 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532993.44798064 20 183254.429505146 30 0.0 11 533154.7660373612 21 183348.3247837068 31 0.0 0 LINE 5 291 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533020.7270185264 20 183200.3049458331 30 0.0 11 532993.7175981719 21 183255.2331889633 31 0.0 0 LINE 5 292 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532740.2254147078 20 183101.4565594727 30 0.0 11 533004.5635047808 21 183237.3658685307 31 0.0 0 LINE 5 293 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532802.6632449139 20 183129.4420001883 30 0.0 11 532757.9244439029 21 183233.3469615745 31 0.0 0 LINE 5 294 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.7206542239 20 183195.6187514277 30 0.0 11 533412.4422479266 21 183553.0579135474 31 0.0 0 LINE 5 295 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533130.6806038581 20 183490.7750957559 30 0.0 11 533024.5381114682 21 183916.9411888579 31 0.0 0 LINE 5 296 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533194.7538784246 20 183517.6868499452 30 0.0 11 533013.3144771753 21 183449.2086651994 31 0.0 0 LINE 5 297 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533168.0923122618 20 183585.2261651385 30 0.0 11 533108.1152453137 21 183562.0227786959 31 0.0 0 LINE 5 298 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533205.9844550757 20 183546.2203893963 30 0.0 11 533152.9953396826 21 183590.1454297818 31 0.0 0 LINE 5 299 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533162.6574581374 20 183572.125795115 30 0.0 11 533089.5755333647 21 183968.6811254574 31 0.0 0 LINE 5 29A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533327.1256725954 20 183697.8633855617 30 0.0 11 532922.5243948965 21 183650.8580632188 31 0.0 0 LINE 5 29B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532927.2110360585 20 183638.3948216737 30 0.0 11 532885.6939141481 21 183873.5800684076 31 0.0 0 LINE 5 29C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532779.4795621642 20 183518.0569124989 30 0.0 11 532935.2056681789 21 183654.6448395154 31 0.0 0 LINE 5 29D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532860.8690292618 20 183486.7880927641 30 0.0 11 532821.5502885538 21 183562.5862219661 31 0.0 0 LINE 5 29F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533293.6322814212 20 183952.7605173787 30 0.0 11 532883.8273047613 21 183871.1016442716 31 0.0 0 LINE 5 2A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533047.8398997946 20 183487.189023119 30 0.0 11 532953.4969078967 21 183900.6314329289 31 0.0 0 LINE 5 2A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532548.7839254298 20 183646.44825568 30 0.0 11 532960.4479911811 21 183900.052022287 31 0.0 0 LINE 5 2A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532323.5859293173 20 183530.3935634832 30 0.0 11 532794.9132185243 21 183792.7256292301 31 0.0 0 LINE 5 2A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532577.2654881728 20 183558.3489116874 30 0.0 11 532571.2553581126 21 183675.6238282977 31 0.0 0 LINE 5 2A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.3005233718 20 183590.633500544 30 0.0 11 532543.0686538527 21 183657.3882892886 31 0.0 0 LINE 5 2A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532798.8253221348 20 183678.3983628817 30 0.0 11 532612.008295049 21 183601.5437615102 31 0.0 0 LINE 5 2A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532817.6548659477 20 183429.3920899996 30 0.0 11 532708.2644265074 21 183746.131200443 31 0.0 0 LINE 5 2A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532982.2371375846 20 183070.6166723318 30 0.0 11 532758.2115810168 21 183586.6884875571 31 0.0 0 LINE 5 2A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532762.7409918191 20 183598.9569105556 30 0.0 11 532740.5404720749 21 183589.1135627954 31 0.0 0 LINE 5 2A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.0553973926 20 183775.6181090037 30 0.0 11 532810.8274301857 21 183815.1156361047 31 0.0 0 LINE 5 2AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532846.8096853747 20 183768.3969423502 30 0.0 11 532826.4564207106 21 183781.2379333611 31 0.0 0 LINE 5 2AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532907.2699385936 20 183789.6813889798 30 0.0 11 532838.8392540151 21 183767.7929495795 31 0.0 0 LINE 5 2AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532820.202091548 20 183548.1021399771 30 0.0 11 532411.6965931075 21 183400.5198149712 31 0.0 0 LINE 5 2AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532705.5512352486 20 183195.8969469713 30 0.0 11 532420.1445797267 21 183419.7888982393 31 0.0 0 LINE 5 2AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532468.0705552293 20 183288.5226947296 30 0.0 11 532792.8610919387 21 183514.7460345087 31 0.0 0 LINE 5 2B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532650.440516718 20 183476.9836669457 30 0.0 11 532606.5484086562 21 183559.3567393084 31 0.0 0 LINE 5 2B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532619.308676055 20 183526.6044619072 30 0.0 11 532627.2382057076 21 183609.6087075904 31 0.0 0 LINE 5 2B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532632.0497533188 20 183529.7565979628 30 0.0 11 532567.0871053734 21 183576.7033975304 31 0.0 0 LINE 5 2B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532319.1054598828 20 183440.943242896 30 0.0 11 532579.7002024197 21 183577.2303830341 31 0.0 0 LINE 5 2B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532691.0044244704 20 182972.7019742909 30 0.0 11 532839.9141442266 21 183067.6876560392 31 0.0 0 LINE 5 2B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532793.2164716504 20 183024.5212818305 30 0.0 11 532655.4838754236 21 183248.9506764272 31 0.0 0 LINE 5 2B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533026.9073257412 20 183601.5368553743 30 0.0 11 532980.1110058653 21 183597.0408144468 31 0.0 0 LINE 5 2B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532997.9421264003 20 183535.767804562 30 0.0 11 532980.888773864 21 183598.7755883294 31 0.0 0 LINE 5 2B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533045.9449296638 20 183523.46754336 30 0.0 11 532948.9701949887 21 183485.011804273 31 0.0 0 LINE 5 2B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533022.747934971 20 183353.2179265787 30 0.0 11 532882.0015395169 21 183616.5602579835 31 0.0 0 LINE 5 2BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532918.0536104154 20 183708.2663477616 30 0.0 11 532851.1196203771 21 183692.1603013838 31 0.0 0 LINE 5 2BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532859.5161003121 20 183661.4447183112 30 0.0 11 532845.2798621558 21 183719.8390800234 31 0.0 0 LINE 5 2BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532864.808334425 20 183668.2312208995 30 0.0 11 532795.6968644821 21 183650.5654166575 31 0.0 0 LINE 5 2BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532798.7413366781 20 183648.4322205175 30 0.0 11 532784.0778326244 21 183702.6223620896 31 0.0 0 LINE 5 2BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532853.7488820336 20 183716.6901838713 30 0.0 11 532778.4554968875 21 183698.3327888569 31 0.0 0 LINE 5 2C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533236.9410300952 20 184128.2527506047 30 0.0 11 533126.981531269 21 184343.3517983396 31 0.0 0 LINE 5 2C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532835.6102659117 20 183916.0876363871 30 0.0 11 533298.551877255 21 184154.1088557825 31 0.0 0 LINE 5 2C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532781.1055054279 20 184010.2498283422 30 0.0 11 533459.0946851481 21 184343.719875779 31 0.0 0 LINE 5 2C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533226.0654550621 20 184305.4061726703 30 0.0 11 533119.9229626722 21 184731.5722657724 31 0.0 0 LINE 5 2C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533290.1387296285 20 184332.3179268596 30 0.0 11 533108.6993283792 21 184263.8397421138 31 0.0 0 LINE 5 2C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533263.4771634658 20 184399.8572420528 30 0.0 11 533203.5000965176 21 184376.6538556104 31 0.0 0 LINE 5 2CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533301.3693062795 20 184360.8514663108 30 0.0 11 533248.3801908866 21 184404.7765066962 31 0.0 0 LINE 5 2CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533258.0423093414 20 184386.7568720294 30 0.0 11 533184.9603845684 21 184783.3122023718 31 0.0 0 LINE 5 2CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533313.2245827507 20 184499.6854179535 30 0.0 11 533017.9092461005 21 184465.4891401333 31 0.0 0 LINE 5 2CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533022.5958872625 20 184453.0258985883 30 0.0 11 532981.0787653522 21 184688.211145322 31 0.0 0 LINE 5 2CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532874.8644133682 20 184332.6879894133 30 0.0 11 533030.5905193829 21 184469.2759164299 31 0.0 0 LINE 5 2CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532956.2538804658 20 184301.4191696784 30 0.0 11 532916.9351397578 21 184377.2172988805 31 0.0 0 LINE 5 2D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533312.5190293062 20 184749.7419374041 30 0.0 11 532979.2121559653 21 184685.7327211861 31 0.0 0 LINE 5 2D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533143.2247509987 20 184301.8201000335 30 0.0 11 533048.8817591007 21 184715.2625098432 31 0.0 0 LINE 5 2D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532593.9135947571 20 184428.0269791083 30 0.0 11 533055.8328423851 21 184714.6830992013 31 0.0 0 LINE 5 2D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532672.6503393768 20 184372.9799886018 30 0.0 11 532666.6402093166 21 184490.254905212 31 0.0 0 LINE 5 2D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532725.6853745756 20 184405.2645774584 30 0.0 11 532638.4535050566 21 184472.0193662031 31 0.0 0 LINE 5 2D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532894.2101733389 20 184493.0294397962 30 0.0 11 532707.3931462528 21 184416.1748384246 31 0.0 0 LINE 5 2D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532913.0397171517 20 184244.0231669139 30 0.0 11 532803.6492777113 21 184560.7622773574 31 0.0 0 LINE 5 2D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533002.9879995437 20 184269.8284089141 30 0.0 11 532884.4483571425 21 184243.4500331875 31 0.0 0 LINE 5 2D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533018.0305508438 20 184217.9793931889 30 0.0 11 533001.3606235288 21 184271.2685517172 31 0.0 0 LINE 5 2D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533077.6219887886 20 183885.2477492463 30 0.0 11 532853.5964322206 21 184401.3195644716 31 0.0 0 LINE 5 2DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532858.1258430229 20 184413.5879874701 30 0.0 11 532835.9253232789 21 184403.7446397097 31 0.0 0 LINE 5 2DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532928.4402485964 20 184590.2491859182 30 0.0 11 532906.2122813898 21 184629.7467130191 31 0.0 0 LINE 5 2DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532942.1945365787 20 184583.0280192646 30 0.0 11 532921.8412719146 21 184595.8690102754 31 0.0 0 LINE 5 2DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533002.6547897976 20 184604.3124658941 30 0.0 11 532934.2241052192 21 184582.424026494 31 0.0 0 LINE 5 2DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532915.586942752 20 184362.7332168916 30 0.0 11 532579.4868776007 21 184248.3190809244 31 0.0 0 LINE 5 2DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532800.9360864524 20 184010.5280238858 30 0.0 11 532637.6889675159 21 184132.908686197 31 0.0 0 LINE 5 2E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532627.4102219 20 184103.5541580553 30 0.0 11 532888.2459431427 21 184329.3771114232 31 0.0 0 LINE 5 2E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532939.1957581605 20 184211.3855460326 30 0.0 11 532906.4862421954 21 184197.5262063909 31 0.0 0 LINE 5 2E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532745.8253679221 20 184291.6147438601 30 0.0 11 532701.9332598602 21 184373.9878162229 31 0.0 0 LINE 5 2E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532714.6935272589 20 184341.2355388216 30 0.0 11 532722.6230569118 21 184424.2397845048 31 0.0 0 LINE 5 2E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532727.4346045228 20 184344.3876748772 30 0.0 11 532662.4719565772 21 184391.3344744447 31 0.0 0 LINE 5 2E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532564.7483924605 20 184331.0512654725 30 0.0 11 532675.0850536235 21 184391.8614599485 31 0.0 0 LINE 5 2E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532906.0166036281 20 183843.1770056994 30 0.0 11 532750.8687266275 21 184063.5817533417 31 0.0 0 LINE 5 2E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533122.292176945 20 184416.1679322887 30 0.0 11 533075.4958570691 21 184411.6718913614 31 0.0 0 LINE 5 2E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533093.3269776042 20 184350.3988814763 30 0.0 11 533076.273625068 21 184413.4066652438 31 0.0 0 LINE 5 2E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533141.3297808676 20 184338.0986202742 30 0.0 11 533044.3550461925 21 184299.6428811874 31 0.0 0 LINE 5 2EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533118.132786175 20 184167.8490034932 30 0.0 11 532977.3863907207 21 184431.1913348979 31 0.0 0 LINE 5 2EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533013.4384616195 20 184522.897424676 30 0.0 11 532946.5044715811 21 184506.7913782983 31 0.0 0 LINE 5 2EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532954.9009515162 20 184476.0757952258 30 0.0 11 532940.6647133597 21 184534.470156938 31 0.0 0 LINE 5 2ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532960.1931856289 20 184482.8622978139 30 0.0 11 532891.0817156861 21 184465.196493572 31 0.0 0 LINE 5 2EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532894.1261878822 20 184463.0632974319 30 0.0 11 532879.4626838282 21 184517.2534390039 31 0.0 0 LINE 5 2EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532949.1337332375 20 184531.3212607857 30 0.0 11 532873.8403480914 21 184512.9638657713 31 0.0 0 LINE 5 2F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532962.7457486525 20 183975.8869687485 30 0.0 11 532917.3537715828 21 184079.0574052173 31 0.0 0 LINE 5 2F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532635.2106572713 20 184438.4366176368 30 0.0 11 532065.2785999623 21 184514.0689499459 31 0.0 0 LINE 5 2F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532590.2300880724 20 184386.4198395649 30 0.0 11 532364.6295972854 21 184414.239316967 31 0.0 0 LINE 5 2F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532652.7847925186 20 184210.3495376971 30 0.0 11 532489.8745094785 21 184162.4628243181 31 0.0 0 LINE 5 2F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532763.565424586 20 183767.8992291204 30 0.0 11 532542.4660997646 21 184490.3856919131 31 0.0 0 LINE 5 2F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532543.1334552761 20 184254.2287175145 30 0.0 11 532030.3823403246 21 184165.1226977185 31 0.0 0 LINE 5 2F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532526.7823938887 20 184321.7732940453 30 0.0 11 532565.4542369875 21 184131.7364379803 31 0.0 0 LINE 5 2F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532455.8560125364 20 184306.2218749684 30 0.0 11 532469.199284479 21 184243.3123939978 31 0.0 0 LINE 5 2F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532500.404604757 20 184337.4098207074 30 0.0 11 532448.5924934926 21 184292.102419002 31 0.0 0 LINE 5 2F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532467.9222000074 20 184298.7677181402 30 0.0 11 532151.5594281791 21 184344.7377033163 31 0.0 0 LINE 5 2FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532546.3727587354 20 184062.6106464354 30 0.0 11 532126.1632264118 21 184073.4140238009 31 0.0 0 LINE 5 307 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532584.4903761105 20 183864.2182182287 30 0.0 11 532532.7635513458 21 183974.0899667647 31 0.0 0 LINE 5 308 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532631.8950520743 20 183998.5224476362 30 0.0 11 532632.3872072136 21 183877.743770919 31 0.0 0 LINE 5 309 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532634.6940095361 20 183884.0725369571 30 0.0 11 532582.3553185839 21 183864.6230556592 31 0.0 0 LINE 5 30A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532934.2473785581 20 184040.6907525797 30 0.0 11 532934.235328054 21 184040.6876830364 31 0.0 0 LINE 5 30B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532792.4137581561 20 184004.5624334069 30 0.0 11 532167.9345982127 21 183901.8182242516 31 0.0 0 LINE 5 310 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532368.5085479771 20 184092.6775787239 30 0.0 11 532506.9565822644 21 183612.623907776 31 0.0 0 LINE 5 311 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532594.1521268948 20 183661.7019549843 30 0.0 11 532478.1241977714 21 183964.5209857737 31 0.0 0 LINE 5 312 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532590.2102493453 20 183956.0377104505 30 0.0 11 532598.6767912577 21 183921.5368206355 31 0.0 0 LINE 5 317 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532306.0587504182 20 184266.992331815 30 0.0 11 532414.2191715132 21 184122.5293847503 31 0.0 0 LINE 5 318 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532477.551415465 20 184130.3624860479 30 0.0 11 532412.6306058845 21 184123.5738093414 31 0.0 0 LINE 5 319 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532661.721044324 20 184125.7436229359 30 0.0 11 532439.6824280089 21 184049.5153294456 31 0.0 0 LINE 5 31C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532847.7714891929 20 183350.8987513204 30 0.0 11 532995.8222172223 21 183426.7421009539 31 0.0 0 LINE 5 31D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532774.0262611857 20 183284.1426261447 30 0.0 11 532909.8188335092 21 183159.1966094306 31 0.0 0 LINE 5 31E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532709.4902750978 20 183812.8863756505 30 0.0 11 532835.4314276548 21 183979.9680373762 31 0.0 0 LINE 5 31F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532463.9437321764 20 184141.8423292799 30 0.0 11 532481.318514892 21 184025.9617418272 31 0.0 0 LINE 5 320 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533323.0645174747 20 183697.3915731477 30 0.0 11 533469.8168568623 21 183830.5378952181 31 0.0 0 LINE 5 322 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530605.199969855 20 185171.8313899503 30 0.0 11 532736.3514167985 21 185388.7767557458 31 0.0 0 LINE 5 323 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530632.5473901829 20 185377.7313809267 30 0.0 11 530347.847156352 21 185292.772304566 31 0.0 0 LINE 5 324 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530537.8475188889 20 185421.3935488612 30 0.0 11 530918.4513398055 21 185724.2180642567 31 0.0 0 LINE 5 325 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530524.4682282156 20 184838.4117535552 30 0.0 11 530539.0027126899 21 185369.0524173398 31 0.0 0 LINE 5 326 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530335.1690853607 20 184982.8667579243 30 0.0 11 530559.2802786548 21 185043.4543895813 31 0.0 0 LINE 5 327 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530707.0247008471 20 184994.505863614 30 0.0 11 530707.477024887 21 185313.5574728215 31 0.0 0 LINE 5 332 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531131.4314460383 20 185132.7716499767 30 0.0 11 531131.4314460383 21 185359.3560314326 31 0.0 0 LINE 5 333 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530501.6760625544 20 185036.5091148205 30 0.0 11 530743.4035747344 21 185005.6828851596 31 0.0 0 LINE 5 334 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530485.4823504737 20 185236.4996961124 30 0.0 11 530775.1816292018 21 185251.6757933341 31 0.0 0 LINE 5 335 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532544.9929155682 20 185376.4324141973 30 0.0 11 536042.6124124007 21 185481.9872221566 31 0.0 0 LINE 5 358 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532320.5649707108 20 184501.5680036159 30 0.0 11 532310.185466446 21 184245.5571047196 31 0.0 0 LINE 5 366 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532121.1286102474 20 185156.5429902478 30 0.0 11 532552.7822942476 21 185237.5298082478 31 0.0 0 LINE 5 367 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532107.1836522989 20 185396.4993852853 30 0.0 11 532132.2182172474 21 185032.5284892478 31 0.0 0 LINE 5 368 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532191.4177562475 20 185229.8919942478 30 0.0 11 532195.3011802475 21 185165.7003692478 31 0.0 0 LINE 5 36B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532227.5888392475 20 185421.3871792478 30 0.0 11 532353.3590012474 21 185033.9680772478 31 0.0 0 LINE 5 36C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532340.0762082474 20 185033.0383432478 30 0.0 11 532571.1852702475 21 185093.2411102478 31 0.0 0 LINE 5 36D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532292.1971382474 20 184848.6111342478 30 0.0 11 532351.5203522474 21 185047.0743252478 31 0.0 0 LINE 5 36E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532229.8727212474 20 184909.5836812478 30 0.0 11 532315.1596332476 21 184905.4048772478 31 0.0 0 LINE 5 36F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532325.0415939529 20 185475.0242132333 30 0.0 11 532348.3174009531 21 185387.9591352333 31 0.0 0 LINE 5 370 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532458.4917752475 20 185549.4005362478 30 0.0 11 532569.7094042475 21 185090.5118912478 31 0.0 0 LINE 5 371 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532152.3691472474 20 185079.7349762478 30 0.0 11 532567.5409532475 21 185166.1502402478 31 0.0 0 LINE 5 372 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532505.0021652475 20 184692.3458652478 30 0.0 11 532564.1192532476 21 185172.2285002478 31 0.0 0 LINE 5 373 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532493.2797917234 20 184439.2739090913 30 0.0 11 532535.4841562475 21 184977.0343742478 31 0.0 0 LINE 5 374 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532413.0449982474 20 184681.5489552478 30 0.0 11 532522.1683822475 21 184724.9265392478 31 0.0 0 LINE 5 375 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532420.3088972474 20 184743.2113052478 30 0.0 11 532517.3285312475 21 184691.7060482478 31 0.0 0 LINE 5 376 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532429.9143932474 20 184932.9769852478 30 0.0 11 532437.8461422474 21 184731.1247652478 31 0.0 0 LINE 5 377 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532009.6784914185 20 184830.2079244615 30 0.0 11 532529.2096642474 21 184878.8524782478 31 0.0 0 LINE 5 37C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532372.7184052476 20 184867.0858462478 30 0.0 11 532373.0152272474 21 184842.8027972478 31 0.0 0 LINE 5 37D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532504.0457382474 20 185004.5864872478 30 0.0 11 532549.2121822474 21 185000.8275632478 31 0.0 0 LINE 5 37E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532491.7523522475 20 185014.0837682478 30 0.0 11 532511.9032812475 21 185000.9275342478 31 0.0 0 LINE 5 37F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532485.9230932474 20 185077.9154972478 30 0.0 11 532494.5226922474 21 185006.5859152478 31 0.0 0 LINE 5 380 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532302.5529352474 20 184898.1469552478 30 0.0 11 532338.5096462474 21 184465.2908592478 31 0.0 0 LINE 5 381 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532317.2044082475 20 184488.8441172478 30 0.0 11 532511.6971542474 21 184540.6792792478 31 0.0 0 LINE 5 383 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532213.2094522475 20 184469.8995392478 30 0.0 11 532283.6140292475 21 184859.3980472478 31 0.0 0 LINE 5 385 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532308.5965642474 20 184714.1896122478 30 0.0 11 532401.7657552476 21 184708.5912152478 31 0.0 0 LINE 5 386 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532366.6747752475 20 184706.5517982478 30 0.0 11 532438.8355502475 21 184748.3298402478 31 0.0 0 LINE 5 387 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532364.2342372475 20 184719.4481072478 30 0.0 11 532433.9709632472 21 184679.9394162478 31 0.0 0 LINE 5 388 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532419.8636642474 20 184513.3471032478 30 0.0 11 532429.1970732474 21 184691.6260712478 31 0.0 0 LINE 5 38B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532265.0461522474 20 185108.3267922478 30 0.0 11 532280.4479262474 21 185063.9095062478 31 0.0 0 LINE 5 38C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532217.3154932475 20 185054.6021702478 30 0.0 11 532281.7011752476 21 185065.3390972478 31 0.0 0 LINE 5 38D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532186.1409172473 20 185093.1211442478 30 0.0 11 532191.5661672472 21 184988.9409652478 31 0.0 0 LINE 5 38E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532041.0195962473 20 185001.1274772478 30 0.0 11 532339.0538202476 21 184982.8427112478 31 0.0 0 LINE 5 38F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532407.4136222474 20 185053.8123962478 30 0.0 11 532420.6469452474 21 184986.2517352478 31 0.0 0 LINE 5 390 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532389.2250172473 20 184981.0932122478 30 0.0 11 532448.2431642476 21 184992.4699552478 31 0.0 0 LINE 5 391 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532393.1908912475 20 184988.7310262478 30 0.0 11 532405.9130212474 21 184918.5411172478 31 0.0 0 LINE 5 392 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532402.7056922474 20 184920.4205792478 30 0.0 11 532458.0795222474 21 184929.6579352478 31 0.0 0 LINE 5 393 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532441.8532422473 20 184998.8581272478 30 0.0 11 532456.5212062474 21 184922.7599102478 31 0.0 0 LINE 5 396 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532481.8907751978 20 185659.2708376926 30 0.0 11 533213.4750461979 21 185960.1946986926 31 0.0 0 LINE 5 397 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532608.229846198 20 185714.4250496926 30 0.0 11 532641.5976081978 21 185570.3962776926 31 0.0 0 LINE 5 398 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532494.571678198 20 185595.3291406926 30 0.0 11 532951.4964751979 21 185784.2850526926 31 0.0 0 LINE 5 399 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532625.5362291979 20 185598.8181416926 30 0.0 11 532683.5732141979 21 185540.9147166926 31 0.0 0 LINE 5 39A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532574.6806921979 20 185537.4257156926 30 0.0 11 532637.5657731979 21 185598.7681566926 31 0.0 0 LINE 5 39C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532379.7822005875 20 185516.783209897 30 0.0 11 532897.7881471978 21 185508.2540656925 31 0.0 0 LINE 5 3A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.1287281979 20 185133.8312426926 30 0.0 11 532743.226231198 21 185136.4304986926 31 0.0 0 LINE 5 3A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532738.9965151979 20 185055.0737866926 30 0.0 11 532759.8070491979 21 185810.3475926926 31 0.0 0 LINE 5 3A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532822.0242801978 20 185582.5328036926 30 0.0 11 533308.048428696 21 185701.9470633644 31 0.0 0 LINE 5 3A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532819.806359198 20 185651.9929206926 30 0.0 11 532833.1138871978 21 185458.5183026926 31 0.0 0 LINE 5 3A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532892.3134261978 20 185655.8818076926 30 0.0 11 532896.1968501978 21 185591.6901826926 31 0.0 0 LINE 5 3A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532841.0703711978 20 185674.0865966926 30 0.0 11 532903.0732311979 21 185644.2051496926 31 0.0 0 LINE 5 3A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532882.6667051979 20 185645.4847836926 30 0.0 11 533018.9643670911 21 185679.8975924009 31 0.0 0 LINE 5 3A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532928.4845091979 20 185847.3769926925 30 0.0 11 533171.7912461943 21 185088.6905515849 31 0.0 0 LINE 5 3A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533040.9718781979 20 185459.0281566926 30 0.0 11 533342.0861666041 21 185539.2294065369 31 0.0 0 LINE 5 3AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533040.8696871645 20 185902.6867872737 30 0.0 11 533064.1454941646 21 185815.6217092737 31 0.0 0 LINE 5 3AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532853.2648171979 20 185505.7247896926 30 0.0 11 533314.949234796 21 185601.8213459973 31 0.0 0 LINE 5 3B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532896.5843681978 20 185272.3815836926 30 0.0 11 533323.6153840747 21 185304.8422916926 31 0.0 0 LINE 5 3B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532501.8603121979 20 185272.5915236926 30 0.0 11 533064.3466261978 21 185283.8483006926 31 0.0 0 LINE 5 3B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533003.4486051978 20 185324.1367686926 30 0.0 11 533056.9763947938 21 184798.3148205676 31 0.0 0 LINE 5 3BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532730.9905601978 20 185073.2185936926 30 0.0 11 532910.2405847092 21 184975.7707765721 31 0.0 0 LINE 5 3BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532887.8337612262 20 184954.2005379262 30 0.0 11 532984.509699198 21 185285.3878606926 31 0.0 0 LINE 5 3BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533009.4922341978 20 185140.1794256926 30 0.0 11 533223.8406176101 21 185128.4247817856 31 0.0 0 LINE 5 3C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533120.7593341979 20 184991.9777295595 30 0.0 11 533164.6698493871 21 185152.1929908819 31 0.0 0 LINE 5 3C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532535.0805407667 20 185099.0554407228 30 0.0 11 532800.0759271978 21 185049.7952976926 31 0.0 0 LINE 5 3C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532965.9418221979 20 185534.3166056926 30 0.0 11 532981.3435961978 21 185489.8993196926 31 0.0 0 LINE 5 3C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532918.2111631979 20 185480.5919836926 30 0.0 11 532982.596845198 21 185491.3289106925 31 0.0 0 LINE 5 3C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532887.0365871978 20 185519.1109576926 30 0.0 11 532892.4618371978 21 185414.9307786926 31 0.0 0 LINE 5 3CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532632.1075431978 20 185205.9006136926 30 0.0 11 532744.8092831978 21 185207.6001266926 31 0.0 0 LINE 5 3CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532964.0619481979 20 185729.5307256926 30 0.0 11 533287.3999608604 21 185848.0166997513 31 0.0 0 LINE 5 3CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533160.4851943644 20 185038.2038243795 30 0.0 11 533312.3771077996 21 184720.5496568575 31 0.0 0 LINE 5 3D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532525.9687370664 20 184938.1950755283 30 0.0 11 533310.1590899808 21 185042.7807927709 31 0.0 0 LINE 5 3D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532783.2026042486 20 184722.3529153568 30 0.0 11 533016.3547312032 21 184679.6358716281 31 0.0 0 LINE 5 3D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.4575456594 20 184793.6019525844 30 0.0 11 532842.931078161 21 184708.7398765826 31 0.0 0 LINE 5 3DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532637.5467937776 20 184576.4133326699 30 0.0 11 532697.7689800461 21 184475.6025395458 31 0.0 0 LINE 5 3DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532699.5784686391 20 184579.0743381345 30 0.0 11 532664.2017968141 21 184475.0835117567 31 0.0 0 LINE 5 3E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532790.6590954802 20 184784.0174906387 30 0.0 11 532807.6186704129 21 184536.4242881813 31 0.0 0 LINE 5 3E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532688.1167109437 20 184815.5033675087 30 0.0 11 532809.5492248078 21 184814.234469069 31 0.0 0 LINE 5 3E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532790.4765161498 20 184914.5351786511 30 0.0 11 532680.4657737823 21 184864.6817180896 31 0.0 0 LINE 5 3E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.2588451061 20 184869.4146964122 30 0.0 11 532689.3739594284 21 184813.7308861308 31 0.0 0 LINE 5 3E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532702.8925823753 20 185206.9803013947 30 0.0 11 532702.8948103981 21 185206.968067317 31 0.0 0 LINE 5 3E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532729.1162602199 20 185062.9860305268 30 0.0 11 532803.6929663337 21 184653.4851785078 31 0.0 0 LINE 5 3EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532833.7558926337 20 184720.028022434 30 0.0 11 532491.6707096186 21 184640.2317074956 31 0.0 0 LINE 5 3EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532499.9754730116 20 184739.9450397345 30 0.0 11 532792.482947854 21 184732.5461716932 31 0.0 0 LINE 5 3ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532769.2121150372 20 184858.9438041617 30 0.0 11 532734.3196016032 21 184852.2725047208 31 0.0 0 LINE 5 3EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532653.1157034118 20 184684.7299837778 30 0.0 11 532662.4446227496 21 184591.8601207191 31 0.0 0 LINE 5 3EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532654.8360919118 20 184626.1769731031 30 0.0 11 532707.5855661703 21 184561.6008536206 31 0.0 0 LINE 5 3F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532667.1782684115 20 184630.6425851331 30 0.0 11 532639.2944614704 21 184555.4984507766 31 0.0 0 LINE 5 3F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532472.5841021193 20 184542.862362741 30 0.0 11 532650.0704104144 21 184562.0746848949 31 0.0 0 LINE 5 3F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532893.7177966846 20 184994.6354611215 30 0.0 11 532923.1880844783 21 184697.4987358915 31 0.0 0 LINE 5 3FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531861.8278255367 20 185191.7735766143 30 0.0 11 531538.5384386285 21 185607.8478836246 31 0.0 0 LINE 5 3FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531733.7040754842 20 185347.6380927605 30 0.0 11 532464.1482035561 21 185651.3189967688 31 0.0 0 LINE 5 3FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531862.0971573802 20 185397.8253868076 30 0.0 11 531783.9926877962 21 185523.3538160008 31 0.0 0 LINE 5 3FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531697.5197138976 20 185401.8602090297 30 0.0 11 532154.4445108975 21 185590.8161210297 31 0.0 0 LINE 5 400 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531792.6965981643 20 185491.8893567981 30 0.0 11 531792.885563927 21 185573.87144354 31 0.0 0 LINE 5 401 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531713.3339456926 20 185499.4315717521 30 0.0 11 531801.1772682144 21 185500.4211012181 31 0.0 0 LINE 5 402 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.3606550528 20 185490.9574299569 30 0.0 11 531610.7000381212 21 185649.8145655846 31 0.0 0 LINE 5 403 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531620.0352627024 20 185437.4863894554 30 0.0 11 531921.4650168662 21 185748.2907083182 31 0.0 0 LINE 5 404 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531650.9979007347 20 185688.8051328634 30 0.0 11 531795.0736114228 21 185570.1374104197 31 0.0 0 LINE 5 405 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531609.7161111208 20 185644.4268986138 30 0.0 11 531651.8451968421 21 185688.8314120956 31 0.0 0 LINE 5 406 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531419.6038351391 20 185873.1395474812 30 0.0 11 531638.8567267734 21 185672.4553785438 31 0.0 0 LINE 5 407 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531467.5316540078 20 185824.3072660336 30 0.0 11 531549.4316502019 21 185902.346947863 31 0.0 0 LINE 5 408 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531488.9758274058 20 185956.9537109508 30 0.0 11 532119.1862890298 21 185356.9691234335 31 0.0 0 LINE 5 409 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531920.2925450763 20 185642.1958461826 30 0.0 11 532283.0697733463 21 185889.7366514033 31 0.0 0 LINE 5 40A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531967.7814881132 20 185591.4570314894 30 0.0 11 531840.5527883868 21 185737.8208797502 31 0.0 0 LINE 5 40B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532021.8574928065 20 185639.9150950438 30 0.0 11 531979.268683928 21 185688.1005602838 31 0.0 0 LINE 5 40C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531998.4393065221 20 185590.8350219038 30 0.0 11 532021.2274724078 21 185655.7808071295 31 0.0 0 LINE 5 40D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532007.6850459294 20 185640.4619804239 30 0.0 11 532354.1763415755 21 185846.7163859356 31 0.0 0 LINE 5 40E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532182.715114118 20 185529.8988290208 30 0.0 11 531998.1198935781 21 185892.9915152565 31 0.0 0 LINE 5 40F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.0600547572 20 185884.2681765558 30 0.0 11 532194.1878251482 21 186004.8795937868 31 0.0 0 LINE 5 410 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531823.9061445957 20 185981.011623581 30 0.0 11 532006.0750995708 21 185882.4146979472 31 0.0 0 LINE 5 411 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531822.8497064442 20 185893.8286643487 30 0.0 11 531880.2747016837 21 185957.0243104261 31 0.0 0 LINE 5 412 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532356.2144154167 20 185600.3187829731 30 0.0 11 532311.1985787343 21 185678.3935256651 31 0.0 0 LINE 5 413 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532436.5909745613 20 185602.3600801 30 0.0 11 532191.2154048476 21 186005.769275952 31 0.0 0 LINE 5 414 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531888.1595850236 20 185718.6348090544 30 0.0 11 532243.1029985761 21 185950.691697608 31 0.0 0 LINE 5 415 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531983.707795175 20 186179.1651187459 30 0.0 11 532196.6318225811 21 185988.747421823 31 0.0 0 LINE 5 416 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531651.967628694 20 186274.3789995667 30 0.0 11 531834.7205437863 21 186117.8592350517 31 0.0 0 LINE 5 417 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531474.7328130902 20 185635.481035244 30 0.0 11 531880.8795836971 21 186024.7911548032 31 0.0 0 LINE 5 419 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532084.0423358651 20 186020.2200672802 30 0.0 11 532125.4763841526 21 186066.8963861565 31 0.0 0 LINE 5 41A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532082.0474267376 20 186004.8140287462 30 0.0 11 532087.0205745952 21 186028.360031231 31 0.0 0 LINE 5 41B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532123.0045456797 20 185955.5090158614 30 0.0 11 532078.7129439776 21 186012.0785870981 31 0.0 0 LINE 5 41C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531418.7788685433 20 186104.3451573058 30 0.0 11 531495.3612063181 21 186318.6540757437 31 0.0 0 LINE 5 41D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531496.1237532815 20 185938.45407603 30 0.0 11 531405.175342562 21 186133.5223115784 31 0.0 0 LINE 5 41F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531988.1202134396 20 185777.976802319 30 0.0 11 531967.6519314506 21 185820.2988931271 31 0.0 0 LINE 5 420 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531916.3854307389 20 185782.2978865 30 0.0 11 531969.5488407774 21 185820.1720133031 31 0.0 0 LINE 5 421 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531921.5218807102 20 185733.0111496584 30 0.0 11 531851.7810069742 21 185810.5943537981 31 0.0 0 LINE 5 422 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531753.8130619647 20 185695.637566851 30 0.0 11 531951.8835598482 21 185919.0806450864 31 0.0 0 LINE 5 423 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532050.4021916367 20 185917.1215869044 30 0.0 11 532012.0528583068 21 185974.2958152379 31 0.0 0 LINE 5 424 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531986.1651783409 20 185955.7546193549 30 0.0 11 532035.9806907252 21 185989.3847647976 31 0.0 0 LINE 5 425 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531994.3672256759 20 185953.1487070773 30 0.0 11 531953.7989935165 21 186011.8231858276 31 0.0 0 LINE 5 426 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531952.8559031887 20 186008.2273663998 30 0.0 11 531998.5804950235 21 186040.7980817171 31 0.0 0 LINE 5 427 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532035.9690354825 20 185980.3492953121 30 0.0 11 531992.6053163253 21 186044.5807179909 31 0.0 0 LINE 5 428 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532589.7485624646 20 185685.3582884609 30 0.0 11 532589.9375282275 21 185767.3403752028 31 0.0 0 LINE 5 429 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532510.3859099931 20 185692.900503415 30 0.0 11 532598.229232515 21 185693.8900328809 31 0.0 0 LINE 5 42A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532526.4656307082 20 185685.9832563354 30 0.0 11 532406.8050137765 21 185844.8403919632 31 0.0 0 LINE 5 42B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532357.8334418678 20 185569.8587237367 30 0.0 11 532718.5169811667 21 185941.7596399811 31 0.0 0 LINE 5 42C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532448.049865035 20 185882.2740645263 30 0.0 11 532592.1255757233 21 185763.6063420826 31 0.0 0 LINE 5 42D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.7680754211 20 185837.8958302767 30 0.0 11 532448.8971611424 21 185882.3003437585 31 0.0 0 LINE 5 42E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532216.6557994395 20 186066.608479144 30 0.0 11 532435.9086910739 21 185865.9243102067 31 0.0 0 LINE 5 42F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532360.5330683786 20 186075.9173659413 30 0.0 11 532834.2031285817 21 185630.4462966165 31 0.0 0 LINE 5 430 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532717.3445093768 20 185835.6647778455 30 0.0 11 532936.5865712611 21 185985.2644558515 31 0.0 0 LINE 5 431 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532764.8334524136 20 185784.9259631524 30 0.0 11 532637.6047526871 21 185931.289811413 31 0.0 0 LINE 5 432 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532818.9094571071 20 185833.3840267067 30 0.0 11 532776.3206482284 21 185881.5694919468 31 0.0 0 LINE 5 433 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532795.4912708226 20 185784.3039535667 30 0.0 11 532818.2794367084 21 185849.2497387923 31 0.0 0 LINE 5 434 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532804.7370102297 20 185833.9309120868 30 0.0 11 533151.2283058758 21 186040.1853175985 31 0.0 0 LINE 5 435 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532929.8009410545 20 185821.4028240506 30 0.0 11 532795.1718578784 21 186086.4604469193 31 0.0 0 LINE 5 436 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532785.1120190575 20 186077.7371082186 30 0.0 11 532991.2397894489 21 186198.3485254497 31 0.0 0 LINE 5 438 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532487.8955622168 20 185923.2211543541 30 0.0 11 532719.6710319343 21 186201.2963692519 31 0.0 0 LINE 5 439 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.2115493238 20 185912.1037407173 30 0.0 11 533069.5807117685 21 186166.970324897 31 0.0 0 LINE 5 43A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532596.3237212511 20 186341.3319926437 30 0.0 11 532804.5149513248 21 186072.8212737525 31 0.0 0 LINE 5 43B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532563.3363404315 20 186239.6670789878 30 0.0 11 532671.2243390242 21 186286.0320171303 31 0.0 0 LINE 5 43C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532612.0301757858 20 186201.1453963313 30 0.0 11 532644.3347693412 21 186306.1311768702 31 0.0 0 LINE 5 43D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532271.7847773906 20 185828.9499669069 30 0.0 11 532505.4397367133 21 186045.7682751822 31 0.0 0 LINE 5 43E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532456.1709398957 20 185958.2385074901 30 0.0 11 532414.07966705 21 186283.737681027 31 0.0 0 LINE 5 43F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.7909252194 20 186170.6980676144 30 0.0 11 532571.9985347014 21 186193.8794666497 31 0.0 0 LINE 5 440 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532548.1691416875 20 186189.2161541062 30 0.0 11 532628.7607689065 21 186210.607083589 31 0.0 0 LINE 5 441 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532555.5499794265 20 186178.3628483507 30 0.0 11 532577.0134800563 21 186255.5863276716 31 0.0 0 LINE 5 442 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532486.5436966105 20 186326.2911970296 30 0.0 11 532581.8881197563 21 186243.9413365331 31 0.0 0 LINE 5 443 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532172.7351168023 20 185975.263057285 30 0.0 11 532257.3461442857 21 186098.2095402245 31 0.0 0 LINE 5 444 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532785.17217774 20 185971.4457339819 30 0.0 11 532764.7038957511 21 186013.76782479 31 0.0 0 LINE 5 445 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532713.4373950393 20 185975.7668181629 30 0.0 11 532766.6008050778 21 186013.640944966 31 0.0 0 LINE 5 446 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532718.5738450106 20 185926.4800813213 30 0.0 11 532648.8329712746 21 186004.063285461 31 0.0 0 LINE 5 447 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532550.865026265 20 185889.1064985139 30 0.0 11 532766.6531342508 21 186130.2671868515 31 0.0 0 LINE 5 448 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532847.4541559371 20 186110.5905185672 30 0.0 11 532809.1048226073 21 186167.7647469007 31 0.0 0 LINE 5 449 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532783.2171426415 20 186149.2235510178 30 0.0 11 532833.0326550259 21 186182.8536964605 31 0.0 0 LINE 5 44A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532316.8864140805 20 185968.1543527131 30 0.0 11 532397.8707606938 21 186046.5514581896 31 0.0 0 LINE 5 44B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532611.7161158065 20 186297.5090828903 30 0.0 11 532545.1449756013 21 186591.4088218426 31 0.0 0 LINE 5 44C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532547.3155668865 20 186321.6247646187 30 0.0 11 532495.053707063 21 186542.8445710875 31 0.0 0 LINE 5 44D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532403.9294344441 20 186201.8155025754 30 0.0 11 532302.4455707475 21 186337.9548541522 31 0.0 0 LINE 5 44E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532279.8671234338 20 186136.1577846746 30 0.0 11 533406.1995619062 21 186996.2805453936 31 0.0 0 LINE 5 44F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532406.9961318524 20 186319.8807114539 30 0.0 11 532220.4666046975 21 186717.4866760719 31 0.0 0 LINE 5 450 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532464.6578491668 20 186358.671862295 30 0.0 11 532299.8801138759 21 186256.40839832 31 0.0 0 LINE 5 451 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532425.4420865872 20 186419.7825992595 30 0.0 11 532371.082371042 21 186385.4217635892 31 0.0 0 LINE 5 452 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532470.160245401 20 186388.8382734374 30 0.0 11 532409.6789007655 21 186421.6904038722 31 0.0 0 LINE 5 453 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532422.6424219159 20 186405.8786713312 30 0.0 11 532274.2743179815 21 186780.8240053286 31 0.0 0 LINE 5 454 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532644.1853054258 20 186588.1231077161 30 0.0 11 532171.8185395161 21 186436.7013597309 31 0.0 0 LINE 5 455 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532178.8262472758 20 186425.3793004152 30 0.0 11 532092.6246762097 21 186648.1012365569 31 0.0 0 LINE 5 456 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532057.1464107401 20 186278.7511375533 30 0.0 11 532183.5284855803 21 186442.8683306205 31 0.0 0 LINE 5 457 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532143.045524667 20 186263.8070193578 30 0.0 11 532089.8147203099 21 186330.5737867564 31 0.0 0 LINE 5 459 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532428.4229887346 20 186782.4538492132 30 0.0 11 532091.2724283363 21 186645.3087032108 31 0.0 0 LINE 5 45A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532326.4115569843 20 186300.3469340414 30 0.0 11 532153.9187586503 21 186687.7504199219 31 0.0 0 LINE 5 45B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531805.9814634882 20 186360.1205610736 30 0.0 11 532160.8507210284 21 186688.5257734576 31 0.0 0 LINE 5 45C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531638.584156153 20 186248.3972793169 30 0.0 11 532019.1879770698 21 186551.2217947124 31 0.0 0 LINE 5 45D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531850.9576992835 20 186279.1895284476 30 0.0 11 531822.388527218 21 186393.0900558247 31 0.0 0 LINE 5 45E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531896.7507059305 20 186321.1181604121 30 0.0 11 531798.2590085679 21 186369.7492865638 31 0.0 0 LINE 5 45F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532045.128842458 20 186439.807702748 30 0.0 11 531876.6943226217 21 186328.2862075614 31 0.0 0 LINE 5 460 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532093.9829120121 20 186228.3962886964 30 0.0 11 531943.1818398332 21 186488.7548350109 31 0.0 0 LINE 5 461 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532011.4998620817 20 186166.3447629878 30 0.0 11 531995.1789584217 21 186015.2308868018 31 0.0 0 LINE 5 462 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532367.7592458358 20 186017.384856327 30 0.0 11 532367.7521822822 21 186017.3950907273 31 0.0 0 LINE 5 463 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532159.4363386243 20 186124.1371738739 30 0.0 11 532023.0113161725 21 186341.976254682 31 0.0 0 LINE 5 464 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532025.08345726 20 186354.8888840192 30 0.0 11 532005.2047513147 21 186340.9392739177 31 0.0 0 LINE 5 465 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532059.9179272102 20 186541.8109382867 30 0.0 11 532030.473360213 21 186576.266048903 31 0.0 0 LINE 5 466 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532074.8087792434 20 186537.3850811423 30 0.0 11 532052.356979825 21 186546.0489795433 31 0.0 0 LINE 5 467 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532130.0135486268 20 186569.9565920827 30 0.0 11 532067.1054834822 21 186535.2515821992 31 0.0 0 LINE 5 468 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532091.2921244135 20 186316.102313323 30 0.0 11 531792.7632140843 21 186130.9801536181 31 0.0 0 LINE 5 469 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531936.6804172386 20 186133.8679621811 30 0.0 11 532070.9155718749 21 186278.0897346377 31 0.0 0 LINE 5 46A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532468.8458028386 20 186177.5755427393 30 0.0 11 531769.5162369404 21 186138.5166020882 31 0.0 0 LINE 5 46B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531938.4823451721 20 186213.5060128864 30 0.0 11 531879.4933379066 21 186285.8395267122 31 0.0 0 LINE 5 46C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531898.3447794365 20 186256.1720487052 30 0.0 11 531890.077737924 21 186339.1433586055 31 0.0 0 LINE 5 46D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531910.2360944391 20 186261.7279139901 30 0.0 11 531837.4229176238 21 186295.2299870572 31 0.0 0 LINE 5 46E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531710.4802981255 20 186186.4293161462 30 0.0 11 531849.6961797504 21 186298.185484916 31 0.0 0 LINE 5 46F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532283.7673474868 20 186408.4906846435 30 0.0 11 532238.7230775654 21 186395.0324646574 31 0.0 0 LINE 5 470 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532268.0635396029 20 186338.3626500527 30 0.0 11 532239.1507935487 21 186396.88487458 31 0.0 0 LINE 5 471 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532327.6932205972 20 186164.0523312674 30 0.0 11 532138.6908716636 21 186395.2164362678 31 0.0 0 LINE 5 472 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532156.333518464 20 186492.1622754376 30 0.0 11 532006.4397393707 21 186419.1755808819 31 0.0 0 LINE 5 473 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532443.2785890483 20 186521.0440070698 30 0.0 11 532392.4614716871 21 186789.2089363239 31 0.0 0 LINE 5 474 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531690.8699317568 20 185858.9173803943 30 0.0 11 531813.4096672386 21 185746.4218472305 31 0.0 0 LINE 5 475 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531602.6576685688 20 185904.8884095925 30 0.0 11 531532.6487409198 21 185734.1550506949 31 0.0 0 LINE 5 476 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532274.1029641282 20 186355.1102229073 30 0.0 11 532171.4693846109 21 186298.5722535568 31 0.0 0 LINE 5 477 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532180.8622533723 20 185533.5433447531 30 0.0 11 532356.6872845859 21 185442.1663750327 31 0.0 0 LINE 5 478 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534574.6571852977 20 184195.4021252921 30 0.0 11 535121.1408465514 21 184069.916780534 31 0.0 0 LINE 5 479 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534591.6805218133 20 184183.5721895806 30 0.0 11 534563.5622932388 21 184974.1290065872 31 0.0 0 LINE 5 47A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534583.8361464561 20 184321.2021780923 30 0.0 11 534730.4884537673 21 184302.4726435274 31 0.0 0 LINE 5 47C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534698.2576499472 20 184297.2817347705 30 0.0 11 534772.7128564283 21 184331.596753093 31 0.0 0 LINE 5 47D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534738.1669447289 20 184228.2704037896 30 0.0 11 534702.4823148565 21 184308.5451549328 31 0.0 0 LINE 5 47E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534723.3715470947 20 184240.2209736357 30 0.0 11 534917.6315636337 21 184197.5911864141 31 0.0 0 LINE 5 47F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534720.7058270503 20 184117.6496135786 30 0.0 11 534877.7361941458 21 184521.135282629 31 0.0 0 LINE 5 480 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.2968661421 20 184250.4664032003 30 0.0 11 534768.4068052764 21 184332.030894389 31 0.0 0 LINE 5 481 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534913.1431511226 20 184194.4528395783 30 0.0 11 534935.9678830071 21 184251.2476658892 31 0.0 0 LINE 5 482 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535200.2533381722 20 184116.8648654899 30 0.0 11 534926.4889642517 21 184232.6190607658 31 0.0 0 LINE 5 483 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535135.8969533211 20 184140.101114365 30 0.0 11 535172.7375945441 21 184247.0617074395 31 0.0 0 LINE 5 484 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535247.5614010104 20 184214.8405486959 30 0.0 11 534562.2605079586 21 184461.1649807091 31 0.0 0 LINE 5 485 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534781.7684923542 20 184475.8838221603 30 0.0 11 534855.7334321526 21 184908.796001801 31 0.0 0 LINE 5 486 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534715.8615647035 20 184497.9270504825 30 0.0 11 534901.9152180392 21 184443.2136500017 31 0.0 0 LINE 5 487 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534737.396022412 20 184567.2715912787 30 0.0 11 534798.940808514 21 184548.6199155959 31 0.0 0 LINE 5 488 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534702.5279512712 20 184525.5405160086 30 0.0 11 534752.0826991785 21 184573.3064294077 31 0.0 0 LINE 5 489 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534743.7956458011 20 184554.6144922988 30 0.0 11 534787.0077403957 21 184955.5257201689 31 0.0 0 LINE 5 48A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534570.3822305559 20 184667.6964211436 30 0.0 11 534977.3661527182 21 184651.0897554535 31 0.0 0 LINE 5 48B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534973.6249792506 20 184638.3108424999 30 0.0 11 534997.4323029246 21 184875.9428753415 31 0.0 0 LINE 5 48C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535129.9446164009 20 184529.3614422962 30 0.0 11 534964.4371350048 21 184653.9172751708 31 0.0 0 LINE 5 48D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535051.1223213111 20 184492.0917463117 30 0.0 11 535084.6606727746 21 184570.6188037027 31 0.0 0 LINE 5 48E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534553.9285474718 20 184777.7111798236 30 0.0 11 534643.6579189425 21 184769.3010137052 31 0.0 0 LINE 5 48F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534530.5281655633 20 184928.6853843727 30 0.0 11 534999.4790852679 21 184873.6110308273 31 0.0 0 LINE 5 490 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534864.6453430343 20 184478.5048502061 30 0.0 11 534927.7956627994 21 184897.846314246 31 0.0 0 LINE 5 491 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535350.3893007875 20 184674.6506536572 30 0.0 11 534920.9074000498 21 184896.7485383992 31 0.0 0 LINE 5 492 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535583.6379881881 20 184575.7674960427 30 0.0 11 535094.0071012423 21 184802.1060054018 31 0.0 0 LINE 5 493 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535328.5779771762 20 184584.6675441836 30 0.0 11 535325.7982992511 21 184702.0634602962 31 0.0 0 LINE 5 494 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535273.2764353342 20 184612.8942887018 30 0.0 11 535355.2701688879 21 184685.9875752475 31 0.0 0 LINE 5 495 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535098.6584225843 20 184687.8064271212 30 0.0 11 535290.7012472688 21 184625.1423636691 31 0.0 0 LINE 5 496 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535098.5090148775 20 184438.0892804688 30 0.0 11 535183.8986896964 21 184762.1240560096 31 0.0 0 LINE 5 497 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535006.8823547946 20 184457.0934690072 30 0.0 11 535127.0631374186 21 184439.6565824029 31 0.0 0 LINE 5 498 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535092.7796099318 20 184343.4867310913 30 0.0 11 534991.7531499059 21 184409.6787649087 31 0.0 0 LINE 5 499 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534995.7606139729 20 184404.26444609 30 0.0 11 535008.3974384137 21 184458.6513154741 31 0.0 0 LINE 5 49A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534961.226757078 20 184068.0072542187 30 0.0 11 535146.0188931681 21 184599.3917053508 31 0.0 0 LINE 5 49B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535140.5844114282 20 184611.286921755 30 0.0 11 535163.459076143 21 184603.1319057388 31 0.0 0 LINE 5 49C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535057.2515549811 20 184782.193123236 30 0.0 11 535076.4625545096 21 184823.2427842622 31 0.0 0 LINE 5 49D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535044.0759987184 20 184773.9632749442 30 0.0 11 535063.411640211 21 184788.2908497806 31 0.0 0 LINE 5 49E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534982.1929300688 20 184790.6652419575 30 0.0 11 535052.0692800618 21 184773.9572174507 31 0.0 0 LINE 5 49F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535087.0886008305 20 184556.2761598885 30 0.0 11 535505.4896536701 21 184439.6663665903 31 0.0 0 LINE 5 4A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535227.7655735143 20 184213.6345013193 30 0.0 11 535495.623878412 21 184458.2494913671 31 0.0 0 LINE 5 4A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535457.6518015389 20 184323.7658987257 30 0.0 11 535116.8482574903 21 184525.0588110716 31 0.0 0 LINE 5 4A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535074.8677798265 20 184403.5864576378 30 0.0 11 535108.5224187205 21 184392.2128473538 31 0.0 0 LINE 5 4A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535261.6946601973 20 184498.0562876151 30 0.0 11 535299.3017138008 21 184583.481984685 31 0.0 0 LINE 5 4A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535289.0272950536 20 184549.86692231 30 0.0 11 535274.9106969223 21 184632.0454103658 31 0.0 0 LINE 5 4A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535276.0861163686 20 184552.0571062738 30 0.0 11 535337.3547991832 21 184603.7320143421 31 0.0 0 LINE 5 4A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535404.9953774325 20 184001.071612279 30 0.0 11 535103.3700778348 21 184075.7331806402 31 0.0 0 LINE 5 4A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535153.1660462351 20 184036.1810629035 30 0.0 11 535273.7238639583 21 184270.2849582326 31 0.0 0 LINE 5 4AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534876.9652630151 20 184594.0981846576 30 0.0 11 534923.966796239 21 184593.1154270327 31 0.0 0 LINE 5 4AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534910.7692790155 20 184530.6802114966 30 0.0 11 534923.0614345329 21 184594.787157772 31 0.0 0 LINE 5 4AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534863.8211214823 20 184514.823476302 30 0.0 11 534963.400889941 21 184483.7298636502 31 0.0 0 LINE 5 4AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534899.6889578032 20 184346.7861861114 30 0.0 11 535020.3411757364 21 184619.9194386656 31 0.0 0 LINE 5 4AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534977.5298769468 20 184708.6716297057 30 0.0 11 535045.4811634307 21 184697.6178331832 31 0.0 0 LINE 5 4AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535039.4059462963 20 184666.3601996268 30 0.0 11 535049.2339964726 21 184725.6559109923 31 0.0 0 LINE 5 4B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535033.6208638784 20 184672.7317913196 30 0.0 11 535103.8602096413 21 184660.2854977361 31 0.0 0 LINE 5 4B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535100.983845627 20 184657.9305313283 30 0.0 11 535111.5524690118 21 184713.0657650223 31 0.0 0 LINE 5 4B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535041.0242654582 20 184721.8822971619 30 0.0 11 535117.4799406871 21 184709.2088002577 31 0.0 0 LINE 5 4B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535069.0006836904 20 184166.9860368055 30 0.0 11 535106.5476183001 21 184273.2630251185 31 0.0 0 LINE 5 4B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534693.2491391094 20 184660.1320577132 30 0.0 11 534706.6944115045 21 184924.3913516068 31 0.0 0 LINE 5 4B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534453.6923026645 20 184480.7570328502 30 0.0 11 534405.8297581176 21 185826.4342959219 31 0.0 0 LINE 5 4B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534427.7785696117 20 185126.4152517712 30 0.0 11 534574.430876923 21 185107.6857172062 31 0.0 0 LINE 5 4B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534499.9886731898 20 184978.4702767471 30 0.0 11 534481.4814355449 21 185472.5776425573 31 0.0 0 LINE 5 4B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534542.2000731028 20 185102.4948084494 30 0.0 11 534616.655279584 21 185136.8098267719 31 0.0 0 LINE 5 4B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534582.1093678846 20 185033.4834774686 30 0.0 11 534546.4247380123 21 185113.7582286117 31 0.0 0 LINE 5 4BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534569.1238130012 20 185045.2214964583 30 0.0 11 534763.3838295403 21 185002.5917092368 31 0.0 0 LINE 5 4BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534533.7798853447 20 184843.5471823721 30 0.0 11 534721.6786173013 21 185326.3483563077 31 0.0 0 LINE 5 4BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534780.2392892977 20 185055.6794768792 30 0.0 11 534612.3492284322 21 185137.243968068 31 0.0 0 LINE 5 4BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534757.0855742783 20 184999.6659132573 30 0.0 11 534779.9103061629 21 185056.460739568 31 0.0 0 LINE 5 4BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535044.1957613281 20 184922.0779391688 30 0.0 11 534770.4313874075 21 185037.8321344448 31 0.0 0 LINE 5 4BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534979.8393764768 20 184945.3141880438 30 0.0 11 535016.6800176997 21 185052.2747811184 31 0.0 0 LINE 5 4C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535091.5038241661 20 185020.0536223748 30 0.0 11 534390.4684959374 21 185301.8710613853 31 0.0 0 LINE 5 4C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534625.7109155097 20 185281.0968958392 30 0.0 11 534699.6758553083 21 185714.0090754798 31 0.0 0 LINE 5 4C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534559.803987859 20 185303.1401241614 30 0.0 11 534745.8576411947 21 185248.4267236806 31 0.0 0 LINE 5 4C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534581.3384455677 20 185372.4846649576 30 0.0 11 534642.8832316696 21 185353.8329892748 31 0.0 0 LINE 5 4C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534546.4703744269 20 185330.7535896875 30 0.0 11 534596.0251223342 21 185378.5195030866 31 0.0 0 LINE 5 4C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534587.7380689568 20 185359.8275659777 30 0.0 11 534630.9501635514 21 185760.7387938477 31 0.0 0 LINE 5 4C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534157.7326287101 20 185538.9153082807 30 0.0 11 534848.8426457485 21 185522.3086425906 31 0.0 0 LINE 5 4C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534817.5674024061 20 185443.5239161787 30 0.0 11 534840.6786983336 21 185674.2085705321 31 0.0 0 LINE 5 4C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534973.8870395568 20 185334.5745159751 30 0.0 11 534808.3795581604 21 185459.1303488497 31 0.0 0 LINE 5 4C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534895.0647444666 20 185297.3048199906 30 0.0 11 534928.6030959303 21 185375.8318773816 31 0.0 0 LINE 5 4CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534406.089309661 20 185659.9740734423 30 0.0 11 534495.8186811316 21 185651.5639073239 31 0.0 0 LINE 5 4CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534374.470588719 20 185733.8984580516 30 0.0 11 534808.8712390222 21 185692.4860401358 31 0.0 0 LINE 5 4CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534708.5877661901 20 185283.717923885 30 0.0 11 534771.7380859553 21 185703.0593879249 31 0.0 0 LINE 5 4CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535078.9923763787 20 185538.2018863312 30 0.0 11 534764.8498232055 21 185701.9616120782 31 0.0 0 LINE 5 4D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534942.4514380332 20 185243.3023541477 30 0.0 11 535027.841112852 21 185567.3371296885 31 0.0 0 LINE 5 4D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534850.8247779503 20 185262.3065426861 30 0.0 11 534971.0055605743 21 185244.8696560818 31 0.0 0 LINE 5 4D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.7220330874 20 185148.6998047703 30 0.0 11 534835.6955730616 21 185214.8918385876 31 0.0 0 LINE 5 4D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534839.7030371286 20 185209.4775197689 30 0.0 11 534852.3398615693 21 185263.864389153 31 0.0 0 LINE 5 4D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534805.1691802337 20 184873.2203278976 30 0.0 11 534989.9613163239 21 185404.6047790297 31 0.0 0 LINE 5 4D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534984.5268345839 20 185416.4999954338 30 0.0 11 535007.4014992987 21 185408.3449794178 31 0.0 0 LINE 5 4D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534901.1939781368 20 185587.4061969149 30 0.0 11 535027.7864360749 21 185783.166830838 31 0.0 0 LINE 5 4D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534888.0184218741 20 185579.1763486232 30 0.0 11 534907.3540633668 21 185593.5039234594 31 0.0 0 LINE 5 4D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534826.1353532244 20 185595.8783156365 30 0.0 11 534896.0117032174 21 185579.1702911296 31 0.0 0 LINE 5 4DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534931.0310239862 20 185361.4892335674 30 0.0 11 535274.7483125908 21 185272.5382705694 31 0.0 0 LINE 5 4DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535071.7079966699 20 185018.8475749982 30 0.0 11 535225.3427913389 21 185153.0973355788 31 0.0 0 LINE 5 4DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535237.7886563097 20 185124.5939782508 30 0.0 11 534960.7906806459 21 185330.2718847505 31 0.0 0 LINE 5 4DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534918.8102029823 20 185208.7995313166 30 0.0 11 534952.4648418761 21 185197.4259210327 31 0.0 0 LINE 5 4E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534979.4409143216 20 184844.1047242348 30 0.0 11 535117.6662871139 21 185075.4980319115 31 0.0 0 LINE 5 4E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534720.9076861708 20 185399.3112583365 30 0.0 11 534767.9092193946 21 185398.3285007116 31 0.0 0 LINE 5 4E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534754.7117021711 20 185335.8932851755 30 0.0 11 534767.0038576885 21 185400.0002314509 31 0.0 0 LINE 5 4E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534707.7635446379 20 185320.0365499808 30 0.0 11 534807.3433130968 21 185288.9429373291 31 0.0 0 LINE 5 4E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534743.6313809589 20 185151.9992597903 30 0.0 11 534864.2835988922 21 185425.1325123446 31 0.0 0 LINE 5 4EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534912.9431068461 20 184972.1991104843 30 0.0 11 534950.4900414558 21 185078.4760987974 31 0.0 0 LINE 5 4ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534537.1915622653 20 185503.4776332377 30 0.0 11 534550.6368346601 21 185729.6044252857 31 0.0 0 LINE 5 4F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535204.4961575484 20 185229.1919298231 30 0.0 11 535370.5322272507 21 185193.6261991774 31 0.0 0 LINE 5 4F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535127.1242449161 20 184779.6941977527 30 0.0 11 535293.5571175311 21 185516.6960290042 31 0.0 0 LINE 5 4F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535310.5577928031 20 185281.1508338489 30 0.0 11 535749.7250002055 21 185277.1594001404 31 0.0 0 LINE 5 4F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535321.8102417574 20 185349.72932479 30 0.0 11 535297.4628153631 21 185157.3320250695 31 0.0 0 LINE 5 4F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535393.7012431163 20 185339.5272597694 30 0.0 11 535385.1014189776 21 185275.795880317 31 0.0 0 LINE 5 4F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535346.9444020168 20 185367.2952780401 30 0.0 11 535402.0006421976 21 185325.9907269572 31 0.0 0 LINE 5 4F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535382.2264866398 20 185331.1913556245 30 0.0 11 535784.8986583672 21 185352.4568174781 31 0.0 0 LINE 5 4F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535466.2111560569 20 185520.4169102442 30 0.0 11 535514.7099456254 21 185115.9919336981 31 0.0 0 LINE 5 4F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535501.4979983462 20 185117.6476644367 30 0.0 11 535720.675878737 21 185130.8756334432 31 0.0 0 LINE 5 4F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535418.8674089755 20 184945.9561199044 30 0.0 11 535515.4397776947 21 185129.2063845734 31 0.0 0 LINE 5 4FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535369.5064323646 20 185017.8273827992 30 0.0 11 535452.3764747868 21 184997.2391378445 31 0.0 0 LINE 5 4FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535717.5064167423 20 185601.3754019604 30 0.0 11 535737.9102122855 21 185175.1889393928 31 0.0 0 LINE 5 4FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535326.3598811705 20 185199.7522087382 30 0.0 11 535750.4056180268 21 185204.2732045837 31 0.0 0 LINE 5 4FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535281.2005158721 20 183938.4377093622 30 0.0 11 535738.3484018436 21 185214.8857648657 31 0.0 0 LINE 5 502 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535570.296748796 20 185002.1058677334 30 0.0 11 535539.0553429453 21 184802.52829905 31 0.0 0 LINE 5 503 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535357.746004057 20 184958.474605842 30 0.0 11 535657.2550122715 21 184929.8059817427 31 0.0 0 LINE 5 504 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535298.4922117697 20 184889.1393465063 30 0.0 11 535341.8549400053 21 185002.5727601311 31 0.0 0 LINE 5 505 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535241.173484526 20 185019.5210662647 30 0.0 11 535249.717781515 21 184899.043989793 31 0.0 0 LINE 5 506 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535246.9440076642 20 184905.1824582619 30 0.0 11 535300.5910023385 21 184889.7027665412 31 0.0 0 LINE 5 507 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534936.51385834 20 185038.9531902914 30 0.0 11 534936.5261047019 21 185038.9510308092 31 0.0 0 LINE 5 508 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535080.6527128276 20 185013.5362284448 30 0.0 11 535490.5647417293 21 184941.2537170008 31 0.0 0 LINE 5 509 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535501.4412534025 20 184948.5153462196 30 0.0 11 535497.0379026665 21 184924.6330290301 31 0.0 0 LINE 5 50D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535438.6044568951 20 184992.5553584505 30 0.0 11 535394.6297386166 21 184644.0500522233 31 0.0 0 LINE 5 50E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535304.00713784 20 184686.4677601972 30 0.0 11 535412.5316292262 21 184958.1988788722 31 0.0 0 LINE 5 50F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535285.9196378086 20 184980.2736785974 30 0.0 11 535280.0577219055 21 184945.2361034543 31 0.0 0 LINE 5 510 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535408.97011748 20 184810.9000931193 30 0.0 11 535499.2992886764 21 184787.3951780687 31 0.0 0 LINE 5 511 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535464.4760482091 20 184792.1782756448 30 0.0 11 535543.352293473 21 184819.2175096397 31 0.0 0 LINE 5 512 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535464.5747593957 20 184805.3031096497 30 0.0 11 535525.357753368 21 184753.0577724275 31 0.0 0 LINE 5 513 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535479.3097783617 20 184592.3356562343 30 0.0 11 535522.9332737854 21 184765.446873669 31 0.0 0 LINE 5 514 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535442.4387356393 20 185206.0210956518 30 0.0 11 535448.962877189 21 185159.464189451 31 0.0 0 LINE 5 515 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535385.2221178641 20 185162.5376566434 30 0.0 11 535450.4688616026 21 185160.624523209 31 0.0 0 LINE 5 516 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535362.082434586 20 185206.3568374276 30 0.0 11 535347.2644751583 21 185103.0932372945 31 0.0 0 LINE 5 517 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535201.914047268 20 185144.1545844069 30 0.0 11 535490.7907191858 21 185068.5966611639 31 0.0 0 LINE 5 518 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535571.5812368377 20 185125.0116500937 30 0.0 11 535571.5035935779 21 185056.1672042472 31 0.0 0 LINE 5 519 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535539.6771781332 20 185057.1807123762 30 0.0 11 535599.7813427349 21 185056.9330147139 31 0.0 0 LINE 5 51A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535545.0448302518 20 185063.9077228577 30 0.0 11 535543.9573329221 21 184992.5824589834 31 0.0 0 LINE 5 51B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535541.1738633348 20 184995.0465275259 30 0.0 11 535597.2888617337 21 184993.4043492656 31 0.0 0 LINE 5 51C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535594.7469779589 20 185064.4360151786 30 0.0 11 535594.4263687718 21 184986.9377248218 31 0.0 0 LINE 5 521 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534391.2765926996 20 184519.6503847673 30 0.0 11 534386.096584341 21 184657.946565643 31 0.0 0 LINE 5 52B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.5953021054 20 184456.2129860037 30 0.0 11 534150.4528097157 21 184882.3790791057 31 0.0 0 LINE 5 52F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534288.5721563849 20 184537.5636853628 30 0.0 11 534215.4902316121 21 184934.1190157052 31 0.0 0 LINE 5 530 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534453.0403708429 20 184663.3012758095 30 0.0 11 534104.3003871109 21 184622.7857454523 31 0.0 0 LINE 5 534 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534447.258926724 20 184850.4577674675 30 0.0 11 534358.4101113065 21 184835.3587940743 31 0.0 0 LINE 5 535 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534473.2590024992 20 184926.5403161469 30 0.0 11 534009.7420030087 21 184836.5395345194 31 0.0 0 LINE 5 536 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534173.7545980421 20 184452.6269133669 30 0.0 11 534079.4116061442 21 184866.0693231767 31 0.0 0 LINE 5 537 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533755.4398820817 20 184661.6264292206 30 0.0 11 534086.3626894285 21 184865.4899125348 31 0.0 0 LINE 5 54B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534152.8220239885 20 184566.9747456222 30 0.0 11 534106.0257041126 21 184562.4787046947 31 0.0 0 LINE 5 54C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534123.8568246478 20 184501.2056948098 30 0.0 11 534106.8034721114 21 184564.2134785772 31 0.0 0 LINE 5 557 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534476.3853151561 20 184841.3974169092 30 0.0 11 534252.8962295165 21 185308.7896885875 31 0.0 0 LINE 5 55A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533961.5249641592 20 184881.5255266349 30 0.0 11 534304.3350339336 21 185057.7811684468 31 0.0 0 LINE 5 55B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533907.0202036754 20 184975.68771859 30 0.0 11 534585.0093833957 21 185309.1577660268 31 0.0 0 LINE 5 55C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534351.9801533095 20 185270.8440629181 30 0.0 11 534245.8376609196 21 185697.0101560202 31 0.0 0 LINE 5 55D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534416.053427876 20 185297.7558171074 30 0.0 11 534234.6140266268 21 185229.2776323616 31 0.0 0 LINE 5 55E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534389.3918617133 20 185365.2951323006 30 0.0 11 534329.4147947651 21 185342.0917458582 31 0.0 0 LINE 5 55F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534427.284004527 20 185326.2893565586 30 0.0 11 534374.294889134 21 185370.214396944 31 0.0 0 LINE 5 564 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534082.1685787133 20 185266.8570599263 30 0.0 11 534042.8498380052 21 185342.6551891283 31 0.0 0 LINE 5 565 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534438.4337275536 20 185715.179827652 30 0.0 11 534231.2455671621 21 185651.1706114339 31 0.0 0 LINE 5 566 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534269.1394492462 20 185267.2579902813 30 0.0 11 534174.7964573482 21 185680.700400091 31 0.0 0 LINE 5 56B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534038.9544153993 20 185209.4610571617 30 0.0 11 533929.5639759587 21 185526.2001676052 31 0.0 0 LINE 5 56C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534128.9026977911 20 185235.266299162 30 0.0 11 534010.36305539 21 185208.8879234353 31 0.0 0 LINE 5 56D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534143.9452490914 20 185183.4172834368 30 0.0 11 534127.2753217763 21 185236.706441965 31 0.0 0 LINE 5 56E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534203.536687036 20 184850.6856394941 30 0.0 11 533979.511130468 21 185366.7574547194 31 0.0 0 LINE 5 56F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533984.0405412705 20 185379.0258777179 30 0.0 11 533961.8400215265 21 185369.1825299575 31 0.0 0 LINE 5 573 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534041.5016409996 20 185328.1711071394 30 0.0 11 533705.4015758481 21 185213.7569711722 31 0.0 0 LINE 5 574 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533926.8507846999 20 184975.9659141336 30 0.0 11 533763.6036657633 21 185098.3465764448 31 0.0 0 LINE 5 575 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533753.3249201474 20 185068.9920483031 30 0.0 11 534014.1606413901 21 185294.815001671 31 0.0 0 LINE 5 57B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534031.9313018756 20 184808.6148959472 30 0.0 11 533876.783424875 21 185029.0196435895 31 0.0 0 LINE 5 57C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534248.2068751925 20 185381.6058225365 30 0.0 11 534201.4105553166 21 185377.1097816092 31 0.0 0 LINE 5 57D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534219.2416758518 20 185315.8367717241 30 0.0 11 534202.1883233154 21 185378.8445554916 31 0.0 0 LINE 5 57E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534267.2444791151 20 185303.536510522 30 0.0 11 534170.26974444 21 185265.0807714352 31 0.0 0 LINE 5 585 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534088.6604468999 20 184941.3248589964 30 0.0 11 534043.2684698303 21 185044.4952954651 31 0.0 0 LINE 5 588 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533778.699490766 20 185175.787427945 30 0.0 11 533615.7892077258 21 185127.9007145659 31 0.0 0 LINE 5 589 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533889.4801228333 20 184733.3371193682 30 0.0 11 533668.380798012 21 185455.8235821609 31 0.0 0 LINE 5 58A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533669.0481535236 20 185219.6666077623 30 0.0 11 533156.2970385719 21 185130.5605879663 31 0.0 0 LINE 5 58B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533652.6970921362 20 185287.2111842932 30 0.0 11 533691.368935235 21 185097.1743282281 31 0.0 0 LINE 5 58D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533726.3554435947 20 185312.8337458587 30 0.0 11 533574.50719174 21 185257.5403092498 31 0.0 0 LINE 5 58E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533593.8368982549 20 185264.2056083881 30 0.0 11 533277.4741264265 21 185310.1755935641 31 0.0 0 LINE 5 58F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533672.2874569829 20 185028.0485366832 30 0.0 11 533252.0779246593 21 185038.8519140487 31 0.0 0 LINE 5 590 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533710.405074358 20 184829.6561084765 30 0.0 11 533658.6782495932 21 184939.5278570125 31 0.0 0 LINE 5 591 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533757.8097503218 20 184963.9603378841 30 0.0 11 533758.301905461 21 184843.1816611668 31 0.0 0 LINE 5 592 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533760.6087077835 20 184849.5104272049 30 0.0 11 533708.2700168314 21 184830.060945907 31 0.0 0 LINE 5 593 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534060.1620768055 20 185006.1286428275 30 0.0 11 534060.1500263014 21 185006.1255732843 31 0.0 0 LINE 5 594 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.3284564037 20 184970.0003236548 30 0.0 11 532885.2387837082 21 184800.028308228 31 0.0 0 LINE 5 595 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533494.4232462246 20 185058.1154689717 30 0.0 11 533576.3287827944 21 184703.1402534146 31 0.0 0 LINE 5 596 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533720.0668251423 20 184684.4216508722 30 0.0 11 533604.0388960189 21 184929.9588760215 31 0.0 0 LINE 5 597 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533716.1249475926 20 184921.4756006983 30 0.0 11 533724.5914895053 21 184886.9747108834 31 0.0 0 LINE 5 598 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533431.9734486657 20 185232.4302220629 30 0.0 11 533540.1338697607 21 185087.9672749981 31 0.0 0 LINE 5 599 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533603.4661137124 20 185095.8003762957 30 0.0 11 533538.5453041319 21 185089.0116995892 31 0.0 0 LINE 5 59A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533787.6357425715 20 185091.1815131837 30 0.0 11 533565.5971262563 21 185014.9532196935 31 0.0 0 LINE 5 59D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.4049733451 20 184778.3242658983 30 0.0 11 533961.3461259023 21 184945.405927624 31 0.0 0 LINE 5 59E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533589.8584304239 20 185107.2802195277 30 0.0 11 533607.2332131394 21 184991.399632075 31 0.0 0 LINE 5 59F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534448.9792157222 20 184662.8294633956 30 0.0 11 534595.7315551097 21 184795.9757854659 31 0.0 0 LINE 5 5A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531733.2840274471 20 186204.7351113824 30 0.0 11 531448.5837936163 21 186119.7760350217 31 0.0 0 LINE 5 5A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531632.4721077171 20 185930.7358159032 30 0.0 11 531639.7393499542 21 186196.0561477955 31 0.0 0 LINE 5 5A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531358.4579136721 20 185930.1338576855 30 0.0 11 531685.1949769023 21 186008.8922798291 31 0.0 0 LINE 5 5A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531770.0292339276 20 185963.2831550198 30 0.0 11 531808.2136621511 21 186140.5612032772 31 0.0 0 LINE 5 5A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532232.1680833026 20 186022.1457130604 30 0.0 11 532232.1680833026 21 186186.3597618883 31 0.0 0 LINE 5 5A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531627.5907608017 20 186001.9470050684 30 0.0 11 531869.3182729818 21 185971.1207754074 31 0.0 0 LINE 5 5A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531611.397048721 20 186201.9375863602 30 0.0 11 531901.0963274493 21 186217.1136835819 31 0.0 0 LINE 5 5A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533414.1140397175 20 185165.5370379062 30 0.0 11 533424.4254015407 21 184724.7392205304 31 0.0 0 LINE 5 5A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533322.7171241251 20 184642.9320605513 30 0.0 11 532990.6437599907 21 184514.5291438661 31 0.0 0 LINE 5 5AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534153.2048046347 20 184752.2472177889 30 0.0 11 533885.0218290623 21 184579.4395168853 31 0.0 0 LINE 5 5AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531550.2442337178 20 185166.8802593773 30 0.0 11 531510.6297846931 21 185399.9897693373 31 0.0 0 LINE 5 5AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532988.2362401025 20 186147.3083667564 30 0.0 11 533381.9029377306 21 186201.5675327487 31 0.0 0 LINE 5 5C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532850.8247731416 20 187339.4336963453 30 0.0 11 533427.582290831 21 185080.1812356924 31 0.0 0 LINE 5 5D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534248.5818166204 20 185619.4487363936 30 0.0 11 534493.593518952 21 185630.1835954607 31 0.0 0 LINE 5 5DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534282.0183703715 20 185616.188519107 30 0.0 11 534172.0588715453 21 185831.2875668419 31 0.0 0 LINE 5 5DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533826.1828457042 20 185498.1855968445 30 0.0 11 534909.8834741084 21 186031.2054602447 31 0.0 0 LINE 5 5E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534271.1427953386 20 185793.3419411726 30 0.0 11 534165.0003029485 21 186219.5080342747 31 0.0 0 LINE 5 5E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534335.216069905 20 185820.2536953619 30 0.0 11 534153.7766686557 21 185751.7755106161 31 0.0 0 LINE 5 5E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534308.5545037421 20 185887.7930105551 30 0.0 11 534248.577436794 21 185864.5896241127 31 0.0 0 LINE 5 5E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534570.7220163379 20 186012.2185426509 30 0.0 11 534062.9865863768 21 185953.4249086355 31 0.0 0 LINE 5 5E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534067.6732275388 20 185940.9616670905 30 0.0 11 534026.1561056284 21 186176.1469138242 31 0.0 0 LINE 5 5E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533919.9417536444 20 185820.6237579156 30 0.0 11 534075.6678596591 21 185957.2116849322 31 0.0 0 LINE 5 5E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534001.3312207422 20 185789.3549381808 30 0.0 11 533962.012480034 21 185865.1530673827 31 0.0 0 LINE 5 5E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534357.5963695824 20 186237.6777059064 30 0.0 11 534024.2894962416 21 186173.6684896884 31 0.0 0 LINE 5 5E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534188.3020912749 20 185789.7558685358 30 0.0 11 534093.959099377 21 186203.1982783455 31 0.0 0 LINE 5 5EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533638.9909350334 20 185915.9627476106 30 0.0 11 534100.9101826614 21 186202.6188677036 31 0.0 0 LINE 5 5EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533717.7276796531 20 185860.915757104 30 0.0 11 533711.7175495929 21 185978.1906737143 31 0.0 0 LINE 5 5EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533770.762714852 20 185893.2003459607 30 0.0 11 533683.5308453329 21 185959.9551347054 31 0.0 0 LINE 5 5ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533939.2875136152 20 185980.9652082985 30 0.0 11 533752.4704865293 21 185904.110606927 31 0.0 0 LINE 5 5EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533958.117057428 20 185731.9589354162 30 0.0 11 533848.7266179877 21 186048.6980458597 31 0.0 0 LINE 5 5EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534048.06533982 20 185757.7641774165 30 0.0 11 533929.525697419 21 185731.3858016898 31 0.0 0 LINE 5 5F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534063.1078911201 20 185705.9151616913 30 0.0 11 534046.4379638053 21 185759.2043202194 31 0.0 0 LINE 5 5F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534282.8840061187 20 185012.2849875451 30 0.0 11 533898.6737724969 21 185889.2553329739 31 0.0 0 LINE 5 5F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533903.2031832994 20 185901.5237559724 30 0.0 11 533881.0026635552 21 185891.680408212 31 0.0 0 LINE 5 5F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533973.5175888728 20 186078.1849544206 30 0.0 11 533951.289621666 21 186117.6824815214 31 0.0 0 LINE 5 5F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533987.2718768551 20 186070.9637877669 30 0.0 11 533966.918612191 21 186083.8047787778 31 0.0 0 LINE 5 5F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534047.7321300739 20 186092.2482343965 30 0.0 11 533979.3014454953 21 186070.3597949963 31 0.0 0 LINE 5 5F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533960.6642830283 20 185850.6689853939 30 0.0 11 533624.564217877 21 185736.2548494267 31 0.0 0 LINE 5 5F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533846.0134267288 20 185498.4637923881 30 0.0 11 533682.7663077922 21 185620.8444546993 31 0.0 0 LINE 5 5F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533672.4875621763 20 185591.4899265576 30 0.0 11 533933.323283419 21 185817.3128799255 31 0.0 0 LINE 5 5F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533984.2730984368 20 185699.3213145349 30 0.0 11 533951.5635824718 21 185685.4619748932 31 0.0 0 LINE 5 5FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533790.9027081983 20 185779.5505123624 30 0.0 11 533747.0106001366 21 185861.9235847253 31 0.0 0 LINE 5 5FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533759.7708675354 20 185829.171307324 30 0.0 11 533767.7003971879 21 185912.175553007 31 0.0 0 LINE 5 5FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533772.511944799 20 185832.3234433795 30 0.0 11 533707.5492968536 21 185879.270242947 31 0.0 0 LINE 5 5FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533609.8257327368 20 185818.9870339748 30 0.0 11 533720.1623939 21 185879.7972284508 31 0.0 0 LINE 5 5FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533892.3579233192 20 185253.3677321921 30 0.0 11 533795.9460669039 21 185551.517521844 31 0.0 0 LINE 5 5FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534167.3695172214 20 185904.103700791 30 0.0 11 534120.5731973455 21 185899.6076598636 31 0.0 0 LINE 5 600 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534138.4043178805 20 185838.3346499785 30 0.0 11 534121.3509653443 21 185901.3424337461 31 0.0 0 LINE 5 601 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534186.407121144 20 185826.0343887765 30 0.0 11 534089.4323864689 21 185787.5786496897 31 0.0 0 LINE 5 602 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534163.2101264513 20 185655.7847719955 30 0.0 11 534022.4637309971 21 185919.1271034002 31 0.0 0 LINE 5 603 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534058.515801896 20 186010.8331931783 30 0.0 11 533991.5818118574 21 185994.7271468006 31 0.0 0 LINE 5 604 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533999.9782917924 20 185964.0115637281 30 0.0 11 533985.742053636 21 186022.4059254402 31 0.0 0 LINE 5 605 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534005.2705259052 20 185970.7980663162 30 0.0 11 533936.1590559625 21 185953.1322620743 31 0.0 0 LINE 5 606 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533939.2035281585 20 185950.9990659342 30 0.0 11 533924.5400241045 21 186005.1892075063 31 0.0 0 LINE 5 607 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533994.211073514 20 186019.257029288 30 0.0 11 533918.9176883678 21 186000.8996342736 31 0.0 0 LINE 5 608 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534007.823088929 20 185463.8227372508 30 0.0 11 533962.4311118591 21 185566.9931737196 31 0.0 0 LINE 5 609 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533680.2879975476 20 185926.3723861391 30 0.0 11 533183.0921970396 21 185960.4920697405 31 0.0 0 LINE 5 60A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533635.3074283488 20 185874.3556080671 30 0.0 11 533409.7069375618 21 185902.1750854693 31 0.0 0 LINE 5 60B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533697.8621327951 20 185698.2853061994 30 0.0 11 533534.9518497547 21 185650.3985928204 31 0.0 0 LINE 5 60C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533771.9073970045 20 185375.8751922475 30 0.0 11 533587.5434400409 21 185978.3214604154 31 0.0 0 LINE 5 60E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533571.859734165 20 185809.7090625476 30 0.0 11 533610.5315772639 21 185619.6722064826 31 0.0 0 LINE 5 60F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533500.9333528128 20 185794.1576434707 30 0.0 11 533514.2766247555 21 185731.2481625001 31 0.0 0 LINE 5 610 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533545.4819450334 20 185825.3455892097 30 0.0 11 533493.6698337688 21 185780.0381875042 31 0.0 0 LINE 5 611 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533512.9995402838 20 185786.7034866426 30 0.0 11 533196.6367684554 21 185832.6734718186 31 0.0 0 LINE 5 612 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533591.4500990117 20 185550.5464149377 30 0.0 11 533281.9833857183 21 185528.8296416967 31 0.0 0 LINE 5 616 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533979.3247188342 20 185528.626521082 30 0.0 11 533979.3126683303 21 185528.6234515387 31 0.0 0 LINE 5 619 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533592.716804391 20 185246.1291783604 30 0.0 11 533497.5594804018 21 185639.2600493747 31 0.0 0 LINE 5 61B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533351.1360906946 20 185754.9281003174 30 0.0 11 533459.2965117895 21 185610.4651532526 31 0.0 0 LINE 5 61C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533522.6287557413 20 185618.2982545502 30 0.0 11 533457.707946161 21 185611.5095778437 31 0.0 0 LINE 5 61D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533706.7983846004 20 185613.6793914381 30 0.0 11 533484.7597682852 21 185537.451097948 31 0.0 0 LINE 5 620 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533365.6423109871 20 185989.5037721182 30 0.0 11 533355.2628067224 21 185733.4928732219 31 0.0 0 LINE 5 623 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533538.3571319998 20 185927.2096775935 30 0.0 11 533580.5614965238 21 186464.9701427501 31 0.0 0 LINE 5 624 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533458.1223385239 20 186169.4847237501 30 0.0 11 533567.2457225238 21 186212.8623077501 31 0.0 0 LINE 5 625 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533465.3862375239 20 186231.1470737501 30 0.0 11 533562.4058715238 21 186179.6418167501 31 0.0 0 LINE 5 626 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533474.9917335238 20 186420.9127537501 30 0.0 11 533482.9234825239 21 186219.0605337501 31 0.0 0 LINE 5 629 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533360.3675759997 20 186232.7478384316 30 0.0 11 533383.5869865237 21 185953.2266277501 31 0.0 0 LINE 5 62A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533362.2817485238 20 185976.7798857501 30 0.0 11 533556.7744945239 21 186028.6150477501 31 0.0 0 LINE 5 62B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533258.2867925238 20 185940.5511634717 30 0.0 11 533382.6655621308 21 186525.8843834039 31 0.0 0 LINE 5 62C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533353.6739045237 20 186202.1253807501 30 0.0 11 533446.8430955237 21 186196.5269837501 31 0.0 0 LINE 5 62D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533411.7521155238 20 186194.4875667501 30 0.0 11 533483.9128905238 21 186236.2656087501 31 0.0 0 LINE 5 62E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533409.3115775239 20 186207.3838757501 30 0.0 11 533479.0483035237 21 186167.8751847501 31 0.0 0 LINE 5 62F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533464.9410045238 20 186001.2828717501 30 0.0 11 533474.2744135237 21 186179.5618397501 31 0.0 0 LINE 5 631 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533828.2799445249 20 186210.2886838591 30 0.0 11 534061.4320714794 21 186167.5716401304 31 0.0 0 LINE 5 633 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533682.6241340539 20 186064.3491011722 30 0.0 11 533742.8463203225 21 185963.5383080481 31 0.0 0 LINE 5 634 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533744.6558089154 20 186067.0101066368 30 0.0 11 533709.2791370904 21 185963.019280259 31 0.0 0 LINE 5 635 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533835.7364357564 20 186271.9532591409 30 0.0 11 533852.6960106894 21 186024.3600566836 31 0.0 0 LINE 5 63A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533878.8332329101 20 186207.9637909363 30 0.0 11 533536.7480498949 21 186128.1674759979 31 0.0 0 LINE 5 63B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533545.052813288 20 186227.8808082367 30 0.0 11 533837.5602881303 21 186220.4819401955 31 0.0 0 LINE 5 63D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533698.1930436881 20 186172.6657522801 30 0.0 11 533707.5219630261 21 186079.7958892214 31 0.0 0 LINE 5 63E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533699.9134321882 20 186114.1127416054 30 0.0 11 533752.6629064465 21 186049.5366221229 31 0.0 0 LINE 5 63F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533712.2556086878 20 186118.5783536354 30 0.0 11 533684.3718017468 21 186043.434219279 31 0.0 0 LINE 5 640 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533517.6614423957 20 186030.7981312432 30 0.0 11 533695.1477506907 21 186050.0104533972 31 0.0 0 LINE 5 641 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533938.7951369609 20 186482.5712296237 30 0.0 11 533968.2654247546 21 186185.4345043938 31 0.0 0 LINE 5 643 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534367.7944644015 20 186130.8678290536 30 0.0 11 534035.7211002672 21 186002.4649123684 31 0.0 0 LINE 5 64E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532380.4365915808 20 183829.5073398477 30 0.0 11 532354.2882743065 21 183002.9918967023 31 0.0 0 LINE 5 666 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536721.8421223054 20 187156.3816589114 30 0.0 11 536115.335826082 21 187063.9140026928 31 0.0 0 LINE 5 667 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536616.706362917 20 187155.7945168107 30 0.0 11 536886.3043911481 21 186412.0959092634 31 0.0 0 LINE 5 668 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536666.447967984 20 187027.2281110592 30 0.0 11 536521.132606101 21 187000.0042188773 31 0.0 0 LINE 5 669 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536552.2840148339 20 187145.8392677637 30 0.0 11 536721.6738765864 21 186681.3054352729 31 0.0 0 LINE 5 66A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536550.2106325194 20 187014.8446578274 30 0.0 11 536489.8958197851 21 186959.3178929346 31 0.0 0 LINE 5 66B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536491.0322792968 20 187068.2603682839 30 0.0 11 536549.6500574119 21 187002.8280783266 31 0.0 0 LINE 5 66C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536508.7832802601 20 187061.4323469309 30 0.0 11 536310.8203374363 21 187042.3293091405 31 0.0 0 LINE 5 66D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536473.6692727942 20 187178.8966004267 30 0.0 11 536448.1715212629 21 186746.6824336228 31 0.0 0 LINE 5 66E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536309.2993856575 20 186986.2769338689 30 0.0 11 536494.1270439047 21 186960.2274519697 31 0.0 0 LINE 5 66F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536314.1277275352 20 187046.694654312 30 0.0 11 536309.8524477744 21 186985.6344982014 31 0.0 0 LINE 5 672 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536127.4745693341 20 186916.0368669632 30 0.0 11 536816.4822066296 21 186869.139699889 31 0.0 0 LINE 5 673 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536525.5993654336 20 186819.2249963617 30 0.0 11 536588.1901689714 21 186384.522616666 31 0.0 0 LINE 5 674 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536595.0910224655 20 186818.4924458963 30 0.0 11 536401.2259074044 21 186813.4096047542 31 0.0 0 LINE 5 675 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536595.8985936714 20 186745.8856553338 30 0.0 11 536531.5999819602 21 186744.7305648122 31 0.0 0 LINE 5 676 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536616.2621607849 20 186796.3097583272 30 0.0 11 536583.7757235719 21 186735.6312042886 31 0.0 0 LINE 5 677 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536585.9204290146 20 186755.9650186167 30 0.0 11 536667.9473822077 21 186361.1629457988 31 0.0 0 LINE 5 678 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536785.6857709126 20 186701.6185063583 30 0.0 11 536393.2771205099 21 186592.4070356544 31 0.0 0 LINE 5 679 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536392.9120581205 20 186605.7173220767 30 0.0 11 536443.2503469226 21 186372.2610555652 31 0.0 0 LINE 5 67A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536210.6834718002 20 186661.3818807413 30 0.0 11 536406.449603067 21 186593.6876878588 31 0.0 0 LINE 5 67B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536274.2466349336 20 186721.0619338121 30 0.0 11 536266.4513026214 21 186636.0292779937 31 0.0 0 LINE 5 67C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536835.1377440049 20 186601.9767823079 30 0.0 11 536747.1631200043 21 186582.4177299131 31 0.0 0 LINE 5 67D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536903.7822790087 20 186465.4897275121 30 0.0 11 536440.586236061 21 186373.8514423475 31 0.0 0 LINE 5 67E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536447.5344701054 20 186791.2729967184 30 0.0 11 536516.2484564788 21 186372.8072102721 31 0.0 0 LINE 5 67F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536045.525813408 20 186455.4018776182 30 0.0 11 536522.4664836628 21 186375.9678136094 31 0.0 0 LINE 5 681 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536038.6420717368 20 186547.7344716945 30 0.0 11 536077.3484423033 21 186436.8681350233 31 0.0 0 LINE 5 682 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536099.9405019144 20 186537.8596504822 30 0.0 11 536044.3633383144 21 186443.113781093 31 0.0 0 LINE 5 683 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536289.1274002778 20 186520.2075586261 30 0.0 11 536087.1204276245 21 186520.8512670621 31 0.0 0 LINE 5 684 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536212.562739197 20 186757.897542278 30 0.0 11 536230.836750314 21 186423.2992863901 31 0.0 0 LINE 5 685 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536305.597141756 20 186767.9575601927 30 0.0 11 536185.8705566588 21 186747.6349041769 31 0.0 0 LINE 5 686 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536188.9556141511 20 186849.6862783888 30 0.0 11 536305.430287944 21 186817.7272212837 31 0.0 0 LINE 5 687 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536299.9534294918 20 186821.6487819443 30 0.0 11 536304.633839147 21 186766.0096351245 31 0.0 0 LINE 5 688 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536229.5279032986 20 187152.256905888 30 0.0 11 536216.8978776463 21 186589.7997511483 31 0.0 0 LINE 5 689 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536225.7235310675 20 186580.1489684459 30 0.0 11 536201.4497697369 21 186580.8831910964 31 0.0 0 LINE 5 68A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536357.5255991142 20 186443.1033208429 30 0.0 11 536351.8528189064 21 186398.1371475795 31 0.0 0 LINE 5 68B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536367.5361546681 20 186454.9824817241 30 0.0 11 536353.5364037751 21 186435.4081769457 31 0.0 0 LINE 5 68C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536431.5577923935 20 186458.0969304032 30 0.0 11 536359.9274632249 21 186452.5329107725 31 0.0 0 LINE 5 68D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536259.7350569179 20 186648.932700403 30 0.0 11 535923.953342475 21 186656.2281362882 31 0.0 0 LINE 5 68E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535865.5521283698 20 186582.2711223863 30 0.0 11 535909.5661554791 21 186409.5705157149 31 0.0 0 LINE 5 690 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535965.3597747557 20 186727.1967157956 30 0.0 11 536221.8250015524 21 186669.4993660018 31 0.0 0 LINE 5 691 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536224.4625911634 20 186797.9942541284 30 0.0 11 536188.9413628585 21 186798.4801241541 31 0.0 0 LINE 5 692 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536077.8143043649 20 186671.3894402389 30 0.0 11 536066.1387435208 21 186557.85564699 31 0.0 0 LINE 5 693 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536065.5907214598 20 186593.0015681029 30 0.0 11 536104.2679961856 21 186519.1324225704 31 0.0 0 LINE 5 694 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536078.5790034816 20 186594.8924783798 30 0.0 11 536036.145709285 21 186526.8956905047 31 0.0 0 LINE 5 695 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535870.3023852617 20 186548.0618548403 30 0.0 11 536048.0244747275 21 186531.1691975403 31 0.0 0 LINE 5 698 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536471.3175540789 20 186677.4838745904 30 0.0 11 536426.2865221732 21 186663.981426536 31 0.0 0 LINE 5 699 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536419.667447414 20 186727.4520374456 30 0.0 11 536427.6616261824 21 186662.6686232577 31 0.0 0 LINE 5 69A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536459.4750142634 20 186756.9634448726 30 0.0 11 536355.1584437736 21 186755.9653690792 31 0.0 0 LINE 5 69B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536373.7244359636 20 186905.8589481565 30 0.0 11 536342.8050682326 21 186608.8695139299 31 0.0 0 LINE 5 69C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536410.8090196552 20 186537.5587762437 30 0.0 11 536342.7475201335 21 186527.2052244266 31 0.0 0 LINE 5 69D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536338.9274579809 20 186558.8178017327 30 0.0 11 536347.7887194486 21 186499.3699253886 31 0.0 0 LINE 5 69E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536346.3900426166 20 186554.5312891829 30 0.0 11 536275.7233642788 21 186544.8000770359 31 0.0 0 LINE 5 69F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536277.7372782987 20 186547.9247349442 30 0.0 11 536284.6157765886 21 186492.208704432 31 0.0 0 LINE 5 6A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536354.4423756366 20 186505.4829200722 30 0.0 11 536277.790117113 21 186494.0584261355 31 0.0 0 LINE 5 6A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536666.4355173762 20 186671.0755228247 30 0.0 11 536734.8141109666 21 186415.4623038834 31 0.0 0 LINE 5 6A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537062.3019043448 20 186308.8815913478 30 0.0 11 536916.986542462 21 186281.6576991659 31 0.0 0 LINE 5 6A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536948.1379511946 20 186427.4927480521 30 0.0 11 537117.5278129472 21 185962.9589155613 31 0.0 0 LINE 5 6A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536946.0645688802 20 186296.4981381159 30 0.0 11 536885.7497561461 21 186240.971373223 31 0.0 0 LINE 5 6A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536886.8862156576 20 186349.9138485724 30 0.0 11 536945.5039937727 21 186284.4815586153 31 0.0 0 LINE 5 6A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536902.8495839172 20 186342.7321635861 30 0.0 11 536704.8866410933 21 186323.6291257958 31 0.0 0 LINE 5 6A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536874.5354492202 20 186545.5129120825 30 0.0 11 536844.0254576235 21 186028.3359139113 31 0.0 0 LINE 5 6A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536705.1533220182 20 186267.9304141575 30 0.0 11 536889.9809802655 21 186241.8809322582 31 0.0 0 LINE 5 6AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536709.981663896 20 186328.3481346005 30 0.0 11 536705.7063841352 21 186267.2879784899 31 0.0 0 LINE 5 6AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536412.9192928441 20 186313.9919186686 30 0.0 11 536709.0047859222 21 186287.9276338956 31 0.0 0 LINE 5 6AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536481.3018370568 20 186311.6477386654 30 0.0 11 536479.0979397001 21 186198.5418407067 31 0.0 0 LINE 5 6AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536397.9941025675 20 186206.2212083415 30 0.0 11 537151.7037753856 21 186153.369250425 31 0.0 0 LINE 5 6AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536921.4533017945 20 186100.8784766501 30 0.0 11 536990.7057561739 21 185456.6421274363 31 0.0 0 LINE 5 6AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536990.9449588264 20 186100.1459261849 30 0.0 11 536797.0798437653 21 186095.0630850427 31 0.0 0 LINE 5 6B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536991.7525300322 20 186027.5391356223 30 0.0 11 536927.453918321 21 186026.3840451008 31 0.0 0 LINE 5 6B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537012.1160971457 20 186077.9632386158 30 0.0 11 536979.6296599327 21 186017.2846845772 31 0.0 0 LINE 5 6B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536981.7743653753 20 186037.6184989052 30 0.0 11 537010.3705357475 21 185899.982918183 31 0.0 0 LINE 5 6B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537181.5397072733 20 185983.2719866468 30 0.0 11 536789.1310568708 21 185874.0605159429 31 0.0 0 LINE 5 6B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536788.7659944812 20 185887.3708023651 30 0.0 11 536839.1042832833 21 185653.9145358537 31 0.0 0 LINE 5 6B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536606.537408161 20 185943.0353610298 30 0.0 11 536802.3035394278 21 185875.3411681474 31 0.0 0 LINE 5 6B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536670.1005712944 20 186002.7154141007 30 0.0 11 536662.3052389822 21 185917.6827582823 31 0.0 0 LINE 5 6B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537232.0290754295 20 185868.6402924852 30 0.0 11 537144.0544514289 21 185849.0812400903 31 0.0 0 LINE 5 6B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536843.3884064661 20 186072.926477007 30 0.0 11 536912.1023928396 21 185654.4606905605 31 0.0 0 LINE 5 6B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536434.4960080977 20 185829.387951983 30 0.0 11 536473.2023786641 21 185718.5216153119 31 0.0 0 LINE 5 6BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536495.7944382751 20 185819.5131307709 30 0.0 11 536440.2172746752 21 185724.7672613815 31 0.0 0 LINE 5 6BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536684.9813366386 20 185801.8610389146 30 0.0 11 536482.9743639853 21 185802.5047473506 31 0.0 0 LINE 5 6BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536608.4166755578 20 186039.5510225665 30 0.0 11 536622.7213326102 21 185611.5270011947 31 0.0 0 LINE 5 6BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536701.4510781167 20 186049.6110404813 30 0.0 11 536581.7244930196 21 186029.2883844655 31 0.0 0 LINE 5 6BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536584.8095505118 20 186131.3397586772 30 0.0 11 536701.2842243047 21 186099.3807015723 31 0.0 0 LINE 5 6BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536695.8073658528 20 186103.3022622328 30 0.0 11 536700.4877755078 21 186047.6631154132 31 0.0 0 LINE 5 6C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536625.3818396596 20 186433.9103861764 30 0.0 11 536612.7518140071 21 185871.4532314369 31 0.0 0 LINE 5 6C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536621.5774674283 20 185861.8024487344 30 0.0 11 536597.3037060976 21 185862.5366713851 31 0.0 0 LINE 5 6C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536753.379535475 20 185724.7568011315 30 0.0 11 536746.3417123108 21 185647.6619285755 31 0.0 0 LINE 5 6C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536763.3900910289 20 185736.6359620126 30 0.0 11 536749.3903401359 21 185717.0616572342 31 0.0 0 LINE 5 6C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536827.4117287541 20 185739.7504106917 30 0.0 11 536755.7813995857 21 185734.186391061 31 0.0 0 LINE 5 6C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536655.5889932786 20 185930.5861806915 30 0.0 11 536301.1658749766 21 185909.6553059632 31 0.0 0 LINE 5 6C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536416.4623950756 20 186213.4497288245 30 0.0 11 536311.4935309209 21 186038.497775686 31 0.0 0 LINE 5 6C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536290.8938687045 20 186061.8000255862 30 0.0 11 536617.6789379133 21 185951.1528462902 31 0.0 0 LINE 5 6C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536620.3165275241 20 186079.647734417 30 0.0 11 536584.7952992191 21 186080.1336044426 31 0.0 0 LINE 5 6C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536471.5409159631 20 185932.356697997 30 0.0 11 536461.9926798815 21 185839.5091272786 31 0.0 0 LINE 5 6CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536461.4446578205 20 185874.6550483916 30 0.0 11 536500.1219325463 21 185800.785902859 31 0.0 0 LINE 5 6CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536474.4329398423 20 185876.5459586684 30 0.0 11 536431.9996456458 21 185808.5491707931 31 0.0 0 LINE 5 6CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536318.7496871943 20 185827.4808156863 30 0.0 11 536443.8784110883 21 185812.8226778289 31 0.0 0 LINE 5 6CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536450.5920255018 20 186408.0864332379 30 0.0 11 536390.1276466231 21 186145.4209132169 31 0.0 0 LINE 5 6CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536867.1714904397 20 185959.137354879 30 0.0 11 536822.1404585341 21 185945.6349068246 31 0.0 0 LINE 5 6CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536815.5213837749 20 186009.1055177341 30 0.0 11 536823.5155625431 21 185944.3221035461 31 0.0 0 LINE 5 6D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536855.3289506244 20 186038.6169251611 30 0.0 11 536751.0123801345 21 186037.6188493678 31 0.0 0 LINE 5 6D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536769.5783723245 20 186187.512428445 30 0.0 11 536738.6590045934 21 185890.5229942185 31 0.0 0 LINE 5 6D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536806.6629560161 20 185819.2122565322 30 0.0 11 536738.6014564944 21 185808.8587047152 31 0.0 0 LINE 5 6D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536734.7813943418 20 185840.471282021 30 0.0 11 536743.6426558093 21 185781.0234056772 31 0.0 0 LINE 5 6D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536742.2439789774 20 185836.1847694715 30 0.0 11 536671.5773006395 21 185826.4535573242 31 0.0 0 LINE 5 6D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536673.5912146595 20 185829.5782152326 30 0.0 11 536680.4697129492 21 185773.8621847206 31 0.0 0 LINE 5 6D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536750.2963119973 20 185787.1364003606 30 0.0 11 536673.6440534738 21 185775.711906424 31 0.0 0 LINE 5 6D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536553.2222514413 20 186306.6114761733 30 0.0 11 536550.1362215744 21 186193.939177168 31 0.0 0 LINE 5 6D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537062.2894537369 20 185952.7290031131 30 0.0 11 537130.6680473274 21 185697.1157841719 31 0.0 0 LINE 5 6D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537784.5734153324 20 185861.9936452161 30 0.0 11 535864.4230040797 21 185456.3307235448 31 0.0 0 LINE 5 6DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536363.2478164847 20 185785.8285372621 30 0.0 11 536164.8419804048 21 185674.9023051266 31 0.0 0 LINE 5 6DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536354.7066451306 20 185972.485684567 30 0.0 11 536185.7730090109 21 185955.3298043531 31 0.0 0 LINE 5 6DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536290.2634319545 20 186424.0182927763 30 0.0 11 536361.4672387756 21 185636.0952636998 31 0.0 0 LINE 5 6DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536269.7332366472 20 185890.4593593341 30 0.0 11 535793.3462899222 21 185739.96058906 31 0.0 0 LINE 5 6DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536280.0904017486 20 185821.7399577195 30 0.0 11 536244.1610790384 21 186012.3143575776 31 0.0 0 LINE 5 6DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536208.5412910284 20 185809.3656713885 30 0.0 11 536197.1486584764 21 185872.657484648 31 0.0 0 LINE 5 6E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536261.5672213085 20 185797.3026806227 30 0.0 11 536196.4850589806 21 185819.6983871253 31 0.0 0 LINE 5 6E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536216.9006975449 20 185820.8233176042 30 0.0 11 535801.6962948423 21 185660.6602255008 31 0.0 0 LINE 5 6E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536197.4579107648 20 185611.9391870522 30 0.0 11 536024.7185410833 21 185984.9229118754 31 0.0 0 LINE 5 6E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536037.8003302407 20 185987.4056095272 30 0.0 11 535815.3572137982 21 185900.4870750231 31 0.0 0 LINE 5 6E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536063.6966472942 20 186176.1784400052 30 0.0 11 536028.0831420887 21 185972.1231530161 31 0.0 0 LINE 5 6E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536132.7482219166 20 186122.944386203 30 0.0 11 536047.5604990329 21 186117.0816537993 31 0.0 0 LINE 5 6E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536069.9974182161 20 185220.2754154892 30 0.0 11 535816.5024649587 21 185903.3706867481 31 0.0 0 LINE 5 6E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536229.6915143036 20 185963.0686055666 30 0.0 11 535827.5358233733 21 185828.5099692703 31 0.0 0 LINE 5 6E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535834.0177546548 20 186166.9563758262 30 0.0 11 535831.6474460902 21 185822.8754476268 31 0.0 0 LINE 5 6E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535817.4316180108 20 186521.407981259 30 0.0 11 535837.1688361796 21 186020.0815070079 31 0.0 0 LINE 5 6EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535936.8362455865 20 186076.2280642266 30 0.0 11 535905.2620010249 21 186275.7532467011 31 0.0 0 LINE 5 6ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536125.7083849122 20 186183.0401472969 30 0.0 11 535831.8734352128 21 186118.321074803 31 0.0 0 LINE 5 6EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536160.7993853049 20 186267.2245388372 30 0.0 11 536154.3770119736 21 186145.9553397494 31 0.0 0 LINE 5 6EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536255.3969228534 20 186160.7532505492 30 0.0 11 536210.2581796578 21 186272.7810365171 31 0.0 0 LINE 5 6F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536214.7834336409 20 186267.7913779211 30 0.0 11 536158.9751333219 21 186266.0436625988 31 0.0 0 LINE 5 6F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536551.2962527581 20 186235.8444073774 30 0.0 11 536551.2839351317 21 186235.84270068 31 0.0 0 LINE 5 6F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536406.3186160096 20 186215.75669558 30 0.0 11 535994.0212001858 21 186158.6298734732 31 0.0 0 LINE 5 6F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535985.9011248552 20 186148.3783300915 30 0.0 11 535982.7555381509 21 186172.4586094986 31 0.0 0 LINE 5 6F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535871.6244540257 20 185996.4107770663 30 0.0 11 535826.3290506108 21 185994.8411902611 31 0.0 0 LINE 5 6F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535884.9478042856 20 185988.4224090485 30 0.0 11 535863.3916885597 21 185999.1219561155 31 0.0 0 LINE 5 6F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535898.2305643401 20 185925.7164430408 30 0.0 11 535881.3163777869 21 185995.543176206 31 0.0 0 LINE 5 6F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536059.2279425693 20 186125.769405381 30 0.0 11 535994.0245275108 21 186470.9334808305 31 0.0 0 LINE 5 6F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536093.2954599856 20 186458.4035292444 30 0.0 11 536073.4867800939 21 186166.4737735018 31 0.0 0 LINE 5 6F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536200.7582953935 20 186184.3582513239 30 0.0 11 536195.5741412019 21 186219.5025008576 31 0.0 0 LINE 5 6FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535897.5531420586 20 186494.1360598406 30 0.0 11 535909.2141336433 21 186315.9941943792 31 0.0 0 LINE 5 6FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536121.1503608934 20 185921.4462868624 30 0.0 11 536100.6405274615 21 185963.7482569175 31 0.0 0 LINE 5 6FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536162.2437088341 20 185980.402945287 30 0.0 11 536099.5637782036 21 185962.1814210873 31 0.0 0 LINE 5 700 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536197.7248129734 20 185945.8102177876 30 0.0 11 536180.1063811039 21 186048.6330454697 31 0.0 0 LINE 5 701 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536331.0425782463 20 186054.2048949611 30 0.0 11 536032.9227071588 21 186037.3741550549 31 0.0 0 LINE 5 702 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535973.3674328742 20 185958.8698365539 30 0.0 11 535952.2940349445 21 186024.4097148881 31 0.0 0 LINE 5 703 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535982.8930652049 20 186033.2214834902 30 0.0 11 535925.6186659056 21 186014.9947135762 31 0.0 0 LINE 5 704 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535979.8512915146 20 186025.1708951824 30 0.0 11 535958.9768792235 21 186093.3818534568 31 0.0 0 LINE 5 705 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535962.3826766682 20 186091.8919271197 30 0.0 11 535908.4762301635 21 186076.2175907711 31 0.0 0 LINE 5 706 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535932.7143681951 20 186009.4008907609 30 0.0 11 535909.2139455117 21 186083.2508598345 31 0.0 0 LINE 5 707 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536145.9352710763 20 185727.8028134352 30 0.0 11 535904.4951732374 21 185619.541883666 31 0.0 0 LINE 5 708 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536656.4544441961 20 187136.1251621236 30 0.0 11 537180.346752627 21 187503.3080437654 31 0.0 0 LINE 5 709 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536515.4172762577 20 187784.5523831475 30 0.0 11 537317.0023862222 21 185624.0405922396 31 0.0 0 LINE 5 70A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536777.6597608433 20 187067.7809166893 30 0.0 11 536906.3904576726 21 187140.4865038101 31 0.0 0 LINE 5 70B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536788.6769991006 20 187232.0387480244 30 0.0 11 536958.0668608531 21 186767.5049155334 31 0.0 0 LINE 5 70C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536874.5848913998 20 187133.126055273 30 0.0 11 536956.4850630701 21 187129.4572496127 31 0.0 0 LINE 5 70D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536885.4891276186 20 187212.0970198499 30 0.0 11 536882.7489547515 21 187124.2908701058 31 0.0 0 LINE 5 70E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536876.2998669652 20 187195.4453712998 30 0.0 11 537040.0932225991 21 187308.2548985325 31 0.0 0 LINE 5 70F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536827.560160896 20 187307.9410842041 30 0.0 11 537125.289121818 21 186993.5898679707 31 0.0 0 LINE 5 710 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537077.3380654208 20 187266.3382699572 30 0.0 11 536952.6615164215 21 187127.4296781066 31 0.0 0 LINE 5 711 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537034.7521778992 20 187309.4666366411 30 0.0 11 537077.3283545836 21 187265.49062204 31 0.0 0 LINE 5 712 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537271.3286449298 20 187489.6990656824 30 0.0 11 537061.5184214732 21 187279.1625218589 31 0.0 0 LINE 5 713 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537220.5059177099 20 187443.88729939 30 0.0 11 537294.9987336095 21 187358.7484616252 31 0.0 0 LINE 5 714 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537352.1225316942 20 187416.831822214 30 0.0 11 536770.3320429272 21 186853.4430962436 31 0.0 0 LINE 5 715 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537019.3396568531 20 186999.2648424513 30 0.0 11 537251.2580226249 21 186626.306883402 31 0.0 0 LINE 5 716 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536966.6307444098 20 186953.9724857423 30 0.0 11 537118.2633265551 21 187074.8735946857 31 0.0 0 LINE 5 717 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537012.7496896793 20 186897.8882536064 30 0.0 11 537062.6995511437 21 186938.3932785016 31 0.0 0 LINE 5 718 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536964.7079194511 20 186923.3687037914 30 0.0 11 537028.6278447282 21 186897.8442316993 31 0.0 0 LINE 5 719 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537013.8976801362 20 186912.0247118622 30 0.0 11 537205.2581714437 21 186557.0905487869 31 0.0 0 LINE 5 71A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536896.0044335675 20 186741.8456366742 30 0.0 11 537266.6056255017 21 186910.8617624756 31 0.0 0 LINE 5 71B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537258.3171737836 20 186921.2828259197 30 0.0 11 537370.0700804652 21 186710.2210824861 31 0.0 0 LINE 5 71C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537361.9414964869 20 187081.1821708461 30 0.0 11 537255.7006555645 21 186903.3626960374 31 0.0 0 LINE 5 71D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537274.8819629169 20 187085.9384358377 30 0.0 11 537335.5830477656 21 187025.8826446133 31 0.0 0 LINE 5 71E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536958.9961435952 20 186565.5135013908 30 0.0 11 537038.9113655967 21 186607.1746138472 31 0.0 0 LINE 5 71F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536957.6237427116 20 186485.1227390502 30 0.0 11 537371.0851352754 21 186713.1530580203 31 0.0 0 LINE 5 720 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537097.0737156445 20 187028.1241264085 30 0.0 11 537313.8546541034 21 186663.650188972 31 0.0 0 LINE 5 721 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537553.1330599754 20 186913.1132527656 30 0.0 11 537307.0616539335 21 186662.0663884133 31 0.0 0 LINE 5 722 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537799.5835817962 20 187209.4810507865 30 0.0 11 537635.4473220064 21 187033.5368753194 31 0.0 0 LINE 5 723 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537031.5442058048 20 187444.7080065458 30 0.0 11 537403.263134856 21 187022.4017121923 31 0.0 0 LINE 5 724 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537402.7212590529 20 187009.3351083603 30 0.0 11 537420.8248222389 21 187025.5220034305 31 0.0 0 LINE 5 725 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537390.0722291867 20 186819.6161142883 30 0.0 11 537434.9476668381 21 186776.2380761014 31 0.0 0 LINE 5 726 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537374.7647574835 20 186822.2631873493 30 0.0 11 537398.078434724 21 186816.2950313399 31 0.0 0 LINE 5 727 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537323.7656201309 20 186783.4359047135 30 0.0 11 537382.1643115266 21 186825.2862955662 31 0.0 0 LINE 5 728 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537502.3608783106 20 187480.7089753924 30 0.0 11 537713.225832049 21 187395.0985889557 31 0.0 0 LINE 5 729 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537333.3361530685 20 187410.4756193646 30 0.0 11 537532.0891822454 21 187493.0617158058 31 0.0 0 LINE 5 72A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537278.6197715838 20 187627.3482159066 30 0.0 11 537166.0865990719 21 187491.2134684705 31 0.0 0 LINE 5 72B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537197.2669548719 20 187546.6372350203 30 0.0 11 537397.2796850536 21 187375.3663122469 31 0.0 0 LINE 5 72C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537152.1190506236 20 186925.7346225763 30 0.0 11 537195.271841091 21 186944.3879497008 31 0.0 0 LINE 5 72D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537159.4812683694 20 186997.2213246088 30 0.0 11 537195.0645548211 21 186942.4981359836 31 0.0 0 LINE 5 72E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537110.0209214624 20 186994.1816485354 30 0.0 11 537190.4945867636 21 187060.5663774045 31 0.0 0 LINE 5 72F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537079.7999997003 20 187163.3257541517 30 0.0 11 537294.6338995522 21 186955.9489791322 31 0.0 0 LINE 5 730 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537288.4946466848 20 186857.6023051026 30 0.0 11 537347.2452102594 21 186893.4901168504 31 0.0 0 LINE 5 731 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537329.8196174723 20 186920.1415077109 30 0.0 11 537361.3048608085 21 186868.9433494563 31 0.0 0 LINE 5 732 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537326.8678900417 20 186912.0574700774 30 0.0 11 537387.2115405508 21 186950.0984974087 31 0.0 0 LINE 5 733 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537383.6589948769 20 186951.1933745518 30 0.0 11 537414.259416117 21 186904.1274206714 31 0.0 0 LINE 5 734 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537352.2780301041 20 186869.3385356161 30 0.0 11 537418.292279855 21 186909.9366467582 31 0.0 0 LINE 5 735 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537012.3990757676 20 186374.590466218 30 0.0 11 537201.1498642903 21 186504.5889459221 31 0.0 0 LINE 5 736 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537056.5950085385 20 186425.7206142945 30 0.0 11 537284.7500739119 21 186189.0438679987 31 0.0 0 LINE 5 737 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537236.7990175147 20 186461.792269985 30 0.0 11 537112.1224685155 21 186322.8836781344 31 0.0 0 LINE 5 738 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537194.2131299931 20 186504.9206366692 30 0.0 11 537236.7893066778 21 186460.944622068 31 0.0 0 LINE 5 739 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537430.7895970239 20 186685.1530657104 30 0.0 11 537220.9793735673 21 186474.6165218867 31 0.0 0 LINE 5 73A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537433.9827303069 20 186541.0103316215 30 0.0 11 536968.8066354515 21 186086.6767533849 31 0.0 0 LINE 5 73B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537178.8006089473 20 186194.7188424793 30 0.0 11 537318.9589671305 21 185969.3241220662 31 0.0 0 LINE 5 73C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537126.0916965039 20 186149.4264857703 30 0.0 11 537277.724278649 21 186270.3275947137 31 0.0 0 LINE 5 73D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537172.2106417733 20 186093.3422536341 30 0.0 11 537222.1605032379 21 186133.8472785297 31 0.0 0 LINE 5 73E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537124.1688715451 20 186118.8227038192 30 0.0 11 537188.0887968223 21 186093.2982317269 31 0.0 0 LINE 5 73F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537173.3586322302 20 186107.4787118903 30 0.0 11 537364.7191235379 21 185752.5445488149 31 0.0 0 LINE 5 740 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537155.5330697457 20 185983.0593038168 30 0.0 11 537426.066577596 21 186106.3157625034 31 0.0 0 LINE 5 741 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537417.7781258776 20 186116.7368259474 30 0.0 11 537529.5310325594 21 185905.6750825138 31 0.0 0 LINE 5 742 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537503.9215296564 20 186247.3776691965 30 0.0 11 537415.1616076585 21 186098.816696065 31 0.0 0 LINE 5 743 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537276.0178131017 20 186420.2443479916 30 0.0 11 537495.0439998595 21 186221.3366446411 31 0.0 0 LINE 5 744 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537256.5346677385 20 186223.5781264364 30 0.0 11 537473.3156061973 21 185859.104189 31 0.0 0 LINE 5 745 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537826.3898014322 20 186263.1340956899 30 0.0 11 537506.7061623534 21 186088.9441168782 31 0.0 0 LINE 5 746 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537726.2167847417 20 186300.4072588124 30 0.0 11 537767.9602569887 21 186190.6483855762 31 0.0 0 LINE 5 747 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537685.6628467619 20 186253.3924978269 30 0.0 11 537789.1827203455 21 186216.6605409855 31 0.0 0 LINE 5 748 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537191.005157899 20 186640.1620065737 30 0.0 11 537397.7097547258 21 186397.5140548614 31 0.0 0 LINE 5 749 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537376.1880186199 20 186413.0837926604 30 0.0 11 537776.5833744317 21 186447.6586735969 31 0.0 0 LINE 5 74A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537663.9550437875 20 186459.7391990096 30 0.0 11 537680.1027461536 21 186293.6964840227 31 0.0 0 LINE 5 74B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537676.4551569747 20 186317.7023488992 30 0.0 11 537694.4058185397 21 186236.2753509728 31 0.0 0 LINE 5 74C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537665.2983288273 20 186310.7888695116 30 0.0 11 537741.541111767 21 186286.0666999599 31 0.0 0 LINE 5 74D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537816.0225515165 20 186373.4536291914 30 0.0 11 537729.6996959669 21 186281.6907654688 31 0.0 0 LINE 5 74E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537341.3908721648 20 186732.9116298796 30 0.0 11 537460.6349338569 21 186643.1579815403 31 0.0 0 LINE 5 74F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537311.5800027175 20 186121.188622604 30 0.0 11 537354.732793185 21 186139.8419497287 31 0.0 0 LINE 5 750 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537318.9422204634 20 186192.6753246367 30 0.0 11 537354.5255069153 21 186137.9521360115 31 0.0 0 LINE 5 751 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537269.4818735563 20 186189.6356485634 30 0.0 11 537349.9555388575 21 186256.0203774324 31 0.0 0 LINE 5 752 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537239.2609517944 20 186358.7797541795 30 0.0 11 537454.0948516461 21 186151.40297916 31 0.0 0 LINE 5 753 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537447.955598779 20 186053.0563051304 30 0.0 11 537506.7061623534 21 186088.9441168782 31 0.0 0 LINE 5 754 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537486.2387035479 20 186250.673700184 30 0.0 11 537520.7658129026 21 186064.3973494842 31 0.0 0 LINE 5 755 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537328.1695798477 20 186589.1920152922 30 0.0 11 537403.0583651141 21 186504.9528297262 31 0.0 0 LINE 5 756 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537781.9530081804 20 186249.6157882923 30 0.0 11 538347.5629563361 21 186352.7088830488 31 0.0 0 LINE 5 757 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537808.7806551505 20 186312.9346177544 30 0.0 11 538032.0195007378 21 186355.7589401335 31 0.0 0 LINE 5 758 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537695.1658971131 20 186461.2772245947 30 0.0 11 537835.4903706611 21 186556.8907161218 31 0.0 0 LINE 5 759 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537634.8336085112 20 186588.0147797442 30 0.0 11 538187.0293206833 21 185797.4692952484 31 0.0 0 LINE 5 75A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537812.9945125742 20 186453.201609507 30 0.0 11 538218.1599829396 21 186622.6852642468 31 0.0 0 LINE 5 75B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537849.3030504672 20 186393.945241889 30 0.0 11 537754.1263155464 21 186562.9153790184 31 0.0 0 LINE 5 75C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537912.0233530926 20 186430.531603359 30 0.0 11 537880.0009723833 21 186486.3008855473 31 0.0 0 LINE 5 75D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537879.2087033646 20 186387.1672886349 30 0.0 11 537914.5985604886 21 186446.1995978881 31 0.0 0 LINE 5 75E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537898.2507986851 20 186433.9189443802 30 0.0 11 538279.1561711739 21 186566.2374803479 31 0.0 0 LINE 5 75F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538047.4547373327 20 186290.3991899553 30 0.0 11 537939.6927833727 21 186683.2083745763 31 0.0 0 LINE 5 760 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537928.0834629505 20 186676.6875866997 30 0.0 11 538154.263771468 21 186753.3572660519 31 0.0 0 LINE 5 761 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537786.7525790449 20 186804.481882418 30 0.0 11 537945.3571269888 21 186671.247204977 31 0.0 0 LINE 5 762 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537768.1756487449 20 186719.2945470756 30 0.0 11 537837.1418002041 21 186769.6432284317 31 0.0 0 LINE 5 763 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538310.7182931293 20 186310.2960644154 30 0.0 11 538151.5311559336 21 186754.8268337236 31 0.0 0 LINE 5 764 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537796.8990297919 20 186534.5427282644 30 0.0 11 538191.2753803375 21 186690.4353851786 31 0.0 0 LINE 5 765 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537878.7102166998 20 187051.9664409037 30 0.0 11 538191.7557841509 21 186683.4767583245 31 0.0 0 LINE 5 766 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537774.1933872137 20 187223.955343289 30 0.0 11 538060.5889229859 21 186830.8401531596 31 0.0 0 LINE 5 767 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537795.9429602493 20 187010.4661386416 30 0.0 11 537910.9535407448 21 187034.1746624962 31 0.0 0 LINE 5 768 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537835.8899593667 20 186962.9346028185 30 0.0 11 537888.6580694558 21 187059.2732110594 31 0.0 0 LINE 5 769 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537948.1741042493 20 186809.6520217234 30 0.0 11 537843.9029074889 21 186982.6686362065 31 0.0 0 LINE 5 76A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537734.8794656979 20 186769.8160672527 30 0.0 11 538001.4046078766 21 186909.4294068588 31 0.0 0 LINE 5 76B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537676.3851448579 20 186854.8587612249 30 0.0 11 537393.6749490265 21 186911.1355924097 31 0.0 0 LINE 5 76C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537375.1962385819 20 186536.2752800831 30 0.0 11 537375.2067635943 21 186536.2819028361 31 0.0 0 LINE 5 76D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537627.9359291571 20 186708.8472713734 30 0.0 11 537851.369689718 21 186835.902403186 31 0.0 0 LINE 5 76E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537864.1827212604 20 186833.2840090631 30 0.0 11 537851.0895042071 21 186853.7369364632 31 0.0 0 LINE 5 76F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538049.4576268318 20 186790.5463905774 30 0.0 11 538085.1315570698 21 186818.5018529167 31 0.0 0 LINE 5 770 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538044.4036657193 20 186775.8568309237 30 0.0 11 538054.0127984559 21 186797.9206248104 31 0.0 0 LINE 5 771 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538074.6024632878 20 186719.3192105897 30 0.0 11 538042.5990825349 21 186783.6437470564 31 0.0 0 LINE 5 772 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537822.6206570225 20 186768.7814471842 30 0.0 11 537650.3374365978 21 187074.8994248929 31 0.0 0 LINE 5 773 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537647.1135840797 20 186930.989357222 30 0.0 11 537785.5072931152 21 186790.7532074953 31 0.0 0 LINE 5 774 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537668.1921883292 20 186397.4483159966 30 0.0 11 537658.8538896595 21 187097.8055382497 31 0.0 0 LINE 5 775 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537726.6033647893 20 186925.8085438502 30 0.0 11 537801.3756717691 21 186981.6739384116 31 0.0 0 LINE 5 776 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537770.9347203141 20 186964.0988260768 30 0.0 11 537854.1821676819 21 186968.8364149881 31 0.0 0 LINE 5 777 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537775.9808103146 20 186951.9823914832 30 0.0 11 537812.5434910686 21 187023.3078286975 31 0.0 0 LINE 5 778 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537709.2294004969 20 187154.7544464749 30 0.0 11 537814.9753444068 21 187010.9201727383 31 0.0 0 LINE 5 779 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537906.755485458 20 186572.5579692403 30 0.0 11 537895.2214540916 21 186618.1329191403 31 0.0 0 LINE 5 77A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537837.3572619683 20 186591.2244470575 30 0.0 11 537897.0540384935 21 186617.6269567964 31 0.0 0 LINE 5 77B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537660.6728702619 20 186539.0477106908 30 0.0 11 537899.6514691774 21 186718.0671526615 31 0.0 0 LINE 5 77C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537995.7610246206 20 186696.325209994 30 0.0 11 537929.2028703271 21 186849.182053773 31 0.0 0 LINE 5 77D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538012.4363585128 20 186408.4127906819 30 0.0 11 538266.8927353087 21 186480.9779480708 31 0.0 0 LINE 5 77E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537245.604479096 20 187219.2811807284 30 0.0 11 537128.0087242979 21 187101.6271531425 31 0.0 0 LINE 5 77F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537295.2785441242 20 187305.4625369827 30 0.0 11 537127.6708426229 21 187382.6557244311 31 0.0 0 LINE 5 780 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537853.8333755165 20 186584.479558069 30 0.0 11 537801.7029996276 21 186689.4205773728 31 0.0 0 LINE 5 781 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536899.7243153653 20 186743.5421234196 30 0.0 11 536800.9662122712 21 186571.7543786009 31 0.0 0 LINE 5 783 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535586.4734308382 20 184394.1960974984 30 0.0 11 535561.5356189229 21 184248.4710130359 31 0.0 0 LINE 5 784 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535435.5965996541 20 184328.331110552 30 0.0 11 535930.0442095312 21 184325.8475888641 31 0.0 0 LINE 5 785 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535557.7175357064 20 184280.8931118137 30 0.0 11 535588.8411184842 21 184205.0483964429 31 0.0 0 LINE 5 786 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535487.0743208422 20 184243.9492109997 30 0.0 11 535568.7914733332 21 184276.1941403529 31 0.0 0 LINE 5 787 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535499.6421604393 20 184258.2239901103 30 0.0 11 535448.8047659976 21 184065.9486351876 31 0.0 0 LINE 5 788 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535377.2944345197 20 184266.0902682582 30 0.0 11 535773.7507343056 21 184092.074109011 31 0.0 0 LINE 5 789 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535500.8400115718 20 184045.0556869529 30 0.0 11 535589.4576535479 21 184209.3321377636 31 0.0 0 LINE 5 78A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535445.8597739096 20 184070.5662199818 30 0.0 11 535501.6345348921 21 184045.3512101935 31 0.0 0 LINE 5 78B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535356.1543586029 20 183787.0083040362 30 0.0 11 535483.4250856285 21 184055.6123401087 31 0.0 0 LINE 5 78C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535382.1014906933 20 183850.3203397732 30 0.0 11 535487.4018487683 21 183808.9725961122 31 0.0 0 LINE 5 78D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535452.0335797415 20 183735.5839687168 30 0.0 11 535786.827845811 21 184479.9884451362 31 0.0 0 LINE 5 78E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535732.6137383202 20 184189.8761643216 30 0.0 11 536161.9960217083 21 184097.6014531979 31 0.0 0 LINE 5 78F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535757.4347432706 20 184254.7879871313 30 0.0 11 535694.8729741883 21 184071.2245290002 31 0.0 0 LINE 5 790 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535825.8026772756 20 184230.3293729652 30 0.0 11 535804.5553340466 21 184169.6317938717 31 0.0 0 LINE 5 791 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535785.5893105132 20 184266.9374343987 30 0.0 11 535831.2086497067 21 184215.3997645391 31 0.0 0 LINE 5 792 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535812.8853327367 20 184224.4727916954 30 0.0 11 536211.6009178603 21 184164.2815968987 31 0.0 0 LINE 5 793 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535933.2264621044 20 184392.9297529669 30 0.0 11 535899.3589393718 21 183987.0175886406 31 0.0 0 LINE 5 794 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535886.7503514801 20 183991.2978347278 30 0.0 11 536123.1576136287 21 183957.4248647315 31 0.0 0 LINE 5 795 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535771.2636298454 20 183839.7438249173 30 0.0 11 535902.732726932 21 183999.8149291566 31 0.0 0 LINE 5 796 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535737.3734085965 20 183920.0771140679 30 0.0 11 535814.406036274 21 183883.2356424019 31 0.0 0 LINE 5 797 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536201.106608945 20 184618.9043009928 30 0.0 11 536031.6290369863 21 184315.407156295 31 0.0 0 LINE 5 798 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536195.6719275892 20 184421.6693262116 30 0.0 11 536120.7409882194 21 183955.4789103561 31 0.0 0 LINE 5 799 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535731.7144123902 20 184106.9627553966 30 0.0 11 536147.9972755684 21 184026.0689721152 31 0.0 0 LINE 5 79A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535907.0643571541 20 183613.3305384817 30 0.0 11 536147.1928850759 21 184032.9976250471 31 0.0 0 LINE 5 79B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535798.3692882026 20 183384.4895215734 30 0.0 11 536045.2878480483 21 183864.0713718078 31 0.0 0 LINE 5 79C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535818.0882093698 20 183638.9418436739 30 0.0 11 535935.4963047334 21 183636.7357447668 31 0.0 0 LINE 5 79D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535848.6369751698 20 183692.9953592331 30 0.0 11 535918.1838751691 21 183607.9728352728 31 0.0 0 LINE 5 79E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535930.8938513525 20 183864.276079631 30 0.0 11 535860.13435468 21 183675.0663415311 31 0.0 0 LINE 5 79F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535681.4081269931 20 183875.025451509 30 0.0 11 536001.5261799184 21 183775.9579769436 31 0.0 0 LINE 5 7A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535704.284593427 20 183965.7628269584 30 0.0 11 535681.7619388092 21 183846.4305364603 31 0.0 0 LINE 5 7A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535587.1340509217 20 183884.7654212547 30 0.0 11 535657.5548369951 21 183982.8910746541 31 0.0 0 LINE 5 7A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535651.975287795 20 183979.1170519671 30 0.0 11 535705.7767228348 21 183964.1829808213 31 0.0 0 LINE 5 7A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535317.4870858738 20 184027.8933693026 30 0.0 11 535840.5484441047 21 183820.7113623827 31 0.0 0 LINE 5 7A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535852.6636240436 20 183825.6360126378 30 0.0 11 535843.5449650507 21 183803.1281333459 31 0.0 0 LINE 5 7A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536026.9531291101 20 183901.6390592341 30 0.0 11 536067.1503137992 21 183880.7028820203 31 0.0 0 LINE 5 7A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536019.289980287 20 183915.1520839083 30 0.0 11 536032.7838736293 21 183895.2256874684 31 0.0 0 LINE 5 7A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536038.6037317582 20 183976.2704026984 30 0.0 11 536018.9446260733 21 183907.1662643642 31 0.0 0 LINE 5 7A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535799.9732583504 20 183881.4187253341 30 0.0 11 535665.7081056945 21 183468.3446960213 31 0.0 0 LINE 5 7A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535655.1711830809 20 183498.3053767629 30 0.0 11 535854.5755331281 21 183470.8787938838 31 0.0 0 LINE 5 7AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535451.6689210649 20 183755.4131482404 30 0.0 11 535684.6932673409 21 183477.412754533 31 0.0 0 LINE 5 7AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535551.9427449507 20 183521.0592219379 30 0.0 11 535767.5207965271 21 183853.0110194557 31 0.0 0 LINE 5 7AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535647.9399360763 20 183900.109968144 30 0.0 11 535635.1479909715 21 183866.968455348 31 0.0 0 LINE 5 7AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535734.3941103009 20 183709.4413871868 30 0.0 11 535818.1464496484 21 183668.2420442983 31 0.0 0 LINE 5 7AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535784.997818753 20 183679.9341086515 30 0.0 11 535867.701463327 21 183690.5496357759 31 0.0 0 LINE 5 7AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535787.7353612302 20 183692.7706530751 30 0.0 11 535836.7629337048 21 183629.3636758962 31 0.0 0 LINE 5 7B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535759.317802778 20 183481.1939545241 30 0.0 11 535836.8808525597 21 183641.9872263462 31 0.0 0 LINE 5 7B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535229.0626630619 20 183733.640242334 30 0.0 11 535319.1722889316 21 183885.5502146886 31 0.0 0 LINE 5 7B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535277.5420608356 20 183837.4780543974 30 0.0 11 535506.3174597182 21 183707.0915593584 31 0.0 0 LINE 5 7B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535846.6805967275 20 184089.7471852094 30 0.0 11 535843.7035839816 21 184042.8297328804 31 0.0 0 LINE 5 7B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535781.8848576137 20 184058.6656310285 30 0.0 11 535845.4122390982 21 184043.6633162154 31 0.0 0 LINE 5 7B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535768.0352899427 20 184106.2445656752 30 0.0 11 535732.7426991815 21 184008.0744272857 31 0.0 0 LINE 5 7B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535598.6269255083 20 184077.5419763038 30 0.0 11 535866.3924957366 21 183945.4044315131 31 0.0 0 LINE 5 7B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535956.8819629148 20 183984.4097522817 30 0.0 11 535942.9537047379 21 183916.9889292629 31 0.0 0 LINE 5 7B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535911.9821283329 20 183924.3855077801 30 0.0 11 535970.8072088518 21 183912.0493066405 31 0.0 0 LINE 5 7B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535918.5935446724 20 183929.8949118557 30 0.0 11 535903.1769200424 21 183860.2472011814 31 0.0 0 LINE 5 7BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535900.9461733749 20 183863.2209372202 30 0.0 11 535955.5830900649 21 183850.3214360929 31 0.0 0 LINE 5 7BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535967.3854864592 20 183920.4118218448 30 0.0 11 535951.4779899194 21 183844.563029156 31 0.0 0 LINE 5 7BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535411.801821753 20 183916.0150905535 30 0.0 11 535516.3892101873 21 183873.9907080598 31 0.0 0 LINE 5 7BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535920.4534103485 20 184270.4946846228 30 0.0 11 536183.9037860471 21 184245.8441409534 31 0.0 0 LINE 5 7BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536459.1144204453 20 184515.8449592403 30 0.0 11 537050.7840434664 21 184508.4728549048 31 0.0 0 LINE 5 7BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536372.3224962037 20 184615.45444566 30 0.0 11 536372.6473193558 21 184370.2079044642 31 0.0 0 LINE 5 7C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535421.6860749543 20 184433.5942901648 30 0.0 11 536741.1559099641 21 184447.5844802925 31 0.0 0 LINE 5 7C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536368.8292361395 20 184402.6300032422 30 0.0 11 536399.9528189172 21 184326.7852878713 31 0.0 0 LINE 5 7C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536298.1860212753 20 184365.686102428 30 0.0 11 536379.9031737661 21 184397.9310317812 31 0.0 0 LINE 5 7C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536310.4646766277 20 184378.1616925207 30 0.0 11 536259.6272821861 21 184185.886337598 31 0.0 0 LINE 5 7C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536110.4724337224 20 184422.0345196693 30 0.0 11 536584.8624347385 21 184213.8110004394 31 0.0 0 LINE 5 7C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536311.9517120049 20 184166.7925783813 30 0.0 11 536400.5693539809 21 184331.069029192 31 0.0 0 LINE 5 7C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536256.9714743426 20 184192.3031114103 30 0.0 11 536312.7462353251 21 184167.0881016221 31 0.0 0 LINE 5 7C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536167.266059036 20 183908.7451954644 30 0.0 11 536294.5367860616 21 184177.349231537 31 0.0 0 LINE 5 7C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536193.2131911263 20 183972.0572312018 30 0.0 11 536298.5135492011 21 183930.7094875404 31 0.0 0 LINE 5 7C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536263.1452801746 20 183857.3208601452 30 0.0 11 536574.4665492171 21 184545.7616112611 31 0.0 0 LINE 5 7CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536543.7254387533 20 184311.6130557499 30 0.0 11 536973.1077221413 21 184219.3383446261 31 0.0 0 LINE 5 7CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536568.5464437036 20 184376.5248785597 30 0.0 11 536505.9846746213 21 184192.9614204287 31 0.0 0 LINE 5 7CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536636.9143777085 20 184352.0662643937 30 0.0 11 536615.6670344794 21 184291.3686853001 31 0.0 0 LINE 5 7CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536596.7010109462 20 184388.6743258272 30 0.0 11 536642.3203501395 21 184337.1366559674 31 0.0 0 LINE 5 7CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536623.9970331696 20 184346.2096831239 30 0.0 11 537022.7126182932 21 184286.0184883272 31 0.0 0 LINE 5 7CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536744.3381625373 20 184514.6666443953 30 0.0 11 536710.4706398047 21 184108.7544800689 31 0.0 0 LINE 5 7D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536697.8620519129 20 184113.0347261562 30 0.0 11 536934.2693140616 21 184079.16175616 31 0.0 0 LINE 5 7D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536582.3753302783 20 183961.4807163454 30 0.0 11 536713.8444273649 21 184121.5518205851 31 0.0 0 LINE 5 7D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536548.4851090295 20 184041.8140054961 30 0.0 11 536625.517736707 21 184004.9725338305 31 0.0 0 LINE 5 7D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536875.2099065892 20 184517.34910723 30 0.0 11 536862.9984506618 21 184428.0576107547 31 0.0 0 LINE 5 7D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537006.7836280222 20 184543.4062176398 30 0.0 11 536931.8526886525 21 184077.2158017846 31 0.0 0 LINE 5 7D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536542.8261128231 20 184228.6996468251 30 0.0 11 536959.1089760015 21 184147.8058635433 31 0.0 0 LINE 5 7D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536686.7698355978 20 183683.7674240936 30 0.0 11 536958.3045855089 21 184154.7345164754 31 0.0 0 LINE 5 7D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536629.1999098027 20 183760.6787351024 30 0.0 11 536746.6080051664 21 183758.472636195 31 0.0 0 LINE 5 7D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536659.7486756028 20 183814.7322506615 30 0.0 11 536729.295575602 21 183729.7097267011 31 0.0 0 LINE 5 7D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536742.0055517852 20 183986.0129710593 30 0.0 11 536671.246055113 21 183796.8032329595 31 0.0 0 LINE 5 7DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536492.5198274261 20 183996.7623429372 30 0.0 11 536812.6378803514 21 183897.694868372 31 0.0 0 LINE 5 7DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536515.3962938599 20 184087.4997183867 30 0.0 11 536492.8736392421 21 183968.1674278886 31 0.0 0 LINE 5 7DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536398.2457513548 20 184006.5023126832 30 0.0 11 536468.666537428 21 184104.6279660823 31 0.0 0 LINE 5 7DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536463.0869882278 20 184100.8539433953 30 0.0 11 536516.8884232679 21 184085.9198722496 31 0.0 0 LINE 5 7DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536128.598786307 20 184149.630260731 30 0.0 11 536651.6601445378 21 183942.4482538111 31 0.0 0 LINE 5 7DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536663.7753244765 20 183947.3729040663 30 0.0 11 536654.6566654839 21 183924.8650247745 31 0.0 0 LINE 5 7E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536838.0648295431 20 184023.3759506626 30 0.0 11 536878.262014232 21 184002.4397734485 31 0.0 0 LINE 5 7E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536830.40168072 20 184036.8889753371 30 0.0 11 536843.8955740622 21 184016.9625788967 31 0.0 0 LINE 5 7E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536849.7154321912 20 184098.007294127 30 0.0 11 536830.0563265061 21 184028.9031557928 31 0.0 0 LINE 5 7E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536611.0849587833 20 184003.1556167623 30 0.0 11 536507.6239143502 21 183663.5239624828 31 0.0 0 LINE 5 7E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536262.780621498 20 183877.1500396689 30 0.0 11 536390.3878227272 21 183717.9550317594 31 0.0 0 LINE 5 7E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536361.3818492996 20 183706.7303072926 30 0.0 11 536578.6324969599 21 183974.7479108842 31 0.0 0 LINE 5 7E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536459.0516365094 20 184021.8468595721 30 0.0 11 536446.2596914044 21 183988.7053467764 31 0.0 0 LINE 5 7E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536545.505810734 20 183831.1782786151 30 0.0 11 536629.2581500811 21 183789.9789357268 31 0.0 0 LINE 5 7E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536596.1095191861 20 183801.67100008 30 0.0 11 536678.81316376 21 183812.2865272042 31 0.0 0 LINE 5 7E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536598.8470616633 20 183814.5075445035 30 0.0 11 536647.8746341377 21 183751.1005673246 31 0.0 0 LINE 5 7EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536590.7903098636 20 183651.4745657494 30 0.0 11 536647.9925529926 21 183763.7241177747 31 0.0 0 LINE 5 7EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536092.1118655931 20 183976.7515162437 30 0.0 11 536317.4291601512 21 183828.8284507869 31 0.0 0 LINE 5 7EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536657.7922971604 20 184211.4840766378 30 0.0 11 536654.8152844146 21 184164.5666243088 31 0.0 0 LINE 5 7ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536592.9965580466 20 184180.4025224566 30 0.0 11 536656.5239395312 21 184165.4002076438 31 0.0 0 LINE 5 7EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536579.1469903754 20 184227.9814571035 30 0.0 11 536543.8543996145 21 184129.8113187139 31 0.0 0 LINE 5 7EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536409.7386259413 20 184199.2788677323 30 0.0 11 536677.5041961697 21 184067.1413229414 31 0.0 0 LINE 5 7F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536767.9936633479 20 184106.1466437101 30 0.0 11 536754.0654051708 21 184038.7258206911 31 0.0 0 LINE 5 7F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536723.0938287659 20 184046.1223992084 30 0.0 11 536781.9189092848 21 184033.786198069 31 0.0 0 LINE 5 7F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536729.7052451053 20 184051.6318032842 30 0.0 11 536714.2886204753 21 183981.9840926098 31 0.0 0 LINE 5 7F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536712.0578738078 20 183984.9578286487 30 0.0 11 536766.6947904981 21 183972.0583275212 31 0.0 0 LINE 5 7F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536778.4971868923 20 184042.148713273 30 0.0 11 536762.5896903524 21 183966.2999205845 31 0.0 0 LINE 5 7F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536222.9135221859 20 184037.7519819821 30 0.0 11 536327.5009106202 21 183995.7275994882 31 0.0 0 LINE 5 7F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536731.5651107815 20 184392.2315760508 30 0.0 11 536995.0154864801 21 184367.5810323819 31 0.0 0 LINE 5 7F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536695.8355699313 20 183725.3801674254 30 0.0 11 536789.8996370914 21 183158.1987582552 31 0.0 0 LINE 5 7F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536467.2987365435 20 183735.5527801813 30 0.0 11 536424.7170935654 21 183571.1760746548 31 0.0 0 LINE 5 7F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536021.4904705762 20 183831.9354238264 30 0.0 11 536750.7631994243 21 183634.3679990988 31 0.0 0 LINE 5 7FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536514.7086588478 20 183627.3811690832 30 0.0 11 536502.1850618724 21 183188.349851915 31 0.0 0 LINE 5 7FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536582.7476885168 20 183613.2278136884 30 0.0 11 536391.5573141017 21 183645.7202565448 31 0.0 0 LINE 5 7FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536569.5031594619 20 183541.8346721609 30 0.0 11 536506.194272646 21 183553.1320414237 31 0.0 0 LINE 5 7FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536599.2309034192 20 183587.3706608673 30 0.0 11 536555.6265312794 21 183534.1173581218 31 0.0 0 LINE 5 7FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536561.6618541108 20 183553.6529319524 30 0.0 11 536565.8153502428 21 183150.4410196515 31 0.0 0 LINE 5 7FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536747.1518353845 20 183461.7116351087 30 0.0 11 536341.0326863496 21 183430.4237615611 31 0.0 0 LINE 5 800 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536343.2477510256 20 183443.5535172205 30 0.0 11 536347.5029372484 21 183204.7697969143 31 0.0 0 LINE 5 801 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536175.2184971649 20 183533.3976634438 30 0.0 11 536354.2042462857 21 183429.1336547311 31 0.0 0 LINE 5 802 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536249.1202751502 20 183579.663327307 30 0.0 11 536225.0328846765 21 183497.7419175195 31 0.0 0 LINE 5 803 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536777.2915141768 20 183276.9074759882 30 0.0 11 536687.1952927396 21 183274.7253024385 31 0.0 0 LINE 5 804 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536432.7126278959 20 183615.0485669723 30 0.0 11 536419.2294763712 21 183191.193130562 31 0.0 0 LINE 5 805 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535973.3551159433 20 183363.2330692008 30 0.0 11 536390.3861526087 21 183209.9348118807 31 0.0 0 LINE 5 806 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535765.9509262584 20 183422.3573275007 30 0.0 11 536242.9275657301 21 183266.7582370015 31 0.0 0 LINE 5 807 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535984.4516391039 20 183455.1545628895 30 0.0 11 536000.9943142841 21 183338.8967991611 31 0.0 0 LINE 5 808 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536042.6845632144 20 183433.6153849628 30 0.0 11 535969.8389488495 21 183351.4015336484 31 0.0 0 LINE 5 809 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536224.8896984233 20 183379.7213448218 30 0.0 11 536026.8181654621 21 183419.4063443993 31 0.0 0 LINE 5 80A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536190.3202068777 20 183593.9325871916 30 0.0 11 536148.9637381762 21 183295.9104764247 31 0.0 0 LINE 5 80B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536123.5626722017 20 183656.0761439899 30 0.0 11 536235.0531643094 21 183607.9374309185 31 0.0 0 LINE 5 80C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536256.2599631653 20 183707.8087092746 30 0.0 11 536135.528785634 21 183704.3861753978 31 0.0 0 LINE 5 80D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536141.7794635759 20 183706.8968808336 30 0.0 11 536124.0364940552 21 183653.9553288545 31 0.0 0 LINE 5 80E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536288.6068926312 20 184011.3688704059 30 0.0 11 536288.6042152567 21 184011.3567267488 31 0.0 0 LINE 5 80F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536257.0943731896 20 183868.4388440262 30 0.0 11 536167.4768940855 21 183461.9645639813 31 0.0 0 LINE 5 810 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536174.2702873457 20 183450.7896110464 30 0.0 11 536150.5964115458 21 183456.202759544 31 0.0 0 LINE 5 811 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536277.091176984 20 183290.848499001 30 0.0 11 536262.8322347262 21 183247.8273444499 31 0.0 0 LINE 5 812 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536289.2094413577 20 183300.5682394452 30 0.0 11 536271.6895600724 21 183284.0697488365 31 0.0 0 LINE 5 813 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536352.6253766384 20 183291.2468103648 30 0.0 11 536281.2707242392 21 183299.6358479864 31 0.0 0 LINE 5 814 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536220.9379273907 20 183511.7003411787 30 0.0 11 535874.6134005037 21 183570.4289235953 31 0.0 0 LINE 5 815 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535920.839662087 20 183659.1692777822 30 0.0 11 536187.7191650914 21 183539.2080466986 31 0.0 0 LINE 5 816 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536215.1485471566 20 183664.7688771879 30 0.0 11 536180.3913818786 21 183672.1127992867 31 0.0 0 LINE 5 817 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536040.7043262499 20 183549.0189493377 30 0.0 11 536013.3862663467 21 183459.7689420341 31 0.0 0 LINE 5 818 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536019.6432443323 20 183494.3577599607 30 0.0 11 536043.3099346213 21 183414.4048362322 31 0.0 0 LINE 5 819 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536032.7520582591 20 183493.7020092531 30 0.0 11 535977.9736696914 21 183435.1915335789 31 0.0 0 LINE 5 81A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535819.3510827251 20 183488.0204039051 30 0.0 11 535990.454519467 21 183437.0879300813 31 0.0 0 LINE 5 81B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536434.0485002005 20 183498.8082347155 30 0.0 11 536387.2566181096 21 183494.2662408433 31 0.0 0 LINE 5 81C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536393.0330097161 20 183557.8190842093 30 0.0 11 536388.3519793497 21 183492.7123594973 31 0.0 0 LINE 5 81D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536437.7949375415 20 183579.0778556736 30 0.0 11 536335.2534120668 21 183598.2658359574 31 0.0 0 LINE 5 81E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536382.4476452358 20 183741.7422642311 30 0.0 11 536294.6954665122 21 183456.3332831664 31 0.0 0 LINE 5 81F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536347.6301763369 20 183373.220858017 30 0.0 11 536278.8510786098 21 183376.2207693881 31 0.0 0 LINE 5 820 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536281.2146543384 20 183407.9754765754 30 0.0 11 536278.4158529892 21 183347.936000665 31 0.0 0 LINE 5 821 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536287.7077531305 20 183402.327111559 30 0.0 11 536216.4929401491 21 183406.4412735882 31 0.0 0 LINE 5 822 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536219.0729416188 20 183409.1176385002 30 0.0 11 536215.050250384 21 183353.1229266965 31 0.0 0 LINE 5 823 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536286.1257915368 20 183352.6473372339 30 0.0 11 536208.7109628799 21 183356.2573375812 31 0.0 0 LINE 5 824 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536624.2465273168 20 183454.7991782079 30 0.0 11 536641.9181354303 21 183190.7888298772 31 0.0 0 LINE 5 832 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535735.2534055224 20 184715.4109906729 30 0.0 11 536165.5409591916 21 184803.3677343476 31 0.0 0 LINE 5 836 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535509.6257709515 20 184600.3551137814 30 0.0 11 536214.4735245573 21 184667.7356093472 31 0.0 0 LINE 5 837 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535933.8162550799 20 184510.3524146965 30 0.0 11 535889.0382171611 21 185121.0044603166 31 0.0 0 LINE 5 838 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535891.3770378981 20 184912.4309386843 30 0.0 11 536128.1126389638 21 184943.9273969149 31 0.0 0 LINE 5 83A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535720.2179529596 20 184854.8705574998 30 0.0 11 535798.7532048145 21 185134.6910814056 31 0.0 0 LINE 5 83B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536189.9053794 20 184532.9956358863 30 0.0 11 536125.7156833548 21 184945.8975290452 31 0.0 0 LINE 5 83C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535735.1870223283 20 184798.3292501815 30 0.0 11 536152.2614908992 21 184875.0372290103 31 0.0 0 LINE 5 83D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535789.271791806 20 185515.9908257694 30 0.0 11 536151.3875399865 21 184868.1170060862 31 0.0 0 LINE 5 842 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535694.3790202402 20 185135.4241570543 30 0.0 11 536071.6732173155 21 185063.2439938016 31 0.0 0 LINE 5 845 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536032.473398615 20 185000.676799044 30 0.0 11 536072.8788671299 21 185021.2081235834 31 0.0 0 LINE 5 846 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536024.6748928699 20 184987.2414354884 30 0.0 11 536038.3682737447 21 185007.031275125 31 0.0 0 LINE 5 847 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536043.3737126193 20 184925.9321863689 30 0.0 11 536024.4097767367 21 184995.2303213156 31 0.0 0 LINE 5 851 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535850.3203429926 20 184814.3890718129 30 0.0 11 535847.8147844659 21 184861.3340621145 31 0.0 0 LINE 5 852 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535785.8400994945 20 184846.119956075 30 0.0 11 535849.5149797025 21 184860.4833567355 31 0.0 0 LINE 5 853 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535771.5132817625 20 184389.55211422 30 0.0 11 535737.208628857 21 184897.2022592253 31 0.0 0 LINE 5 854 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535602.4017936732 20 184829.0854602525 30 0.0 11 535923.2220377361 21 184983.4165245147 31 0.0 0 LINE 5 85A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536367.6458885368 20 184582.1864207075 30 0.0 11 536587.2186660103 21 184682.9161934223 31 0.0 0 LINE 5 85B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536172.7078649907 20 184992.1615235455 30 0.0 11 536390.8634053164 21 184519.5335550324 31 0.0 0 LINE 5 85C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536269.0988258286 20 185042.6201202157 30 0.0 11 536573.4887323567 21 184351.0867622647 31 0.0 0 LINE 5 85D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536545.101286052 20 184585.5323099143 30 0.0 11 536975.3888397213 21 184673.4890535888 31 0.0 0 LINE 5 85E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536569.2689741861 20 184520.3744256831 30 0.0 11 536508.5543278837 21 184704.5570791448 31 0.0 0 LINE 5 85F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536637.8791548743 20 184544.1450233398 30 0.0 11 536617.2426144353 21 184605.0529776709 31 0.0 0 LINE 5 860 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536597.3000749455 20 184507.9427678797 30 0.0 11 536643.4348282493 21 184559.0195733847 31 0.0 0 LINE 5 861 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536625.0212937263 20 184550.1310688461 30 0.0 11 537024.321405087 21 184606.3139738869 31 0.0 0 LINE 5 862 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536735.5056521489 20 184490.2048948725 30 0.0 11 536713.875866871 21 184786.7056298909 31 0.0 0 LINE 5 863 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536701.2249184277 20 184782.5522579256 30 0.0 11 536937.9605194933 21 184814.0487161564 31 0.0 0 LINE 5 864 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536587.2664426376 20 184935.2587298225 30 0.0 11 536717.1209299521 21 184773.8750440749 31 0.0 0 LINE 5 865 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536552.5709523043 20 184855.2699344034 30 0.0 11 536629.9697800855 21 184891.3357245587 31 0.0 0 LINE 5 866 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536985.3667351677 20 184480.2953076949 30 0.0 11 536935.5635638845 21 184816.0188482864 31 0.0 0 LINE 5 867 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536545.0349028581 20 184668.4505694229 30 0.0 11 536962.1093714287 21 184745.1585482518 31 0.0 0 LINE 5 868 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536694.4454183708 20 185211.9093264152 30 0.0 11 536961.235420516 21 184738.2383253276 31 0.0 0 LINE 5 869 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536636.1057933771 20 185135.5802082968 30 0.0 11 536753.5301258957 21 185136.6067860254 31 0.0 0 LINE 5 86A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536666.1100292685 20 185081.2225458677 30 0.0 11 536736.5075044353 21 185165.5421543244 31 0.0 0 LINE 5 86B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536746.6421737969 20 184909.1241654075 30 0.0 11 536677.7869326034 21 185099.0351633024 31 0.0 0 LINE 5 86C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536497.061055924 20 184900.8815167933 30 0.0 11 536818.1581281305 21 184996.7282827578 31 0.0 0 LINE 5 86D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536519.0248759599 20 184809.918916625 30 0.0 11 536497.7020969032 21 184929.4714348748 31 0.0 0 LINE 5 86E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536466.5840612846 20 184797.0908326885 30 0.0 11 536520.5328002478 21 184811.4836940305 31 0.0 0 LINE 5 86F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536131.6227593306 20 184751.6770401758 30 0.0 11 536656.7389495195 21 184953.5942392125 31 0.0 0 LINE 5 870 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536668.8040481505 20 184948.548135754 30 0.0 11 536659.91194963 21 184971.1464798513 31 0.0 0 LINE 5 871 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536842.3212791448 20 184870.7981182857 30 0.0 11 536882.7267476596 21 184891.3294428248 31 0.0 0 LINE 5 872 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536834.5227733995 20 184857.3627547297 30 0.0 11 536848.2161542742 21 184877.1525943664 31 0.0 0 LINE 5 873 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536853.2215931489 20 184796.0535056102 30 0.0 11 536834.2576572664 21 184865.3516405568 31 0.0 0 LINE 5 874 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536615.5559820213 20 184893.2975328055 30 0.0 11 536515.5118895682 21 185233.9513568983 31 0.0 0 LINE 5 875 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536268.5349937502 20 185022.7956043346 30 0.0 11 536397.7349320228 21 185180.7007160287 31 0.0 0 LINE 5 876 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536368.8431788377 20 185192.2162503954 30 0.0 11 536583.390524052 21 184922.0298029087 31 0.0 0 LINE 5 877 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536463.342569983 20 184876.1344667894 30 0.0 11 536450.8841896643 21 184909.4028074425 31 0.0 0 LINE 5 878 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536551.7077219273 20 185065.9249616169 30 0.0 11 536635.8696988342 21 185106.2809010026 31 0.0 0 LINE 5 879 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536602.6052891701 20 185094.9224174441 30 0.0 11 536685.1981237456 21 185083.4766357432 31 0.0 0 LINE 5 87A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536605.2137454526 20 185082.0590210273 30 0.0 11 536654.875791868 21 185144.9702979461 31 0.0 0 LINE 5 87B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536598.7951296876 20 185245.1647069569 30 0.0 11 536654.8668963114 21 185132.3461998914 31 0.0 0 LINE 5 87C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536096.8743136659 20 184924.9135871356 30 0.0 11 536323.666184154 21 185070.5657893215 31 0.0 0 LINE 5 87D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536660.1682235223 20 184684.5103910543 30 0.0 11 536657.6626649958 21 184731.455381356 31 0.0 0 LINE 5 87E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536595.6879800242 20 184716.2412753165 30 0.0 11 536659.362860232 21 184730.6046759769 31 0.0 0 LINE 5 87F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536581.3611622921 20 184668.8038656017 30 0.0 11 536547.0565093866 21 184767.3235784669 31 0.0 0 LINE 5 880 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536412.2496742029 20 184699.2067794937 30 0.0 11 536681.3291069041 21 184828.6478480936 31 0.0 0 LINE 5 881 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536771.4221847498 20 184788.7354935804 30 0.0 11 536758.1718976634 21 184856.292829559 31 0.0 0 LINE 5 882 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536727.1275824649 20 184849.2077457455 30 0.0 11 536786.0736168213 21 184860.9524036919 31 0.0 0 LINE 5 883 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536733.6833211163 20 184843.6322054112 30 0.0 11 536718.9671126245 21 184913.4312679034 31 0.0 0 LINE 5 884 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536716.7066061798 20 184910.4800906235 30 0.0 11 536771.4703465928 21 184922.8300918665 31 0.0 0 LINE 5 885 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536782.5680623663 20 184852.6246829575 30 0.0 11 536767.4232990065 21 184928.6294455796 31 0.0 0 LINE 5 886 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536227.0565971623 20 184862.6022458617 30 0.0 11 536332.060859742 21 184903.5738870732 31 0.0 0 LINE 5 887 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536703.092679131 20 185170.207613885 30 0.0 11 536802.8495574758 21 185736.4154951988 31 0.0 0 LINE 5 888 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536653.0321400727 20 185217.3556704263 30 0.0 11 536690.4029275054 21 185441.5719254414 31 0.0 0 LINE 5 889 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536474.4651889979 20 185162.3312555545 30 0.0 11 536433.5369223055 21 185327.1274163836 31 0.0 0 LINE 5 88A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536027.7112157658 20 185070.4317919967 30 0.0 11 536758.9317897254 21 185260.6634207374 31 0.0 0 LINE 5 88B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536522.959344978 20 185270.0211576637 30 0.0 11 536455.699115787 21 185786.0925192186 31 0.0 0 LINE 5 88C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536591.1371176031 20 185283.4903204848 30 0.0 11 536399.6299907303 21 185252.9200985578 31 0.0 0 LINE 5 88D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536578.6104286209 20 185355.0129062195 30 0.0 11 536515.1912496727 21 185344.3520693082 31 0.0 0 LINE 5 88E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536607.879245957 20 185309.1805883639 30 0.0 11 536564.8120240138 21 185362.8692269859 31 0.0 0 LINE 5 88F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536570.6507999075 20 185343.2740116868 30 0.0 11 536630.0084509401 21 185657.4002796109 31 0.0 0 LINE 5 890 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536331.3764837016 20 185274.9186586766 30 0.0 11 536360.0073551307 21 185694.2908528184 31 0.0 0 LINE 5 891 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536131.5448419101 20 185245.2568437803 30 0.0 11 536243.5132806817 21 185292.273162709 31 0.0 0 LINE 5 892 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536263.7157637863 20 185192.1938929543 30 0.0 11 536143.0250585699 21 185196.8290456603 31 0.0 0 LINE 5 893 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536149.2502001165 20 185194.2556764203 30 0.0 11 536132.0399442671 21 185247.3727921829 31 0.0 0 LINE 5 894 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536293.0116815622 20 184888.3241108541 30 0.0 11 536293.0091263105 21 184888.3362807939 31 0.0 0 LINE 5 895 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536262.9365396879 20 185031.563481014 30 0.0 11 536186.7930930003 21 185659.8411021697 31 0.0 0 LINE 5 896 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536368.966370536 20 185451.3462593905 30 0.0 11 535883.4684907984 21 185333.4005347594 31 0.0 0 LINE 5 897 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535705.8904213834 20 185192.8603974879 30 0.0 11 536236.2722789427 21 185347.2694557663 31 0.0 0 LINE 5 898 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536223.0387739137 20 185235.6445335389 30 0.0 11 536188.2095898026 21 185228.6501311959 31 0.0 0 LINE 5 899 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536545.7749020496 20 185506.3403822074 30 0.0 11 536396.8509260806 21 185404.4096746278 31 0.0 0 LINE 5 89A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536401.9886132652 20 185340.8020118011 30 0.0 11 536397.9618413939 21 185405.9524742422 31 0.0 0 LINE 5 89B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536389.5562031839 20 185156.9944459336 30 0.0 11 536322.8218062403 21 185382.0687006323 31 0.0 0 LINE 5 89E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536074.9532183286 20 185122.5485679805 30 0.0 11 536236.5382793906 21 184989.6285783852 31 0.0 0 LINE 5 89F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536414.0357339334 20 185353.9101287031 30 0.0 11 536297.5220622345 21 185341.469954668 31 0.0 0 LINE 5 8A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535933.5172575562 20 184514.429937026 30 0.0 11 536060.3141642157 21 184362.1580201859 31 0.0 0 LINE 5 8A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537477.0561138507 20 187928.2588438897 30 0.0 11 537648.2829715595 21 185028.8175773283 31 0.0 0 LINE 5 8A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537726.5507136519 20 187131.1942189549 30 0.0 11 537653.7532900338 21 187419.2442196735 31 0.0 0 LINE 5 8A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537192.3049867737 20 187262.0692319707 30 0.0 11 537721.8503967186 21 187225.0229891532 31 0.0 0 LINE 5 8A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537344.6652379133 20 187445.065864851 30 0.0 11 537395.6850929626 21 187218.5848226858 31 0.0 0 LINE 5 8A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537340.5091686917 20 187073.0513562111 30 0.0 11 537659.2540033284 21 187059.0562025004 31 0.0 0 LINE 5 8A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537460.6349338569 20 186643.1579815403 30 0.0 11 537687.0150856387 21 186633.5398320825 31 0.0 0 LINE 5 8A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537391.191286337 20 187276.4319337291 30 0.0 11 537350.1318901424 21 187036.2308251472 31 0.0 0 LINE 5 8A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537591.6890055485 20 187284.1217651576 30 0.0 11 537594.5541466836 21 186994.0394027349 31 0.0 0 LINE 5 8A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537644.0726228921 20 185220.5275972164 30 0.0 11 537601.0638613992 21 181721.5800113643 31 0.0 0 LINE 5 8AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536779.5233751413 20 185481.8898698351 30 0.0 11 536524.1838228082 21 185503.1272773228 31 0.0 0 LINE 5 8AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537442.3737651119 20 185653.3438155586 30 0.0 11 537504.9645686496 21 185218.641435863 31 0.0 0 LINE 5 8AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537682.705819199 20 185657.090434018 30 0.0 11 537318.0003070827 21 185647.5284239513 31 0.0 0 LINE 5 8AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537512.6729933498 20 185580.0044745308 30 0.0 11 537448.3743816385 21 185578.8493840094 31 0.0 0 LINE 5 8AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537702.4601705908 20 185535.7373255553 30 0.0 11 537310.0515201883 21 185426.5258548515 31 0.0 0 LINE 5 8AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537309.6864577988 20 185439.8361412739 30 0.0 11 537360.0247466008 21 185206.3798747624 31 0.0 0 LINE 5 8B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537127.4578714785 20 185495.5006999384 30 0.0 11 537323.2240027454 21 185427.806507056 31 0.0 0 LINE 5 8B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537191.0210346118 20 185555.1807530092 30 0.0 11 537183.2257022997 21 185470.1480971908 31 0.0 0 LINE 5 8B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537751.9121436832 20 185436.0956015051 30 0.0 11 537663.9375196824 21 185416.53654911 31 0.0 0 LINE 5 8B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537820.5566786869 20 185299.6085467093 30 0.0 11 537357.3606357392 21 185207.9702615446 31 0.0 0 LINE 5 8B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537364.3088697837 20 185625.3918159156 30 0.0 11 537433.0228561571 21 185206.9260294692 31 0.0 0 LINE 5 8B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536962.3002130862 20 185289.5206968154 30 0.0 11 537439.2408833411 21 185210.0866328064 31 0.0 0 LINE 5 8B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536709.953957186 20 185311.975009698 30 0.0 11 537245.4382083907 21 185246.98160248 31 0.0 0 LINE 5 8B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536955.4164714151 20 185381.8532908917 30 0.0 11 536994.1228419815 21 185270.9869542205 31 0.0 0 LINE 5 8B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537016.7149015927 20 185371.9784696792 30 0.0 11 536961.1377379927 21 185277.2326002901 31 0.0 0 LINE 5 8B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537205.9017999561 20 185354.3263778232 30 0.0 11 537003.8948273027 21 185354.9700862593 31 0.0 0 LINE 5 8BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537121.0637200125 20 185778.5458884923 30 0.0 11 537147.6111499923 21 185257.4181055872 31 0.0 0 LINE 5 8BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537142.4979307457 20 185414.2677876428 30 0.0 11 537118.2241694152 21 185415.0020102937 31 0.0 0 LINE 5 8BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537274.2999987925 20 185277.2221400399 30 0.0 11 537268.6272185847 21 185232.2559667765 31 0.0 0 LINE 5 8BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537284.3105543463 20 185289.1013009212 30 0.0 11 537270.3108034533 21 185269.5269961427 31 0.0 0 LINE 5 8BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537348.3321920717 20 185292.2157496004 30 0.0 11 537276.7018629033 21 185286.6517299696 31 0.0 0 LINE 5 8BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537176.5094565962 20 185483.0515196001 30 0.0 11 536742.5172056709 21 185465.5012760965 31 0.0 0 LINE 5 8C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536766.9536079009 20 185485.7875121864 30 0.0 11 536810.4861386002 21 185289.2697495361 31 0.0 0 LINE 5 8C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536752.440527201 20 185590.4929007661 30 0.0 11 537138.5994012306 21 185503.6181851989 31 0.0 0 LINE 5 8C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536992.4613792804 20 185484.8220369056 30 0.0 11 536982.9131431991 21 185391.9744661871 31 0.0 0 LINE 5 8C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536982.365121138 20 185427.1203873002 30 0.0 11 537021.0423958639 21 185353.2512417675 31 0.0 0 LINE 5 8C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536995.3534031598 20 185429.011297577 30 0.0 11 536952.9201089633 21 185361.0145097018 31 0.0 0 LINE 5 8C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536787.0767849401 20 185382.1806740374 30 0.0 11 536964.7988744056 21 185365.2880167373 31 0.0 0 LINE 5 8C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537388.0919537572 20 185511.6026937876 30 0.0 11 537343.0609218514 21 185498.100245733 31 0.0 0 LINE 5 8C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537336.4418470921 20 185561.5708566427 30 0.0 11 537344.4360258606 21 185496.7874424549 31 0.0 0 LINE 5 8C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537376.2494139416 20 185591.0822640697 30 0.0 11 537271.932843452 21 185590.0841882765 31 0.0 0 LINE 5 8C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537290.498835642 20 185739.9777673537 30 0.0 11 537259.5794679108 21 185442.9883331271 31 0.0 0 LINE 5 8CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537327.5834193336 20 185371.6775954408 30 0.0 11 537259.5219198117 21 185361.3240436236 31 0.0 0 LINE 5 8CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537255.7018576593 20 185392.9366209298 30 0.0 11 537264.5631191268 21 185333.4887445855 31 0.0 0 LINE 5 8CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537263.1644422948 20 185388.65010838 30 0.0 11 537192.497763957 21 185378.918896233 31 0.0 0 LINE 5 8CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537194.511677977 20 185382.0435541413 30 0.0 11 537201.3901762668 21 185326.3275236292 31 0.0 0 LINE 5 8CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537271.2167753149 20 185339.6017392693 30 0.0 11 537194.5645167913 21 185328.1772453325 31 0.0 0 LINE 5 8CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537929.3346989562 20 185271.5668162964 30 0.0 11 538198.9327271872 21 184527.868208749 31 0.0 0 LINE 5 8D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537979.076304023 20 185143.0004105447 30 0.0 11 537833.7609421401 21 185115.7765183631 31 0.0 0 LINE 5 8D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537864.912350873 20 185261.6115672493 30 0.0 11 538034.3022126254 21 184797.0777347585 31 0.0 0 LINE 5 8D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537862.8389685585 20 185130.6169573129 30 0.0 11 537802.5241558244 21 185075.0901924201 31 0.0 0 LINE 5 8D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537803.6606153359 20 185184.0326677696 30 0.0 11 537862.278393451 21 185118.6003778122 31 0.0 0 LINE 5 8D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537791.3098488985 20 185379.6317312794 30 0.0 11 537760.7998573019 21 184862.4547331083 31 0.0 0 LINE 5 8D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537398.0762367352 20 185145.7665578626 30 0.0 11 537395.8723393784 21 185032.6606599039 31 0.0 0 LINE 5 8D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537314.7685022459 20 185040.3400275386 30 0.0 11 538068.478175064 21 184987.488069622 31 0.0 0 LINE 5 8D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537838.2277014728 20 184934.9972958472 30 0.0 11 537936.9033700488 21 184444.3422736906 31 0.0 0 LINE 5 8D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537907.7193585047 20 184934.2647453819 30 0.0 11 537713.8542434436 21 184929.1819042397 31 0.0 0 LINE 5 8D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537908.5269297106 20 184861.6579548194 30 0.0 11 537844.2283179992 21 184860.5028642978 31 0.0 0 LINE 5 8DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537928.8904968241 20 184912.0820578129 30 0.0 11 537896.4040596111 21 184851.4035037743 31 0.0 0 LINE 5 8DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537898.5487650536 20 184871.7373181024 30 0.0 11 537927.1449354257 21 184734.1017373799 31 0.0 0 LINE 5 8DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538098.3141069516 20 184817.3908058439 30 0.0 11 537329.9835135775 21 184606.5084133261 31 0.0 0 LINE 5 8DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537705.5403941596 20 184721.4896215623 30 0.0 11 537772.8875289665 21 184417.2423231482 31 0.0 0 LINE 5 8DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538148.8034751078 20 184702.7591116822 30 0.0 11 538060.8288511072 21 184683.2000592873 31 0.0 0 LINE 5 8DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537760.1628061444 20 184907.0452962041 30 0.0 11 537836.5749717135 21 184441.6978662771 31 0.0 0 LINE 5 8E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537525.1910752361 20 184873.6698417635 30 0.0 11 537539.4957322885 21 184445.6458203916 31 0.0 0 LINE 5 8E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537542.1562393378 20 185268.0292053734 30 0.0 11 537529.5262136854 21 184705.572050634 31 0.0 0 LINE 5 8E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537572.3633929569 20 184764.7049998887 30 0.0 11 537044.7432192317 21 184733.545769042 31 0.0 0 LINE 5 8E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537333.2367947538 20 185047.5685480215 30 0.0 11 537228.2679305992 21 184872.616594883 31 0.0 0 LINE 5 8E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537207.6682683828 20 184895.9188447834 30 0.0 11 537534.4533375916 21 184785.2716654875 31 0.0 0 LINE 5 8E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537388.3153156413 20 184766.4755171942 30 0.0 11 537367.4725160221 21 184552.8193007415 31 0.0 0 LINE 5 8E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537235.5240868724 20 184661.5996348834 30 0.0 11 537393.7310076131 21 184610.9278129846 31 0.0 0 LINE 5 8E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537367.36642518 20 185242.2052524351 30 0.0 11 537306.9020463016 21 184979.539732414 31 0.0 0 LINE 5 8E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537783.945890118 20 184793.256174076 30 0.0 11 537738.9148582124 21 184779.7537260216 31 0.0 0 LINE 5 8E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537732.2957834531 20 184843.2243369311 30 0.0 11 537740.2899622214 21 184778.4409227434 31 0.0 0 LINE 5 8EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537772.1033503026 20 184872.7357443583 30 0.0 11 537667.7867798128 21 184871.7376685649 31 0.0 0 LINE 5 8EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537469.9966511197 20 185140.7302953704 30 0.0 11 537466.9106212527 21 185028.057996365 31 0.0 0 LINE 5 8EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537979.0638534152 20 184786.8478223103 30 0.0 11 538083.7178428379 21 184458.7717046499 31 0.0 0 LINE 5 8ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537280.0222161629 20 184619.9473564593 30 0.0 11 536956.2067911491 21 184481.6762675277 31 0.0 0 LINE 5 8EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537207.0378316328 20 185258.1371119735 30 0.0 11 537278.2416384539 21 184470.2140828968 31 0.0 0 LINE 5 8EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536980.4710469725 20 185010.2972592024 30 0.0 11 536927.8955659535 21 184779.1685527982 31 0.0 0 LINE 5 8F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537049.5226215949 20 184957.0632054001 30 0.0 11 536964.3348987111 21 184951.2004729965 31 0.0 0 LINE 5 8F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536840.8458648577 20 185162.016689198 30 0.0 11 536737.5695998013 21 185106.128042719 31 0.0 0 LINE 5 8F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536840.8713251344 20 185099.9279705128 30 0.0 11 536738.4759137944 21 185139.6870024007 31 0.0 0 LINE 5 8F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537041.7635251898 20 185000.2299248898 30 0.0 11 536793.6735813123 21 184993.7955770673 31 0.0 0 LINE 5 8F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537077.5737849831 20 185101.3433580342 30 0.0 11 537071.1514116518 21 184980.0741589464 31 0.0 0 LINE 5 8F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537172.1713225316 20 184994.8720697461 30 0.0 11 537127.032579336 21 185106.8998557143 31 0.0 0 LINE 5 8F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537131.5578333191 20 185101.9101971182 30 0.0 11 537075.7495330001 21 185100.162481796 31 0.0 0 LINE 5 8F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537468.0706524365 20 185069.9632265745 30 0.0 11 537468.0583348098 21 185069.9615198771 31 0.0 0 LINE 5 8F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537323.0930156879 20 185049.8755147771 30 0.0 11 536910.7955998639 21 184992.7486926704 31 0.0 0 LINE 5 8F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536976.0023422475 20 184959.8882245781 30 0.0 11 536910.7989271889 21 185305.0523000277 31 0.0 0 LINE 5 8FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537010.069859664 20 185292.5223484414 30 0.0 11 536990.2611797721 21 185000.592592699 31 0.0 0 LINE 5 8FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537117.5326950717 20 185018.477070521 30 0.0 11 537112.3485408801 21 185053.6213200548 31 0.0 0 LINE 5 8FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536948.4040101366 20 185141.8639415291 30 0.0 11 536855.2218565389 21 185136.4856098683 31 0.0 0 LINE 5 8FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536889.8307478832 20 185142.6305865953 30 0.0 11 536823.0737015237 21 185092.6698119482 31 0.0 0 LINE 5 8FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536893.7684289591 20 185130.1099764146 30 0.0 11 536819.8756486581 21 185161.1584004829 31 0.0 0 LINE 5 8FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536814.3275417369 20 185328.2548790376 30 0.0 11 536825.9885333216 21 185150.1130135764 31 0.0 0 LINE 5 900 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537247.8169779245 20 184888.3237141581 30 0.0 11 536949.6971068369 21 184871.492974252 31 0.0 0 LINE 5 901 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537488.5795058766 20 185910.915399177 30 0.0 11 537918.0019126186 21 186216.2516944803 31 0.0 0 LINE 5 902 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537649.7421860449 20 186032.3074633412 30 0.0 11 537922.143169518 21 185289.6309389398 31 0.0 0 LINE 5 903 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537694.4341605217 20 185901.8997358865 30 0.0 11 537823.164857351 21 185974.605323007 31 0.0 0 LINE 5 904 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537705.4513987788 20 186066.1575672213 30 0.0 11 537874.8412605314 21 185601.6237347305 31 0.0 0 LINE 5 905 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537791.3592910779 20 185967.24487447 30 0.0 11 537873.2594627485 21 185963.5760688097 31 0.0 0 LINE 5 906 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537802.2635272968 20 186046.215839047 30 0.0 11 537799.5233544297 21 185958.4096893029 31 0.0 0 LINE 5 907 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537793.0742666434 20 186029.5641904967 30 0.0 11 537956.8676222774 21 186142.3737177295 31 0.0 0 LINE 5 908 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537744.3345605741 20 186142.0599034011 30 0.0 11 538042.0635214961 21 185827.7086871679 31 0.0 0 LINE 5 909 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537994.112465099 20 186100.4570891543 30 0.0 11 537869.4359160997 21 185961.5484973036 31 0.0 0 LINE 5 90A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537951.5265775774 20 186143.5854558382 30 0.0 11 537994.1027542618 21 186099.6094412371 31 0.0 0 LINE 5 90B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538188.1030446081 20 186323.8178848796 30 0.0 11 537978.2928211513 21 186113.281341056 31 0.0 0 LINE 5 90C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538137.2803173881 20 186278.0061185872 30 0.0 11 538211.7731332879 21 186192.8672808224 31 0.0 0 LINE 5 90D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538268.8969313724 20 186250.9506414111 30 0.0 11 537642.7016945823 21 185646.7766129888 31 0.0 0 LINE 5 90E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537936.1140565315 20 185833.3836616485 30 0.0 11 538168.0324223031 21 185460.4257025991 31 0.0 0 LINE 5 90F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537883.405144088 20 185788.0913049394 30 0.0 11 538035.0377262333 21 185908.9924138828 31 0.0 0 LINE 5 910 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537929.5240893575 20 185732.0070728036 30 0.0 11 537979.4739508218 21 185772.5120976989 31 0.0 0 LINE 5 911 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537881.4823191293 20 185757.4875229886 30 0.0 11 537945.4022444065 21 185731.9630508963 31 0.0 0 LINE 5 912 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537930.6720798144 20 185746.1435310593 30 0.0 11 538122.0325711219 21 185391.209367984 31 0.0 0 LINE 5 913 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537812.7788332458 20 185575.9644558714 30 0.0 11 538183.3800251802 21 185744.9805816725 31 0.0 0 LINE 5 914 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538175.0915734619 20 185755.4016451168 30 0.0 11 538286.8444801435 21 185544.3399016834 31 0.0 0 LINE 5 915 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538278.7158961651 20 185915.3009900432 30 0.0 11 538172.4750552428 21 185737.4815152343 31 0.0 0 LINE 5 916 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538191.6563625952 20 185920.0572550347 30 0.0 11 538252.3574474437 21 185860.0014638102 31 0.0 0 LINE 5 917 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537875.7705432734 20 185399.632320588 30 0.0 11 537955.6857652751 21 185441.2934330443 31 0.0 0 LINE 5 918 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537874.3981423898 20 185319.2415582475 30 0.0 11 538287.8595349536 21 185547.2718772174 31 0.0 0 LINE 5 919 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538013.8481153227 20 185862.2429456056 30 0.0 11 538230.6290537816 21 185497.7690081691 31 0.0 0 LINE 5 91A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538469.9074596536 20 185747.2320719628 30 0.0 11 538270.6231049247 21 185542.5828923688 31 0.0 0 LINE 5 91B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538579.1173669532 20 186074.6315486046 30 0.0 11 538414.9811071633 21 185898.6873731377 31 0.0 0 LINE 5 91C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537948.318605483 20 186278.8268257429 30 0.0 11 538320.0375345342 21 185856.5205313893 31 0.0 0 LINE 5 91D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538306.8466288651 20 185653.7349334854 30 0.0 11 538351.7220665163 21 185610.3568952985 31 0.0 0 LINE 5 91E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538291.5391571618 20 185656.3820065465 30 0.0 11 538314.8528344023 21 185650.4138505369 31 0.0 0 LINE 5 91F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538240.5400198092 20 185617.5547239104 30 0.0 11 538298.9387112047 21 185659.4051147633 31 0.0 0 LINE 5 920 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538419.1352779886 20 186314.8277945895 30 0.0 11 538630.0002317273 21 186229.2174081527 31 0.0 0 LINE 5 921 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538250.1105527468 20 186244.5944385616 30 0.0 11 538448.8635819237 21 186327.1805350029 31 0.0 0 LINE 5 922 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538068.8934503017 20 185759.8534417735 30 0.0 11 538112.0462407692 21 185778.5067688979 31 0.0 0 LINE 5 923 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538076.2556680476 20 185831.3401438057 30 0.0 11 538111.8389544994 21 185776.6169551807 31 0.0 0 LINE 5 924 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538026.7953211405 20 185828.3004677325 30 0.0 11 538107.2689864418 21 185894.6851966017 31 0.0 0 LINE 5 925 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537996.5743993786 20 185997.4445733489 30 0.0 11 538211.4082992304 21 185790.0677983291 31 0.0 0 LINE 5 926 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538205.2690463632 20 185691.7211242995 30 0.0 11 538264.0196099377 21 185727.6089360475 31 0.0 0 LINE 5 927 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538246.5940171504 20 185754.2603269081 30 0.0 11 538278.0792604868 21 185703.0621686534 31 0.0 0 LINE 5 928 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538243.6422897201 20 185746.1762892745 30 0.0 11 538303.985940229 21 185784.2173166059 31 0.0 0 LINE 5 929 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538300.4333945551 20 185785.3121937489 30 0.0 11 538331.0338157953 21 185738.2462398686 31 0.0 0 LINE 5 92A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538269.0524297824 20 185703.4573548131 30 0.0 11 538335.0666795332 21 185744.0554659552 31 0.0 0 LINE 5 92B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537950.820243172 20 185162.6988744979 30 0.0 11 538032.7204148425 21 185159.0300688376 31 0.0 0 LINE 5 92C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537961.7244793911 20 185241.6698390747 30 0.0 11 537958.9843065237 21 185153.8636893305 31 0.0 0 LINE 5 92D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537954.1309083346 20 185225.8982378864 30 0.0 11 538117.9242639685 21 185338.7077651193 31 0.0 0 LINE 5 92E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537845.2692138033 20 185399.3077348817 30 0.0 11 538201.5244735902 21 185023.1626871957 31 0.0 0 LINE 5 92F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538153.573417193 20 185295.9110891822 30 0.0 11 538028.8968681939 21 185157.0024973315 31 0.0 0 LINE 5 930 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538110.9875296714 20 185339.0394558662 30 0.0 11 538153.563706356 21 185295.063441265 31 0.0 0 LINE 5 931 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538347.5639967021 20 185519.2718849074 30 0.0 11 538137.7537732455 21 185308.7353410838 31 0.0 0 LINE 5 932 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538350.7571299851 20 185375.1291508186 30 0.0 11 537885.5810351296 21 184920.7955725819 31 0.0 0 LINE 5 933 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538095.5750086255 20 185028.8376616764 30 0.0 11 538235.7333668089 21 184803.4429412633 31 0.0 0 LINE 5 934 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538042.8660961822 20 184983.5453049674 30 0.0 11 538194.4986783272 21 185104.4464139107 31 0.0 0 LINE 5 935 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538088.9850414515 20 184927.4610728313 30 0.0 11 538138.9349029161 21 184967.9660977267 31 0.0 0 LINE 5 936 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538040.9432712235 20 184952.9415230164 30 0.0 11 538104.8631965004 21 184927.417050924 31 0.0 0 LINE 5 937 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538090.1330319084 20 184941.5975310872 30 0.0 11 538281.4935232161 21 184586.6633680119 31 0.0 0 LINE 5 938 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538072.307469424 20 184817.178123014 30 0.0 11 538342.8409772741 21 184940.4345817006 31 0.0 0 LINE 5 939 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538334.5525255559 20 184950.8556451446 30 0.0 11 538446.3054322376 21 184739.793901711 31 0.0 0 LINE 5 93A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538438.1768482592 20 185110.754990071 30 0.0 11 538331.9360073368 21 184932.9355152621 31 0.0 0 LINE 5 93B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538192.79221278 20 185254.3631671886 30 0.0 11 538411.8183995378 21 185055.4554638381 31 0.0 0 LINE 5 93C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538173.3090674167 20 185057.6969456334 30 0.0 11 538411.6300655914 21 184662.8555463364 31 0.0 0 LINE 5 93D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538605.9235865892 20 185128.2845935083 30 0.0 11 538286.2399475104 21 184954.0946146965 31 0.0 0 LINE 5 93E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538505.7505698988 20 185165.5577566305 30 0.0 11 538547.4940421457 21 185055.7988833945 31 0.0 0 LINE 5 93F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538465.1966319189 20 185118.542995645 30 0.0 11 538568.7165055024 21 185081.811038804 31 0.0 0 LINE 5 940 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538107.7795575772 20 185474.2808257707 30 0.0 11 538314.4841544041 21 185231.6328740587 31 0.0 0 LINE 5 941 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538229.1246635165 20 185284.572763438 30 0.0 11 538556.1171595886 21 185312.809171415 31 0.0 0 LINE 5 942 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538443.4888289444 20 185324.8896968279 30 0.0 11 538459.6365313105 21 185158.8469818409 31 0.0 0 LINE 5 943 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538455.9889421318 20 185182.8528467175 30 0.0 11 538473.9396036967 21 185101.4258487909 31 0.0 0 LINE 5 944 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538444.8321139844 20 185175.9393673298 30 0.0 11 538521.074896924 21 185151.2171977781 31 0.0 0 LINE 5 945 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538595.5563366735 20 185238.6041270096 30 0.0 11 538509.233481124 21 185146.8412632869 31 0.0 0 LINE 5 946 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538258.1652718431 20 185567.0304490767 30 0.0 11 538377.4093335351 21 185477.2768007374 31 0.0 0 LINE 5 947 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538228.3544023958 20 184955.3074418012 30 0.0 11 538271.5071928632 21 184973.9607689259 31 0.0 0 LINE 5 948 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538235.7166201418 20 185026.7941438338 30 0.0 11 538271.2999065937 21 184972.0709552085 31 0.0 0 LINE 5 949 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538186.2562732346 20 185023.7544677603 30 0.0 11 538266.7299385358 21 185090.1391966294 31 0.0 0 LINE 5 94A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538156.0353514726 20 185192.8985733767 30 0.0 11 538370.8692513245 21 184985.521798357 31 0.0 0 LINE 5 94B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538364.7299984572 20 184887.1751243276 30 0.0 11 538423.4805620318 21 184923.0629360754 31 0.0 0 LINE 5 94C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538406.0549692446 20 184949.7143269358 30 0.0 11 538437.5402125808 21 184898.5161686812 31 0.0 0 LINE 5 94D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538244.943979526 20 185423.3108344892 30 0.0 11 538319.8327647924 21 185339.0716489233 31 0.0 0 LINE 5 94E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538561.4867933374 20 185114.7662861104 30 0.0 11 539127.0967414929 21 185217.8593808671 31 0.0 0 LINE 5 94F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538588.3144403077 20 185178.0851155726 30 0.0 11 538811.5532858948 21 185220.909437952 31 0.0 0 LINE 5 950 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538474.6996822701 20 185326.427722413 30 0.0 11 538615.0241558182 21 185422.04121394 31 0.0 0 LINE 5 951 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538414.3673936683 20 185453.1652775622 30 0.0 11 539150.8013019747 21 184398.8570169071 31 0.0 0 LINE 5 952 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538592.5282977311 20 185318.3521073253 30 0.0 11 538997.6937680966 21 185487.835762065 31 0.0 0 LINE 5 953 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538628.8368356242 20 185259.0957397071 30 0.0 11 538533.6601007033 21 185428.0658768367 31 0.0 0 LINE 5 954 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538691.5571382496 20 185295.6821011772 30 0.0 11 538659.5347575402 21 185351.4513833656 31 0.0 0 LINE 5 955 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538658.7424885215 20 185252.317786453 30 0.0 11 538694.1323456457 21 185311.3500957061 31 0.0 0 LINE 5 956 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538677.7845838421 20 185299.0694421985 30 0.0 11 539058.6899563309 21 185431.387978166 31 0.0 0 LINE 5 957 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538826.9885224897 20 185155.5496877736 30 0.0 11 538719.2265685296 21 185548.3588723946 31 0.0 0 LINE 5 958 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538707.6172481076 20 185541.838084518 30 0.0 11 538933.7975566249 21 185618.5077638701 31 0.0 0 LINE 5 959 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538566.286364202 20 185669.632380236 30 0.0 11 538724.8909121459 21 185536.3977027955 31 0.0 0 LINE 5 95A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538547.7094339019 20 185584.4450448938 30 0.0 11 538616.6755853611 21 185634.7937262498 31 0.0 0 LINE 5 95B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 539011.1086433176 20 185189.6195949093 30 0.0 11 538982.7228988433 21 185275.1552045073 31 0.0 0 LINE 5 95C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 539090.2520782862 20 185175.4465622335 30 0.0 11 538931.0649410907 21 185619.9773315418 31 0.0 0 LINE 5 95D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538576.4328149488 20 185399.6932260825 30 0.0 11 538970.8091654945 21 185555.5858829968 31 0.0 0 LINE 5 95E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538658.2440018568 20 185917.1169387221 30 0.0 11 538971.2895693079 21 185548.6272561428 31 0.0 0 LINE 5 95F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538553.7271723706 20 186089.1058411073 30 0.0 11 538840.1227081429 21 185695.9906509777 31 0.0 0 LINE 5 960 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538575.4767454062 20 185875.6166364597 30 0.0 11 538690.4873259018 21 185899.3251603142 31 0.0 0 LINE 5 961 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538615.4237445238 20 185828.0851006367 30 0.0 11 538668.1918546128 21 185924.4237088775 31 0.0 0 LINE 5 962 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538727.7078894064 20 185674.8025195414 30 0.0 11 538623.4366926458 21 185847.8191340247 31 0.0 0 LINE 5 963 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538514.4132508551 20 185634.9665650709 30 0.0 11 538780.9383930338 21 185774.579904677 31 0.0 0 LINE 5 964 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538455.918930015 20 185720.009259043 30 0.0 11 538305.634055489 21 185742.7299976086 31 0.0 0 LINE 5 965 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538291.9706382603 20 185370.3940992804 30 0.0 11 538291.9811632725 21 185370.4007220331 31 0.0 0 LINE 5 966 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538407.4697143141 20 185573.9977691916 30 0.0 11 538630.9034748751 21 185701.0529010041 31 0.0 0 LINE 5 967 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538643.7165064174 20 185698.4345068811 30 0.0 11 538630.6232893641 21 185718.8874342814 31 0.0 0 LINE 5 968 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538828.9914119887 20 185655.6968883955 30 0.0 11 538864.6653422267 21 185683.6523507348 31 0.0 0 LINE 5 969 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538823.9374508764 20 185641.007328742 30 0.0 11 538833.5465836131 21 185663.0711226288 31 0.0 0 LINE 5 96A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538854.1362484448 20 185584.4697084079 30 0.0 11 538822.132867692 21 185648.7942448745 31 0.0 0 LINE 5 96B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538602.1544421794 20 185633.9319450027 30 0.0 11 538429.8712217547 21 185940.049922711 31 0.0 0 LINE 5 96C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538426.6473692368 20 185796.1398550403 30 0.0 11 538565.0410782722 21 185655.9037053136 31 0.0 0 LINE 5 96D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538447.7259734861 20 185262.5988138148 30 0.0 11 538438.3876748164 21 185962.9560360679 31 0.0 0 LINE 5 96E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538506.1371499462 20 185790.9590416683 30 0.0 11 538580.909456926 21 185846.8244362297 31 0.0 0 LINE 5 96F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538550.468505471 20 185829.2493238951 30 0.0 11 538633.7159528389 21 185833.9869128063 31 0.0 0 LINE 5 970 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538555.5145954715 20 185817.1328893014 30 0.0 11 538592.0772762257 21 185888.4583265156 31 0.0 0 LINE 5 971 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538488.7631856539 20 186019.9049442931 30 0.0 11 538594.5091295639 21 185876.0706705564 31 0.0 0 LINE 5 972 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538686.2892706148 20 185437.7084670585 30 0.0 11 538674.7552392485 21 185483.2834169584 31 0.0 0 LINE 5 973 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538616.8910471252 20 185456.3749448757 30 0.0 11 538676.5878236505 21 185482.7774546147 31 0.0 0 LINE 5 974 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538440.206655419 20 185404.1982085089 30 0.0 11 538679.1852543343 21 185583.2176504797 31 0.0 0 LINE 5 975 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538775.2948097776 20 185561.4757078123 30 0.0 11 538708.736655484 21 185714.3325515911 31 0.0 0 LINE 5 976 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538791.9701436699 20 185273.5632884998 30 0.0 11 539046.4265204657 21 185346.1284458889 31 0.0 0 LINE 5 977 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538162.3788787743 20 186053.3999999256 30 0.0 11 538044.7831239762 21 185935.7459723394 31 0.0 0 LINE 5 978 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538212.0529438026 20 186139.58135618 30 0.0 11 538044.4452423011 21 186216.7745436283 31 0.0 0 LINE 5 979 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538633.3671606733 20 185449.6300558871 30 0.0 11 538581.2367847845 21 185554.5710751908 31 0.0 0 LINE 5 97A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537816.4987150436 20 185577.6609426168 30 0.0 11 537717.7406119495 21 185405.8731977982 31 0.0 0 LINE 5 97B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536377.950798813 20 183242.8256182219 30 0.0 11 536229.3811899697 21 182702.1611796888 31 0.0 0 LINE 5 97C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536365.4089121279 20 183226.3197876327 30 0.0 11 537156.4467427117 21 183220.8547826734 31 0.0 0 LINE 5 97D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536503.2478305164 20 183228.3149166955 30 0.0 11 536478.3100186013 21 183082.589832233 31 0.0 0 LINE 5 97E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536474.4919353847 20 183115.0119310109 30 0.0 11 536505.6155181625 21 183039.1672156401 31 0.0 0 LINE 5 97F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536403.8487205204 20 183078.0680301967 30 0.0 11 536485.5658730114 21 183110.3129595501 31 0.0 0 LINE 5 980 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536416.4165601175 20 183092.3428093075 30 0.0 11 536365.5791656758 21 182900.0674543847 31 0.0 0 LINE 5 981 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536294.0688341979 20 183100.2090874555 30 0.0 11 536690.5251339838 21 182926.1929282078 31 0.0 0 LINE 5 982 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536417.6144112501 20 182879.17450615 30 0.0 11 536506.2320532261 21 183043.4509569607 31 0.0 0 LINE 5 983 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536362.6341735878 20 182904.685039179 30 0.0 11 536418.4089345704 21 182879.4700293907 31 0.0 0 LINE 5 984 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536272.9287582812 20 182621.1271232333 30 0.0 11 536400.1994853068 21 182889.7311593058 31 0.0 0 LINE 5 985 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536298.8758903715 20 182684.4391589704 30 0.0 11 536404.1762484465 21 182643.0914153091 31 0.0 0 LINE 5 986 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536368.8079794198 20 182569.702787914 30 0.0 11 536644.0003308036 21 183243.9299080776 31 0.0 0 LINE 5 987 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536649.3881379984 20 183023.9949835186 30 0.0 11 537078.7704213867 21 182931.720272395 31 0.0 0 LINE 5 988 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536674.2091429489 20 183088.9068063282 30 0.0 11 536611.6473738665 21 182905.3433481972 31 0.0 0 LINE 5 989 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536742.5770769539 20 183064.4481921625 30 0.0 11 536721.3297337248 21 183003.7506130688 31 0.0 0 LINE 5 98A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536702.3637101915 20 183101.0562535959 30 0.0 11 536747.9830493849 21 183049.5185837362 31 0.0 0 LINE 5 98B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536729.6597324148 20 183058.5916108926 30 0.0 11 537128.3753175386 21 182998.4004160958 31 0.0 0 LINE 5 98C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536850.0008617826 20 183227.0485721637 30 0.0 11 536816.1333390501 21 182821.1364078377 31 0.0 0 LINE 5 98D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536803.5247511583 20 182825.4166539249 30 0.0 11 537039.9320133069 21 182791.5436839286 31 0.0 0 LINE 5 98E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536688.0380295237 20 182673.8626441143 30 0.0 11 536819.5071266102 21 182833.9337483539 31 0.0 0 LINE 5 98F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536654.1478082748 20 182754.1959332648 30 0.0 11 536731.1804359523 21 182717.354461599 31 0.0 0 LINE 5 990 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536960.6148925918 20 183238.8174719675 30 0.0 11 536948.4034366646 21 183149.5259754921 31 0.0 0 LINE 5 991 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537112.4463272675 20 183255.7881454086 30 0.0 11 537037.5153878978 21 182789.5977295533 31 0.0 0 LINE 5 992 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536648.4888120684 20 182941.0815745938 30 0.0 11 537064.7716752467 21 182860.1877913121 31 0.0 0 LINE 5 993 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536823.8387568325 20 182447.4493576788 30 0.0 11 537063.9672847543 21 182867.1164442443 31 0.0 0 LINE 5 994 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536715.143687881 20 182218.6083407707 30 0.0 11 536962.0622477265 21 182698.1901910048 31 0.0 0 LINE 5 995 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536734.862609048 20 182473.0606628711 30 0.0 11 536852.2707044117 21 182470.854563964 31 0.0 0 LINE 5 996 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536765.411374848 20 182527.1141784302 30 0.0 11 536834.9582748474 21 182442.0916544697 31 0.0 0 LINE 5 997 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536847.6682510308 20 182698.3948988279 30 0.0 11 536776.9087543582 21 182509.1851607281 31 0.0 0 LINE 5 998 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536598.1825266714 20 182709.144270706 30 0.0 11 536918.3005795967 21 182610.0767961406 31 0.0 0 LINE 5 999 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536621.0589931053 20 182799.8816461554 30 0.0 11 536598.5363384874 21 182680.5493556573 31 0.0 0 LINE 5 99A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536503.9084506 20 182718.8842404519 30 0.0 11 536574.3292366733 21 182817.0098938511 31 0.0 0 LINE 5 99B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536568.7496874731 20 182813.2358711641 30 0.0 11 536622.5511225131 21 182798.3018000183 31 0.0 0 LINE 5 99C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536234.2614855521 20 182862.0121884998 30 0.0 11 536757.322843783 21 182654.8301815798 31 0.0 0 LINE 5 99D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536769.4380237217 20 182659.7548318349 30 0.0 11 536760.3193647292 21 182637.2469525432 31 0.0 0 LINE 5 99E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536943.7275287886 20 182735.7578784313 30 0.0 11 536983.9247134773 21 182714.8217012172 31 0.0 0 LINE 5 99F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536936.0643799653 20 182749.2709031056 30 0.0 11 536949.5582733074 21 182729.3445066654 31 0.0 0 LINE 5 9A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536955.3781314365 20 182810.3892218956 30 0.0 11 536935.7190257515 21 182741.2850835613 31 0.0 0 LINE 5 9A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536716.7476580286 20 182715.5375445312 30 0.0 11 536582.4825053728 21 182302.4635152185 31 0.0 0 LINE 5 9A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536571.9455827591 20 182332.4241959598 30 0.0 11 536771.3499328064 21 182304.9976130809 31 0.0 0 LINE 5 9A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536368.4433207431 20 182589.5319674376 30 0.0 11 536601.4676670191 21 182311.5315737302 31 0.0 0 LINE 5 9A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536468.717144629 20 182355.1780411351 30 0.0 11 536684.2951962053 21 182687.1298386529 31 0.0 0 LINE 5 9A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536564.7143357547 20 182734.2287873409 30 0.0 11 536551.9223906497 21 182701.0872745451 31 0.0 0 LINE 5 9A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536651.1685099792 20 182543.560206384 30 0.0 11 536734.9208493266 21 182502.3608634954 31 0.0 0 LINE 5 9A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536701.7722184314 20 182514.0529278487 30 0.0 11 536784.4758630052 21 182524.6684549728 31 0.0 0 LINE 5 9A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536704.5097609086 20 182526.8894722722 30 0.0 11 536753.5373333831 21 182463.4824950933 31 0.0 0 LINE 5 9A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536676.0922024562 20 182315.3127737212 30 0.0 11 536753.655252238 21 182476.1060455431 31 0.0 0 LINE 5 9AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536145.8370627403 20 182567.7590615311 30 0.0 11 536235.94668861 21 182719.6690338856 31 0.0 0 LINE 5 9AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536194.3164605139 20 182671.5968735944 30 0.0 11 536423.0918593966 21 182541.2103785556 31 0.0 0 LINE 5 9AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536763.4549964057 20 182923.8660044065 30 0.0 11 536760.47798366 21 182876.9485520774 31 0.0 0 LINE 5 9AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536698.659257292 20 182892.7844502254 30 0.0 11 536762.1866387764 21 182877.7821354124 31 0.0 0 LINE 5 9AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536684.8096896209 20 182940.3633848721 30 0.0 11 536649.5170988597 21 182842.1932464827 31 0.0 0 LINE 5 9AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536515.4013251864 20 182911.6607955009 30 0.0 11 536783.1668954148 21 182779.5232507103 31 0.0 0 LINE 5 9B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536873.6563625932 20 182818.5285714787 30 0.0 11 536859.7281044162 21 182751.1077484599 31 0.0 0 LINE 5 9B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536828.7565280112 20 182758.5043269772 30 0.0 11 536887.58160853 21 182746.1681258376 31 0.0 0 LINE 5 9B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536835.3679443507 20 182764.0137310528 30 0.0 11 536819.9513197208 21 182694.3660203783 31 0.0 0 LINE 5 9B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536817.7205730532 20 182697.3397564173 30 0.0 11 536872.3574897433 21 182684.44025529 31 0.0 0 LINE 5 9B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536884.1598861377 20 182754.5306410416 30 0.0 11 536868.2523895976 21 182678.6818483531 31 0.0 0 LINE 5 9B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536328.5762214313 20 182750.1339097506 30 0.0 11 536433.1636098655 21 182708.109527257 31 0.0 0 LINE 5 9B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536837.2278100268 20 183104.6135038196 30 0.0 11 537100.6781857253 21 183079.9629601505 31 0.0 0 LINE 5 9B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536668.1832728364 20 183351.5686047555 30 0.0 11 537967.5584431446 21 183342.5916741019 31 0.0 0 LINE 5 9B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537314.3595309493 20 183350.051808124 30 0.0 11 537289.4217190342 21 183204.3267236614 31 0.0 0 LINE 5 9B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537163.4826997652 20 183284.1868211775 30 0.0 11 537657.9303096423 21 183281.7032994896 31 0.0 0 LINE 5 9BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537285.6036358177 20 183236.7488224393 30 0.0 11 537316.7272185955 21 183160.9041070683 31 0.0 0 LINE 5 9BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537214.9604209535 20 183199.8049216252 30 0.0 11 537296.6775734443 21 183232.0498509783 31 0.0 0 LINE 5 9BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537227.239076306 20 183212.280511718 30 0.0 11 537176.4016818643 21 183020.0051567952 31 0.0 0 LINE 5 9BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537027.2468334006 20 183256.1533388664 30 0.0 11 537501.6368344167 21 183047.9298196365 31 0.0 0 LINE 5 9BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537228.7261116832 20 183000.9113975783 30 0.0 11 537317.3437536592 21 183165.187848389 31 0.0 0 LINE 5 9BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537173.7458740209 20 183026.4219306075 30 0.0 11 537229.5206350034 21 183001.206920819 31 0.0 0 LINE 5 9C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537084.0404587141 20 182742.8640146615 30 0.0 11 537211.3111857398 21 183011.4680507342 31 0.0 0 LINE 5 9C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537109.9875908043 20 182806.1760503987 30 0.0 11 537215.2879488794 21 182764.8283067376 31 0.0 0 LINE 5 9C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537179.9196798528 20 182691.4396793422 30 0.0 11 537491.2409488954 21 183379.880430458 31 0.0 0 LINE 5 9C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537460.4998384315 20 183145.7318749472 30 0.0 11 537889.8821218196 21 183053.4571638233 31 0.0 0 LINE 5 9C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537485.3208433818 20 183210.643697757 30 0.0 11 537422.7590742995 21 183027.0802396259 31 0.0 0 LINE 5 9C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537553.6887773869 20 183186.1850835907 30 0.0 11 537532.4414341579 21 183125.4875044973 31 0.0 0 LINE 5 9C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537513.4754106245 20 183222.7931450241 30 0.0 11 537559.0947498179 21 183171.2554751645 31 0.0 0 LINE 5 9C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537540.7714328479 20 183180.328502321 30 0.0 11 537939.4870179715 21 183120.1373075241 31 0.0 0 LINE 5 9C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537737.9508085389 20 183602.3443691874 30 0.0 11 537692.0225814107 21 182912.5622043346 31 0.0 0 LINE 5 9C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537614.6364515911 20 182947.1535453535 30 0.0 11 537851.0437137399 21 182913.2805753571 31 0.0 0 LINE 5 9CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537499.1497299565 20 182795.5995355427 30 0.0 11 537630.6188270431 21 182955.6706397822 31 0.0 0 LINE 5 9CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537465.2595087079 20 182875.9328246934 30 0.0 11 537542.2921363853 21 182839.0913530274 31 0.0 0 LINE 5 9CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537848.3581093194 20 183349.0727886068 30 0.0 11 537836.146653392 21 183259.7812921317 31 0.0 0 LINE 5 9CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537923.5580277004 20 183377.525036837 30 0.0 11 537848.6270883307 21 182911.3346209815 31 0.0 0 LINE 5 9CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537459.6005125013 20 183062.8184660221 30 0.0 11 537875.8833756796 21 182981.9246827404 31 0.0 0 LINE 5 9CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537698.132007023 20 182681.9452738537 30 0.0 11 537875.0789851874 21 182988.8533356727 31 0.0 0 LINE 5 9D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537409.2942271043 20 182830.8811621344 30 0.0 11 537729.4122800297 21 182731.8136875691 31 0.0 0 LINE 5 9D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537432.1706935382 20 182921.6185375839 30 0.0 11 537409.6480389204 21 182802.2862470857 31 0.0 0 LINE 5 9D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537315.020151033 20 182840.6211318802 30 0.0 11 537385.4409371062 21 182938.7467852796 31 0.0 0 LINE 5 9D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537379.8613879062 20 182934.9727625926 30 0.0 11 537433.662822946 21 182920.0386914467 31 0.0 0 LINE 5 9D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537045.3731859852 20 182983.7490799281 30 0.0 11 537568.434544216 21 182776.567073008 31 0.0 0 LINE 5 9D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537580.5497241547 20 182781.4917232632 30 0.0 11 537571.4310651623 21 182758.9838439715 31 0.0 0 LINE 5 9D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537754.8392292213 20 182857.4947698596 30 0.0 11 537795.0364139103 21 182836.5585926457 31 0.0 0 LINE 5 9D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537747.1760803985 20 182871.0077945341 30 0.0 11 537760.6699737404 21 182851.0813980939 31 0.0 0 LINE 5 9D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537766.4898318695 20 182932.1261133241 30 0.0 11 537746.8307261844 21 182863.0219749897 31 0.0 0 LINE 5 9D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537527.8593584616 20 182837.2744359597 30 0.0 11 537424.3983140284 21 182497.6427816799 31 0.0 0 LINE 5 9DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537179.5550211762 20 182711.268858866 30 0.0 11 537307.1622224056 21 182552.0738509563 31 0.0 0 LINE 5 9DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537278.1562489779 20 182540.8491264896 30 0.0 11 537495.4068966384 21 182808.8667300813 31 0.0 0 LINE 5 9DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537375.8260361876 20 182855.9656787693 30 0.0 11 537363.0340910828 21 182822.8241659735 31 0.0 0 LINE 5 9DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537008.8862652714 20 182810.8703354409 30 0.0 11 537234.2035598295 21 182662.9472699839 31 0.0 0 LINE 5 9DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537574.5666968386 20 183045.6028958351 30 0.0 11 537571.5896840929 21 182998.685443506 31 0.0 0 LINE 5 9DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537509.770957725 20 183014.5213416539 30 0.0 11 537573.2983392094 21 182999.5190268409 31 0.0 0 LINE 5 9E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537495.9213900537 20 183062.1002763007 30 0.0 11 537460.6287992928 21 182963.930137911 31 0.0 0 LINE 5 9E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537326.5130256195 20 183033.3976869292 30 0.0 11 537594.2785958478 21 182901.2601421385 31 0.0 0 LINE 5 9E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537139.6879218641 20 182871.870801179 30 0.0 11 537244.2753102984 21 182829.8464186852 31 0.0 0 LINE 5 9E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537686.437641938 20 183224.7317307152 30 0.0 11 537911.7898861585 21 183201.699851579 31 0.0 0 LINE 5 9E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537384.0731362219 20 182569.6715993786 30 0.0 11 537341.4914932436 21 182405.2948938519 31 0.0 0 LINE 5 9E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536938.2648702544 20 182666.0542430234 30 0.0 11 537667.5375991025 21 182468.4868182959 31 0.0 0 LINE 5 9E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537431.4830585261 20 182461.4999882802 30 0.0 11 537408.8532674805 21 182022.8980501202 31 0.0 0 LINE 5 9E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537499.522088195 20 182447.3466328855 30 0.0 11 537308.3317137799 21 182479.8390757421 31 0.0 0 LINE 5 9E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537486.27755914 20 182375.9534913579 30 0.0 11 537422.9686723243 21 182387.250860621 31 0.0 0 LINE 5 9E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537516.0053030976 20 182421.4894800645 30 0.0 11 537472.4009309577 21 182368.2361773191 31 0.0 0 LINE 5 9EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537478.4362537891 20 182387.7717511494 30 0.0 11 537482.5897499209 21 181984.5598388484 31 0.0 0 LINE 5 9EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537663.9262350628 20 182295.8304543059 30 0.0 11 537257.8070860278 21 182264.5425807582 31 0.0 0 LINE 5 9EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537260.0221507038 20 182277.6723364173 30 0.0 11 537264.2773369267 21 182038.8886161115 31 0.0 0 LINE 5 9ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537091.9928968431 20 182367.516482641 30 0.0 11 537270.978645964 21 182263.2524739281 31 0.0 0 LINE 5 9EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537165.8946748286 20 182413.7821465039 30 0.0 11 537141.8072843549 21 182331.8607367166 31 0.0 0 LINE 5 9EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537734.1446683246 20 182041.325135984 30 0.0 11 537261.9709512213 21 182040.9640442066 31 0.0 0 LINE 5 9F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537349.4870275742 20 182449.1673861692 30 0.0 11 537336.0038760495 21 182025.3119497591 31 0.0 0 LINE 5 9F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536890.1295156216 20 182197.3518883977 30 0.0 11 537342.7156265724 21 182027.2108126912 31 0.0 0 LINE 5 9F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536682.7253259366 20 182256.4761466977 30 0.0 11 537159.7019654085 21 182100.8770561987 31 0.0 0 LINE 5 9F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536901.2260387822 20 182289.2733820865 30 0.0 11 536917.7687139625 21 182173.0156183581 31 0.0 0 LINE 5 9F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536959.4589628925 20 182267.73420416 30 0.0 11 536886.6133485277 21 182185.5203528457 31 0.0 0 LINE 5 9F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537141.6640981017 20 182213.8401640188 30 0.0 11 536943.5925651405 21 182253.5251635965 31 0.0 0 LINE 5 9F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537107.0946065559 20 182428.0514063887 30 0.0 11 537065.7381378544 21 182130.0292956218 31 0.0 0 LINE 5 9F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537040.3370718799 20 182490.194963187 30 0.0 11 537151.8275639878 21 182442.0562501154 31 0.0 0 LINE 5 9F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537173.0343628435 20 182541.9275284717 30 0.0 11 537052.3031853124 21 182538.504994595 31 0.0 0 LINE 5 9F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537058.5538632543 20 182541.0157000306 30 0.0 11 537040.8108937336 21 182488.0741480516 31 0.0 0 LINE 5 9FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537205.3812923094 20 182845.4876896032 30 0.0 11 537205.378614935 21 182845.4755459459 31 0.0 0 LINE 5 9FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537173.8687728678 20 182702.5576632234 30 0.0 11 537084.2512937638 21 182296.0833831784 31 0.0 0 LINE 5 9FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537091.0446870241 20 182284.9084302434 30 0.0 11 537067.3708112243 21 182290.3215787412 31 0.0 0 LINE 5 9FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537193.8655766623 20 182124.9673181983 30 0.0 11 537179.6066344044 21 182081.9461636468 31 0.0 0 LINE 5 9FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537205.983841036 20 182134.6870586424 30 0.0 11 537188.4639597507 21 182118.1885680334 31 0.0 0 LINE 5 9FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537269.3997763168 20 182125.365629562 30 0.0 11 537198.0451239174 21 182133.7546671835 31 0.0 0 LINE 5 A00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537137.7123270689 20 182345.8191603759 30 0.0 11 536791.3878001819 21 182404.5477427922 31 0.0 0 LINE 5 A01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536837.6140617653 20 182493.2880969794 30 0.0 11 537104.4935647696 21 182373.3268658957 31 0.0 0 LINE 5 A02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537131.9229468348 20 182498.8876963849 30 0.0 11 537097.1657815568 21 182506.2316184839 31 0.0 0 LINE 5 A03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536957.4787259281 20 182383.1377685347 30 0.0 11 536930.1606660249 21 182293.8877612312 31 0.0 0 LINE 5 A04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536936.4176440107 20 182328.4765791578 30 0.0 11 536960.0843342996 21 182248.5236554292 31 0.0 0 LINE 5 A05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536949.5264579374 20 182327.82082845 30 0.0 11 536894.7480693696 21 182269.3103527759 31 0.0 0 LINE 5 A06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536736.1254824033 20 182322.1392231021 30 0.0 11 536907.2289191453 21 182271.2067492784 31 0.0 0 LINE 5 A07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537350.8228998787 20 182332.9270539126 30 0.0 11 537304.0310177877 21 182328.3850600403 31 0.0 0 LINE 5 A08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537309.8074093944 20 182391.9379034063 30 0.0 11 537305.126379028 21 182326.8311786943 31 0.0 0 LINE 5 A09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537354.5693372198 20 182413.1966748707 30 0.0 11 537252.0278117451 21 182432.3846551545 31 0.0 0 LINE 5 A0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537299.2220449141 20 182575.8610834282 30 0.0 11 537211.4698661906 21 182290.4521023634 31 0.0 0 LINE 5 A0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537264.4045760152 20 182207.3396772141 30 0.0 11 537195.625478288 21 182210.3395885852 31 0.0 0 LINE 5 A0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537197.9890540169 20 182242.0942957727 30 0.0 11 537195.1902526674 21 182182.054819862 31 0.0 0 LINE 5 A0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537204.4821528088 20 182236.4459307558 30 0.0 11 537133.2673398275 21 182240.5600927853 31 0.0 0 LINE 5 A0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537135.8473412971 20 182243.2364576972 30 0.0 11 537131.8246500621 21 182187.2417458936 31 0.0 0 LINE 5 A0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537202.9001912149 20 182186.7661564309 30 0.0 11 537125.4853625582 21 182190.3761567784 31 0.0 0 LINE 5 A10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537541.020926995 20 182288.917997405 30 0.0 11 537558.6925351086 21 182024.9076490744 31 0.0 0 LINE 5 A11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536709.6910170015 20 183412.2770954969 30 0.0 11 536848.0824291129 21 183411.5819802481 31 0.0 0 LINE 5 A12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536652.0278052007 20 183549.5298098701 30 0.0 11 537082.31535887 21 183637.4865535445 31 0.0 0 LINE 5 A13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536731.9478128749 20 183514.1285688017 30 0.0 11 537131.2479242355 21 183570.3114738424 31 0.0 0 LINE 5 A14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536850.5906547582 20 183344.4712338936 30 0.0 11 536824.9151047095 21 183694.6167044956 31 0.0 0 LINE 5 A15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537037.8238678751 20 183342.3029692122 30 0.0 11 537026.5099958148 21 183431.7126291917 31 0.0 0 LINE 5 A16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537112.7341780836 20 183313.0967442194 30 0.0 11 537042.4900830331 21 183780.0163482421 31 0.0 0 LINE 5 A17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536651.9614220067 20 183632.4480693786 30 0.0 11 537069.0358905775 21 183709.1560482073 31 0.0 0 LINE 5 A18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536878.5293577574 20 184041.5140416933 30 0.0 11 537068.1619396648 21 183702.2358252833 31 0.0 0 LINE 5 A19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536767.0947426709 20 183648.50789101 30 0.0 11 536764.5891841443 21 183695.4528813116 31 0.0 0 LINE 5 A1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536702.6144991729 20 183680.2387752721 30 0.0 11 536766.2893793806 21 183694.6021759327 31 0.0 0 LINE 5 A1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537027.5353145481 20 183313.5874311575 30 0.0 11 537503.9930656886 21 183517.0350126194 31 0.0 0 LINE 5 A1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537089.482264669 20 183826.2803427426 30 0.0 11 537251.0272936064 21 183476.297487684 31 0.0 0 LINE 5 A1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537185.8732255069 20 183876.7389394128 30 0.0 11 537490.2631320349 21 183185.2055814617 31 0.0 0 LINE 5 A1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537461.8756857302 20 183419.6511291113 30 0.0 11 537892.1632393996 21 183507.607872786 31 0.0 0 LINE 5 A1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537486.0433738643 20 183354.4932448803 30 0.0 11 537425.3287275618 21 183538.6758983417 31 0.0 0 LINE 5 A20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537554.6535545524 20 183378.2638425367 30 0.0 11 537534.0170141136 21 183439.1717968681 31 0.0 0 LINE 5 A21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537514.0744746237 20 183342.0615870769 30 0.0 11 537560.2092279274 21 183393.1383925819 31 0.0 0 LINE 5 A22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537705.0470616232 20 183407.2199194994 30 0.0 11 537941.0958047653 21 183440.4327930841 31 0.0 0 LINE 5 A23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537469.3453519826 20 183689.3887536004 30 0.0 11 537546.7441797636 21 183725.4545437557 31 0.0 0 LINE 5 A24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537902.141134846 20 183314.4141268921 30 0.0 11 537846.9844232049 21 183524.1326304348 31 0.0 0 LINE 5 A25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537461.8093025364 20 183502.5693886199 30 0.0 11 537878.883771107 21 183579.2773674488 31 0.0 0 LINE 5 A26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537413.8354556022 20 183735.0003359903 30 0.0 11 537734.9325278087 21 183830.847101955 31 0.0 0 LINE 5 A27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537435.7992756382 20 183644.037735822 30 0.0 11 537414.4764965815 21 183763.5902540719 31 0.0 0 LINE 5 A28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537383.3584609629 20 183631.2096518854 30 0.0 11 537437.3071999261 21 183645.6025132274 31 0.0 0 LINE 5 A29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537048.3971590088 20 183585.795859373 30 0.0 11 537573.5133491979 21 183787.7130584098 31 0.0 0 LINE 5 A2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537585.5784478287 20 183782.666954951 30 0.0 11 537576.6863493082 21 183805.2652990483 31 0.0 0 LINE 5 A2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537532.3303816995 20 183727.4163520024 30 0.0 11 537432.2862892464 21 184068.0701760955 31 0.0 0 LINE 5 A2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537185.3093934284 20 183856.9144235318 30 0.0 11 537314.5093317011 21 184014.8195352259 31 0.0 0 LINE 5 A2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537285.6175785159 20 184026.3350695925 30 0.0 11 537500.1649237304 21 183756.1486221057 31 0.0 0 LINE 5 A2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537013.6487133441 20 183759.0324063326 30 0.0 11 537240.4405838322 21 183904.6846085185 31 0.0 0 LINE 5 A2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537576.9426232004 20 183518.6292102514 30 0.0 11 537574.4370646741 21 183565.574200553 31 0.0 0 LINE 5 A30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537512.4623797024 20 183550.3600945134 30 0.0 11 537576.1372599103 21 183564.723495174 31 0.0 0 LINE 5 A31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537498.1355619702 20 183502.9226847985 30 0.0 11 537463.8309090649 21 183601.4423976639 31 0.0 0 LINE 5 A32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537143.8309968407 20 183696.7210650589 30 0.0 11 537248.8352594203 21 183737.6927062702 31 0.0 0 LINE 5 A33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537391.2395886763 20 183996.4500747515 30 0.0 11 537350.3113219837 21 184161.2462355808 31 0.0 0 LINE 5 A34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536944.4856154441 20 183904.550611194 30 0.0 11 537675.7061894037 21 184094.7822399344 31 0.0 0 LINE 5 A35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537439.7337446563 20 184104.1399768607 30 0.0 11 537372.4735154652 21 184620.2113384158 31 0.0 0 LINE 5 A36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537507.9115172814 20 184117.6091396818 30 0.0 11 537316.4043904086 21 184087.038917755 31 0.0 0 LINE 5 A37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537530.3843034036 20 184042.9295421691 30 0.0 11 537481.5864236921 21 184196.9880461829 31 0.0 0 LINE 5 A38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537487.4251995858 20 184177.3928308839 30 0.0 11 537546.7828506184 21 184491.519098808 31 0.0 0 LINE 5 A39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537248.15088338 20 184109.0374778735 30 0.0 11 537276.7817548089 21 184528.4096720155 31 0.0 0 LINE 5 A3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537048.3192415882 20 184079.3756629772 30 0.0 11 537160.2876803599 21 184126.3919819062 31 0.0 0 LINE 5 A3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537180.4901634646 20 184026.3127121513 30 0.0 11 537059.7994582482 21 184030.9478648575 31 0.0 0 LINE 5 A3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537066.0245997946 20 184028.3744956174 30 0.0 11 537048.8143439454 21 184081.4916113799 31 0.0 0 LINE 5 A3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537209.7860812404 20 183722.4429300512 30 0.0 11 537209.7835259888 21 183722.4550999909 31 0.0 0 LINE 5 A3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537179.7109393662 20 183865.6823002111 30 0.0 11 537053.7451530563 21 184905.0558512203 31 0.0 0 LINE 5 A3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537285.7407702143 20 184285.4650785877 30 0.0 11 536927.6087474007 21 184218.7015045664 31 0.0 0 LINE 5 A40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536902.8055636038 20 184075.8875942751 30 0.0 11 537153.0466786208 21 184181.3882749635 31 0.0 0 LINE 5 A41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537139.813173592 20 184069.7633527361 30 0.0 11 537104.983989481 21 184062.768950393 31 0.0 0 LINE 5 A42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537462.5493017278 20 184340.4592014045 30 0.0 11 537313.6253257588 21 184238.528493825 31 0.0 0 LINE 5 A43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537318.7630129435 20 184174.9208309981 30 0.0 11 537314.7362410721 21 184240.0712934394 31 0.0 0 LINE 5 A44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537306.3306028621 20 183991.1132651308 30 0.0 11 537239.5962059187 21 184216.1875198294 31 0.0 0 LINE 5 A45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536991.7276180069 20 183956.6673871777 30 0.0 11 537153.3126790687 21 183823.7473975823 31 0.0 0 LINE 5 A46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537330.8101336117 20 184188.0289479002 30 0.0 11 537214.2964619126 21 184175.5887738653 31 0.0 0 LINE 5 A47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536850.2916572344 20 183348.5487562232 30 0.0 11 536977.0885638939 21 183196.2768393831 31 0.0 0 LINE 5 A48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538506.0844988089 20 185996.3447167731 30 0.0 11 538433.2870751908 21 186284.3947174916 31 0.0 0 LINE 5 A49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538236.611476903 20 186108.6966083801 30 0.0 11 538501.3841818756 21 186090.1734869714 31 0.0 0 LINE 5 A4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538247.6415314158 20 186382.4893745176 30 0.0 11 538312.4594926409 21 186052.7036418829 31 0.0 0 LINE 5 A4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538263.2903968339 20 185969.8818847871 30 0.0 11 538438.7877884853 21 185924.2067003186 31 0.0 0 LINE 5 A4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538302.4828347366 20 185505.6609571547 30 0.0 11 538466.5488707956 21 185498.6903299007 31 0.0 0 LINE 5 A4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538307.9656860152 20 186110.5507529264 30 0.0 11 538266.9062898205 21 185870.3496443443 31 0.0 0 LINE 5 A4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538508.4634052267 20 186118.2405843548 30 0.0 11 538511.3285463617 21 185828.1582219318 31 0.0 0 LINE 5 A4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537396.4745148345 20 184361.1420230591 30 0.0 11 536955.6363053342 21 184369.5511270819 31 0.0 0 LINE 5 A50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536878.220237347 20 184474.6403155652 30 0.0 11 536764.0290457257 21 184811.8648697378 31 0.0 0 LINE 5 A51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536952.1839728251 20 183640.2609312836 30 0.0 11 536790.915974635 21 183915.5375969097 31 0.0 0 LINE 5 A52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537476.9348578087 20 186223.2748301299 30 0.0 11 537711.5158275844 21 186252.9584421817 31 0.0 0 LINE 5 A53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538395.4387740356 20 184744.9613180355 30 0.0 11 538432.9385039107 21 184349.3462321565 31 0.0 0 LINE 5 A54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 539877.8866788756 20 184891.7611603959 30 0.0 11 537310.6239412522 21 184351.3091305436 31 0.0 0 LINE 5 A55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537814.5552439405 20 183508.1585503803 30 0.0 11 537814.8800670928 21 183262.9120091844 31 0.0 0 LINE 5 A56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537809.8786362737 20 183474.8905254279 30 0.0 11 538029.4514137471 21 183575.6202981426 31 0.0 0 LINE 5 A57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537711.3315735654 20 183935.324224936 30 0.0 11 538015.7214800934 21 183243.7908669849 31 0.0 0 LINE 5 A58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537987.3340337887 20 183478.2364146344 30 0.0 11 538417.6215874582 21 183566.1931583092 31 0.0 0 LINE 5 A59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538011.5017219228 20 183413.0785304034 30 0.0 11 537950.7870756203 21 183597.2611838649 31 0.0 0 LINE 5 A5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538080.1119026109 20 183436.8491280599 30 0.0 11 538059.475362172 21 183497.7570823913 31 0.0 0 LINE 5 A5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538067.254041463 20 183442.8351735665 30 0.0 11 538466.5541528236 21 183499.0180786073 31 0.0 0 LINE 5 A5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538177.7383998855 20 183382.9089995929 30 0.0 11 538156.1086146076 21 183679.4097346112 31 0.0 0 LINE 5 A5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538143.4576661646 20 183675.2563626459 30 0.0 11 538380.1932672301 21 183706.7528208766 31 0.0 0 LINE 5 A5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538029.4991903743 20 183827.9628345427 30 0.0 11 538159.3536776889 21 183666.5791487954 31 0.0 0 LINE 5 A5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537994.8037000412 20 183747.9740391237 30 0.0 11 538072.202527822 21 183784.0398292791 31 0.0 0 LINE 5 A60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538427.5994829046 20 183372.9994124152 30 0.0 11 538377.7963116212 21 183708.7229530068 31 0.0 0 LINE 5 A61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537987.2676505948 20 183561.1546741433 30 0.0 11 538404.3421191655 21 183637.8626529719 31 0.0 0 LINE 5 A62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538136.6781661074 20 184104.6134311353 30 0.0 11 538403.4681682527 21 183630.9424300478 31 0.0 0 LINE 5 A63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538078.3385411136 20 184028.2843130171 30 0.0 11 538195.7628736324 21 184029.3108907458 31 0.0 0 LINE 5 A64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538108.3427770053 20 183973.9266505879 30 0.0 11 538178.740252172 21 184058.2462590448 31 0.0 0 LINE 5 A65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538188.8749215336 20 183801.8282701278 30 0.0 11 538120.0196803401 21 183991.7392680226 31 0.0 0 LINE 5 A66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537939.2938036606 20 183793.5856215137 30 0.0 11 538260.3908758672 21 183889.432387478 31 0.0 0 LINE 5 A67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537961.2576236966 20 183702.6230213453 30 0.0 11 537939.9348446399 21 183822.175539595 31 0.0 0 LINE 5 A68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537908.8168090213 20 183689.7949374087 30 0.0 11 537962.7655479845 21 183704.1877987506 31 0.0 0 LINE 5 A69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537206.4826825364 20 183499.6604219087 30 0.0 11 538098.9716972564 21 183846.2983439329 31 0.0 0 LINE 5 A6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538111.0367958871 20 183841.2522404741 30 0.0 11 538102.1446973668 21 183863.8505845716 31 0.0 0 LINE 5 A6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538284.5540268816 20 183763.5022230059 30 0.0 11 538324.9594953962 21 183784.0335475451 31 0.0 0 LINE 5 A6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538276.7555211362 20 183750.06685945 30 0.0 11 538290.4489020112 21 183769.8566990866 31 0.0 0 LINE 5 A6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538295.4543408857 20 183688.7576103305 30 0.0 11 538276.4904050032 21 183758.0557452773 31 0.0 0 LINE 5 A6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538057.7887297581 20 183786.0016375257 30 0.0 11 537957.7446373048 21 184126.6554616186 31 0.0 0 LINE 5 A6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537710.7677414869 20 183915.499709055 30 0.0 11 537839.9676797596 21 184073.4048207491 31 0.0 0 LINE 5 A70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537811.0759265745 20 184084.9203551157 30 0.0 11 538025.6232717888 21 183814.7339076289 31 0.0 0 LINE 5 A71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537905.5753177196 20 183768.8385715097 30 0.0 11 537893.116937401 21 183802.1069121628 31 0.0 0 LINE 5 A72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537993.940469664 20 183958.6290663373 30 0.0 11 538078.1024465711 21 183998.9850057228 31 0.0 0 LINE 5 A73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538044.8380369068 20 183987.6265221644 30 0.0 11 538127.4308714822 21 183976.1807404638 31 0.0 0 LINE 5 A74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538047.4464931892 20 183974.7631257476 30 0.0 11 538097.1085396048 21 184037.6744026663 31 0.0 0 LINE 5 A75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538041.0278774243 20 184137.8688116774 30 0.0 11 538097.0996440481 21 184025.0503046117 31 0.0 0 LINE 5 A76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537463.9253455385 20 183879.6009256452 30 0.0 11 537765.8989318906 21 183963.2698940417 31 0.0 0 LINE 5 A77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538102.4009712589 20 183577.2144957746 30 0.0 11 538099.8954127324 21 183624.1594860762 31 0.0 0 LINE 5 A78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538037.9207277609 20 183608.9453800368 30 0.0 11 538101.5956079687 21 183623.3087806971 31 0.0 0 LINE 5 A79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538023.5939100288 20 183561.5079703217 30 0.0 11 537989.2892571234 21 183660.0276831871 31 0.0 0 LINE 5 A7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537854.4824219396 20 183591.9108842141 30 0.0 11 538123.5618546408 21 183721.3519528138 31 0.0 0 LINE 5 A7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538213.6549324865 20 183681.4395983006 30 0.0 11 538200.4046453999 21 183748.9969342792 31 0.0 0 LINE 5 A7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538169.3603302017 20 183741.9118504657 30 0.0 11 538228.306364558 21 183753.6565084122 31 0.0 0 LINE 5 A7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538175.916068853 20 183736.3363101316 30 0.0 11 538161.1998603613 21 183806.1353726237 31 0.0 0 LINE 5 A7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538158.9393539165 20 183803.1841953439 30 0.0 11 538213.7030943297 21 183815.5341965869 31 0.0 0 LINE 5 A7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538224.8008101031 20 183745.3287876775 30 0.0 11 538209.6560467433 21 183821.3335502998 31 0.0 0 LINE 5 A80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537669.289344899 20 183755.306350582 30 0.0 11 537774.2936074787 21 183796.2779917936 31 0.0 0 LINE 5 A81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538145.3254268677 20 184062.9117186055 30 0.0 11 538200.5195342072 21 184558.2110496839 31 0.0 0 LINE 5 A82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538095.2648878094 20 184110.0597751467 30 0.0 11 538132.635675242 21 184334.2760301617 31 0.0 0 LINE 5 A83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537916.6979367347 20 184055.0353602746 30 0.0 11 537875.7696700422 21 184219.831521104 31 0.0 0 LINE 5 A84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537591.4353194408 20 183994.7426366546 30 0.0 11 538201.1645374622 21 184153.3675254576 31 0.0 0 LINE 5 A85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538033.3698653398 20 184176.194425205 30 0.0 11 537841.8627384671 21 184145.6242032781 31 0.0 0 LINE 5 A86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538020.8431763577 20 184247.7170109398 30 0.0 11 537957.4239974094 21 184237.0561740283 31 0.0 0 LINE 5 A87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538050.1119936939 20 184201.8846930842 30 0.0 11 538007.0447717504 21 184255.5733317061 31 0.0 0 LINE 5 A88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538012.8835476444 20 184235.978116407 30 0.0 11 538072.241198677 21 184550.104384331 31 0.0 0 LINE 5 A89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537773.6092314384 20 184167.6227633967 30 0.0 11 537765.0484060659 21 184477.7323845723 31 0.0 0 LINE 5 A8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537735.2444292989 20 183781.0282155746 30 0.0 11 537735.2418740472 21 183781.0403855143 31 0.0 0 LINE 5 A8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537469.4126087932 20 184179.279231093 30 0.0 11 537866.2284132929 21 184257.6630007943 31 0.0 0 LINE 5 A8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537988.0076497864 20 184399.0444869277 30 0.0 11 537839.0836738173 21 184297.1137793482 31 0.0 0 LINE 5 A8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537844.221361002 20 184233.5061165213 30 0.0 11 537840.1945891305 21 184298.6565789625 31 0.0 0 LINE 5 A8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 537831.7889509204 20 184049.6985506539 30 0.0 11 537765.0545539771 21 184274.7728053526 31 0.0 0 LINE 5 A8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538221.7561228781 20 184374.5939745554 30 0.0 11 537966.4165705449 21 184395.8313820429 31 0.0 0 LINE 5 A90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538569.6906192152 20 184388.2048046587 30 0.0 11 538765.456750482 21 184320.5106117761 31 0.0 0 LINE 5 A91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538404.532960823 20 184182.2248015356 30 0.0 11 538881.4736310778 21 184102.7907375266 31 0.0 0 LINE 5 A92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538152.1867049226 20 184204.6791144183 30 0.0 11 538687.6709561274 21 184139.6857072004 31 0.0 0 LINE 5 A93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538397.6492191518 20 184274.5573956118 30 0.0 11 538436.3555897182 21 184163.6910589407 31 0.0 0 LINE 5 A94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538458.9476493293 20 184264.6825743995 30 0.0 11 538403.3704857294 21 184169.9367050105 31 0.0 0 LINE 5 A95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538648.1345476928 20 184247.0304825434 30 0.0 11 538446.1275750394 21 184247.6741909795 31 0.0 0 LINE 5 A96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538563.296467749 20 184671.2499932127 30 0.0 11 538589.843897729 21 184150.1222103075 31 0.0 0 LINE 5 A97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538584.7306784826 20 184306.9718923631 30 0.0 11 538560.4569171519 21 184307.7061150138 31 0.0 0 LINE 5 A98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538618.7422043328 20 184375.7556243205 30 0.0 11 538184.7499534075 21 184358.2053808167 31 0.0 0 LINE 5 A99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538209.1863556376 20 184378.4916169066 30 0.0 11 538252.7188863369 21 184181.9738542562 31 0.0 0 LINE 5 A9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538177.4047095581 20 184483.9306901377 30 0.0 11 538580.8321489674 21 184396.3222899192 31 0.0 0 LINE 5 A9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538434.6941270173 20 184377.5261416259 30 0.0 11 538425.1458909358 21 184284.6785709076 31 0.0 0 LINE 5 A9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538424.5978688746 20 184319.8244920206 30 0.0 11 538463.2751436005 21 184245.9553464877 31 0.0 0 LINE 5 A9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538437.5861508965 20 184321.7154022971 30 0.0 11 538395.1528567 21 184253.718614422 31 0.0 0 LINE 5 A9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538229.3095326769 20 184274.8847787577 30 0.0 11 538407.0316221425 21 184257.9921214577 31 0.0 0 LINE 5 A9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538422.7037947091 20 183903.0013639225 30 0.0 11 538370.1283136902 21 183671.8726575186 31 0.0 0 LINE 5 AA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538491.7553693318 20 183849.7673101204 30 0.0 11 538406.5676464476 21 183843.9045777167 31 0.0 0 LINE 5 AA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538283.0786125945 20 184054.7207939183 30 0.0 11 538179.8023475381 21 183998.8321474391 31 0.0 0 LINE 5 AA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538283.104072871 20 183992.6320752329 30 0.0 11 538180.7086615311 21 184032.3911071209 31 0.0 0 LINE 5 AA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538483.9962729265 20 183892.9340296101 30 0.0 11 538235.9063290492 21 183886.4996817873 31 0.0 0 LINE 5 AA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538519.8065327198 20 183994.0474627546 30 0.0 11 538513.3841593884 21 183872.7782636668 31 0.0 0 LINE 5 AA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538614.4040702685 20 183887.5761744664 30 0.0 11 538569.2653270726 21 183999.6039604346 31 0.0 0 LINE 5 AA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538573.7905810559 20 183994.6143018384 30 0.0 11 538517.9822807369 21 183992.8665865164 31 0.0 0 LINE 5 AA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538765.3257634245 20 183942.5796194973 30 0.0 11 538353.0283476007 21 183885.4527973906 31 0.0 0 LINE 5 AA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538418.2350899841 20 183852.5923292984 30 0.0 11 538353.0316749258 21 184197.756404748 31 0.0 0 LINE 5 AA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538452.3026074006 20 184185.2264531618 30 0.0 11 538432.4939275087 21 183893.2966974193 31 0.0 0 LINE 5 AAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538559.7654428084 20 183911.1811752413 30 0.0 11 538554.581288617 21 183946.3254247748 31 0.0 0 LINE 5 AAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538390.6367578734 20 184034.5680462495 30 0.0 11 538297.4546042756 21 184029.1897145885 31 0.0 0 LINE 5 AAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538332.0634956199 20 184035.3346913154 30 0.0 11 538265.3064492604 21 183985.3739166687 31 0.0 0 LINE 5 AAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538336.0011766956 20 184022.814081135 30 0.0 11 538262.108396395 21 184053.8625052031 31 0.0 0 LINE 5 AAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538256.5602894736 20 184220.9589837579 30 0.0 11 538268.2212810583 21 184042.8171182967 31 0.0 0 LINE 5 AAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538690.0497256613 20 183781.0278188786 30 0.0 11 538391.9298545738 21 183764.1970789722 31 0.0 0 LINE 5 AB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 538320.4529850837 20 183367.3444202856 30 0.0 11 538206.2617934625 21 183704.568974458 31 0.0 0 LINE 5 AB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535649.0581230556 20 184628.1294401782 30 0.0 11 535631.7063125931 21 184416.4013498721 31 0.0 0 LINE 5 ABA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536044.1049790082 20 186337.1683777391 30 0.0 11 535278.8738929772 21 186537.6480541799 31 0.0 0 LINE 5 ABC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536072.4992580615 20 186395.8464045735 30 0.0 11 535593.9523860775 21 186520.2549979555 31 0.0 0 LINE 5 AC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535947.4422199873 20 186595.5290238438 30 0.0 11 535803.0955322193 21 186708.2359403478 31 0.0 0 LINE 5 AC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536202.8271529145 20 186974.3219773433 30 0.0 11 535694.707314849 21 186335.5423163722 31 0.0 0 LINE 5 AC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535818.8285570935 20 186603.307553388 30 0.0 11 535425.4906564561 21 186798.6765978215 31 0.0 0 LINE 5 AC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535778.7584118029 20 186546.5271828044 30 0.0 11 535884.678955602 21 186708.9782724068 31 0.0 0 LINE 5 AC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535718.5393726928 20 186587.098916015 30 0.0 11 535754.1065128451 21 186640.6771228112 31 0.0 0 LINE 5 AC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535748.4765621386 20 186541.7003508794 30 0.0 11 535716.9843364775 21 186602.9008022333 31 0.0 0 LINE 5 ACA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535732.5023976116 20 186589.5871421354 30 0.0 11 535360.9665969115 21 186746.2978518829 31 0.0 0 LINE 5 ACB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535574.3164212192 20 186456.0321643507 30 0.0 11 535707.2930778238 21 186841.0372332034 31 0.0 0 LINE 5 ACC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535718.4556937626 20 186833.7782387417 30 0.0 11 535497.7159083774 21 186924.9358979981 31 0.0 0 LINE 5 ACD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535867.7666592935 20 186952.1506862782 30 0.0 11 535700.8659413488 21 186829.4680377467 31 0.0 0 LINE 5 ACE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535880.7872831714 20 186865.9390409171 30 0.0 11 535815.2268489009 21 186920.6487221414 31 0.0 0 LINE 5 ACF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535464.218589661 20 186471.9204713913 30 0.0 11 535498.0845958487 21 186555.4380421386 31 0.0 0 LINE 5 AD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535312.8942598835 20 186492.9379767162 30 0.0 11 535500.5379656564 21 186926.2253977131 31 0.0 0 LINE 5 AD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535840.1584424718 20 186683.4354396475 30 0.0 11 535456.7067650441 21 186864.5432457396 31 0.0 0 LINE 5 AD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535792.0308519474 20 187205.0714274164 30 0.0 11 535455.7766825467 21 186857.6303431607 31 0.0 0 LINE 5 AD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535953.8302439406 20 187400.0170244034 30 0.0 11 535596.2123914296 21 186996.1890934282 31 0.0 0 LINE 5 AD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535871.9364952116 20 187158.2976954422 30 0.0 11 535758.7029100819 21 187189.4052978565 31 0.0 0 LINE 5 AD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535828.9949065974 20 187113.4531907232 30 0.0 11 535782.5771207934 21 187213.0071461503 31 0.0 0 LINE 5 AD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535707.0189022852 20 186967.7647106319 30 0.0 11 535822.2768904915 21 187133.664763422 31 0.0 0 LINE 5 AD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535946.1383772131 20 186895.7886565231 30 0.0 11 535660.3624120137 21 187070.7801707167 31 0.0 0 LINE 5 ADB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536093.3785918208 20 186779.22303751 30 0.0 11 535805.3202201372 21 186987.6902748207 31 0.0 0 LINE 5 ADC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535792.3645056573 20 186985.9072360099 30 0.0 11 535806.7549013131 21 187005.4692166076 31 0.0 0 LINE 5 ADD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535604.7106224969 20 186955.2589929417 30 0.0 11 535570.922175215 21 186985.4662437851 31 0.0 0 LINE 5 ADE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535608.8025781208 20 186940.2729466015 30 0.0 11 535600.642619605 21 186962.912767927 31 0.0 0 LINE 5 ADF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535575.0054296454 20 186885.809907368 30 0.0 11 535611.107705352 21 186947.9266366771 31 0.0 0 LINE 5 AE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535829.6616892381 20 186918.8482636828 30 0.0 11 536061.6989027946 21 187286.0212698194 31 0.0 0 LINE 5 AE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536064.5174208748 20 187254.3870307029 30 0.0 11 535878.0458398946 21 187330.167382727 31 0.0 0 LINE 5 AE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536198.2878103921 20 186955.0159237332 30 0.0 11 536041.0632611067 21 187281.9180588759 31 0.0 0 LINE 5 AE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536158.9397449123 20 187206.8657446049 30 0.0 11 535868.1201696403 21 186938.3701825645 31 0.0 0 LINE 5 AE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535935.6475141795 20 187069.3269479096 30 0.0 11 535864.6504141312 21 187129.9178051844 31 0.0 0 LINE 5 AE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535893.8891706733 20 187110.4080328917 30 0.0 11 535811.1233449206 21 187120.5273376794 31 0.0 0 LINE 5 AE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535888.0689337474 20 187098.643856181 30 0.0 11 535856.2025322552 21 187172.1875851703 31 0.0 0 LINE 5 AE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535967.8130721198 20 187296.6669088628 30 0.0 11 535852.9734771124 21 187159.9834410502 31 0.0 0 LINE 5 AEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535732.9947596506 20 186728.4859055958 30 0.0 11 535747.4563138236 21 186773.2181466402 31 0.0 0 LINE 5 AEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535803.4562431559 20 186742.6184977095 30 0.0 11 535745.5948075422 21 186772.8319370493 31 0.0 0 LINE 5 AED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535805.1377876865 20 186693.0933732292 30 0.0 11 535863.5620270077 21 186779.5199391322 31 0.0 0 LINE 5 AEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535976.3903589083 20 186679.1080442436 30 0.0 11 535749.5080107486 21 186873.2294790124 31 0.0 0 LINE 5 AEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535652.1920898013 20 186857.7578841165 30 0.0 11 535682.3253639074 21 186919.6573957788 31 0.0 0 LINE 5 AF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535710.5142631384 20 186904.8474707648 30 0.0 11 535656.5518900161 21 186931.3169672393 31 0.0 0 LINE 5 AF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535702.7478557151 20 186901.1397389758 30 0.0 11 535734.8729477382 21 186964.8300394907 31 0.0 0 LINE 5 AF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535736.3009706147 20 186961.3978262998 30 0.0 11 535686.5362572322 21 186987.3798026816 31 0.0 0 LINE 5 AF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535657.8044169427 20 186922.3687260173 30 0.0 11 535691.9352817553 21 186991.9472562233 31 0.0 0 LINE 5 AF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535616.9046285221 20 186571.529962643 30 0.0 11 535367.6823060016 21 186660.4230653926 31 0.0 0 LINE 5 AF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535093.9650888768 20 186451.4096970502 30 0.0 11 535154.0885972468 21 186586.4758232478 31 0.0 0 LINE 5 AF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535256.4286973283 20 186478.0102726568 30 0.0 11 534777.8818253441 21 186602.4188660389 31 0.0 0 LINE 5 AF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535149.7886778084 20 186554.1141029375 30 0.0 11 535138.3416224898 21 186635.2933070427 31 0.0 0 LINE 5 AF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535227.3633349829 20 186572.484954252 30 0.0 11 535140.2165797861 21 186561.4002107324 31 0.0 0 LINE 5 AFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535212.3860523695 20 186563.4247814637 30 0.0 11 535309.0943364181 21 186737.2113188613 31 0.0 0 LINE 5 AFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535395.3693409279 20 186471.5616316553 30 0.0 11 534987.024971486 21 186790.399808431 31 0.0 0 LINE 5 AFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535263.0990040753 20 186768.6254398828 30 0.0 11 535136.6871637996 21 186631.2941419262 31 0.0 0 LINE 5 AFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535310.0847298305 20 186730.337642818 30 0.0 11 535262.2561282982 21 186768.5350976643 31 0.0 0 LINE 5 AFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535466.9826670145 20 186982.9939123589 30 0.0 11 535277.370685492 21 186754.098166188 31 0.0 0 LINE 5 AFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535426.2159510503 20 186928.0417294869 30 0.0 11 535334.3736976055 21 186994.0932381661 31 0.0 0 LINE 5 B00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535386.7565921814 20 187056.4858454265 30 0.0 11 534915.1926836778 21 186466.1477384471 31 0.0 0 LINE 5 B01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535002.7579963602 20 186685.4714214713 30 0.0 11 534433.1757887198 21 186994.3605355972 31 0.0 0 LINE 5 B02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534962.6878510696 20 186628.6910508876 30 0.0 11 535068.6083948688 21 186791.1421404901 31 0.0 0 LINE 5 B03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534902.4688119596 20 186669.2627840982 30 0.0 11 534938.0359521117 21 186722.8409908944 31 0.0 0 LINE 5 B04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534932.4060014054 20 186623.8642189625 30 0.0 11 534900.9137757443 21 186685.0646703165 31 0.0 0 LINE 5 B05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534916.4318368784 20 186671.7510102187 30 0.0 11 534786.9073252073 21 186726.3833716639 31 0.0 0 LINE 5 B06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534758.2458604859 20 186538.196032434 30 0.0 11 534891.2225170906 21 186923.2011012866 31 0.0 0 LINE 5 B07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534902.3851330294 20 186915.9421068249 30 0.0 11 534681.6453476442 21 187007.0997660814 31 0.0 0 LINE 5 B08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535051.6960985602 20 187034.3145543616 30 0.0 11 534884.7953806155 21 186911.63190583 31 0.0 0 LINE 5 B09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535064.716722438 20 186948.1029090003 30 0.0 11 534999.1562881677 21 187002.8125902247 31 0.0 0 LINE 5 B0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534635.2210719854 20 186561.7439201856 30 0.0 11 534669.0870781731 21 186645.2614909329 31 0.0 0 LINE 5 B0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535024.0878817386 20 186765.5993077308 30 0.0 11 534640.636204311 21 186946.7071138229 31 0.0 0 LINE 5 B0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535055.8659344782 20 187240.4615635254 30 0.0 11 534942.6323493486 21 187271.5691659399 31 0.0 0 LINE 5 B0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535012.9243458644 20 187195.6170588064 30 0.0 11 534966.5065600603 21 187295.1710142336 31 0.0 0 LINE 5 B0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534890.9483415519 20 187049.9285787151 30 0.0 11 535006.2063297581 21 187215.8286315053 31 0.0 0 LINE 5 B0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535130.06781648 20 186977.9525246064 30 0.0 11 534769.6503777293 21 187209.2714730936 31 0.0 0 LINE 5 B10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535085.5097921989 20 186895.6653051118 30 0.0 11 535136.7805609917 21 187005.7506074639 31 0.0 0 LINE 5 B11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535219.0237330307 20 186945.2521677223 30 0.0 11 535126.5684119001 21 186867.5363742124 31 0.0 0 LINE 5 B12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535132.9066622104 20 186869.8169880601 30 0.0 11 535084.4536154681 21 186897.5644772211 31 0.0 0 LINE 5 B13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535445.0174913342 20 186740.0159221909 30 0.0 11 534989.2496594038 21 187069.854142904 31 0.0 0 LINE 5 B14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534976.2939449241 20 187068.0711040932 30 0.0 11 534990.68434058 21 187087.6330846908 31 0.0 0 LINE 5 B15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534788.6400617637 20 187037.422861025 30 0.0 11 534729.1827484464 21 187087.0008624204 31 0.0 0 LINE 5 B16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534792.7320173874 20 187022.4368146847 30 0.0 11 534784.5720588717 21 187045.0766360102 31 0.0 0 LINE 5 B17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534758.9348689123 20 186967.9737754513 30 0.0 11 534795.0371446187 21 187030.0905047604 31 0.0 0 LINE 5 B18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535013.5911285049 20 187001.0121317661 30 0.0 11 535197.6552260111 21 187304.6142666616 31 0.0 0 LINE 5 B19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535382.2172496589 20 187037.1797918165 30 0.0 11 535297.8359402907 21 187222.9388911312 31 0.0 0 LINE 5 B1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535328.7147017309 20 187226.6595128224 30 0.0 11 535052.049608907 21 187020.5340506478 31 0.0 0 LINE 5 B1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535156.3117485155 20 186945.3855350409 30 0.0 11 535176.8856377365 21 186974.3460048628 31 0.0 0 LINE 5 B1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535119.5769534462 20 187151.4908159928 30 0.0 11 535048.579853398 21 187212.0816732677 31 0.0 0 LINE 5 B1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535077.8186099403 20 187192.5719009749 30 0.0 11 534995.0527841873 21 187202.6912057627 31 0.0 0 LINE 5 B1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535071.9983730142 20 187180.8077242643 30 0.0 11 535040.1319715219 21 187254.3514532537 31 0.0 0 LINE 5 B1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535120.0333856632 20 187336.8118939866 30 0.0 11 535036.9029163791 21 187242.1473091334 31 0.0 0 LINE 5 B20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535523.0330148909 20 186898.5464673954 30 0.0 11 535341.1814526257 21 187097.4914995595 31 0.0 0 LINE 5 B21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534916.9241989173 20 186810.649773679 30 0.0 11 534931.3857530902 21 186855.3820147234 31 0.0 0 LINE 5 B22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534987.3856824226 20 186824.7823657927 30 0.0 11 534929.5242468087 21 186854.9958051326 31 0.0 0 LINE 5 B23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534989.0672269532 20 186775.2572413124 30 0.0 11 535047.4914662743 21 186861.6838072155 31 0.0 0 LINE 5 B24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535160.319798175 20 186761.2719123269 30 0.0 11 534933.4374500154 21 186955.3933470955 31 0.0 0 LINE 5 B25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534836.1215290681 20 186939.9217521998 30 0.0 11 534866.254803174 21 187001.821263862 31 0.0 0 LINE 5 B26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534894.4437024051 20 186987.011338848 30 0.0 11 534840.4813292829 21 187013.4808353226 31 0.0 0 LINE 5 B27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534886.6772949818 20 186983.3036070591 30 0.0 11 534918.8023870048 21 187046.9939075741 31 0.0 0 LINE 5 B28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534920.2304098814 20 187043.5616943832 30 0.0 11 534870.465696499 21 187069.5436707649 31 0.0 0 LINE 5 B29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534841.7338562095 20 187004.5325941006 30 0.0 11 534875.864721022 21 187074.1111243065 31 0.0 0 LINE 5 B2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535381.2241621185 20 186871.7065817206 30 0.0 11 535290.2397902417 21 186938.2378872666 31 0.0 0 LINE 5 B2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534800.8340677889 20 186653.6938307262 30 0.0 11 534551.6117452683 21 186742.5869334758 31 0.0 0 LINE 5 B2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534315.9374838286 20 186110.7368073677 30 0.0 11 535072.5823581115 21 187921.5456161805 31 0.0 0 LINE 5 B2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535060.4783531628 20 187323.8429344235 30 0.0 11 535081.8613660606 21 187550.1442192757 31 0.0 0 LINE 5 B2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535218.9609189549 20 187224.8625394553 30 0.0 11 535300.7848955697 21 187373.6500876221 31 0.0 0 LINE 5 B2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535627.2033165716 20 187021.4595680193 30 0.0 11 534938.2488278624 21 187410.3482337611 31 0.0 0 LINE 5 B30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535199.7075450184 20 187341.3876688161 30 0.0 11 535329.8599296329 21 187760.8446086559 31 0.0 0 LINE 5 B31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535137.264482519 20 187371.8916189357 30 0.0 11 535314.5260884354 21 187293.2287866729 31 0.0 0 LINE 5 B32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535167.7153126758 20 187437.8093339281 30 0.0 11 535226.2791814901 21 187411.2401982319 31 0.0 0 LINE 5 B33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535127.6710070983 20 187401.0164185898 30 0.0 11 535183.0670851085 21 187441.8640631253 31 0.0 0 LINE 5 B34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535172.3980890155 20 187424.4216926175 30 0.0 11 535267.8630374448 21 187816.1914481792 31 0.0 0 LINE 5 B35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535011.5144413881 20 187559.0584404998 30 0.0 11 535416.6115988639 21 187489.4018411997 31 0.0 0 LINE 5 B36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535411.2253370809 20 187477.224600987 30 0.0 11 535466.0201099505 21 187709.6752507155 31 0.0 0 LINE 5 B37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535551.890772004 20 187348.698198324 30 0.0 11 535404.165619358 21 187493.9020590748 31 0.0 0 LINE 5 B38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535468.8582171794 20 187322.0978358947 30 0.0 11 535512.4144401708 21 187395.5428847416 31 0.0 0 LINE 5 B39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534761.5383226473 20 187886.4093640894 30 0.0 11 535467.7430850394 21 187707.0949070089 31 0.0 0 LINE 5 B3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535282.211313556 20 187333.1069476038 30 0.0 11 535399.8612585677 21 187740.5302125117 31 0.0 0 LINE 5 B3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535789.4997419352 20 187463.7929037642 30 0.0 11 535392.8884976999 21 187740.3461435108 31 0.0 0 LINE 5 B3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535975.9026101069 20 187355.3210338819 30 0.0 11 535552.0668299141 21 187623.8001261673 31 0.0 0 LINE 5 B3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535756.0652602497 20 187377.4515506207 30 0.0 11 535768.7199492786 21 187494.1965144302 31 0.0 0 LINE 5 B3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535704.9475115667 20 187412.6933639361 30 0.0 11 535795.8265493328 21 187474.3910249521 31 0.0 0 LINE 5 B3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535541.6740385804 20 187509.8790206878 30 0.0 11 535723.8293243902 21 187422.5481371889 31 0.0 0 LINE 5 B40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535522.3193812402 20 187293.7612209985 30 0.0 11 535635.9322342677 21 187572.3642641195 31 0.0 0 LINE 5 B41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535571.6792890632 20 187217.0670909279 30 0.0 11 535475.5139251245 21 187291.2269743228 31 0.0 0 LINE 5 B42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535430.3202100606 20 187199.6762852104 30 0.0 11 535548.1629601752 21 187173.2033327564 31 0.0 0 LINE 5 B43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535541.4860475573 20 187172.3125721767 30 0.0 11 535571.743415313 21 187219.2392446545 31 0.0 0 LINE 5 B44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535324.0718488141 20 186913.4833764857 30 0.0 11 535324.0774397778 21 186913.4944840446 31 0.0 0 LINE 5 B45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535389.8771166202 20 187044.2185976446 30 0.0 11 535577.0186818464 21 187416.0124484055 31 0.0 0 LINE 5 B46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535573.1926850023 20 187428.5181076536 30 0.0 11 535594.7989219584 21 187417.4309485659 31 0.0 0 LINE 5 B47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535513.0154098396 20 187608.8843745172 30 0.0 11 535537.4486776886 21 187647.0570426904 31 0.0 0 LINE 5 B48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535498.8735477308 20 187602.4552671278 30 0.0 11 535519.9226271356 21 187614.120715633 31 0.0 0 LINE 5 B49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535439.7183894071 20 187627.1359707509 30 0.0 11 535506.7968675183 21 187601.4000008731 31 0.0 0 LINE 5 B4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535512.9386306098 20 187381.005639796 30 0.0 11 535834.0641552604 21 187238.6394860438 31 0.0 0 LINE 5 B4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535767.3710462818 20 187164.0489575836 30 0.0 11 535538.3429394452 21 187346.1519294588 31 0.0 0 LINE 5 B4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535480.7803021392 20 187231.2413731987 30 0.0 11 535512.650735354 21 187215.5484060904 31 0.0 0 LINE 5 B4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535678.3914122045 20 187300.3693789839 30 0.0 11 535726.886700457 21 187380.1192831711 31 0.0 0 LINE 5 B4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535712.2886086333 20 187348.143795463 30 0.0 11 535709.0815591129 21 187431.4642435856 31 0.0 0 LINE 5 B4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535699.7469116659 20 187352.0137888389 30 0.0 11 535767.2686885993 21 187395.19893973 31 0.0 0 LINE 5 B50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535907.9515918173 20 187304.8643650759 30 0.0 11 535754.7058132201 21 187396.4407501155 31 0.0 0 LINE 5 B51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535309.5983215623 20 187446.0828352542 30 0.0 11 535356.0641428375 21 187438.9387893999 31 0.0 0 LINE 5 B52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535334.7850856074 20 187378.7762402243 30 0.0 11 535355.3860598539 21 187440.7148994615 31 0.0 0 LINE 5 B53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535286.161693467 20 187369.219500009 30 0.0 11 535380.7981985624 21 187325.3233163779 31 0.0 0 LINE 5 B54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535299.6612624473 20 187197.9279525986 30 0.0 11 535455.1230943988 21 187452.8600026617 31 0.0 0 LINE 5 B55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535424.3325575165 20 187546.4639638863 30 0.0 11 535490.2448484002 21 187526.585994603 31 0.0 0 LINE 5 B56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535480.1190769222 20 187496.3963163875 30 0.0 11 535497.6457072415 21 187553.8888305634 31 0.0 0 LINE 5 B57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535475.2204386095 20 187503.472169832 30 0.0 11 535543.2181998905 21 187481.9134041444 31 0.0 0 LINE 5 B58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535540.0575937758 20 187479.9563896547 30 0.0 11 535557.7722519484 21 187533.2272135696 31 0.0 0 LINE 5 B59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535489.0116612563 20 187551.2255441356 30 0.0 11 535563.1421371856 21 187528.6255366802 31 0.0 0 LINE 5 B5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535136.1400328259 20 187535.6613407249 30 0.0 11 535184.1577223208 21 187795.8690486325 31 0.0 0 LINE 5 B5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536619.1422674942 20 186063.4384918894 30 0.0 11 534385.6388024107 21 186630.7233926483 31 0.0 0 LINE 5 B5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536009.1899432151 20 186152.3224343746 30 0.0 11 535530.6430712309 21 186276.7310277567 31 0.0 0 LINE 5 B62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535789.7596570048 20 186038.0820289988 30 0.0 11 535621.7540618088 21 186010.6925386679 31 0.0 0 LINE 5 B67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535841.2831803683 20 185583.6162998391 30 0.0 11 535707.9985295088 21 186382.4418322399 31 0.0 0 LINE 5 B68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535686.5980695482 20 186094.6731859741 30 0.0 11 535247.9119028322 21 186115.6067650437 31 0.0 0 LINE 5 B69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535679.254929043 20 186163.7796640695 30 0.0 11 535692.6464049468 21 185970.3108384543 31 0.0 0 LINE 5 B6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535606.9008764697 20 186157.6731688996 30 0.0 11 535611.8706933489 21 186093.5565047453 31 0.0 0 LINE 5 B6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535655.1579625586 20 186182.7434435389 30 0.0 11 535597.8467779507 21 186144.6293563551 31 0.0 0 LINE 5 B6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535617.8841629698 20 186148.6996104211 30 0.0 11 535217.06732667 21 186192.7786472781 31 0.0 0 LINE 5 B6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535544.7715556255 20 186342.3856498398 30 0.0 11 535473.4036100022 21 185941.3640661544 31 0.0 0 LINE 5 B6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535486.6882193292 20 185942.2674764811 30 0.0 11 535249.5007487831 21 185970.1578961421 31 0.0 0 LINE 5 B6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535559.443817224 20 185766.1640303519 30 0.0 11 535473.4247487389 21 185954.5986390577 31 0.0 0 LINE 5 B70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535612.8032851592 20 185835.1187373975 30 0.0 11 535528.8985618088 21 185819.265751531 31 0.0 0 LINE 5 B71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535363.8624569724 20 186390.6854996359 30 0.0 11 535352.7652373983 21 186301.2486911264 31 0.0 0 LINE 5 B72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535298.4747702867 20 186437.4723416302 30 0.0 11 535251.3374745445 21 185967.6572451714 31 0.0 0 LINE 5 B73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535666.2028374502 20 186014.3023164108 30 0.0 11 535243.0967797666 21 186042.8766108213 31 0.0 0 LINE 5 B74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535312.5258796923 20 185704.2535522482 30 0.0 11 535245.6512305763 21 186049.3672237799 31 0.0 0 LINE 5 B75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535416.487460791 20 185333.088196827 30 0.0 11 535364.8931120207 21 185568.1096593225 31 0.0 0 LINE 5 B76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 536046.2969796299 20 185831.6422799202 30 0.0 11 535487.5951750196 21 185765.5373482527 31 0.0 0 LINE 5 B77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535477.148214591 20 185773.4044177763 30 0.0 11 535480.189375884 21 185749.310727523 31 0.0 0 LINE 5 B78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535328.1803358655 20 185891.5647570459 30 0.0 11 535266.9905951748 21 185879.2653775681 31 0.0 0 LINE 5 B79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535339.0528098024 20 185902.6604767717 30 0.0 11 535320.899798502 21 185886.861280167 31 0.0 0 LINE 5 B7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535336.0598177444 20 185966.6879075037 30 0.0 11 535337.3385210526 21 185894.8531854739 31 0.0 0 LINE 5 B7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535550.6666908782 20 186027.1474802185 30 0.0 11 535541.5113962165 21 185981.0357624278 31 0.0 0 LINE 5 B80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535605.323856681 20 185980.4875933348 30 0.0 11 535540.0736759655 21 185982.279677201 31 0.0 0 LINE 5 B81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535630.9125847318 20 186022.9232215679 30 0.0 11 535639.8474398627 21 185918.985204472 31 0.0 0 LINE 5 B82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535787.2935449371 20 185951.7331389566 30 0.0 11 535494.595068434 21 185892.687959679 31 0.0 0 LINE 5 B83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535417.1357243587 20 185953.5961589125 30 0.0 11 535413.306971826 21 185884.8582188327 31 0.0 0 LINE 5 B84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535445.1396205757 20 185884.0642463102 30 0.0 11 535385.1182318035 21 185887.2272901695 31 0.0 0 LINE 5 B85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535440.162310145 20 185891.0849827503 30 0.0 11 535437.201021822 21 185819.8129216839 31 0.0 0 LINE 5 B86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535440.1198196912 20 185822.1150849543 30 0.0 11 535384.0020468323 21 185823.6595473568 31 0.0 0 LINE 5 B87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535390.570210269 20 185894.4325504339 30 0.0 11 535386.493008466 21 185817.0409215329 31 0.0 0 LINE 5 B88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535176.3899097375 20 186455.1643532043 30 0.0 11 535176.1881728044 21 186225.9779133883 31 0.0 0 LINE 5 B89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535193.3728299822 20 186389.7491184667 30 0.0 11 534868.9928159219 21 186336.3803769501 31 0.0 0 LINE 5 B8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535120.7169243895 20 186220.9422211613 30 0.0 11 535077.1945969464 21 186402.45157567 31 0.0 0 LINE 5 B8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535180.4008373886 20 186231.4989421477 30 0.0 11 535120.0247670033 21 186221.4316283989 31 0.0 0 LINE 5 B8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535194.3829037004 20 185934.4187256195 30 0.0 11 535140.2568009018 21 186226.6794502267 31 0.0 0 LINE 5 B8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535073.9299995649 20 186013.6552183236 30 0.0 11 534964.1750705812 21 186654.5621188186 31 0.0 0 LINE 5 B8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534933.8368236612 20 186420.3610242562 30 0.0 11 534668.7196878103 21 186433.0120968159 31 0.0 0 LINE 5 B8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534926.4936831563 20 186489.4675023514 30 0.0 11 534939.8851590602 21 186295.9986767365 31 0.0 0 LINE 5 B90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534854.1396305828 20 186483.3610071817 30 0.0 11 534859.1094474623 21 186419.2443430274 31 0.0 0 LINE 5 B91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534902.3967166717 20 186508.4312818211 30 0.0 11 534845.0855320638 21 186470.3171946374 31 0.0 0 LINE 5 B92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534865.122917083 20 186474.3874487032 30 0.0 11 534464.3060807833 21 186518.4664855602 31 0.0 0 LINE 5 B93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534772.8410603143 20 186559.7220764609 30 0.0 11 534720.6423641154 21 186267.0519044365 31 0.0 0 LINE 5 B94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534733.9269734424 20 186267.9553147632 30 0.0 11 534496.7395028962 21 186295.8457344243 31 0.0 0 LINE 5 B95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534861.5969108653 20 185960.9438478748 30 0.0 11 534720.663502852 21 186280.2864773399 31 0.0 0 LINE 5 B96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535064.2461378692 20 186212.2592482234 30 0.0 11 534776.1373159221 21 186144.9535898132 31 0.0 0 LINE 5 B97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534913.4415915634 20 186339.9901546929 30 0.0 11 534490.33553388 21 186368.5644491034 31 0.0 0 LINE 5 B98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534622.3544160384 20 185848.4946772513 30 0.0 11 534660.5457259393 21 186210.5460571149 31 0.0 0 LINE 5 B9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535293.5357337432 20 186157.3301182024 30 0.0 11 534976.4236209976 21 186125.0078848395 31 0.0 0 LINE 5 B9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535001.4616769477 20 186133.8790524274 30 0.0 11 534802.517987515 21 185784.6896027268 31 0.0 0 LINE 5 B9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534876.4274104778 20 185870.5294370419 30 0.0 11 534730.5918755537 21 185951.5413389166 31 0.0 0 LINE 5 BA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535284.4647476339 20 185980.8759516614 30 0.0 11 535142.8676494943 21 185933.7047163851 31 0.0 0 LINE 5 BA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534797.9054449913 20 186352.8353185006 30 0.0 11 534788.7501503297 21 186306.7236007099 31 0.0 0 LINE 5 BA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534852.5626107943 20 186306.1754316169 30 0.0 11 534787.3124300786 21 186307.9675154832 31 0.0 0 LINE 5 BA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534878.151338845 20 186348.61105985 30 0.0 11 534887.086193976 21 186244.6730427542 31 0.0 0 LINE 5 BA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535034.5322990501 20 186277.4209772388 30 0.0 11 534741.8338225472 21 186218.3757979611 31 0.0 0 LINE 5 BA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534664.374478472 20 186279.2839971947 30 0.0 11 534660.5457259393 21 186210.5460571149 31 0.0 0 LINE 5 BA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535173.6825358063 20 186073.3823391721 30 0.0 11 535061.815428612 21 186059.5866560993 31 0.0 0 LINE 5 BBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535194.578432252 20 185635.8937551822 30 0.0 11 535401.461030561 21 185836.6217479292 31 0.0 0 LINE 5 BBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535103.4200229305 20 186064.72977994 30 0.0 11 535103.419496319 21 186064.7173557932 31 0.0 0 LINE 5 BC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535101.9172540151 20 185758.6967996004 30 0.0 11 535079.5950350825 21 185502.6355365788 31 0.0 0 LINE 5 BC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534987.1535696143 20 185571.4007763362 30 0.0 11 535390.4806209565 21 185532.3625558564 31 0.0 0 LINE 5 BC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535273.8636907524 20 185616.7485285761 30 0.0 11 535079.8401373477 21 185582.4869303215 31 0.0 0 LINE 5 BC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534822.7512757593 20 185902.4195618786 30 0.0 11 535404.497080421 21 185512.3435931971 31 0.0 0 LINE 5 BC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535224.4539681542 20 185554.265367827 30 0.0 11 535175.1006113234 21 185446.6389761997 31 0.0 0 LINE 5 BD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535739.1814437658 20 185783.4852240454 30 0.0 11 535709.1316076679 21 185947.0952454507 31 0.0 0 LINE 5 BD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535544.0552051991 20 186338.3604256307 30 0.0 11 535458.7509072162 21 186517.2105554664 31 0.0 0 LINE 5 BD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534557.5132893847 20 188709.4671073466 30 0.0 11 534078.7111282838 21 189277.7834406533 31 0.0 0 LINE 5 BD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534356.231596675 20 188753.5477289792 30 0.0 11 534250.4530444998 21 188856.8366083633 31 0.0 0 LINE 5 BD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534387.7094145916 20 188915.137214011 30 0.0 11 534104.8479175942 21 188509.583296129 31 0.0 0 LINE 5 BD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534279.3071116973 20 188841.5652935944 30 0.0 11 534199.2053122115 21 188859.023815117 31 0.0 0 LINE 5 BD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534289.0209621512 20 188920.691501156 30 0.0 11 534269.1501844531 21 188835.1194223341 31 0.0 0 LINE 5 BDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534293.6322883562 20 188902.2400626908 30 0.0 11 534164.2491112132 21 189053.2839180996 31 0.0 0 LINE 5 BDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534369.5931450922 20 188998.4730747685 30 0.0 11 534001.2018272664 21 188770.9932772706 31 0.0 0 LINE 5 BDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534117.4997940166 20 189022.3213050065 30 0.0 11 534202.3809702101 21 188856.0834492446 31 0.0 0 LINE 5 BDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534169.7222849479 20 189053.0853305843 30 0.0 11 534117.2917871034 21 189021.4995176764 31 0.0 0 LINE 5 BDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533987.2820451778 20 189287.9634099007 30 0.0 11 534136.0793077706 21 189030.6594247062 31 0.0 0 LINE 5 BDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534024.6557512186 20 189230.6495928087 30 0.0 11 533930.8192540997 21 189167.463256271 31 0.0 0 LINE 5 BE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533890.5024755896 20 189238.254233489 30 0.0 11 534313.0549878999 21 188539.9172092332 31 0.0 0 LINE 5 BE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534105.0630630806 20 188749.3059962787 30 0.0 11 533785.2505457025 21 188448.3014758329 31 0.0 0 LINE 5 BE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534144.393078485 20 188692.0104736309 30 0.0 11 534028.8391525893 21 188847.7564473246 31 0.0 0 LINE 5 BE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534085.4329589249 20 188649.6300240285 30 0.0 11 534047.5419248361 21 188701.5907326242 31 0.0 0 LINE 5 BE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534138.4027586058 20 188661.9371500156 30 0.0 11 534070.0745867984 21 188653.6596829845 31 0.0 0 LINE 5 BE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534087.9488873361 20 188663.5880840061 30 0.0 11 533811.9602070268 21 188369.6028019041 31 0.0 0 LINE 5 BE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534158.2538218248 20 188468.8653287749 30 0.0 11 533843.3949501841 21 188727.2750522629 31 0.0 0 LINE 5 BE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533854.0788294193 20 188735.2218578901 30 0.0 11 533691.9335150255 21 188559.8802806386 31 0.0 0 LINE 5 BE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533794.9291670263 20 188916.3492114355 30 0.0 11 533852.0119277566 21 188717.2300503069 31 0.0 0 LINE 5 BE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533880.2966608565 20 188898.6185758231 30 0.0 11 533806.2235569675 21 188856.1392274093 31 0.0 0 LINE 5 BEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534192.1061369314 20 188120.0411750974 30 0.0 11 534038.560469262 21 188431.9015479835 31 0.0 0 LINE 5 BEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534032.8547598519 20 188236.5322474452 30 0.0 11 533691.7043628487 21 188562.9745181988 31 0.0 0 LINE 5 BEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534037.3303856688 20 188797.1361810715 30 0.0 11 533734.3248614275 21 188500.4496821728 31 0.0 0 LINE 5 BED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533531.4485612727 20 188933.1654001786 30 0.0 11 533740.4844665125 21 188497.1766803831 31 0.0 0 LINE 5 BEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533404.8291103822 20 189152.5972658912 30 0.0 11 533659.3226478687 21 188676.9917932062 31 0.0 0 LINE 5 BEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533603.0616876657 20 188991.8531668461 30 0.0 11 533534.5649698983 21 188896.4711591908 31 0.0 0 LINE 5 BF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533630.2015349752 20 188936.0101876615 30 0.0 11 533520.7235654619 21 188927.0561343128 31 0.0 0 LINE 5 BF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533724.4602508802 20 188771.0296635525 30 0.0 11 533608.9148788381 21 188936.7296887813 31 0.0 0 LINE 5 BF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533875.0010558523 20 188970.2685696257 30 0.0 11 533611.6533331736 21 188763.0539241843 31 0.0 0 LINE 5 BF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533936.6916629213 20 188899.906129223 30 0.0 11 533851.2645282592 21 188986.217601172 31 0.0 0 LINE 5 BF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533936.5598949222 20 189042.3308882265 30 0.0 11 533977.3291642509 21 188928.6400898097 31 0.0 0 LINE 5 BF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533977.39174217 20 188935.3758674577 30 0.0 11 533934.5438983906 21 188899.5752644348 31 0.0 0 LINE 5 BF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534207.5077871861 20 189182.9805769916 30 0.0 11 533739.9144092359 21 188870.1323688091 31 0.0 0 LINE 5 BF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533737.0870201404 20 188857.3638279377 30 0.0 11 533723.7403525454 21 188877.652273816 31 0.0 0 LINE 5 BF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533700.6564906054 20 188670.7462746741 30 0.0 11 533660.5949207275 21 188649.5517519813 31 0.0 0 LINE 5 BF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533716.1308612756 20 188669.3789641419 30 0.0 11 533692.0663216224 21 188669.5895915292 31 0.0 0 LINE 5 BFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533755.4663603712 20 188618.7707790478 30 0.0 11 533709.7541232065 21 188674.198693898 31 0.0 0 LINE 5 BFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533812.9250847721 20 188869.0502998399 30 0.0 11 533549.1915001816 21 189214.1617039826 31 0.0 0 LINE 5 BFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533579.8355596115 20 189205.818398264 30 0.0 11 533444.0115601664 21 189057.2715927079 31 0.0 0 LINE 5 BFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533907.0303599279 20 189227.2925558879 30 0.0 11 533545.8726725557 21 189193.3854812484 31 0.0 0 LINE 5 BFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533657.1912689352 20 189277.8596513352 30 0.0 11 533807.9746921486 21 188911.8948285983 31 0.0 0 LINE 5 BFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533914.6553188072 20 188983.5686526164 30 0.0 11 533894.642651127 21 189012.9197490576 31 0.0 0 LINE 5 C00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533708.6210282044 20 189020.69954408 30 0.0 11 533627.1446922855 21 188975.1644270182 31 0.0 0 LINE 5 C01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533655.5945538338 20 188995.8076214645 30 0.0 11 533617.3610195242 21 188921.7078299929 31 0.0 0 LINE 5 C02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533664.6051489978 20 188986.2640274697 30 0.0 11 533584.572042754 21 188981.9224237718 31 0.0 0 LINE 5 C03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533506.6024791567 20 189129.8168516188 30 0.0 11 533594.8951225617 21 188974.6559284607 31 0.0 0 LINE 5 C04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534015.5371236648 20 189422.8785670367 30 0.0 11 534089.3924771831 21 189262.4361439317 31 0.0 0 LINE 5 C05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534073.4693208243 20 189324.0028685315 30 0.0 11 533836.2211857393 21 189209.7568899539 31 0.0 0 LINE 5 C06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533957.8667029707 20 188712.2885380282 30 0.0 11 533920.9411801206 21 188741.3851993519 31 0.0 0 LINE 5 C07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533969.0846431969 20 188783.2723998186 30 0.0 11 533920.6568601831 21 188739.5054319043 31 0.0 0 LINE 5 C08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534016.1111272417 20 188767.6494889127 30 0.0 11 533955.3544787583 21 188852.4526297691 31 0.0 0 LINE 5 C09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534088.7009854969 20 188923.3856281208 30 0.0 11 533827.8674739919 21 188778.0425491007 31 0.0 0 LINE 5 C0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533808.5788008996 20 188681.410743732 30 0.0 11 533760.9972611464 21 188731.1657517926 31 0.0 0 LINE 5 C0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533784.675202312 20 188752.4566658391 30 0.0 11 533741.112446881 21 188711.0458182762 31 0.0 0 LINE 5 C0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533785.4549223951 20 188743.8859951609 30 0.0 11 533736.8858061241 21 188796.1307734819 31 0.0 0 LINE 5 C0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533740.600329478 20 188796.2779229899 30 0.0 11 533698.9525720323 21 188758.6341440286 31 0.0 0 LINE 5 C0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533749.9387110799 20 188709.1127106841 30 0.0 11 533696.5444641208 21 188765.2833630762 31 0.0 0 LINE 5 C0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534061.8589977427 20 189168.8933915557 30 0.0 11 533967.8705054438 21 189106.6781694724 31 0.0 0 LINE 5 C10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534064.7356819831 20 188548.9144032987 30 0.0 11 533894.8221488595 21 188346.0766823975 31 0.0 0 LINE 5 C11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533960.747825353 20 187966.2146806913 30 0.0 11 533618.6462585406 21 187483.4167843487 31 0.0 0 LINE 5 C12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534092.0260363118 20 187981.0780324602 30 0.0 11 533889.9867732282 21 188120.0964040922 31 0.0 0 LINE 5 C13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534482.2486223949 20 188866.8031900984 30 0.0 11 533744.3816463227 21 187772.8430918578 31 0.0 0 LINE 5 C14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533918.8408404258 20 188104.8250893232 30 0.0 11 533838.7390409401 21 188122.2836108459 31 0.0 0 LINE 5 C15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533928.5546908797 20 188183.9512968847 30 0.0 11 533908.6839131813 21 188098.379218063 31 0.0 0 LINE 5 C16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533931.8494004686 20 188166.7597113222 30 0.0 11 533802.4662233257 21 188317.803566731 31 0.0 0 LINE 5 C17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534081.5436796952 20 188306.4498861776 30 0.0 11 533640.7355559948 21 188034.2530729997 31 0.0 0 LINE 5 C18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533757.033522745 20 188285.5811007354 30 0.0 11 533841.9146989385 21 188119.3432449735 31 0.0 0 LINE 5 C19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533809.2560136765 20 188316.345126313 30 0.0 11 533756.825515832 21 188284.759313405 31 0.0 0 LINE 5 C1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533626.8157739061 20 188551.2232056296 30 0.0 11 533775.613036499 21 188293.9192204351 31 0.0 0 LINE 5 C1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533664.1894799472 20 188493.9093885375 30 0.0 11 533570.3529828282 21 188430.723052 31 0.0 0 LINE 5 C1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533530.0362043181 20 188501.5140292179 30 0.0 11 533919.8580114896 21 187854.2810271168 31 0.0 0 LINE 5 C1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533744.5967918091 20 188012.5657920076 30 0.0 11 533424.7842744307 21 187711.5612715618 31 0.0 0 LINE 5 C1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533783.9268072136 20 187955.2702693596 30 0.0 11 533668.372881318 21 188111.0162430533 31 0.0 0 LINE 5 C1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533724.9666876536 20 187912.8898197572 30 0.0 11 533687.0756535645 21 187964.8505283531 31 0.0 0 LINE 5 C20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533777.9364873344 20 187925.1969457444 30 0.0 11 533709.6083155268 21 187916.9194787134 31 0.0 0 LINE 5 C21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533727.4826160646 20 187926.8478797349 30 0.0 11 533451.4939357553 21 187632.8625976329 31 0.0 0 LINE 5 C22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533797.7875505533 20 187732.1251245037 30 0.0 11 533482.9286789124 21 187990.5348479918 31 0.0 0 LINE 5 C23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533493.6125581479 20 187998.481653619 30 0.0 11 533331.4672437539 21 187823.1400763673 31 0.0 0 LINE 5 C24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533434.4628957546 20 188179.6090071645 30 0.0 11 533491.5456564852 21 187980.4898460357 31 0.0 0 LINE 5 C25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533519.8303895849 20 188161.878371552 30 0.0 11 533445.757285696 21 188119.3990231381 31 0.0 0 LINE 5 C26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533725.6678888035 20 187622.8851895573 30 0.0 11 533659.1102360578 21 187683.6484174145 31 0.0 0 LINE 5 C27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533672.3884885803 20 187499.7920431741 30 0.0 11 533331.2380915771 21 187826.2343139276 31 0.0 0 LINE 5 C28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533676.8641143972 20 188060.3959768004 30 0.0 11 533373.8585901557 21 187763.7094779017 31 0.0 0 LINE 5 C29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533146.5957557968 20 188251.4100877043 30 0.0 11 533380.0181952408 21 187760.4364761121 31 0.0 0 LINE 5 C2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533242.5954163944 20 188255.1129625749 30 0.0 11 533174.0986986265 21 188159.7309549197 31 0.0 0 LINE 5 C2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533269.7352637037 20 188199.2699833903 30 0.0 11 533160.2572941904 21 188190.3159300416 31 0.0 0 LINE 5 C2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533363.9939796087 20 188034.2894592814 30 0.0 11 533248.4486075667 21 188199.9894845101 31 0.0 0 LINE 5 C2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533514.5347845807 20 188233.5283653546 30 0.0 11 533251.187061902 21 188026.3137199132 31 0.0 0 LINE 5 C2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533576.2253916496 20 188163.1659249519 30 0.0 11 533490.7982569877 21 188249.4773969008 31 0.0 0 LINE 5 C2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533576.0936236506 20 188305.5906839552 30 0.0 11 533616.8628929792 21 188191.8998855386 31 0.0 0 LINE 5 C30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533616.9254708984 20 188198.6356631866 30 0.0 11 533574.077627119 21 188162.8350601635 31 0.0 0 LINE 5 C31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533847.0415159145 20 188446.2403727204 30 0.0 11 533379.4481379644 21 188133.3921645379 31 0.0 0 LINE 5 C32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533376.620748869 20 188120.6236236665 30 0.0 11 533363.2740812741 21 188140.9120695446 31 0.0 0 LINE 5 C33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533340.1902193338 20 187934.006070403 30 0.0 11 533300.128649456 21 187912.8115477102 31 0.0 0 LINE 5 C34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533355.6645900042 20 187932.6387598706 30 0.0 11 533331.6000503509 21 187932.8493872581 31 0.0 0 LINE 5 C35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533395.0000890999 20 187882.0305747765 30 0.0 11 533349.2878519349 21 187937.4584896269 31 0.0 0 LINE 5 C36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533452.4588135006 20 188132.3100955687 30 0.0 11 533231.6784224093 21 188410.3566154416 31 0.0 0 LINE 5 C37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533546.5640886565 20 188490.5523516167 30 0.0 11 533343.0621970856 21 188475.9363167254 31 0.0 0 LINE 5 C38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533350.297176501 20 188506.1852176427 30 0.0 11 533447.508420877 21 188175.1546243272 31 0.0 0 LINE 5 C39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533554.1890475354 20 188246.8284483454 30 0.0 11 533534.1763798556 21 188276.1795447865 31 0.0 0 LINE 5 C3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533348.1547569327 20 188283.9593398089 30 0.0 11 533266.6784210141 21 188238.4242227471 31 0.0 0 LINE 5 C3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533295.1282825622 20 188259.0674171934 30 0.0 11 533256.8947482528 21 188184.9676257218 31 0.0 0 LINE 5 C3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533304.1388777264 20 188249.5238231985 30 0.0 11 533224.1057714826 21 188245.1822195005 31 0.0 0 LINE 5 C3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533174.5272803235 20 188348.7483021824 30 0.0 11 533234.4288512903 21 188237.9157241895 31 0.0 0 LINE 5 C3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533725.4728525103 20 188574.456657789 30 0.0 11 533475.7549144679 21 188473.0166856827 31 0.0 0 LINE 5 C3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533597.4004316991 20 187975.548333757 30 0.0 11 533560.4749088491 21 188004.6449950807 31 0.0 0 LINE 5 C40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533608.6183719253 20 188046.5321955475 30 0.0 11 533560.1905889117 21 188002.7652276331 31 0.0 0 LINE 5 C41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533655.6448559702 20 188030.9092846418 30 0.0 11 533594.8882074865 21 188115.712425498 31 0.0 0 LINE 5 C42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533728.2347142254 20 188186.6454238496 30 0.0 11 533467.4012027203 21 188041.3023448295 31 0.0 0 LINE 5 C43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533448.112529628 20 187944.6705394609 30 0.0 11 533400.5309898749 21 187994.4255475215 31 0.0 0 LINE 5 C44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533424.2089310404 20 188015.7164615679 30 0.0 11 533380.6461756096 21 187974.305614005 31 0.0 0 LINE 5 C45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533424.9886511237 20 188007.1457908898 30 0.0 11 533376.4195348527 21 188059.3905692107 31 0.0 0 LINE 5 C46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533380.1340582064 20 188059.5377187187 30 0.0 11 533338.4863007607 21 188021.8939397574 31 0.0 0 LINE 5 C47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533389.4724398083 20 187972.3725064129 30 0.0 11 533336.0781928492 21 188028.543158805 31 0.0 0 LINE 5 C48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533701.3927264713 20 188432.1531872845 30 0.0 11 533607.4042341724 21 188369.9379652012 31 0.0 0 LINE 5 C49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533704.2694107114 20 187812.1741990278 30 0.0 11 533534.3558775881 21 187609.3364781263 31 0.0 0 LINE 5 C4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533175.6970995059 20 188220.3147545992 30 0.0 11 532655.4448627076 21 188465.0194945314 31 0.0 0 LINE 5 C4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533313.8654444766 20 188402.6388471191 30 0.0 11 533202.7559908635 21 188531.0428461079 31 0.0 0 LINE 5 C4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533646.388072575 20 188714.8300158017 30 0.0 11 533069.5921329468 21 188226.7951355077 31 0.0 0 LINE 5 C4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533197.9066944875 20 188425.0523805634 30 0.0 11 532843.6663763799 21 188684.704330224 31 0.0 0 LINE 5 C4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533147.6153106242 20 188377.0898562728 30 0.0 11 533282.943802676 21 188515.9988817203 31 0.0 0 LINE 5 C4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533096.3759611031 20 188428.5381533069 30 0.0 11 533141.6302267151 21 188474.2294779323 31 0.0 0 LINE 5 C50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533116.9715900882 20 188378.2083897967 30 0.0 11 533097.9051955084 21 188444.3425573709 31 0.0 0 LINE 5 C51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533110.5566061437 20 188428.28000541 30 0.0 11 532776.3265078583 21 188653.8622280066 31 0.0 0 LINE 5 C52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532929.5351063394 20 188327.8262756299 30 0.0 11 533134.4350096063 21 188679.8599727173 31 0.0 0 LINE 5 C53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533143.9836746984 20 188670.5798870416 30 0.0 11 532945.0315411522 21 188802.6927942477 31 0.0 0 LINE 5 C54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533313.3624009986 20 188757.8532955949 30 0.0 11 533125.8924855081 21 188669.7515777499 31 0.0 0 LINE 5 C55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533309.4703294126 20 188670.7508488964 30 0.0 11 533255.7236030304 21 188737.1030091067 31 0.0 0 LINE 5 C56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532760.3109855633 20 188407.9772233068 30 0.0 11 532809.6843025367 21 188483.3719616491 31 0.0 0 LINE 5 C57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533234.3250746628 20 188499.5449557109 30 0.0 11 532893.1205218853 21 188751.3676701617 31 0.0 0 LINE 5 C58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533287.9518486706 20 189020.6443107427 30 0.0 11 532924.927540181 21 188764.4635294863 31 0.0 0 LINE 5 C59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533454.4086586428 20 189157.773105065 30 0.0 11 533055.445001969 21 188853.5597059197 31 0.0 0 LINE 5 C5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533357.3073868794 20 188959.3050643503 30 0.0 11 533252.2239717797 21 189011.7169294218 31 0.0 0 LINE 5 C5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533306.5062584413 20 188923.6083560199 30 0.0 11 533280.2106583208 21 189030.2579799969 31 0.0 0 LINE 5 C5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533158.6658703738 20 188804.2496591633 30 0.0 11 533303.8224281221 21 188944.7373992113 31 0.0 0 LINE 5 C5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533354.609919737 20 188711.0432451002 30 0.0 11 533132.8052719798 21 188914.3416323113 31 0.0 0 LINE 5 C5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533443.6727279084 20 188730.6953770002 30 0.0 11 533340.7311606862 21 188666.2710084394 31 0.0 0 LINE 5 C5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533410.8878722348 20 188592.0952955483 30 0.0 11 533476.6391545755 21 188693.4091634875 31 0.0 0 LINE 5 C60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533475.1556176507 20 188686.8384911694 30 0.0 11 533441.6580479251 21 188731.5098882355 31 0.0 0 LINE 5 C61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533642.3676091107 20 188393.0670897887 30 0.0 11 533642.3591346374 21 188393.0761903409 31 0.0 0 LINE 5 C62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533542.6236322993 20 188500.1799760925 30 0.0 11 533258.9648225294 21 188804.7949995876 31 0.0 0 LINE 5 C63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533245.9088162212 20 188805.550290505 30 0.0 11 533263.8095899025 21 188821.9611671926 31 0.0 0 LINE 5 C64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533055.8700081143 20 188811.7588395784 30 0.0 11 533028.5588840766 21 188847.9284356091 31 0.0 0 LINE 5 C65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533056.9875564872 20 188796.2644286064 30 0.0 11 533053.3584333629 21 188820.0546765659 31 0.0 0 LINE 5 C66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533013.2988283583 20 188749.362777014 30 0.0 11 533060.7288621851 21 188803.3280831137 31 0.0 0 LINE 5 C67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533269.5380431569 20 188732.5458707275 30 0.0 11 533514.5678291421 21 188984.2403845657 31 0.0 0 LINE 5 C68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533561.3534292562 20 188895.7936472422 30 0.0 11 533311.0450964412 21 188744.2644269236 31 0.0 0 LINE 5 C69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533398.812013349 20 188650.3769333467 30 0.0 11 533424.5966082207 21 188674.8135533515 31 0.0 0 LINE 5 C6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533402.6159936026 20 188859.6957374214 30 0.0 11 533344.6721587765 21 188932.869176634 31 0.0 0 LINE 5 C6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533369.5875381494 20 188908.0748230476 30 0.0 11 533290.3394802066 21 188934.0041029116 31 0.0 0 LINE 5 C6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533361.6027688713 20 188897.6577951062 30 0.0 11 533344.5555483907 21 188975.9747146804 31 0.0 0 LINE 5 C6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533478.1257172051 20 189076.5283055594 30 0.0 11 533339.0280189092 21 188964.6250737764 31 0.0 0 LINE 5 C6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533137.8925834676 20 188564.4631660981 30 0.0 11 533160.729268282 21 188605.555692969 31 0.0 0 LINE 5 C6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533209.7569790573 20 188564.7070188652 30 0.0 11 533158.8282157264 21 188605.536649204 31 0.0 0 LINE 5 C70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533201.8322482928 20 188515.7911299423 30 0.0 11 533275.8628790885 21 188589.2922097849 31 0.0 0 LINE 5 C71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533367.1502840121 20 188468.961869401 30 0.0 11 533182.077165856 21 188703.2835975423 31 0.0 0 LINE 5 C72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533083.6060937013 20 188706.9176953847 30 0.0 11 533125.1377409663 21 188761.8238519414 31 0.0 0 LINE 5 C73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533149.9316774165 20 188741.8436458843 30 0.0 11 533102.1046123628 21 188778.24617059 31 0.0 0 LINE 5 C74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533141.594983066 20 188739.7073203964 30 0.0 11 533185.4270794335 21 188795.9854088964 31 0.0 0 LINE 5 C75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533186.1646216841 20 188792.3418710342 30 0.0 11 533142.361773903 21 188827.4545513793 31 0.0 0 LINE 5 C76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533101.6035714538 20 188769.2245962995 30 0.0 11 533148.5419551448 21 188830.8920588301 31 0.0 0 LINE 5 C77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532993.6487211053 20 188432.9116752496 30 0.0 11 532766.313591787 21 188568.3091964116 31 0.0 0 LINE 5 C78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534342.418987797 20 188859.4888269258 30 0.0 11 535041.1571359639 21 188606.5066843258 31 0.0 0 LINE 5 C79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534534.3741274379 20 188797.3384682259 30 0.0 11 534222.6936299359 21 188332.6906515765 31 0.0 0 LINE 5 C7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534453.323294102 20 188685.8292292451 30 0.0 11 534586.7963206439 21 188622.2474245328 31 0.0 0 LINE 5 C7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534594.0885719828 20 188771.1940418831 30 0.0 11 534034.5871467995 21 187956.3988856886 31 0.0 0 LINE 5 C7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534562.4969298503 20 188644.0490266683 30 0.0 11 534606.5536739899 21 188574.9107481938 31 0.0 0 LINE 5 C7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534633.395276966 20 188680.5009126278 30 0.0 11 534559.9569102708 21 188632.2905944648 31 0.0 0 LINE 5 C7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534614.4868337088 20 188678.4537965122 30 0.0 11 534800.9292733384 21 188609.2189101521 31 0.0 0 LINE 5 C7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534678.5519897104 20 188782.9836972875 30 0.0 11 534592.3486427728 21 188358.6863907961 31 0.0 0 LINE 5 C80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534788.0238202058 20 188554.6512333887 30 0.0 11 534602.6972417204 21 188576.8750509549 31 0.0 0 LINE 5 C81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534798.8520678092 20 188614.2864820481 30 0.0 11 534787.3244932632 21 188554.1721268046 31 0.0 0 LINE 5 C82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535082.2967784591 20 188524.2240079788 30 0.0 11 534789.4297842628 21 188574.967380576 31 0.0 0 LINE 5 C83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535015.6002069867 20 188539.4960375335 30 0.0 11 534988.7225627527 21 188429.6079419225 31 0.0 0 LINE 5 C84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535069.0832357024 20 188416.2300748297 30 0.0 11 534273.6906374572 21 188568.6690594344 31 0.0 0 LINE 5 C85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534536.1152181576 20 188448.6602559888 30 0.0 11 534364.1314518119 21 188044.5496873147 31 0.0 0 LINE 5 C86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534468.7599584501 20 188465.7744611111 30 0.0 11 534654.8373345632 21 188411.1417949609 31 0.0 0 LINE 5 C87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534449.3582176149 20 188395.8032480332 30 0.0 11 534511.2100066913 21 188378.1963774951 31 0.0 0 LINE 5 C88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534442.607819061 20 188449.7633920994 30 0.0 11 534458.44569778 21 188382.7826700915 31 0.0 0 LINE 5 C89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534461.5876598364 20 188402.9864281824 30 0.0 11 534281.0508963453 21 188042.4263433427 31 0.0 0 LINE 5 C8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534254.5657860476 20 188401.6906691855 30 0.0 11 534605.8405935904 21 188195.4924542807 31 0.0 0 LINE 5 C8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534609.6070830462 20 188208.2639284466 30 0.0 11 534501.0788297879 21 187995.5260852271 31 0.0 0 LINE 5 C8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534800.0167833604 20 188215.3312327294 30 0.0 11 534593.4371319426 21 188200.108568007 31 0.0 0 LINE 5 C8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534753.8855132741 20 188289.3169770472 30 0.0 11 534739.6121234155 21 188205.1291507104 31 0.0 0 LINE 5 C8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534127.7590375945 20 188178.051666309 30 0.0 11 534504.061715031 21 187996.3800245856 31 0.0 0 LINE 5 C8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534604.40035436 20 188401.6221614216 30 0.0 11 534430.6623416044 21 188014.7755131572 31 0.0 0 LINE 5 C90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534906.8235633151 20 187973.8832557906 30 0.0 11 534425.4628749706 21 188019.4251176826 31 0.0 0 LINE 5 C91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535156.488421269 20 187930.8682847123 30 0.0 11 534622.2457847449 21 188005.3822538067 31 0.0 0 LINE 5 C92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534937.1572461826 20 188061.3621761767 30 0.0 11 534871.3120220185 21 187964.1308325468 31 0.0 0 LINE 5 C93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534875.3764938226 20 188067.5386050841 30 0.0 11 534904.7956771976 21 187961.70802099 31 0.0 0 LINE 5 C94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534687.9901235956 20 188098.9969443977 30 0.0 11 534883.405704264 21 188047.8111827726 31 0.0 0 LINE 5 C95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534822.953366526 20 188309.1007252122 30 0.0 11 534719.4774529505 21 187990.380365594 31 0.0 0 LINE 5 C96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534907.6954397033 20 188694.6210301165 30 0.0 11 534775.6518398568 21 188147.7370788022 31 0.0 0 LINE 5 C97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534764.6462774784 20 188140.6725645359 30 0.0 11 534788.2964630404 21 188135.1568329503 31 0.0 0 LINE 5 C98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534602.1050007739 20 188042.0134137412 30 0.0 11 534596.0557457803 21 187997.0963380654 31 0.0 0 LINE 5 C99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534595.4758680417 20 188056.0626231478 30 0.0 11 534603.9872268712 21 188033.5525542118 31 0.0 0 LINE 5 C9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534534.3942980067 20 188075.4922831983 30 0.0 11 534602.2018414045 21 188051.743611033 31 0.0 0 LINE 5 C9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534749.4130227723 20 188215.8785059482 30 0.0 11 535164.3885908858 21 188087.6109622003 31 0.0 0 LINE 5 C9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535053.0865184272 20 188427.9533155489 30 0.0 11 535146.0381762112 21 188077.3188132905 31 0.0 0 LINE 5 C9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535186.8532867293 20 188210.9670159163 30 0.0 11 534791.3297615979 21 188226.0346389663 31 0.0 0 LINE 5 C9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534927.7593634743 20 188170.3877128874 30 0.0 11 534913.1759876781 21 188078.1967949456 31 0.0 0 LINE 5 C9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534922.7194174261 20 188112.0266493305 30 0.0 11 534866.3908411974 21 188050.5475980855 31 0.0 0 LINE 5 CA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534910.6505059065 20 188117.1853687731 30 0.0 11 534934.2256724622 21 188040.5801526349 31 0.0 0 LINE 5 CA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535213.9468003766 20 187999.5703161947 30 0.0 11 534923.8402230674 21 188047.7572252753 31 0.0 0 LINE 5 CA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535199.1434991289 20 188597.3491948433 30 0.0 11 535023.064663989 21 188611.2282506775 31 0.0 0 LINE 5 CA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535086.3416508714 20 188617.5552892779 30 0.0 11 535061.093369618 21 188355.4458741167 31 0.0 0 LINE 5 CA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534552.2296856262 20 188297.7384729914 30 0.0 11 534592.291654657 21 188273.1387052013 31 0.0 0 LINE 5 CA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534614.9674026566 20 188332.7888607126 30 0.0 11 534590.6258539049 21 188272.2224785161 31 0.0 0 LINE 5 CA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534584.0599459788 20 188371.5224981418 30 0.0 11 534684.631491202 21 188343.804140949 31 0.0 0 LINE 5 CA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534705.1290929152 20 188493.4458110767 30 0.0 11 534658.8465861588 21 188198.4599454638 31 0.0 0 LINE 5 CA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534574.828360812 20 188146.9750299248 30 0.0 11 534637.9580877661 21 188119.5123037841 31 0.0 0 LINE 5 CA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534649.7579355233 20 188149.0878259552 30 0.0 11 534625.9466897634 21 188093.9009023957 31 0.0 0 LINE 5 CAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534641.4456051139 20 188146.8585833822 30 0.0 11 534707.2529850864 21 188119.3292416115 31 0.0 0 LINE 5 CAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534706.1077988136 20 188122.8658904667 30 0.0 11 534685.170091141 21 188070.7774830026 31 0.0 0 LINE 5 CAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534621.083352799 20 188101.5158743744 30 0.0 11 534692.2418452411 21 188070.8147872303 31 0.0 0 LINE 5 CAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534067.3002023453 20 188003.8214991741 30 0.0 11 534025.5032141101 21 187765.8893586528 31 0.0 0 LINE 5 CAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534515.4513497963 20 187931.4269758353 30 0.0 11 534002.546387197 21 188020.2950563631 31 0.0 0 LINE 5 CAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534502.2378070394 20 187823.4330426864 30 0.0 11 533760.1825551896 21 187965.6497911978 31 0.0 0 LINE 5 CB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533969.2697894947 20 187855.8632238454 30 0.0 11 533797.2860231489 21 187451.7526551713 31 0.0 0 LINE 5 CB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533901.9145297874 20 187872.9774289677 30 0.0 11 534087.9919059005 21 187818.3447628175 31 0.0 0 LINE 5 CB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533882.512788952 20 187803.0062158899 30 0.0 11 533944.3645780285 21 187785.3993453517 31 0.0 0 LINE 5 CB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533875.7623903983 20 187856.9663599559 30 0.0 11 533891.6002691171 21 187789.9856379482 31 0.0 0 LINE 5 CB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533894.7422311735 20 187810.1893960391 30 0.0 11 533714.2054676827 21 187449.6293111992 31 0.0 0 LINE 5 CB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533782.6701975751 20 187753.2877346548 30 0.0 11 534038.9951649274 21 187602.6954221372 31 0.0 0 LINE 5 CB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534042.7616543834 20 187615.4668963031 30 0.0 11 533934.233401125 21 187402.7290530838 31 0.0 0 LINE 5 CB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534233.1713546975 20 187622.5342005861 30 0.0 11 534026.5917032798 21 187607.3115358635 31 0.0 0 LINE 5 CB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534187.0400846114 20 187696.519944904 30 0.0 11 534172.7666947527 21 187612.332118567 31 0.0 0 LINE 5 CB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533632.607411396 20 187553.2629338686 30 0.0 11 533937.2162863679 21 187403.5829924421 31 0.0 0 LINE 5 CBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534037.5549256969 20 187808.8251292782 30 0.0 11 533863.8169129417 21 187421.9784810139 31 0.0 0 LINE 5 CBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534400.0024326341 20 187377.1971327206 30 0.0 11 533858.6174463078 21 187426.6280855392 31 0.0 0 LINE 5 CBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534370.3118175198 20 187468.5651440334 30 0.0 11 534304.4665933558 21 187371.3338004034 31 0.0 0 LINE 5 CBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534308.5310651599 20 187474.7415729406 30 0.0 11 534337.9502485348 21 187368.9109888465 31 0.0 0 LINE 5 CBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534121.1446949326 20 187506.1999122544 30 0.0 11 534316.5602756013 21 187455.0141506292 31 0.0 0 LINE 5 CBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.1079378633 20 187716.303693069 30 0.0 11 534152.6320242878 21 187397.5833334506 31 0.0 0 LINE 5 CC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534168.7652893984 20 187749.8874060726 30 0.0 11 534279.2753342777 21 187699.5386671871 31 0.0 0 LINE 5 CC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534187.9902158508 20 187800.3354088496 30 0.0 11 534169.1967959018 21 187747.7575783508 31 0.0 0 LINE 5 CC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534340.8500110405 20 188101.8239979731 30 0.0 11 534208.8064111941 21 187554.9400466588 31 0.0 0 LINE 5 CC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534197.8008488156 20 187547.8755323925 30 0.0 11 534221.4510343777 21 187542.3598008071 31 0.0 0 LINE 5 CC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534035.2595721112 20 187449.2163815976 30 0.0 11 534029.2103171174 21 187404.2993059221 31 0.0 0 LINE 5 CC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534028.6304393789 20 187463.2655910044 30 0.0 11 534037.1417982083 21 187440.7555220685 31 0.0 0 LINE 5 CC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533967.5488693438 20 187482.695251055 30 0.0 11 534035.3564127415 21 187458.9465788896 31 0.0 0 LINE 5 CC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534182.5675941095 20 187623.0814738048 30 0.0 11 534519.7683430233 21 187511.9531550208 31 0.0 0 LINE 5 CC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534486.2410897645 20 187835.1562834054 30 0.0 11 534542.8298393397 21 187639.1349535193 31 0.0 0 LINE 5 CC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534568.7167464405 20 187656.3747033612 30 0.0 11 534224.4843329351 21 187633.2376068228 31 0.0 0 LINE 5 CCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534254.8895447855 20 187758.1112079001 30 0.0 11 534289.3473118174 21 187749.4708363137 31 0.0 0 LINE 5 CCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534360.9139348114 20 187577.5906807442 30 0.0 11 534346.3305590152 21 187485.3997628022 31 0.0 0 LINE 5 CCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534355.8739887633 20 187519.2296171871 30 0.0 11 534299.5454125343 21 187457.7505659422 31 0.0 0 LINE 5 CCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534343.8050772437 20 187524.3883366297 30 0.0 11 534367.3802437997 21 187447.7831204914 31 0.0 0 LINE 5 CCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534481.6976816879 20 187437.0367879853 30 0.0 11 534356.9947944047 21 187454.9601931319 31 0.0 0 LINE 5 CCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534503.1707014955 20 188032.0361112815 30 0.0 11 534494.2479409549 21 187762.6488419732 31 0.0 0 LINE 5 CD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533985.3842569635 20 187704.941440848 30 0.0 11 534025.4462259941 21 187680.3416730576 31 0.0 0 LINE 5 CD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534048.121973994 20 187739.9918285693 30 0.0 11 534023.7804252421 21 187679.4254463728 31 0.0 0 LINE 5 CD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534017.2145173163 20 187778.7254659985 30 0.0 11 534117.7860625391 21 187751.0071088056 31 0.0 0 LINE 5 CD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534138.2836642524 20 187900.6487789333 30 0.0 11 534092.0011574961 21 187605.6629133204 31 0.0 0 LINE 5 CD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534007.9829321491 20 187554.1779977815 30 0.0 11 534071.1126591032 21 187526.7152716407 31 0.0 0 LINE 5 CD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534082.9125068603 20 187556.2907938117 30 0.0 11 534059.1012611005 21 187501.103870252 31 0.0 0 LINE 5 CD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534074.6001764511 20 187554.0615512388 30 0.0 11 534140.4075564234 21 187526.5322094681 31 0.0 0 LINE 5 CD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534139.2623701508 20 187530.0688583234 30 0.0 11 534118.3246624784 21 187477.9804508591 31 0.0 0 LINE 5 CD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534054.2379241361 20 187508.718842231 30 0.0 11 534125.3964165783 21 187478.0177550869 31 0.0 0 LINE 5 CD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534377.9482391282 20 187960.2763376868 30 0.0 11 534352.0344263502 21 187850.5811014604 31 0.0 0 LINE 5 CDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534360.7679136229 20 187393.7639810799 30 0.0 11 534770.1398838371 21 186990.0841702868 31 0.0 0 LINE 5 CDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534428.0054739007 20 187408.1899054635 30 0.0 11 534591.3264570555 21 187250.0894271984 31 0.0 0 LINE 5 CDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534484.1322009104 20 187586.4134526264 30 0.0 11 534643.0156503759 21 187526.5056307297 31 0.0 0 LINE 5 CDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534662.2228028087 20 188006.316252708 30 0.0 11 534403.5059120892 21 187296.4309304117 31 0.0 0 LINE 5 CDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534545.2265514975 20 187485.3378447537 30 0.0 11 535008.1886856977 21 187247.5992257941 31 0.0 0 LINE 5 CDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534517.5916033422 20 187421.5731470936 30 0.0 11 534601.1950789026 21 187596.5587950364 31 0.0 0 LINE 5 CE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534583.5740422579 20 187391.2628194515 30 0.0 11 534610.8178324108 21 187449.5159017755 31 0.0 0 LINE 5 CE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534529.2279100611 20 187393.2026502444 30 0.0 11 534597.8770235372 21 187398.1579243974 31 0.0 0 LINE 5 CE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534578.4327287344 20 187404.4811487468 30 0.0 11 534803.2685851388 21 187177.2203280783 31 0.0 0 LINE 5 CE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534658.0654168236 20 187640.2422304982 30 0.0 11 534986.9769317319 21 187378.4981200029 31 0.0 0 LINE 5 CE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534747.144412568 20 187821.5636049725 30 0.0 11 534722.2505399106 21 187702.7033482393 31 0.0 0 LINE 5 CE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534628.4045815115 20 187742.9144990611 30 0.0 11 534700.7649085668 21 187839.6187597465 31 0.0 0 LINE 5 CE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534695.1113314549 20 187835.9565633617 30 0.0 11 534748.6047944875 21 187819.9543664458 31 0.0 0 LINE 5 CE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534361.6604653533 20 187891.3822456155 30 0.0 11 534361.6719332852 21 187891.3774369479 31 0.0 0 LINE 5 CE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534496.6372509165 20 187834.7845541287 30 0.0 11 535056.9980084965 21 187540.6308271714 31 0.0 0 LINE 5 CE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534781.928612762 20 187509.102585166 30 0.0 11 534960.5856270645 21 187975.6870431467 31 0.0 0 LINE 5 CEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534861.4214791478 20 187989.0358067275 30 0.0 11 534771.6287406363 21 187677.4285060179 31 0.0 0 LINE 5 CEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534687.2696056447 20 187751.7170331342 30 0.0 11 534701.2936751604 21 187784.3562611305 31 0.0 0 LINE 5 CEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534726.7756330002 20 187332.3435424447 30 0.0 11 534727.4597728151 21 187512.8089178462 31 0.0 0 LINE 5 CED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534672.1883820148 20 187544.7056881982 30 0.0 11 534728.0986680131 21 187511.0183379375 31 0.0 0 LINE 5 CEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534527.9629881593 20 187659.3303882316 30 0.0 11 534751.1158335205 21 187586.4283479941 31 0.0 0 LINE 5 CEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534846.1955660799 20 188389.8968598512 30 0.0 11 534682.3331169241 21 188418.5382548995 31 0.0 0 LINE 5 CF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534945.2721225843 20 188398.7611056485 30 0.0 11 534912.1433930747 21 188580.2924171957 31 0.0 0 LINE 5 CF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534678.2877958446 20 187937.8335458117 30 0.0 11 534477.114611199 21 187880.3287166929 31 0.0 0 LINE 5 CF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534676.1352028901 20 187527.3454333013 30 0.0 11 534732.0690495518 21 187630.3094970343 31 0.0 0 LINE 5 CF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534258.091680705 20 188399.6209699965 30 0.0 11 534060.7481695947 21 188381.7399515909 31 0.0 0 LINE 5 CF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535780.3901278204 20 185439.4290383135 30 0.0 11 533707.5812551458 21 186696.108607327 31 0.0 0 LINE 5 CF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535804.6699560423 20 185803.0532584575 30 0.0 11 535577.8025029244 21 185518.9490408467 31 0.0 0 LINE 5 CF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535564.9239086284 20 185788.4221394258 30 0.0 11 535372.3764689632 21 185534.021633504 31 0.0 0 LINE 5 CF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535142.8676494943 20 185933.7047163851 30 0.0 11 535006.3805352725 21 185752.840818464 31 0.0 0 LINE 5 CFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535703.5356364426 20 185631.1989691456 30 0.0 11 535529.1529331644 21 185801.4138902812 31 0.0 0 LINE 5 CFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 535595.9938929793 20 185461.8081714932 30 0.0 11 535355.6089108344 21 185624.1998165417 31 0.0 0 LINE 5 CFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533867.7630282873 20 186590.6939104643 30 0.0 11 531012.3148168298 21 188613.2911204371 31 0.0 0 LINE 5 CFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534573.8956867553 20 187153.838925518 30 0.0 11 534736.3934995475 21 187351.9393427316 31 0.0 0 LINE 5 CFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534338.5537451374 20 186510.8915983567 30 0.0 11 533945.2158445 21 186706.2606427902 31 0.0 0 LINE 5 CFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534205.142888429 20 186310.9539163557 30 0.0 11 534404.4041436459 21 186616.5623173755 31 0.0 0 LINE 5 D00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534238.2645607369 20 186494.6829609836 30 0.0 11 534273.831700889 21 186548.2611677799 31 0.0 0 LINE 5 D01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534094.0416092633 20 186363.6162093194 30 0.0 11 534227.0182658679 21 186748.621278172 31 0.0 0 LINE 5 D02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534238.1808818067 20 186741.3622837103 30 0.0 11 534017.4410964214 21 186832.5199429668 31 0.0 0 LINE 5 D03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534387.4918473375 20 186859.734731247 30 0.0 11 534220.5911293927 21 186737.0520827154 31 0.0 0 LINE 5 D04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534400.5124712154 20 186773.5230858858 30 0.0 11 534334.9520369448 21 186828.2327671101 31 0.0 0 LINE 5 D05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533983.943777705 20 186379.5045163599 30 0.0 11 534017.8097838926 21 186463.0220871074 31 0.0 0 LINE 5 D06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533832.6194479275 20 186400.5220216849 30 0.0 11 534020.2631537003 21 186833.8094426817 31 0.0 0 LINE 5 D07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534359.8836305158 20 186591.0194846162 30 0.0 11 533976.4319530882 21 186772.1272907083 31 0.0 0 LINE 5 D08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534311.7560399915 20 187112.655472385 30 0.0 11 533975.5018705906 21 186765.2143881295 31 0.0 0 LINE 5 D09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534473.5554319845 20 187307.601069372 30 0.0 11 534115.9375794735 21 186903.7731383969 31 0.0 0 LINE 5 D0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534391.6616832556 20 187065.8817404109 30 0.0 11 534278.4280981259 21 187096.9893428252 31 0.0 0 LINE 5 D0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534348.7200946414 20 187021.0372356918 30 0.0 11 534302.3023088374 21 187120.591191119 31 0.0 0 LINE 5 D0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534226.7440903293 20 186875.3487556006 30 0.0 11 534342.0020785355 21 187041.2488083907 31 0.0 0 LINE 5 D0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534624.0890229793 20 186704.244408671 30 0.0 11 534180.0876000576 21 186978.3642156855 31 0.0 0 LINE 5 D0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534312.0896937012 20 186893.4912809786 30 0.0 11 534326.4800893573 21 186913.0532615762 31 0.0 0 LINE 5 D0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534124.4358105409 20 186862.8430379104 30 0.0 11 534090.647363259 21 186893.0502887538 31 0.0 0 LINE 5 D10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534128.5277661647 20 186847.8569915702 30 0.0 11 534120.367807649 21 186870.4968128956 31 0.0 0 LINE 5 D11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534094.7306176895 20 186793.3939523367 30 0.0 11 534130.8328933959 21 186855.5106816458 31 0.0 0 LINE 5 D12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534349.3868772822 20 186826.4323086515 30 0.0 11 534581.4240908384 21 187193.605314788 31 0.0 0 LINE 5 D13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534584.2426089188 20 187161.9710756716 30 0.0 11 534397.7710279386 21 187237.7514276956 31 0.0 0 LINE 5 D14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534678.6649329562 20 187114.4497895736 30 0.0 11 534387.8453576843 21 186845.9542275332 31 0.0 0 LINE 5 D15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534455.3727022235 20 186976.9109928783 30 0.0 11 534384.375602175 21 187037.5018501531 31 0.0 0 LINE 5 D16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534413.6143587174 20 187017.9920778603 30 0.0 11 534330.8485329645 21 187028.1113826482 31 0.0 0 LINE 5 D17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534407.7941217914 20 187006.2279011498 30 0.0 11 534375.9277202994 21 187079.771630139 31 0.0 0 LINE 5 D18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534487.5382601636 20 187204.2509538315 30 0.0 11 534372.6986651564 21 187067.5674860189 31 0.0 0 LINE 5 D19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534252.7199476946 20 186636.0699505644 30 0.0 11 534267.1815018675 21 186680.8021916089 31 0.0 0 LINE 5 D1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534323.1814311998 20 186650.2025426782 30 0.0 11 534265.3199955861 21 186680.415982018 31 0.0 0 LINE 5 D1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534324.8629757305 20 186600.6774181978 30 0.0 11 534383.2872150517 21 186687.1039841008 31 0.0 0 LINE 5 D1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534496.1155469523 20 186586.6920892123 30 0.0 11 534269.2331987927 21 186780.813523981 31 0.0 0 LINE 5 D1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534171.9172778454 20 186765.3419290852 30 0.0 11 534202.0505519514 21 186827.2414407475 31 0.0 0 LINE 5 D1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534230.2394511825 20 186812.4315157334 30 0.0 11 534176.27707806 21 186838.901012208 31 0.0 0 LINE 5 D1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534222.4730437592 20 186808.7237839446 30 0.0 11 534254.5981357822 21 186872.4140844594 31 0.0 0 LINE 5 D20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534256.0261586587 20 186868.9818712686 30 0.0 11 534206.2614452762 21 186894.9638476503 31 0.0 0 LINE 5 D21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534177.5296049868 20 186829.9527709859 30 0.0 11 534211.6604697993 21 186899.531301192 31 0.0 0 LINE 5 D22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534302.1858237155 20 186200.0906309843 30 0.0 11 532982.5285202879 21 186527.3959672318 31 0.0 0 LINE 5 D23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533613.6902769207 20 186358.993742019 30 0.0 11 533673.8137852908 21 186494.0598682165 31 0.0 0 LINE 5 D24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533776.1538853722 20 186385.5943176254 30 0.0 11 533297.6070133881 21 186510.0029110075 31 0.0 0 LINE 5 D25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533669.5138658524 20 186461.6981479062 30 0.0 11 533658.0668105337 21 186542.8773520114 31 0.0 0 LINE 5 D26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533747.0885230267 20 186480.0689992206 30 0.0 11 533659.94176783 21 186468.984255701 31 0.0 0 LINE 5 D27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533915.0945289718 20 186379.145676624 30 0.0 11 533506.7501595299 21 186697.9838533997 31 0.0 0 LINE 5 D28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533945.9411390942 20 186835.6257744556 30 0.0 11 533854.0988856495 21 186901.6772831347 31 0.0 0 LINE 5 D29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533906.4817802253 20 186964.0698903952 30 0.0 11 533434.9178717218 21 186373.7317834158 31 0.0 0 LINE 5 D2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533522.483184404 20 186593.0554664399 30 0.0 11 533062.5983105609 21 186790.5020190729 31 0.0 0 LINE 5 D2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533482.4130391135 20 186536.2750958563 30 0.0 11 533588.3335829126 21 186698.7261854587 31 0.0 0 LINE 5 D2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533422.1940000035 20 186576.8468290668 30 0.0 11 533457.7611401558 21 186630.4250358631 31 0.0 0 LINE 5 D2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533452.1311894492 20 186531.4482639312 30 0.0 11 533420.6389637881 21 186592.6487152852 31 0.0 0 LINE 5 D2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533436.1570249224 20 186579.3350551873 30 0.0 11 533306.6325132512 21 186633.9674166327 31 0.0 0 LINE 5 D2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533277.9710485301 20 186445.7800774027 30 0.0 11 533540.7672647548 21 187197.9379284728 31 0.0 0 LINE 5 D30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533422.1103210733 20 186823.5261517935 30 0.0 11 533238.7604418549 21 186898.0710717438 31 0.0 0 LINE 5 D31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533154.9462600293 20 186469.3279651543 30 0.0 11 533188.812266217 21 186552.8455359016 31 0.0 0 LINE 5 D32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533543.8130697824 20 186673.1833526995 30 0.0 11 533159.1539992682 21 186854.8614218153 31 0.0 0 LINE 5 D33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533649.7930045239 20 186885.536569575 30 0.0 11 533289.3755657732 21 187116.8555180623 31 0.0 0 LINE 5 D34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533964.7426793781 20 186647.5999671596 30 0.0 11 533508.9748474477 21 186977.4381878725 31 0.0 0 LINE 5 D35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533533.3163165489 20 186908.5961767348 30 0.0 11 533807.3275931497 21 187360.5605178996 31 0.0 0 LINE 5 D36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533901.9424377028 20 186944.7638367852 30 0.0 11 533817.5611283347 21 187130.5229360999 31 0.0 0 LINE 5 D37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533848.4398897749 20 187134.243557791 30 0.0 11 533571.7747969511 21 186928.1180956163 31 0.0 0 LINE 5 D38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533639.3021414902 20 187059.0748609615 30 0.0 11 533475.2858643194 21 187197.5741820712 31 0.0 0 LINE 5 D39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533639.7585737072 20 187244.3959389553 30 0.0 11 533508.199878366 21 187142.9593923612 31 0.0 0 LINE 5 D3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534042.758202935 20 186806.130512364 30 0.0 11 533860.9066406696 21 187005.0755445281 31 0.0 0 LINE 5 D3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533436.6493869612 20 186718.2338186477 30 0.0 11 533451.1109411342 21 186762.966059692 31 0.0 0 LINE 5 D3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533507.1108704664 20 186732.3664107614 30 0.0 11 533449.2494348529 21 186762.5798501013 31 0.0 0 LINE 5 D3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533508.7924149971 20 186682.8412862811 30 0.0 11 533567.2166543183 21 186769.2678521841 31 0.0 0 LINE 5 D3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533900.9493501624 20 186779.2906266893 30 0.0 11 533809.9649782856 21 186845.8219322354 31 0.0 0 LINE 5 D3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533320.5592558329 20 186561.2778756949 30 0.0 11 532991.0926725162 21 186707.4178168395 31 0.0 0 LINE 5 D40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533580.2035412068 20 187231.4269793923 30 0.0 11 533650.3051828861 21 187576.4792701323 31 0.0 0 LINE 5 D41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534146.9285046155 20 186929.0436129879 30 0.0 11 533457.9740159064 21 187317.9322787298 31 0.0 0 LINE 5 D42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534071.615960048 20 187256.2822432926 30 0.0 11 533911.2409323012 21 187430.823099838 31 0.0 0 LINE 5 D43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533988.5834052235 20 187229.6818808633 30 0.0 11 534032.1396282146 21 187303.1269297103 31 0.0 0 LINE 5 D44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534275.7904482939 20 187285.0355955895 30 0.0 11 534288.4451373226 21 187401.7805593987 31 0.0 0 LINE 5 D45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534224.6726996108 20 187320.2774089048 30 0.0 11 534315.5517373769 21 187381.9750699207 31 0.0 0 LINE 5 D46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534028.5193002688 20 187211.5519736528 30 0.0 11 534164.1239993988 21 187419.4014063171 31 0.0 0 LINE 5 D47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534091.4044771071 20 187124.6511358966 30 0.0 11 533995.2391131685 21 187198.8110192915 31 0.0 0 LINE 5 D48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533950.0453981045 20 187107.2603301792 30 0.0 11 534067.888148219 21 187080.787377725 31 0.0 0 LINE 5 D49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534061.2112356012 20 187079.8966171456 30 0.0 11 534091.4686033571 21 187126.8232896232 31 0.0 0 LINE 5 D4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533843.797036858 20 186821.0674214544 30 0.0 11 533843.8026278218 21 186821.0785290134 31 0.0 0 LINE 5 D4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533909.6023046641 20 186951.8026426131 30 0.0 11 534096.7438698906 21 187323.5964933741 31 0.0 0 LINE 5 D4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534032.6638186539 20 187288.5896847648 30 0.0 11 534353.7893433044 21 187146.2235310125 31 0.0 0 LINE 5 D4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534287.0962343258 20 187071.6330025523 30 0.0 11 534058.0681274892 21 187253.7359744275 31 0.0 0 LINE 5 D4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534000.5054901832 20 187138.8254181675 30 0.0 11 534032.3759233981 21 187123.1324510591 31 0.0 0 LINE 5 D4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534198.1166002486 20 187207.9534239526 30 0.0 11 534246.6118885009 21 187287.7033281399 31 0.0 0 LINE 5 D50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534232.0137966773 20 187255.7278404318 30 0.0 11 534228.8067471569 21 187339.0482885543 31 0.0 0 LINE 5 D51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534219.4720997099 20 187259.5978338077 30 0.0 11 534286.9938766432 21 187302.7829846988 31 0.0 0 LINE 5 D52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534427.6767798613 20 187212.4484100446 30 0.0 11 534274.4310012642 21 187304.0247950843 31 0.0 0 LINE 5 D53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533819.3864504914 20 187105.5119975673 30 0.0 11 533974.8482824426 21 187360.4440476305 31 0.0 0 LINE 5 D54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534524.3107215045 20 186326.5754653182 30 0.0 11 534531.7366402564 21 185799.7180724953 31 0.0 0 LINE 5 D57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534573.6321587367 20 186048.281322406 30 0.0 11 534050.3682592749 21 186184.3150727255 31 0.0 0 LINE 5 D5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534302.7168493062 20 186154.8844698029 30 0.0 11 534471.8062822185 21 185786.7375415203 31 0.0 0 LINE 5 D60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534361.0083684124 20 185491.2003448077 30 0.0 11 534219.3739121182 21 186349.7377126543 31 0.0 0 LINE 5 DB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533623.1452109745 20 185972.3138249086 30 0.0 11 533623.1446843631 21 185972.3014007619 31 0.0 0 LINE 5 DCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534063.780393243 20 186245.9444705994 30 0.0 11 533978.4760952603 21 186424.7946004351 31 0.0 0 LINE 5 DCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532959.0614927691 20 188756.0186229439 30 0.0 11 532598.4363163279 21 189185.367485622 31 0.0 0 LINE 5 DCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532952.5991179057 20 188775.7158074176 30 0.0 11 532498.8377178559 21 188127.7410335887 31 0.0 0 LINE 5 DD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532875.956784719 20 188661.1317739479 30 0.0 11 532770.1782325437 21 188764.4206533319 31 0.0 0 LINE 5 DD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532799.0322997413 20 188749.1493385631 30 0.0 11 532718.9305002555 21 188766.6078600857 31 0.0 0 LINE 5 DD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532808.7461501953 20 188828.2755461247 30 0.0 11 532788.875372497 21 188742.7034673028 31 0.0 0 LINE 5 DD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532813.3574764001 20 188809.8241076595 30 0.0 11 532683.9742992572 21 188960.8679630683 31 0.0 0 LINE 5 DD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532889.3183331362 20 188906.0571197371 30 0.0 11 532520.9270153102 21 188678.5773222394 31 0.0 0 LINE 5 DD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532637.2249820604 20 188929.9053499753 30 0.0 11 532722.1061582541 21 188763.6674942133 31 0.0 0 LINE 5 DD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532689.4474729919 20 188960.6693755529 30 0.0 11 532637.0169751474 21 188929.0835626449 31 0.0 0 LINE 5 DD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532507.0072332216 20 189195.5474548694 30 0.0 11 532655.8044958146 21 188938.243469675 31 0.0 0 LINE 5 DD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532544.3809392626 20 189138.2336377773 30 0.0 11 532450.5444421437 21 189075.0473012399 31 0.0 0 LINE 5 DD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532410.2276636336 20 189145.8382784577 30 0.0 11 532808.8697911184 21 188536.4143750713 31 0.0 0 LINE 5 DDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532624.7882511244 20 188656.8900412475 30 0.0 11 532304.9757337464 21 188355.8855208015 31 0.0 0 LINE 5 DDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532664.118266529 20 188599.5945185996 30 0.0 11 532548.5643406334 21 188755.3404922934 31 0.0 0 LINE 5 DDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532605.1581469689 20 188557.2140689971 30 0.0 11 532567.26711288 21 188609.174777593 31 0.0 0 LINE 5 DDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532658.1279466498 20 188569.5211949843 30 0.0 11 532589.7997748422 21 188561.2437279531 31 0.0 0 LINE 5 DDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532607.6740753801 20 188571.1721289748 30 0.0 11 532331.6853950706 21 188277.1868468728 31 0.0 0 LINE 5 DDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532677.9790098687 20 188376.4493737437 30 0.0 11 532363.1201382281 21 188634.8590972316 31 0.0 0 LINE 5 DE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532373.8040174633 20 188642.8059028588 30 0.0 11 532211.6587030695 21 188467.4643256072 31 0.0 0 LINE 5 DE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532314.6543550703 20 188823.9332564042 30 0.0 11 532371.7371158007 21 188624.8140952755 31 0.0 0 LINE 5 DE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532400.0218489002 20 188806.2026207918 30 0.0 11 532325.9487450115 21 188763.723272378 31 0.0 0 LINE 5 DE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532624.8433100517 20 188278.722365095 30 0.0 11 532558.2856573059 21 188339.4855929523 31 0.0 0 LINE 5 DE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532552.579947896 20 188144.1162924139 30 0.0 11 532211.4295508927 21 188470.5585631675 31 0.0 0 LINE 5 DE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532557.0555737129 20 188704.7202260402 30 0.0 11 532254.0500494715 21 188408.0337271415 31 0.0 0 LINE 5 DE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532051.1737493166 20 188840.7494451472 30 0.0 11 532260.2096545565 21 188404.7607253519 31 0.0 0 LINE 5 DE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531924.5542984262 20 189060.1813108598 30 0.0 11 532179.0478359127 21 188584.5758381749 31 0.0 0 LINE 5 DE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532122.7868757098 20 188899.4372118148 30 0.0 11 532054.2901579421 21 188804.0552041594 31 0.0 0 LINE 5 DE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532149.9267230192 20 188843.5942326302 30 0.0 11 532040.4487535058 21 188834.6401792815 31 0.0 0 LINE 5 DEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532244.1854389241 20 188678.6137085213 30 0.0 11 532128.6400668821 21 188844.31373375 31 0.0 0 LINE 5 DEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532394.7262438962 20 188877.8526145944 30 0.0 11 532131.3785212176 21 188670.6379691531 31 0.0 0 LINE 5 DEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532456.4168509652 20 188807.4901741918 30 0.0 11 532370.9897163031 21 188893.8016461407 31 0.0 0 LINE 5 DED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532456.2850829661 20 188949.9149331953 30 0.0 11 532497.0543522947 21 188836.2241347784 31 0.0 0 LINE 5 DEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532497.116930214 20 188842.9599124264 30 0.0 11 532454.2690864345 21 188807.1593094035 31 0.0 0 LINE 5 DEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532727.23297523 20 189090.5646219603 30 0.0 11 532259.6395972801 21 188777.7164137778 31 0.0 0 LINE 5 DF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532256.8122081843 20 188764.9478729063 30 0.0 11 532243.4655405895 21 188785.2363187846 31 0.0 0 LINE 5 DF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532220.3816786492 20 188578.3303196427 30 0.0 11 532180.3201087714 21 188557.1357969501 31 0.0 0 LINE 5 DF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532235.8560493197 20 188576.9630091105 30 0.0 11 532211.7915096664 21 188577.1736364979 31 0.0 0 LINE 5 DF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532275.1915484151 20 188526.3548240165 30 0.0 11 532229.4793112505 21 188581.7827388668 31 0.0 0 LINE 5 DF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532332.6502728161 20 188776.6343448085 30 0.0 11 532068.9166882257 21 189121.7457489512 31 0.0 0 LINE 5 DF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532426.7555479719 20 189134.8766008566 30 0.0 11 532065.5978605995 21 189100.9695262171 31 0.0 0 LINE 5 DF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532176.9164569791 20 189185.4436963039 30 0.0 11 532327.6998801924 21 188819.4788735671 31 0.0 0 LINE 5 DF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532434.3805068511 20 188891.152697585 30 0.0 11 532414.3678391711 21 188920.5037940263 31 0.0 0 LINE 5 DF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532228.3462162483 20 188928.2835890487 30 0.0 11 532146.8698803295 21 188882.7484719869 31 0.0 0 LINE 5 DF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532175.3197418778 20 188903.3916664333 30 0.0 11 532137.0862075681 21 188829.2918749616 31 0.0 0 LINE 5 DFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532184.3303370418 20 188893.8480724385 30 0.0 11 532104.2972307981 21 188889.5064687405 31 0.0 0 LINE 5 DFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532413.3284184004 20 189411.3057914018 30 0.0 11 532609.1176652272 21 189170.0201889003 31 0.0 0 LINE 5 DFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532593.1945088682 20 189231.5869135002 30 0.0 11 532355.9463737834 21 189117.3409349225 31 0.0 0 LINE 5 DFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532477.5918910147 20 188619.8725829968 30 0.0 11 532440.6663681646 21 188648.9692443206 31 0.0 0 LINE 5 DFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532488.8098312406 20 188690.8564447874 30 0.0 11 532440.3820482271 21 188647.0894768731 31 0.0 0 LINE 5 DFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532535.8363152857 20 188675.2335338815 30 0.0 11 532475.0796668022 21 188760.0366747378 31 0.0 0 LINE 5 E00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532608.426173541 20 188830.9696730895 30 0.0 11 532347.592662036 21 188685.6265940694 31 0.0 0 LINE 5 E01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532328.3039889435 20 188588.9947887008 30 0.0 11 532280.7224491903 21 188638.7497967613 31 0.0 0 LINE 5 E02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532304.400390356 20 188660.0407108078 30 0.0 11 532260.8376349251 21 188618.629863245 31 0.0 0 LINE 5 E03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532305.1801104391 20 188651.4700401296 30 0.0 11 532256.6109941681 21 188703.7148184506 31 0.0 0 LINE 5 E04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532260.325517522 20 188703.8619679585 30 0.0 11 532218.6777600764 21 188666.2181889972 31 0.0 0 LINE 5 E05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532269.6638991237 20 188616.6967556528 30 0.0 11 532216.2696521647 21 188672.8674080448 31 0.0 0 LINE 5 E06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532581.5841857867 20 189076.4774365243 30 0.0 11 532487.5956934878 21 189014.2622144411 31 0.0 0 LINE 5 E07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532584.4608700269 20 188456.4984482675 30 0.0 11 532414.5473369034 21 188253.6607273663 31 0.0 0 LINE 5 E08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532883.7293468934 20 188455.3776511924 30 0.0 11 532138.3714465846 21 187391.0008293174 31 0.0 0 LINE 5 E09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532515.4905134476 20 187924.3915696767 30 0.0 11 532409.7119612722 21 188027.6804490609 31 0.0 0 LINE 5 E0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532546.9683313642 20 188085.9810547085 30 0.0 11 532264.1068343666 21 187680.4271368265 31 0.0 0 LINE 5 E0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532438.5660284698 20 188012.4091342919 30 0.0 11 532358.464228984 21 188029.8676558145 31 0.0 0 LINE 5 E0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532448.2798789237 20 188091.5353418534 30 0.0 11 532428.4091012255 21 188005.9632630317 31 0.0 0 LINE 5 E0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532451.5745885126 20 188074.3437562909 30 0.0 11 532322.1914113697 21 188225.3876116995 31 0.0 0 LINE 5 E0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532601.2688677392 20 188214.0339311463 30 0.0 11 532160.4607440389 21 187941.8371179683 31 0.0 0 LINE 5 E0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532276.758710789 20 188193.1651457041 30 0.0 11 532361.6398869824 21 188026.9272899421 31 0.0 0 LINE 5 E10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532328.9812017204 20 188223.9291712816 30 0.0 11 532276.5507038758 21 188192.3433583738 31 0.0 0 LINE 5 E11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532146.5409619501 20 188458.8072505983 30 0.0 11 532295.338224543 21 188201.5032654037 31 0.0 0 LINE 5 E12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532183.9146679911 20 188401.4934335063 30 0.0 11 532090.0781708722 21 188338.3070969686 31 0.0 0 LINE 5 E13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532049.761392362 20 188409.0980741865 30 0.0 11 532439.5831995335 21 187761.8650720854 31 0.0 0 LINE 5 E14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532264.3219798531 20 187920.1498369762 30 0.0 11 531944.5094624748 21 187619.1453165304 31 0.0 0 LINE 5 E15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532303.6519952577 20 187862.8543143283 30 0.0 11 532188.098069362 21 188018.6002880221 31 0.0 0 LINE 5 E16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532244.6918756974 20 187820.473864726 30 0.0 11 532206.8008416085 21 187872.4345733218 31 0.0 0 LINE 5 E17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532297.6616753782 20 187832.7809907131 30 0.0 11 532229.3335035706 21 187824.503523682 31 0.0 0 LINE 5 E18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532247.2078041085 20 187834.4319247036 30 0.0 11 531971.2191237991 21 187540.4466426017 31 0.0 0 LINE 5 E19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532482.5695292557 20 187432.4593430259 30 0.0 11 531940.9158861035 21 187862.0174506855 31 0.0 0 LINE 5 E1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532013.337746192 20 187906.0656985876 30 0.0 11 531851.1924317979 21 187730.7241213361 31 0.0 0 LINE 5 E1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531954.1880837988 20 188087.193052133 30 0.0 11 532011.2708445293 21 187888.0738910043 31 0.0 0 LINE 5 E1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532039.5555776289 20 188069.4624165206 30 0.0 11 531965.48247374 21 188026.9830681068 31 0.0 0 LINE 5 E1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532211.4046832727 20 187485.430013197 30 0.0 11 532144.847030527 21 187546.1932410541 31 0.0 0 LINE 5 E1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532192.1136766243 20 187407.3760881427 30 0.0 11 531850.963279621 21 187733.8183588964 31 0.0 0 LINE 5 E1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532196.5893024412 20 187967.980021769 30 0.0 11 531893.5837781998 21 187671.2935228705 31 0.0 0 LINE 5 E20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531747.632482898 20 187987.965931228 30 0.0 11 531899.7433832848 21 187668.0205210807 31 0.0 0 LINE 5 E21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532034.2599726247 20 188141.1124103233 30 0.0 11 531770.9122499461 21 187933.8977648818 31 0.0 0 LINE 5 E22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532095.9505796936 20 188070.7499699206 30 0.0 11 532010.5234450315 21 188157.0614418696 31 0.0 0 LINE 5 E23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532095.8188116946 20 188213.1747289239 30 0.0 11 532136.5880810233 21 188099.4839305072 31 0.0 0 LINE 5 E24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532136.6506589425 20 188106.2197081552 30 0.0 11 532093.8028151631 21 188070.4191051323 31 0.0 0 LINE 5 E25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532366.7667039584 20 188353.8244176891 30 0.0 11 531899.1733260084 21 188040.9762095067 31 0.0 0 LINE 5 E26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531896.3459369127 20 188028.2076686353 30 0.0 11 531882.999269318 21 188048.4961145133 31 0.0 0 LINE 5 E27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531859.9154073778 20 187841.5901153716 30 0.0 11 531819.8538374999 21 187820.3955926789 31 0.0 0 LINE 5 E28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531875.3897780482 20 187840.2228048392 30 0.0 11 531851.3252383947 21 187840.4334322268 31 0.0 0 LINE 5 E29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531914.7252771438 20 187789.6146197452 30 0.0 11 531869.0130399789 21 187845.0425345955 31 0.0 0 LINE 5 E2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531972.1840015447 20 188039.8941405374 30 0.0 11 531751.4036104533 21 188317.9406604103 31 0.0 0 LINE 5 E2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532066.2892767004 20 188398.1363965854 30 0.0 11 531862.7873851295 21 188383.5203616941 31 0.0 0 LINE 5 E2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531870.022364545 20 188413.7692626113 30 0.0 11 531967.2336089209 21 188082.7386692958 31 0.0 0 LINE 5 E2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532073.9142355794 20 188154.412493314 30 0.0 11 532053.9015678996 21 188183.7635897552 31 0.0 0 LINE 5 E2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532245.1980405545 20 188482.0407027577 30 0.0 11 531995.480102512 21 188380.6007306513 31 0.0 0 LINE 5 E2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532117.1256197433 20 187883.1323787257 30 0.0 11 532080.2000968932 21 187912.2290400493 31 0.0 0 LINE 5 E30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532128.3435599692 20 187954.1162405161 30 0.0 11 532079.9157769556 21 187910.3492726018 31 0.0 0 LINE 5 E31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532175.3700440142 20 187938.4933296104 30 0.0 11 532114.6133955306 21 188023.2964704667 31 0.0 0 LINE 5 E32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532247.9599022693 20 188094.2294688184 30 0.0 11 531987.1263907643 21 187948.8863897982 31 0.0 0 LINE 5 E33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532221.1179145153 20 188339.7372322532 30 0.0 11 532127.1294222164 21 188277.52201017 31 0.0 0 LINE 5 E34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532201.0248110695 20 187689.3201666808 30 0.0 11 532054.0810656321 21 187516.920523095 31 0.0 0 LINE 5 E35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531833.5906325206 20 188310.2228920877 30 0.0 11 531722.4811789076 21 188438.6268910766 31 0.0 0 LINE 5 E36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532166.1132606188 20 188622.4140607703 30 0.0 11 531589.3173209907 21 188134.3791804765 31 0.0 0 LINE 5 E37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531717.6318825316 20 188332.6364255321 30 0.0 11 531369.4847013599 21 188600.3626062518 31 0.0 0 LINE 5 E38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531667.3404986682 20 188284.6739012414 30 0.0 11 531802.6689907199 21 188423.5829266889 31 0.0 0 LINE 5 E39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531616.1011491471 20 188336.1221982756 30 0.0 11 531661.3554147592 21 188381.813522901 31 0.0 0 LINE 5 E3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531636.6967781323 20 188285.7924347655 30 0.0 11 531617.6303835526 21 188351.9266023396 31 0.0 0 LINE 5 E3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531630.2817941878 20 188335.8640503788 30 0.0 11 531296.0516959023 21 188561.4462729754 31 0.0 0 LINE 5 E3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531449.2602943833 20 188235.4103205985 30 0.0 11 531654.1601976503 21 188587.4440176861 31 0.0 0 LINE 5 E3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531663.7088627422 20 188578.1639320104 30 0.0 11 531480.7888713644 21 188699.6307965083 31 0.0 0 LINE 5 E3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531833.0875890426 20 188665.4373405636 30 0.0 11 531645.617673552 21 188577.3356227187 31 0.0 0 LINE 5 E3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531829.1955174565 20 188578.3348938651 30 0.0 11 531775.4487910742 21 188644.6870540753 31 0.0 0 LINE 5 E40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531199.9049287589 20 188322.1598857742 30 0.0 11 531440.339198993 21 188674.6404915461 31 0.0 0 LINE 5 E41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531754.0502627065 20 188407.1290006797 30 0.0 11 531412.845709929 21 188658.9517151305 31 0.0 0 LINE 5 E42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532549.8724364265 20 189386.7313191874 30 0.0 11 531416.0773421576 21 188643.2176930456 31 0.0 0 LINE 5 E43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531678.3910584178 20 188711.833704132 30 0.0 11 531823.547616166 21 188852.3214441798 31 0.0 0 LINE 5 E44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531874.3351077811 20 188618.6272900689 30 0.0 11 531652.5304600238 21 188821.9256772801 31 0.0 0 LINE 5 E45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531963.3979159524 20 188638.2794219689 30 0.0 11 531860.4563487301 21 188573.8550534082 31 0.0 0 LINE 5 E46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531930.6130602789 20 188499.6793405171 30 0.0 11 531996.3643426193 21 188600.9932084562 31 0.0 0 LINE 5 E47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531994.8808056946 20 188594.422536138 30 0.0 11 531961.383235969 21 188639.0939332041 31 0.0 0 LINE 5 E48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532162.0927971547 20 188300.6511347574 30 0.0 11 532162.0843226814 21 188300.6602353095 31 0.0 0 LINE 5 E49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532062.3488203431 20 188407.7640210612 30 0.0 11 531778.6900105733 21 188712.3790445563 31 0.0 0 LINE 5 E4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531765.6340042651 20 188713.1343354736 30 0.0 11 531783.5347779464 21 188729.5452121612 31 0.0 0 LINE 5 E4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531789.263231201 20 188640.1299156961 30 0.0 11 532034.293017186 21 188891.8244295344 31 0.0 0 LINE 5 E4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532081.0786173002 20 188803.3776922108 30 0.0 11 531830.7702844852 21 188651.8484718924 31 0.0 0 LINE 5 E4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531918.5372013929 20 188557.9609783154 30 0.0 11 531944.3217962647 21 188582.3975983202 31 0.0 0 LINE 5 E4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531922.3411816466 20 188767.2797823902 30 0.0 11 531864.3973468203 21 188840.4532216027 31 0.0 0 LINE 5 E4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531889.3127261933 20 188815.6588680163 30 0.0 11 531810.0646682506 21 188841.5881478804 31 0.0 0 LINE 5 E50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531881.3279569153 20 188805.241840075 30 0.0 11 531864.2807364346 21 188883.5587596492 31 0.0 0 LINE 5 E51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531997.8509052491 20 188984.1123505281 30 0.0 11 531858.7532069532 21 188872.2091187451 31 0.0 0 LINE 5 E52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531657.6177715115 20 188472.0472110668 30 0.0 11 531680.4544563258 21 188513.1397379377 31 0.0 0 LINE 5 E53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531729.4821671011 20 188472.2910638339 30 0.0 11 531678.5534037705 21 188513.1206941728 31 0.0 0 LINE 5 E54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531721.5574363368 20 188423.3751749109 30 0.0 11 531795.5880671324 21 188496.8762547536 31 0.0 0 LINE 5 E55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531886.875472056 20 188376.5459143697 30 0.0 11 531701.8023538999 21 188610.867642511 31 0.0 0 LINE 5 E56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531603.3312817452 20 188614.5017403534 30 0.0 11 531644.8629290103 21 188669.4078969101 31 0.0 0 LINE 5 E57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531669.6568654605 20 188649.4276908528 30 0.0 11 531621.8298004068 21 188685.8302155587 31 0.0 0 LINE 5 E58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531661.3201711099 20 188647.2913653651 30 0.0 11 531705.1522674773 21 188703.5694538651 31 0.0 0 LINE 5 E59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531705.889809728 20 188699.9259160029 30 0.0 11 531662.0869619471 21 188735.038596348 31 0.0 0 LINE 5 E5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531621.3287594976 20 188676.8086412682 30 0.0 11 531668.2671431887 21 188738.4761037986 31 0.0 0 LINE 5 E5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532910.1226366329 20 188386.7350410256 30 0.0 11 532830.9522630293 21 188273.2241689699 31 0.0 0 LINE 5 E5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533055.8404062017 20 188356.2443009575 30 0.0 11 532883.8566398558 21 187952.1337322834 31 0.0 0 LINE 5 E5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532981.3128478802 20 188310.5704731512 30 0.0 11 532800.7760843893 21 187950.0103883114 31 0.0 0 LINE 5 E5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532774.2909740916 20 188309.2747141542 30 0.0 11 533077.067009216 21 188131.5452652497 31 0.0 0 LINE 5 E5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532666.1688044262 20 188156.400341244 30 0.0 11 532746.1847272879 21 188114.9329674759 31 0.0 0 LINE 5 E60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532599.5853865142 20 188111.3314316386 30 0.0 11 533023.7869030749 21 187903.9640695543 31 0.0 0 LINE 5 E61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533124.1255424038 20 188309.2062063903 30 0.0 11 532950.3875296483 21 187922.3595581259 31 0.0 0 LINE 5 E62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533332.1376259856 20 187890.3996014996 30 0.0 11 532945.1880630145 21 187927.0091626512 31 0.0 0 LINE 5 E63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533071.9548736702 20 188205.32251796 30 0.0 11 533112.0168427009 21 188180.7227501699 31 0.0 0 LINE 5 E64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533134.6925907006 20 188240.3729056813 30 0.0 11 533110.351041949 21 188179.8065234848 31 0.0 0 LINE 5 E65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532648.3772381376 20 188181.1772785917 30 0.0 11 532545.2284021539 21 187673.4734036214 31 0.0 0 LINE 5 E66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533035.17653784 20 187839.0110208041 30 0.0 11 532655.3684114847 21 187904.8181812321 31 0.0 0 LINE 5 E67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533021.9629950835 20 187731.017087655 30 0.0 11 532279.9077432335 21 187873.2338361666 31 0.0 0 LINE 5 E68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532488.9949775387 20 187763.4472688142 30 0.0 11 532317.0112111929 21 187359.33670014 31 0.0 0 LINE 5 E69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532421.6397178314 20 187780.5614739364 30 0.0 11 532607.7170939442 21 187725.9288077863 31 0.0 0 LINE 5 E6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532402.237976996 20 187710.5902608587 30 0.0 11 532464.0897660724 21 187692.9833903204 31 0.0 0 LINE 5 E6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532395.4875784423 20 187764.5504049247 30 0.0 11 532411.3254571612 21 187697.5696829169 31 0.0 0 LINE 5 E6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532340.656085799 20 187570.3606917988 30 0.0 11 532233.9306557266 21 187357.2133561679 31 0.0 0 LINE 5 E6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532706.7652726552 20 187604.1039898727 30 0.0 11 532692.4918827968 21 187519.9161635358 31 0.0 0 LINE 5 E6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532152.33259944 20 187460.8469788372 30 0.0 11 532356.271155133 21 187387.1368772966 31 0.0 0 LINE 5 E6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532557.2801137408 20 187716.409174247 30 0.0 11 532383.5421009857 21 187329.5625259826 31 0.0 0 LINE 5 E70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532775.8331259071 20 187623.8877380377 30 0.0 11 532672.357212332 21 187305.1673784193 31 0.0 0 LINE 5 E71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532688.4904774424 20 187657.4714510412 30 0.0 11 532799.0005223217 21 187607.1227121558 31 0.0 0 LINE 5 E72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532707.7154038946 20 187707.9194538183 30 0.0 11 532688.9219839458 21 187655.3416233195 31 0.0 0 LINE 5 E73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532860.5751990845 20 188009.4080429418 30 0.0 11 532728.5315992382 21 187462.5240916274 31 0.0 0 LINE 5 E74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532717.5260368595 20 187455.4595773613 30 0.0 11 532741.1762224215 21 187449.9438457759 31 0.0 0 LINE 5 E75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532702.2927821534 20 187530.6655187736 30 0.0 11 533039.4935310675 21 187419.5371999896 31 0.0 0 LINE 5 E76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533005.9662778086 20 187742.7403283741 30 0.0 11 533062.5550273837 21 187546.7189984879 31 0.0 0 LINE 5 E77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533088.4419344846 20 187563.95874833 30 0.0 11 532744.2095209789 21 187540.8216517915 31 0.0 0 LINE 5 E78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533022.8958895394 20 187939.6201562503 30 0.0 11 533013.973128999 21 187670.232886942 31 0.0 0 LINE 5 E79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532505.1094450074 20 187612.5254858167 30 0.0 11 532545.1714140379 21 187587.9257180264 31 0.0 0 LINE 5 E7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532567.8471620379 20 187647.5758735381 30 0.0 11 532543.5056132862 21 187587.0094913414 31 0.0 0 LINE 5 E7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532536.9397053601 20 187686.3095109673 30 0.0 11 532637.5112505831 21 187658.5911537743 31 0.0 0 LINE 5 E7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532897.6734271721 20 187867.8603826554 30 0.0 11 532871.7596143943 21 187758.1651464291 31 0.0 0 LINE 5 E7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533003.8573889543 20 187493.997497595 30 0.0 11 533162.7408384199 21 187434.0896756984 31 0.0 0 LINE 5 E7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533181.9479908528 20 187913.9002976766 30 0.0 11 532923.2311001333 21 187204.0149753805 31 0.0 0 LINE 5 E7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533064.9517395415 20 187392.9218897224 30 0.0 11 533527.9138737417 21 187155.1832707628 31 0.0 0 LINE 5 E80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533037.3167913862 20 187329.1571920623 30 0.0 11 533120.9202669467 21 187504.1428400051 31 0.0 0 LINE 5 E81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532963.087111749 20 187353.074195673 30 0.0 11 533117.6022115812 21 187305.7419693661 31 0.0 0 LINE 5 E82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533098.1579167783 20 187312.0651937155 30 0.0 11 533322.9937731828 21 187084.8043730471 31 0.0 0 LINE 5 E83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533177.7906048676 20 187547.8262754669 30 0.0 11 533506.7021197757 21 187286.0821649716 31 0.0 0 LINE 5 E84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533266.8696006119 20 187729.1476499413 30 0.0 11 533241.9757279544 21 187610.2873932081 31 0.0 0 LINE 5 E85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533148.1297695554 20 187650.4985440298 30 0.0 11 533220.4900966108 21 187747.2028047152 31 0.0 0 LINE 5 E86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533214.8365194989 20 187743.5406083304 30 0.0 11 533268.3299825314 21 187727.5384114146 31 0.0 0 LINE 5 E87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532881.3856533973 20 187798.9662905841 30 0.0 11 532881.3971213293 21 187798.9614819165 31 0.0 0 LINE 5 E88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533016.3624389602 20 187742.3685990975 30 0.0 11 533943.3796218751 21 187255.7435890138 31 0.0 0 LINE 5 E89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533301.653800806 20 187416.6866301347 30 0.0 11 533450.1008736807 21 187749.3717472283 31 0.0 0 LINE 5 E8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533346.6419572953 20 187850.8964413646 30 0.0 11 533291.3539286802 21 187585.0125509866 31 0.0 0 LINE 5 E8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533206.9947936887 20 187659.3010781028 30 0.0 11 533221.0188632043 21 187691.9403060992 31 0.0 0 LINE 5 E8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533246.5008210441 20 187239.9275874134 30 0.0 11 533247.1849608591 21 187420.3929628149 31 0.0 0 LINE 5 E8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533191.9135700587 20 187452.2897331669 30 0.0 11 533247.8238560572 21 187418.6023829063 31 0.0 0 LINE 5 E8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533047.6881762032 20 187566.9144332003 30 0.0 11 533270.8410215643 21 187494.0123929628 31 0.0 0 LINE 5 E8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533198.0129838886 20 187845.4175907803 30 0.0 11 532996.8397992431 21 187787.9127616617 31 0.0 0 LINE 5 E90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533195.8603909342 20 187434.92947827 30 0.0 11 533251.7942375957 21 187537.893542003 31 0.0 0 LINE 5 E91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532777.816868749 20 188307.2050149652 30 0.0 11 532580.4733576386 21 188289.3239965596 31 0.0 0 LINE 5 E99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533301.0508297613 20 187282.5650489181 30 0.0 11 533558.3424779411 21 187640.6293556604 31 0.0 0 LINE 5 E9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533688.8059216369 20 187644.6635814481 30 0.0 11 534031.2188721263 21 187547.1269241443 31 0.0 0 LINE 5 E9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532960.0471768222 20 188057.6651346364 30 0.0 11 533278.2096303262 21 188034.0587147734 31 0.0 0 LINE 5 E9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532361.5412691713 20 187422.9006690331 30 0.0 11 532159.5020060875 21 187561.9190406652 31 0.0 0 LINE 5 EA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532336.8154352048 20 187445.644135747 30 0.0 11 532295.0184469695 21 187207.7119952258 31 0.0 0 LINE 5 EA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532771.7530398989 20 187265.2556792592 30 0.0 11 532029.6977880492 21 187407.4724277708 31 0.0 0 LINE 5 EA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532238.7850223542 20 187297.6858604184 30 0.0 11 532066.8012560086 21 186893.5752917443 31 0.0 0 LINE 5 EA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532171.4297626468 20 187314.8000655407 30 0.0 11 532357.5071387598 21 187260.1673993905 31 0.0 0 LINE 5 EA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532152.0280218115 20 187244.8288524629 30 0.0 11 532213.8798108879 21 187227.2219819246 31 0.0 0 LINE 5 EA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532164.257464033 20 187252.012032612 30 0.0 11 531983.7207005421 21 186891.4519477722 31 0.0 0 LINE 5 EA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532052.1854304346 20 187195.1103712278 30 0.0 11 532308.5103977871 21 187044.5180587102 31 0.0 0 LINE 5 EA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532312.276887243 20 187057.2895328762 30 0.0 11 532203.7486339846 21 186844.5516896567 31 0.0 0 LINE 5 EA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532502.6865875572 20 187064.356837159 30 0.0 11 532296.1069361393 21 187049.1341724364 31 0.0 0 LINE 5 EA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532456.5553174708 20 187138.342581477 30 0.0 11 532442.2819276124 21 187054.1547551401 31 0.0 0 LINE 5 EAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531902.1226442555 20 186995.0855704415 30 0.0 11 532206.7315192275 21 186845.4056290151 31 0.0 0 LINE 5 EAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532307.0701585566 20 187250.6477658511 30 0.0 11 532133.3321458012 21 186863.8011175869 31 0.0 0 LINE 5 EAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532669.5176654935 20 186819.0197692934 30 0.0 11 532128.1326791673 21 186868.4507221122 31 0.0 0 LINE 5 EAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532639.8270503792 20 186910.3877806064 30 0.0 11 532573.9818262154 21 186813.1564369764 31 0.0 0 LINE 5 EAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532578.0462980195 20 186916.5642095136 30 0.0 11 532607.4654813943 21 186810.7336254195 31 0.0 0 LINE 5 EAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532390.6599277922 20 186948.0225488274 30 0.0 11 532586.0755084608 21 186896.8367872021 31 0.0 0 LINE 5 EB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532525.6231707228 20 187158.1263296419 30 0.0 11 532389.8328575555 21 186741.9088822389 31 0.0 0 LINE 5 EB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532438.280522258 20 187191.7100426455 30 0.0 11 532548.7905671371 21 187141.3613037601 31 0.0 0 LINE 5 EB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532457.5054487103 20 187242.1580454225 30 0.0 11 532438.7120287613 21 187189.5802149239 31 0.0 0 LINE 5 EB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532699.8964538836 20 187928.212678685 30 0.0 11 532478.3216440537 21 186996.7626832316 31 0.0 0 LINE 5 EB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532467.316081675 20 186989.6981689655 30 0.0 11 532490.9662672371 21 186984.18243738 31 0.0 0 LINE 5 EB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532304.7748049706 20 186891.0390181706 30 0.0 11 532298.725549977 21 186846.121942495 31 0.0 0 LINE 5 EB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532298.1456722383 20 186905.0882275774 30 0.0 11 532306.6570310679 21 186882.5781586414 31 0.0 0 LINE 5 EB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532237.0641022033 20 186924.5178876279 30 0.0 11 532304.8716456011 21 186900.7692154624 31 0.0 0 LINE 5 EB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532452.0828269688 20 187064.9041103778 30 0.0 11 532789.2835758827 21 186953.7757915938 31 0.0 0 LINE 5 EB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532755.7563226241 20 187276.9789199783 30 0.0 11 532812.3450721992 21 187080.9575900921 31 0.0 0 LINE 5 EBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532838.2319793 20 187098.1973399342 30 0.0 11 532493.9995657945 21 187075.0602433957 31 0.0 0 LINE 5 EBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532524.4047776451 20 187199.933844473 30 0.0 11 532558.8625446769 21 187191.2934728867 31 0.0 0 LINE 5 EBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.429167671 20 187019.4133173171 30 0.0 11 532615.8457918745 21 186927.2223993751 31 0.0 0 LINE 5 EBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532625.3892216226 20 186961.05225376 30 0.0 11 532569.0606453941 21 186899.5732025151 31 0.0 0 LINE 5 EBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532613.3203101034 20 186966.2109732026 30 0.0 11 532636.8954766592 21 186889.6057570645 31 0.0 0 LINE 5 EBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532751.2129145473 20 186878.8594245582 30 0.0 11 532626.5100272641 21 186896.7828297049 31 0.0 0 LINE 5 EC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532866.401228957 20 187500.5356147793 30 0.0 11 532763.7631738145 21 187204.4714785462 31 0.0 0 LINE 5 EC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532254.8994898229 20 187146.7640774209 30 0.0 11 532294.9614588535 21 187122.1643096307 31 0.0 0 LINE 5 EC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532317.6372068535 20 187181.8144651424 30 0.0 11 532293.2956581016 21 187121.2480829457 31 0.0 0 LINE 5 EC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532286.7297501757 20 187220.5481025715 30 0.0 11 532387.3012953987 21 187192.8297453785 31 0.0 0 LINE 5 EC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532407.7988971119 20 187342.4714155062 30 0.0 11 532361.5163903555 21 187047.4855498933 31 0.0 0 LINE 5 EC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532277.4981650085 20 186996.0006343546 30 0.0 11 532340.6278919628 21 186968.5379082136 31 0.0 0 LINE 5 EC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532352.42773972 20 186998.1134303847 30 0.0 11 532328.6164939601 21 186942.9265068251 31 0.0 0 LINE 5 EC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532344.1154093107 20 186995.8841878118 30 0.0 11 532409.922789283 21 186968.3548460411 31 0.0 0 LINE 5 EC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532408.7776030103 20 186971.8914948963 30 0.0 11 532387.8398953379 21 186919.803087432 31 0.0 0 LINE 5 EC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532323.7531569956 20 186950.541478804 30 0.0 11 532394.9116494379 21 186919.8403916598 31 0.0 0 LINE 5 ECA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532647.4634719876 20 187402.0989742598 30 0.0 11 532621.5496592099 21 187292.4037380333 31 0.0 0 LINE 5 ECB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532630.2831464825 20 186835.5866176528 30 0.0 11 533006.6015529368 21 186508.8569529216 31 0.0 0 LINE 5 ECC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532697.5207067601 20 186850.0125420364 30 0.0 11 532860.8416899149 21 186691.9120637713 31 0.0 0 LINE 5 ECD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532753.6474337698 20 187028.2360891994 30 0.0 11 532868.0969839297 21 187045.2654694289 31 0.0 0 LINE 5 ECE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532888.7525577194 20 187354.0892509376 30 0.0 11 532600.956481905 21 186546.2740326586 31 0.0 0 LINE 5 ED0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532853.0892751174 20 186833.0854560245 30 0.0 11 532880.3330652703 21 186891.3385383485 31 0.0 0 LINE 5 ED1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532798.7431429207 20 186835.0252868174 30 0.0 11 532867.3922563968 21 186839.9805609704 31 0.0 0 LINE 5 ED2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532847.9479615937 20 186846.3037853197 30 0.0 11 533024.8768349366 21 186688.6722408888 31 0.0 0 LINE 5 ED4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532631.1756982129 20 187333.2048821884 30 0.0 11 532631.1871661447 21 187333.2000735208 31 0.0 0 LINE 5 ED5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 533109.9406543836 20 187325.8194304203 30 0.0 11 533029.5141630925 21 187140.257367994 31 0.0 0 LINE 5 ED9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532767.8763670437 20 186595.6615620909 30 0.0 11 532930.3741798359 21 186793.7619793046 31 0.0 0 LINE 5 EE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532826.7197102416 20 186614.8899640539 30 0.0 11 532625.451864467 21 186697.4888187418 31 0.0 0 LINE 5 EE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532312.7807578225 20 186709.8782579019 30 0.0 11 532180.7561651608 21 186872.6457364109 31 0.0 0 LINE 5 EFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531958.3211544966 20 187086.486218021 30 0.0 11 532300.7341049858 21 186988.9495607173 31 0.0 0 LINE 5 EFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 534930.9326781594 20 187726.3550681194 30 0.0 11 535449.6709668517 21 188370.3442761802 31 0.0 0 LINE 5 EFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529378.4635770085 20 187735.7500589992 30 0.0 11 530008.689649875 21 187341.9860925706 31 0.0 0 LINE 5 EFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529545.8148094653 20 187623.0424385107 30 0.0 11 529778.5966375779 21 188379.0737448694 31 0.0 0 LINE 5 EFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529583.5543794686 20 187755.629288607 30 0.0 11 529715.9466170403 21 187689.826628057 31 0.0 0 LINE 5 EFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529603.2346550776 20 187592.1829627211 30 0.0 11 529747.8446735596 21 188065.0175525596 31 0.0 0 LINE 5 F00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529683.7965904536 20 187695.4963757663 30 0.0 11 529765.3885338919 21 187703.4871842719 31 0.0 0 LINE 5 F01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529698.8579615868 20 187617.2118261202 30 0.0 11 529691.4824514415 21 187704.7505622906 31 0.0 0 LINE 5 F02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529688.8017596487 20 187633.3547104158 30 0.0 11 529858.3265421476 21 187529.3566291689 31 0.0 0 LINE 5 F03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529646.0737452123 20 187518.4409986492 30 0.0 11 529926.7783845801 21 187848.0834212173 31 0.0 0 LINE 5 F04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529893.3047350945 20 187573.1825129142 30 0.0 11 529761.4632025456 21 187705.3099099803 31 0.0 0 LINE 5 F05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529853.056978453 20 187527.8643938651 30 0.0 11 529893.2502530519 21 187574.0284638578 31 0.0 0 LINE 5 F06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530098.8254488125 20 187360.3830151751 30 0.0 11 529878.1847450631 21 187559.5403549869 31 0.0 0 LINE 5 F07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530045.6532793329 20 187403.4456199002 30 0.0 11 530115.5438118516 21 187492.4013098859 31 0.0 0 LINE 5 F08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530175.6566109118 20 187437.4171624065 30 0.0 11 529559.0215932507 21 187972.1942001524 31 0.0 0 LINE 5 F09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529821.2767317422 20 187836.8186216117 30 0.0 11 530033.1662553697 21 188221.5088832217 31 0.0 0 LINE 5 F0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529766.2484540445 20 187879.2628871941 30 0.0 11 529924.0569599557 21 187766.5420214515 31 0.0 0 LINE 5 F0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529809.3398214984 20 187937.7054423915 30 0.0 11 529861.3599671114 21 187899.8960500067 31 0.0 0 LINE 5 F0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529762.7113894739 20 187909.7223340005 30 0.0 11 529825.1934736707 21 187938.5883118542 31 0.0 0 LINE 5 F0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529811.2330965048 20 187923.6493816397 30 0.0 11 529983.5736650277 21 188288.1981797348 31 0.0 0 LINE 5 F0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529684.5132423182 20 188087.3619766751 30 0.0 11 530063.5266412746 21 187938.1623196526 31 0.0 0 LINE 5 F0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530055.8003542056 20 187927.3178978922 30 0.0 11 530156.2459049511 21 188143.9892227795 31 0.0 0 LINE 5 F10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530167.72809298 20 187773.1167887638 30 0.0 11 530052.2406954039 21 187945.0747571812 31 0.0 0 LINE 5 F11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530081.0414487262 20 187763.7674492108 30 0.0 11 530138.4847548853 21 187826.9464515684 31 0.0 0 LINE 5 F12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529705.0607078073 20 188196.6861390384 30 0.0 11 529787.0654422633 21 188159.3054685596 31 0.0 0 LINE 5 F13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529732.4827482234 20 188346.9819141357 30 0.0 11 530157.4144505093 21 188141.1149719069 31 0.0 0 LINE 5 F14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529900.4269755176 20 187812.1066593871 30 0.0 11 530097.6484604593 21 188187.5249757049 31 0.0 0 LINE 5 F15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530423.635731933 20 187838.048245992 30 0.0 11 530090.7812692937 21 188188.7476616877 31 0.0 0 LINE 5 F16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530611.5374876814 20 187668.1195573589 30 0.0 11 530223.2538567075 21 188042.5569328811 31 0.0 0 LINE 5 F17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530373.5122905457 20 187760.2000960348 30 0.0 11 530409.3984414326 21 187872.0111505144 31 0.0 0 LINE 5 F18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530330.5310086717 20 187805.0065581208 30 0.0 11 530431.9655938526 21 187847.1565973773 31 0.0 0 LINE 5 F19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530190.1515324173 20 187933.0568666163 30 0.0 11 530351.0095330452 21 187810.8605696383 31 0.0 0 LINE 5 F1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530108.0901088432 20 187697.2081896732 30 0.0 11 530295.0546348895 21 187975.2984597758 31 0.0 0 LINE 5 F1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530027.7684759713 20 187745.2190146273 30 0.0 11 530135.5781907513 21 187689.321510876 31 0.0 0 LINE 5 F1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530071.6431878232 20 187609.7205312413 30 0.0 11 529997.9220251973 21 187705.391431453 31 0.0 0 LINE 5 F1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529999.9315347111 20 187698.9620856049 30 0.0 11 530029.7107693157 21 187746.1936225241 31 0.0 0 LINE 5 F1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529856.9988515898 20 187392.642425033 30 0.0 11 530205.8864010586 21 187833.9983429626 31 0.0 0 LINE 5 F1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530204.6549190094 20 187847.0180671165 30 0.0 11 530223.5884180138 21 187831.8102668979 31 0.0 0 LINE 5 F20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530181.9999116782 20 188035.803779794 30 0.0 11 530213.6142017748 21 188068.2795220475 31 0.0 0 LINE 5 F21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530166.8536758086 20 188032.3516464356 30 0.0 11 530189.8194683097 21 188039.5432253593 31 0.0 0 LINE 5 F22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530113.8743619398 20 188068.4302022495 30 0.0 11 530174.4026182898 21 188029.7237098421 31 0.0 0 LINE 5 F23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530136.0731830577 20 187812.6010485576 30 0.0 11 530493.065627726 21 187565.1870647974 31 0.0 0 LINE 5 F24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530461.3402601847 20 187563.7139106953 30 0.0 11 530544.9677326832 21 187746.8006609251 31 0.0 0 LINE 5 F25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530156.5606465565 20 187442.7719249477 30 0.0 11 530489.8420656007 21 187585.978281576 31 0.0 0 LINE 5 F26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530409.853728282 20 187471.3938969297 30 0.0 11 530153.9450042355 21 187773.3485576881 31 0.0 0 LINE 5 F27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530074.4384597199 20 187672.3703296743 30 0.0 11 530102.4994971649 21 187650.5856582863 31 0.0 0 LINE 5 F28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530281.9173037256 20 187700.3231702298 30 0.0 11 530345.4672628766 21 187768.6842914354 31 0.0 0 LINE 5 F29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530324.7339364529 20 187740.3000480166 30 0.0 11 530338.357399006 21 187822.5617250599 31 0.0 0 LINE 5 F2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530313.2274231444 20 187746.6144096657 30 0.0 11 530388.0575426544 21 187775.3302734317 31 0.0 0 LINE 5 F2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530507.6869767908 20 187658.5363817937 30 0.0 11 530376.0014669189 21 187779.0744647571 31 0.0 0 LINE 5 F2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530113.378969668 20 187223.3113400704 30 0.0 11 529993.8104067042 21 187353.3103520891 31 0.0 0 LINE 5 F2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530027.8754812543 20 187299.6113839214 30 0.0 11 530218.5598977485 21 187481.2105979304 31 0.0 0 LINE 5 F2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529949.985764896 20 187917.2614300507 30 0.0 11 529994.0638168057 21 187900.9140976139 31 0.0 0 LINE 5 F2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529961.1146399412 20 187846.2635500974 30 0.0 11 529993.7569733256 21 187902.7903200321 31 0.0 0 LINE 5 F30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529911.5627755482 20 187846.6857845978 30 0.0 11 529995.4314249195 21 187784.6455340611 31 0.0 0 LINE 5 F31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529890.3206506824 20 187676.1812253975 30 0.0 11 530093.8979136191 21 187894.6189267182 31 0.0 0 LINE 5 F32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530082.5711711842 20 187992.5038776773 30 0.0 11 530143.1357803735 21 187959.7702273141 31 0.0 0 LINE 5 F33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530127.1426298523 20 187932.2353938265 30 0.0 11 530155.8788858883 21 187985.0255401197 31 0.0 0 LINE 5 F34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530123.7679117324 20 187940.1521884365 30 0.0 11 530186.0371461363 21 187905.3524993013 31 0.0 0 LINE 5 F35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530182.5474092204 20 187904.0714555937 30 0.0 11 530210.6184005529 21 187952.6884201263 31 0.0 0 LINE 5 F36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530146.8855422867 20 187984.1539808663 30 0.0 11 530214.9525571921 21 187947.1003807667 31 0.0 0 LINE 5 F37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529991.2787391617 20 187450.7881940411 30 0.0 11 530061.612220368 21 187538.8664090824 31 0.0 0 LINE 5 F38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529798.0991355714 20 188039.9094565575 30 0.0 11 529897.4912097044 21 188285.1337729669 31 0.0 0 LINE 5 F39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529700.2850975303 20 188567.4765653622 30 0.0 11 529832.6773351021 21 188501.6739048121 31 0.0 0 LINE 5 F3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529719.9653731394 20 188404.0302394763 30 0.0 11 529864.5753916216 21 188876.8648293147 31 0.0 0 LINE 5 F3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529800.5273085154 20 188507.3436525215 30 0.0 11 529882.1192519538 21 188515.3344610271 31 0.0 0 LINE 5 F3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529815.5886796486 20 188429.0591028753 30 0.0 11 529808.2131695032 21 188516.5978390456 31 0.0 0 LINE 5 F3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529807.1724351745 20 188444.4074758961 30 0.0 11 529976.6972176732 21 188340.409394649 31 0.0 0 LINE 5 F3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529707.6247334772 20 188265.4885633374 30 0.0 11 530043.5091026421 21 188659.9306979724 31 0.0 0 LINE 5 F3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530010.0354531563 20 188385.0297896692 30 0.0 11 529878.1939206073 21 188517.1571867354 31 0.0 0 LINE 5 F40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529969.7876965147 20 188339.7116706202 30 0.0 11 530009.9809711138 21 188385.875740613 31 0.0 0 LINE 5 F41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530215.5561668745 20 188172.2302919301 30 0.0 11 529994.9154631249 21 188371.3876317421 31 0.0 0 LINE 5 F42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530162.3839973947 20 188215.2928966554 30 0.0 11 530232.2745299135 21 188304.2485866411 31 0.0 0 LINE 5 F43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530292.3873289736 20 188249.2644391616 30 0.0 11 529722.5984614438 21 188745.4622291548 31 0.0 0 LINE 5 F44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529938.0074498041 20 188648.6658983669 30 0.0 11 530270.7960156209 21 189204.6228630211 31 0.0 0 LINE 5 F45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529882.9791721063 20 188691.1101639493 30 0.0 11 530040.7876780177 21 188578.3892982067 31 0.0 0 LINE 5 F46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529926.0705395602 20 188749.5527191465 30 0.0 11 529978.090685173 21 188711.7433267618 31 0.0 0 LINE 5 F47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529879.4421075356 20 188721.5696107556 30 0.0 11 529941.9241917324 21 188750.4355886093 31 0.0 0 LINE 5 F48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529927.9638145668 20 188735.4966583948 30 0.0 11 529988.0450447927 21 188862.5853668438 31 0.0 0 LINE 5 F49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529801.2439603802 20 188899.2092534301 30 0.0 11 530180.2573593365 21 188750.0095964078 31 0.0 0 LINE 5 F4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530172.5310722675 20 188739.1651746473 30 0.0 11 530272.9766230131 21 188955.8364995346 31 0.0 0 LINE 5 F4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530284.4588110418 20 188584.964065519 30 0.0 11 530168.9714134656 21 188756.9220339363 31 0.0 0 LINE 5 F4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530197.772166788 20 188575.6147259658 30 0.0 11 530255.2154729472 21 188638.7937283235 31 0.0 0 LINE 5 F4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529829.9928316144 20 189021.1235840313 30 0.0 11 529911.9975660703 21 188983.7429135527 31 0.0 0 LINE 5 F4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530017.1576935793 20 188623.9539361422 30 0.0 11 530214.3791785211 21 188999.3722524601 31 0.0 0 LINE 5 F4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530490.2430086076 20 188572.0473727899 30 0.0 11 530526.1291594945 21 188683.8584272694 31 0.0 0 LINE 5 F50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530447.2617267332 20 188616.8538348757 30 0.0 11 530548.6963119143 21 188659.0038741323 31 0.0 0 LINE 5 F51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530306.882250479 20 188744.9041433715 30 0.0 11 530467.7402511069 21 188622.7078463936 31 0.0 0 LINE 5 F52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530224.820826905 20 188509.0554664283 30 0.0 11 530471.2304298216 21 188859.3289219959 31 0.0 0 LINE 5 F53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530144.4991940331 20 188557.0662913824 30 0.0 11 530252.3089088132 21 188501.1687876312 31 0.0 0 LINE 5 F54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530188.3739058851 20 188421.5678079964 30 0.0 11 530114.6527432591 21 188517.238708208 31 0.0 0 LINE 5 F55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530116.6622527729 20 188510.8093623602 30 0.0 11 530146.4414873774 21 188558.0408992791 31 0.0 0 LINE 5 F56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529973.7295696518 20 188204.4897017882 30 0.0 11 530322.6171191205 21 188645.8456197177 31 0.0 0 LINE 5 F57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530321.3856370711 20 188658.8653438716 30 0.0 11 530340.3191360755 21 188643.6575436529 31 0.0 0 LINE 5 F58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530298.7306297399 20 188847.6510565491 30 0.0 11 530350.7878136068 21 188904.950270655 31 0.0 0 LINE 5 F59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530283.5843938705 20 188844.1989231907 30 0.0 11 530306.5501863716 21 188851.3905021144 31 0.0 0 LINE 5 F5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530230.6050800018 20 188880.2774790045 30 0.0 11 530291.1333363518 21 188841.5709865972 31 0.0 0 LINE 5 F5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530252.8039011196 20 188624.4483253126 30 0.0 11 530548.3191566242 21 188427.6627006649 31 0.0 0 LINE 5 F5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530273.2913646184 20 188254.619201703 30 0.0 11 530462.4648851728 21 188331.039274131 31 0.0 0 LINE 5 F5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530464.8713986185 20 188300.0304104486 30 0.0 11 530270.6757222974 21 188585.1958344434 31 0.0 0 LINE 5 F5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530191.1691777817 20 188484.2176064294 30 0.0 11 530219.2302152268 21 188462.4329350414 31 0.0 0 LINE 5 F5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530398.6480217873 20 188512.1704469851 30 0.0 11 530462.1979809385 21 188580.5315681904 31 0.0 0 LINE 5 F60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530441.4646545147 20 188552.1473247715 30 0.0 11 530455.0881170677 21 188634.4090018151 31 0.0 0 LINE 5 F61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530429.9581412063 20 188558.4616864207 30 0.0 11 530504.7882607162 21 188587.177550187 31 0.0 0 LINE 5 F62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530583.7826875651 20 188503.8478388322 30 0.0 11 530492.7321849806 21 188590.9217415122 31 0.0 0 LINE 5 F63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530128.8055889876 20 188119.8151252872 30 0.0 11 530335.2906158104 21 188293.0578746854 31 0.0 0 LINE 5 F64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530066.7164829579 20 188729.1087068058 30 0.0 11 530110.7945348675 21 188712.761374369 31 0.0 0 LINE 5 F65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530077.8453580029 20 188658.1108268526 30 0.0 11 530110.4876913875 21 188714.6375967872 31 0.0 0 LINE 5 F66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530028.2934936099 20 188658.5330613529 30 0.0 11 530112.1621429813 21 188596.4928108161 31 0.0 0 LINE 5 F67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530007.0513687442 20 188488.0285021525 30 0.0 11 530210.6286316809 21 188706.4662034733 31 0.0 0 LINE 5 F68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530199.301889246 20 188804.3511544324 30 0.0 11 530259.8664984353 21 188771.6175040693 31 0.0 0 LINE 5 F69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530243.8733479142 20 188744.0826705819 30 0.0 11 530272.6096039502 21 188796.8728168748 31 0.0 0 LINE 5 F6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530240.4986297941 20 188751.9994651915 30 0.0 11 530302.7678641983 21 188717.1997760565 31 0.0 0 LINE 5 F6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530299.2781272823 20 188715.9187323489 30 0.0 11 530327.3491186148 21 188764.5356968813 31 0.0 0 LINE 5 F6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530263.6162603486 20 188796.0012576215 30 0.0 11 530331.6832752539 21 188758.9476575219 31 0.0 0 LINE 5 F6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530108.0094572235 20 188262.6354707962 30 0.0 11 530178.3429384298 21 188350.7136858376 31 0.0 0 LINE 5 F6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529914.8298536334 20 188851.7567333126 30 0.0 11 530014.2219277663 21 189096.9810497221 31 0.0 0 LINE 5 F6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529392.945314271 20 189359.2639292472 30 0.0 11 531170.003586833 21 188526.4350730158 31 0.0 0 LINE 5 F70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530573.3534346061 20 188563.8997038407 30 0.0 11 530798.5430697939 21 188532.9298318643 31 0.0 0 LINE 5 F71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530467.7349198311 20 188409.7615463817 30 0.0 11 530612.9150610638 21 188321.695524386 31 0.0 0 LINE 5 F72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530247.1860381263 20 188010.521249343 30 0.0 11 530664.9692136952 21 188682.3470452653 31 0.0 0 LINE 5 F73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530584.9722957194 20 188424.0512586005 30 0.0 11 530998.5263986866 21 188276.210900377 31 0.0 0 LINE 5 F74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530618.0993608664 20 188485.143194091 30 0.0 11 530531.9829551339 21 188311.3804743395 31 0.0 0 LINE 5 F75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530682.6650718633 20 188451.9217075121 30 0.0 11 530653.6339401833 21 188394.5384425692 31 0.0 0 LINE 5 F76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530647.6051370533 20 188493.4917207355 30 0.0 11 530686.0644878534 21 188436.411655397 31 0.0 0 LINE 5 F77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530669.0907209093 20 188447.811436197 30 0.0 11 531056.4550221097 21 188335.8025262527 31 0.0 0 LINE 5 F78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530810.4353722193 20 188602.8349553812 30 0.0 11 530723.6458221129 21 188201.0597410968 31 0.0 0 LINE 5 F79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530711.7081960532 20 188206.9580526561 30 0.0 11 530941.6233769567 21 188142.3455052437 31 0.0 0 LINE 5 F7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530577.3266136871 20 188071.87514817 30 0.0 11 530728.6702959506 21 188213.3034753897 31 0.0 0 LINE 5 F7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530554.2748281737 20 188155.9620058036 30 0.0 11 530625.8047850881 21 188109.327415367 31 0.0 0 LINE 5 F7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531148.102332967 20 188838.6902303597 30 0.0 11 530938.9722214446 21 188140.7336146608 31 0.0 0 LINE 5 F7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530573.1968834673 20 188341.973357598 30 0.0 11 530975.258866774 21 188207.1349805347 31 0.0 0 LINE 5 F7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530682.2314537685 20 187829.5947561866 30 0.0 11 530975.3709463781 21 188214.1092700097 31 0.0 0 LINE 5 F7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530565.94484635 20 187647.9643601798 30 0.0 11 530852.1731076476 21 188060.0216062034 31 0.0 0 LINE 5 F80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530597.3871645713 20 187866.6641562202 30 0.0 11 530713.4897298386 21 187849.065233877 31 0.0 0 LINE 5 F81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530634.7670807852 20 187916.2398710416 30 0.0 11 530692.55145945 21 187822.8237778752 31 0.0 0 LINE 5 F82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530738.7958414644 20 188075.2408012614 30 0.0 11 530643.8114683718 21 187896.9567575858 31 0.0 0 LINE 5 F83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530523.6944121592 20 188103.751873043 30 0.0 11 530797.2236527434 21 187978.4151643149 31 0.0 0 LINE 5 F84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530444.9741594119 20 188057.692000106 30 0.0 11 530523.1492674589 21 188150.6227162792 31 0.0 0 LINE 5 F85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530433.5994985798 20 188199.6618787103 30 0.0 11 530402.148168475 21 188083.0490800954 31 0.0 0 LINE 5 F86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530401.5416351788 20 188089.7577859227 30 0.0 11 530447.1416332303 21 188057.5357271576 31 0.0 0 LINE 5 F87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530152.1746223897 20 188317.9629113906 30 0.0 11 530152.1854826093 21 188317.9568539679 31 0.0 0 LINE 5 F88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530279.9986768201 20 188246.6674526891 30 0.0 11 530643.5135505878 21 188043.9125034311 31 0.0 0 LINE 5 F89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530656.1703455079 20 188047.2042062475 30 0.0 11 530644.17602906 21 188026.0880762758 31 0.0 0 LINE 5 F8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530838.9284713299 20 188099.6709777739 30 0.0 11 530876.0295792661 21 188073.6393630881 31 0.0 0 LINE 5 F8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530833.1054584868 20 188114.0729987142 30 0.0 11 530843.8668922444 21 188092.5477118147 31 0.0 0 LINE 5 F8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530860.2749595206 20 188172.1271811749 30 0.0 11 530831.7148109637 21 188106.2016149227 31 0.0 0 LINE 5 F8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530611.2583920929 20 188109.420780511 30 0.0 11 530455.3892869106 21 187794.6279178761 31 0.0 0 LINE 5 F8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530383.6970071517 20 187864.4271638903 30 0.0 11 530575.3577239918 21 188085.5188546145 31 0.0 0 LINE 5 F8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530462.9941843908 20 188147.9073801776 30 0.0 11 530445.9625123882 21 188116.7318147655 31 0.0 0 LINE 5 F90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530523.6716025012 20 187947.540010238 30 0.0 11 530601.2910764078 21 187895.7031751591 31 0.0 0 LINE 5 F91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530569.9640754642 20 187911.6454181296 30 0.0 11 530653.3455576861 21 187911.3127554578 31 0.0 0 LINE 5 F92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530574.3629559046 20 187924.0115356457 30 0.0 11 530614.6429893853 21 187854.7174773109 31 0.0 0 LINE 5 F93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530518.4180696863 20 187717.9959374398 30 0.0 11 530616.4169547133 21 187867.2163163705 31 0.0 0 LINE 5 F94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530684.9084061024 20 188309.815386448 30 0.0 11 530675.7983986727 21 188263.694700172 31 0.0 0 LINE 5 F95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530616.5933388403 20 188287.5083830064 30 0.0 11 530677.6016914072 21 188264.2967789023 31 0.0 0 LINE 5 F96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530609.1091987736 20 188336.4936174578 30 0.0 11 530561.2354102382 21 188243.8057358047 31 0.0 0 LINE 5 F97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530437.3990079661 20 188330.2772720863 30 0.0 11 530685.5021679961 21 188164.1341009169 31 0.0 0 LINE 5 F98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530780.328769887 20 188190.9235445889 30 0.0 11 530757.6708446792 21 188125.9144515507 31 0.0 0 LINE 5 F99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530727.9382006641 20 188137.312600464 30 0.0 11 530784.6349167087 21 188117.3613010984 31 0.0 0 LINE 5 F9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530735.215615822 20 188141.9064646223 30 0.0 11 530710.7898842521 21 188074.8851280609 31 0.0 0 LINE 5 F9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530708.9687964411 20 188078.1259575703 30 0.0 11 530761.4396459194 21 188058.1660039187 31 0.0 0 LINE 5 F9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530782.340532437 20 188126.1006171749 30 0.0 11 530756.6141735527 21 188052.9962926993 31 0.0 0 LINE 5 F9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530781.7692014918 20 188479.3148639996 30 0.0 11 531039.7040985098 21 188420.2950481815 31 0.0 0 LINE 5 F9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529629.2416397601 20 187659.0530045348 30 0.0 11 528886.575565366 21 187685.1694001948 31 0.0 0 LINE 5 F9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529247.9222219149 20 187060.1428561345 30 0.0 11 529909.5045036059 21 189267.5528252435 31 0.0 0 LINE 5 FA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529470.3553425334 20 187790.2496720883 30 0.0 11 529323.8045910156 21 187809.7579250679 31 0.0 0 LINE 5 FA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529362.617563407 20 187665.7724225901 30 0.0 11 529507.2275818894 21 188138.6070124287 31 0.0 0 LINE 5 FA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529353.6260863388 20 187796.4745269601 30 0.0 11 529290.4618051137 21 187848.7370549503 31 0.0 0 LINE 5 FA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529297.3525618934 20 187740.0067834225 30 0.0 11 529352.4314082598 21 187808.4447053898 31 0.0 0 LINE 5 FA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529314.7180172402 20 187747.7631273677 30 0.0 11 529116.0222761967 21 187756.3802774495 31 0.0 0 LINE 5 FA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529285.8591790829 20 187628.6077169585 30 0.0 11 529237.5613662758 21 188058.8710579453 31 0.0 0 LINE 5 FA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529111.5419683684 20 187812.2740061647 30 0.0 11 529294.735175274 21 187848.0523194833 31 0.0 0 LINE 5 FA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529119.5556862255 20 187752.1957725445 30 0.0 11 529112.0603154724 21 187812.9447651166 31 0.0 0 LINE 5 FA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528822.1497234687 20 187750.8368952536 30 0.0 11 529116.4445893118 21 187792.5082054131 31 0.0 0 LINE 5 FA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528890.3129050055 20 187756.7907356661 30 0.0 11 528882.1362303199 21 187869.6222175659 31 0.0 0 LINE 5 FAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528801.5514038664 20 187857.6685223063 30 0.0 11 529605.3146455969 21 187956.9241549581 31 0.0 0 LINE 5 FAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529318.7137926164 20 187990.5206507724 30 0.0 11 529358.2500389636 21 188427.9228144905 31 0.0 0 LINE 5 FAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529388.0696869734 20 187994.9237116579 30 0.0 11 529194.2067956202 21 187989.7567523999 31 0.0 0 LINE 5 FAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529385.0400111967 20 188067.4717596795 30 0.0 11 529320.7701771024 21 188065.2280735188 31 0.0 0 LINE 5 FAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529408.0392518247 20 188018.1939760562 30 0.0 11 529372.3922877637 21 188077.0713866332 31 0.0 0 LINE 5 FAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529375.6083177687 20 188056.8792862579 30 0.0 11 529436.6616666444 21 188455.4637645589 31 0.0 0 LINE 5 FB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529572.2232949353 20 188121.7043275001 30 0.0 11 529174.5926249127 21 188210.0306797475 31 0.0 0 LINE 5 FB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529174.9313102554 20 188196.7196960337 30 0.0 11 529212.8648250112 21 188432.5094756071 31 0.0 0 LINE 5 FB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528995.8982329628 20 188131.504989113 30 0.0 11 529187.8143716537 21 188209.4477733275 31 0.0 0 LINE 5 FB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529062.5257631239 20 188075.2665977178 30 0.0 11 529050.2486893053 21 188159.76862858 31 0.0 0 LINE 5 FB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529628.1589158975 20 188300.4001130504 30 0.0 11 529539.2737798636 21 188315.283781647 31 0.0 0 LINE 5 FB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529677.6791911395 20 188363.7428355513 30 0.0 11 529210.288461868 21 188430.7805540487 31 0.0 0 LINE 5 FB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529239.2811099911 20 188014.3091164152 30 0.0 11 529285.7898337491 21 188435.8208777742 31 0.0 0 LINE 5 FB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528944.5248341071 20 188380.8283716183 30 0.0 11 529292.1661640495 21 188432.9932131161 31 0.0 0 LINE 5 FB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528569.2810199707 20 188292.7158789641 30 0.0 11 528806.2807468023 21 188334.287433425 31 0.0 0 LINE 5 FB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529040.6513158122 20 187642.311198794 30 0.0 11 528998.3219772069 21 188203.3154728942 31 0.0 0 LINE 5 FBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529006.6254128079 20 188213.419072367 30 0.0 11 528982.4243466746 21 188211.4033913288 31 0.0 0 LINE 5 FBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529131.0027007718 20 188357.2369603609 30 0.0 11 529121.3118151613 21 188418.8936375129 31 0.0 0 LINE 5 FBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529141.6269001136 20 188345.903290431 30 0.0 11 529126.6125106496 21 188364.7105906532 31 0.0 0 LINE 5 FBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529205.7236681208 20 188346.1757213804 30 0.0 11 529133.8994146958 21 188347.9474412191 31 0.0 0 LINE 5 FBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528643.1508068893 20 187897.179310321 30 0.0 11 528526.4033827907 21 188092.533363126 31 0.0 0 LINE 5 FBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528820.3758145471 20 187851.4258546835 30 0.0 11 528611.9802258696 21 187905.2264917811 31 0.0 0 LINE 5 FC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528733.4144066438 20 187645.3547041817 30 0.0 11 528905.2436686549 21 187686.2336607713 31 0.0 0 LINE 5 FC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528846.9694373976 20 187660.7754114646 30 0.0 11 528790.4836022626 21 187917.9682800507 31 0.0 0 LINE 5 FC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529257.0190230463 20 188129.1958686471 30 0.0 11 529211.3374954253 21 188140.3002809301 31 0.0 0 LINE 5 FC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529208.0810821642 20 188076.5686061319 30 0.0 11 529212.6413179638 21 188141.6839030864 31 0.0 0 LINE 5 FC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529249.3922603196 20 188049.2016167797 30 0.0 11 529145.1686562638 21 188044.6868198139 31 0.0 0 LINE 5 FC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529171.6282192092 20 187895.9835157372 30 0.0 11 529125.0608482104 21 188190.9245459472 31 0.0 0 LINE 5 FC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529189.2021753491 20 188265.7286158319 30 0.0 11 529120.6887160605 21 188272.4717344477 31 0.0 0 LINE 5 FC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529118.5442134677 20 188240.7014806336 30 0.0 11 529124.2522195913 21 188300.534503478 31 0.0 0 LINE 5 FC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529125.769900808 20 188245.3762856292 30 0.0 11 529054.6877821515 21 188251.3602913529 31 0.0 0 LINE 5 FC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529056.8639720252 20 188248.3464011163 30 0.0 11 529060.7891532491 21 188304.3480327632 31 0.0 0 LINE 5 FCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529131.21955758 20 188294.7815871724 30 0.0 11 529054.0707556696 21 188302.1402665566 31 0.0 0 LINE 5 FCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529700.5375658763 20 188484.9666580997 30 0.0 11 529471.5662644893 21 188494.8968159285 31 0.0 0 LINE 5 FCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529634.4603943709 20 188470.7758187421 30 0.0 11 529594.9091760079 21 188797.1288748313 31 0.0 0 LINE 5 FCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529468.8897781007 20 188550.5318230509 30 0.0 11 529652.0829850063 21 188586.3101363694 31 0.0 0 LINE 5 FCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529476.9034959577 20 188490.4535894304 30 0.0 11 529469.4081252046 21 188551.2025820028 31 0.0 0 LINE 5 FCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529179.497533201 20 188489.0947121396 30 0.0 11 529473.7923990441 21 188530.7660222994 31 0.0 0 LINE 5 FD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529263.7756425611 20 188606.075583112 30 0.0 11 529908.763791275 21 188688.5260989179 31 0.0 0 LINE 5 FD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.0616023485 20 188728.7784676585 30 0.0 11 529699.9550760643 21 188993.1196246366 31 0.0 0 LINE 5 FD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529745.4174967054 20 188733.181528544 30 0.0 11 529551.5546053525 21 188728.0145692858 31 0.0 0 LINE 5 FD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529742.387820929 20 188805.7295765657 30 0.0 11 529678.1179868345 21 188803.4858904049 31 0.0 0 LINE 5 FD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529765.3870615571 20 188756.4517929425 30 0.0 11 529729.7400974962 21 188815.3292035195 31 0.0 0 LINE 5 FD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529732.9561275008 20 188795.1371031438 30 0.0 11 529794.0094763765 21 189193.721581445 31 0.0 0 LINE 5 FD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529822.1310589099 20 188883.713462244 30 0.0 11 529531.9404346449 21 188948.2884966338 31 0.0 0 LINE 5 FD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529532.2791199877 20 188934.97751292 30 0.0 11 529570.2126347435 21 189170.7672924934 31 0.0 0 LINE 5 FD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529384.8240162092 20 188882.5875490996 30 0.0 11 529545.1621813861 21 188947.7055902138 31 0.0 0 LINE 5 FD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529462.6117272585 20 188607.3202886658 30 0.0 11 529407.5964990378 21 188898.026445466 31 0.0 0 LINE 5 FDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529596.6289197234 20 188752.5669333013 30 0.0 11 529643.1376434814 21 189174.0786946602 31 0.0 0 LINE 5 FDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529117.932638334 20 189064.2549476437 30 0.0 11 529478.0365257928 21 189010.7295513338 31 0.0 0 LINE 5 FDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529175.4404670244 20 188974.1618202624 30 0.0 11 529208.2352462457 21 189086.918328656 31 0.0 0 LINE 5 FDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529236.1315537773 20 188987.2615005996 30 0.0 11 529175.6261960312 21 189078.9386655001 31 0.0 0 LINE 5 FDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529397.9991255444 20 188380.5690156801 30 0.0 11 529379.1669343232 21 188698.7673302471 31 0.0 0 LINE 5 FDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529386.967280002 20 188673.3752750442 30 0.0 11 529046.5374145823 21 188886.9621896196 31 0.0 0 LINE 5 FE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529129.1625395999 20 188809.4756186941 30 0.0 11 529216.2919105073 21 188951.7408787446 31 0.0 0 LINE 5 FE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529204.7431267487 20 188930.3817577657 30 0.0 11 529239.4635664156 21 189006.191211736 31 0.0 0 LINE 5 FE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529217.8131727024 20 188929.1797135396 30 0.0 11 529171.8465916677 21 188994.8396027087 31 0.0 0 LINE 5 FE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529059.7550470335 20 188969.9509328124 30 0.0 11 529183.9345532104 21 188991.1996691156 31 0.0 0 LINE 5 FE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529222.0890533329 20 188397.1220266792 30 0.0 11 529180.9709087853 21 188540.5938421276 31 0.0 0 LINE 5 FE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529614.3668327786 20 188867.4536855333 30 0.0 11 529568.6853051575 21 188878.5580978163 31 0.0 0 LINE 5 FE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529565.4288918965 20 188814.8264230181 30 0.0 11 529569.989127696 21 188879.9417199727 31 0.0 0 LINE 5 FE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529606.7400700518 20 188787.4594336657 30 0.0 11 529502.5164659961 21 188782.9446366999 31 0.0 0 LINE 5 FE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529528.9760289416 20 188634.2413326233 30 0.0 11 529482.4086579428 21 188929.1823628333 31 0.0 0 LINE 5 FE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529546.5499850815 20 189003.9864327182 30 0.0 11 529478.0365257928 21 189010.7295513338 31 0.0 0 LINE 5 FEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529396.9533566374 20 188869.3050320101 30 0.0 11 529481.6000293236 21 189038.7923203641 31 0.0 0 LINE 5 FEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529319.2145911773 20 188503.8776358344 30 0.0 11 529310.1799248937 21 188616.229517655 31 0.0 0 LINE 5 FEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529161.5459109745 20 189048.278224607 30 0.0 11 528647.9655036306 21 189306.6925524445 31 0.0 0 LINE 5 FED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529101.9903625048 20 189013.8960569484 30 0.0 11 528898.0009451259 21 189114.1847520432 31 0.0 0 LINE 5 FEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529103.3229948528 20 188827.0483480004 30 0.0 11 528933.7188917285 21 188835.2547992389 31 0.0 0 LINE 5 FEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529075.138747387 20 188689.541834962 30 0.0 11 529110.5648560599 21 189653.1949148731 31 0.0 0 LINE 5 FF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529014.134476429 20 188904.4706081191 30 0.0 11 528588.6323275295 21 189013.2441751404 31 0.0 0 LINE 5 FF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529020.8464435756 20 188973.6412415138 30 0.0 11 528995.036142355 21 188781.4347211701 31 0.0 0 LINE 5 FF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528948.7434804165 20 188982.2180072632 30 0.0 11 528940.7107299657 21 188918.4126734558 31 0.0 0 LINE 5 FF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529001.0580113628 20 188997.0657303256 30 0.0 11 528937.2500076989 21 188971.2627422923 31 0.0 0 LINE 5 FF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528957.6965665056 20 188971.2180261912 30 0.0 11 528573.9463495623 21 189095.0439877157 31 0.0 0 LINE 5 FF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528925.0508529476 20 189175.6538170998 30 0.0 11 528774.4528956277 21 188797.1938463038 31 0.0 0 LINE 5 FF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528787.6475847067 20 188795.4057816234 30 0.0 11 528560.9228864532 21 188870.450321031 31 0.0 0 LINE 5 FF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528823.4813869797 20 188608.2648203714 30 0.0 11 528777.1365327426 21 188810.1534936224 31 0.0 0 LINE 5 FF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528889.6239405762 20 188665.0728043687 30 0.0 11 528804.2454468054 21 188666.4265262114 31 0.0 0 LINE 5 FF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528702.9237163125 20 189318.3532235257 30 0.0 11 528562.2188912551 21 188867.6312452332 31 0.0 0 LINE 5 FFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528977.9849291424 20 188829.8472042992 30 0.0 11 528569.281635989 21 188942.9703430246 31 0.0 0 LINE 5 FFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528601.002372018 20 188466.1103209222 30 0.0 11 528573.0898207653 21 188948.8142290799 31 0.0 0 LINE 5 FFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528580.829102545 20 188265.8679942571 30 0.0 11 528589.0227163259 21 188752.1753253903 31 0.0 0 LINE 5 FFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528692.0671885087 20 188449.3803171656 30 0.0 11 528585.9823395023 21 188499.7343889034 31 0.0 0 LINE 5 FFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528688.812207707 20 188511.3836617221 30 0.0 11 528588.6604472116 21 188466.2701853558 31 0.0 0 LINE 5 FFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528691.5173766687 20 188701.3730322669 30 0.0 11 528670.5289779729 21 188500.4583277746 31 0.0 0 LINE 5 1000 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528885.7690453813 20 188604.6890351129 30 0.0 11 528588.9251168373 21 188653.7931906997 31 0.0 0 LINE 5 1001 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528881.2333355238 20 188501.5712737685 30 0.0 11 529072.9985641551 21 188286.3545605624 31 0.0 0 LINE 5 1002 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529313.5523636491 20 188574.4441057497 30 0.0 11 529313.5399730545 21 188574.4451592718 31 0.0 0 LINE 5 1003 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529007.8590133908 20 188588.9361372746 30 0.0 11 528752.9760917203 21 188622.1076328554 31 0.0 0 LINE 5 1004 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528744.3257259774 20 188631.9158405206 30 0.0 11 528742.4567941343 21 188607.7029995927 31 0.0 0 LINE 5 1005 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528622.1795868 20 188777.6334281767 30 0.0 11 528576.8645196604 21 188776.8076779879 31 0.0 0 LINE 5 1006 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528635.0622695969 20 188786.3145669094 30 0.0 11 528614.1015629134 21 188774.4910645538 31 0.0 0 LINE 5 1007 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528645.013460359 20 188849.6347350237 30 0.0 11 528631.8121348874 21 188779.0118819444 31 0.0 0 LINE 5 1008 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528816.3556045137 20 188658.3673484307 30 0.0 11 528769.4797142685 21 188310.2403956821 31 0.0 0 LINE 5 1009 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528858.739831169 20 188423.1701629402 30 0.0 11 528832.7451079655 21 188618.4731858466 31 0.0 0 LINE 5 100A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529163.3023877976 20 188861.749687461 30 0.0 11 528748.8838189233 21 188297.0863431962 31 0.0 0 LINE 5 100B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528798.4103537806 20 188475.1876621353 30 0.0 11 528705.0741880239 21 188475.6352807375 31 0.0 0 LINE 5 100C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528739.9594058419 20 188471.3274185242 30 0.0 11 528670.6559632971 21 188517.691360261 31 0.0 0 LINE 5 100D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528743.2300711934 20 188484.0385852572 30 0.0 11 528671.0809144397 21 188449.1294632764 31 0.0 0 LINE 5 100E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528674.3689592359 20 188281.9732387523 30 0.0 11 528676.6016874598 21 188460.4823922414 31 0.0 0 LINE 5 100F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528867.3962947459 20 188865.6767080673 30 0.0 11 528849.1500965991 21 188822.3502012712 31 0.0 0 LINE 5 1010 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528911.5471733497 20 188808.9735270618 30 0.0 11 528847.9920687762 21 188823.8579595558 31 0.0 0 LINE 5 1011 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529084.0095456938 20 188744.1930036312 30 0.0 11 528785.4168205069 21 188745.2493220176 31 0.0 0 LINE 5 1012 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528721.7970170586 20 188820.4974404503 30 0.0 11 528682.848956227 21 188658.3917614921 31 0.0 0 LINE 5 1013 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528881.9155969028 20 189060.359209691 30 0.0 11 528635.0928427313 21 189155.7126458224 31 0.0 0 LINE 5 1014 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529005.5742357306 20 187951.1941100283 30 0.0 11 529170.3123569273 21 187974.2718737496 31 0.0 0 LINE 5 1015 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528914.0106005493 20 187912.3245896476 30 0.0 11 529001.2995244179 21 187749.7460745823 31 0.0 0 LINE 5 1016 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528902.4585341773 20 188824.2821025381 30 0.0 11 528880.8568956467 21 188709.114560081 31 0.0 0 LINE 5 1017 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529568.232106769 20 188122.590896667 30 0.0 11 529750.5420645888 21 188200.2264006352 31 0.0 0 LINE 5 1018 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532031.6637419214 20 189206.8229816716 30 0.0 11 532139.3496554863 21 189308.1217414095 31 0.0 0 LINE 5 1019 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532191.7713961092 20 189168.5143173241 30 0.0 11 531798.5900445994 21 189468.3359836828 31 0.0 0 LINE 5 101A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532122.8672957487 20 189279.9419247654 30 0.0 11 532143.7102761921 21 189359.2304385668 31 0.0 0 LINE 5 101B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532201.5098460327 20 189266.8780471429 30 0.0 11 532116.8583799476 21 189290.3633142239 31 0.0 0 LINE 5 101C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532182.879295075 20 189263.0541117607 30 0.0 11 532339.2791202549 21 189385.9090972841 31 0.0 0 LINE 5 101D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532275.8011499364 20 189183.076782106 30 0.0 11 532064.1640193323 21 189560.7922123821 31 0.0 0 LINE 5 101E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532310.3288497661 20 189433.9305914979 30 0.0 11 532140.6377589193 21 189356.1824568091 31 0.0 0 LINE 5 101F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532338.8483841458 20 189380.4492864692 30 0.0 11 532309.5166327113 21 189434.1732945015 31 0.0 0 LINE 5 1020 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532581.2590586423 20 189552.7548816218 30 0.0 11 532317.8707829392 21 189415.0138841873 31 0.0 0 LINE 5 1021 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532522.4104459652 20 189517.8477431132 30 0.0 11 532463.2642730652 21 189614.2818218812 31 0.0 0 LINE 5 1022 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532535.7028271408 20 189651.5572959675 30 0.0 11 531820.0585549223 21 189259.0289520904 31 0.0 0 LINE 5 1023 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532038.0875403904 20 189457.9451817606 30 0.0 11 531750.9298642218 21 189790.2466061002 31 0.0 0 LINE 5 1024 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531979.1741634221 20 189421.0827206187 30 0.0 11 532139.6848387839 21 189529.9213222574 31 0.0 0 LINE 5 1025 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531939.3346770747 20 189481.7886802488 30 0.0 11 531992.8569659881 21 189517.4399115257 31 0.0 0 LINE 5 1026 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531949.3822257373 20 189428.3442063141 30 0.0 11 531944.0126425981 21 189496.9621565889 31 0.0 0 LINE 5 1027 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531953.1733588967 20 189478.6825219247 30 0.0 11 531671.1683416162 21 189766.9016538019 31 0.0 0 LINE 5 1028 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531755.6417816337 20 189416.7066298191 30 0.0 11 532027.1838522537 21 189720.312621406 31 0.0 0 LINE 5 1029 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532034.6699812882 20 189709.3010426241 30 0.0 11 531866.3692592388 21 189878.7431821604 31 0.0 0 LINE 5 102A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532218.144887253 20 189760.7088206811 30 0.0 11 532016.7821271637 21 189712.1298051467 31 0.0 0 LINE 5 102B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532196.8065175713 20 189676.1709095325 30 0.0 11 532157.5097438913 21 189751.9804296455 31 0.0 0 LINE 5 102C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531405.6950599251 20 189397.6918620768 30 0.0 11 531723.7921117423 21 189537.8611520869 31 0.0 0 LINE 5 102D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531528.8411038234 20 189551.8548372382 30 0.0 11 531869.470434986 21 189878.8407822911 31 0.0 0 LINE 5 102E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532088.74975918 20 189523.5864930972 30 0.0 11 531805.1927822128 21 189838.9127799219 31 0.0 0 LINE 5 102F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532246.1302548441 20 190023.238120023 30 0.0 11 531801.6612649959 21 189832.8976604999 31 0.0 0 LINE 5 1030 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532470.7391336279 20 190140.428907227 30 0.0 11 531984.7594943132 21 189906.3534569081 31 0.0 0 LINE 5 1031 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532301.7252596375 20 189949.1983383498 30 0.0 11 532209.3368012323 21 190021.6821329716 31 0.0 0 LINE 5 1032 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532244.7805702968 20 189924.453399633 30 0.0 11 532240.4817546558 21 190034.2127776569 31 0.0 0 LINE 5 1033 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532075.9476160555 20 189837.2828058441 30 0.0 11 532246.4030078652 21 189945.6903275581 31 0.0 0 LINE 5 1034 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532268.6167204107 20 189678.4203122155 30 0.0 11 532072.767541199 21 189950.3266036608 31 0.0 0 LINE 5 1035 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532195.6990315971 20 189619.7720839555 30 0.0 11 532285.5589545911 21 189701.4584338929 31 0.0 0 LINE 5 1036 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532338.0010107443 20 189613.8580269038 30 0.0 11 532222.6820952939 21 189577.9514995641 31 0.0 0 LINE 5 1037 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532229.4091453788 20 189577.6030549164 30 0.0 11 532195.459634246 21 189621.9319573072 31 0.0 0 LINE 5 1038 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532467.022615763 20 189337.1839935896 30 0.0 11 532174.3049913963 21 189817.635823486 31 0.0 0 LINE 5 1039 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532161.6679775332 20 189821.0026685536 30 0.0 11 532182.5046815933 21 189833.4760937429 31 0.0 0 LINE 5 103A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531976.7650487176 20 189865.3219824437 30 0.0 11 531957.2901799326 21 189906.2471172519 31 0.0 0 LINE 5 103B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531974.7421079803 20 189849.9195996247 30 0.0 11 531975.9740472566 21 189873.953508134 31 0.0 0 LINE 5 103C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531922.5098082239 20 189812.7677928074 30 0.0 11 531979.8281759879 21 189856.0860001588 31 0.0 0 LINE 5 103D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532170.1247097689 20 189744.736887547 30 0.0 11 532526.1201255466 21 189993.58332384 31 0.0 0 LINE 5 103E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532516.4835480185 20 189963.3210453037 30 0.0 11 532373.8361481662 21 190105.3281985797 31 0.0 0 LINE 5 103F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532524.0494471331 20 189635.5096147978 30 0.0 11 532505.5035082588 21 189997.781077944 31 0.0 0 LINE 5 1040 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532585.1762395939 20 189882.9770222952 30 0.0 11 532213.1407573749 21 189747.8641355415 31 0.0 0 LINE 5 1041 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532280.2215546078 20 189638.2372237165 30 0.0 11 532310.3957018821 21 189656.9859454393 31 0.0 0 LINE 5 1042 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532326.0648090236 20 189842.5096595214 30 0.0 11 532284.0292765015 21 189925.8454513888 31 0.0 0 LINE 5 1043 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532303.4462126704 20 189896.5449618215 30 0.0 11 532231.0361635415 21 189937.8894539226 31 0.0 0 LINE 5 1044 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532293.5287351565 20 189887.9475987774 30 0.0 11 532292.588323795 21 189968.0928621695 31 0.0 0 LINE 5 1045 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532443.6591333519 20 190039.7142635487 30 0.0 11 532284.8901796214 21 189958.0875382314 31 0.0 0 LINE 5 1046 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532714.8532277894 20 189518.7983350472 30 0.0 11 532551.4203747162 21 189451.8200780417 31 0.0 0 LINE 5 1047 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532613.6075195969 20 189465.1154719042 30 0.0 11 532509.5353245167 21 189706.9993271604 31 0.0 0 LINE 5 1048 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532007.3517006937 20 189606.5802005249 30 0.0 11 532037.989566198 21 189642.2373335461 31 0.0 0 LINE 5 1049 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532077.795397995 20 189592.3592185572 30 0.0 11 532036.1235619935 21 189642.6011903765 31 0.0 0 LINE 5 104A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532060.190368608 20 189546.0382893018 30 0.0 11 532147.4960968193 21 189603.1404158431 31 0.0 0 LINE 5 104B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532212.7048115895 20 189466.9031058558 30 0.0 11 532078.5647071548 21 189733.6711019223 31 0.0 0 LINE 5 104C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531982.8387736801 20 189757.0442570122 30 0.0 11 532034.56869682 21 189802.4708880157 31 0.0 0 LINE 5 104D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532054.8353292636 20 189777.9105230313 30 0.0 11 532015.3109772028 21 189823.191838723 31 0.0 0 LINE 5 104E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532046.2392857908 20 189777.4953171877 30 0.0 11 532100.4986561253 21 189823.8029477473 31 0.0 0 LINE 5 104F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532100.4879973464 20 189820.0855261795 30 0.0 11 532064.6460298329 21 189863.2936638331 31 0.0 0 LINE 5 1050 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532013.0049510107 20 189814.4555873601 30 0.0 11 532071.3914760512 21 189865.4173523631 31 0.0 0 LINE 5 1051 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532459.1306889654 20 189483.299482677 30 0.0 11 532400.9612071705 21 189579.8441973495 31 0.0 0 LINE 5 1052 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531839.5884021576 20 189506.7425210747 30 0.0 11 531644.1460684732 21 189685.1130454415 31 0.0 0 LINE 5 1053 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531261.8280108232 20 189635.3713330043 30 0.0 11 530793.9869514637 21 189997.6585587048 31 0.0 0 LINE 5 1054 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531271.1054127446 20 189503.5805225813 30 0.0 11 531418.5747294049 21 189699.5365689853 31 0.0 0 LINE 5 1055 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532139.467897414 20 189076.1120245828 30 0.0 11 531077.8151185179 21 189859.7508112586 31 0.0 0 LINE 5 1056 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531402.0923696672 20 189671.3567523413 30 0.0 11 531422.9353501108 21 189750.6452661428 31 0.0 0 LINE 5 1057 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531480.7349199513 20 189658.2928747189 30 0.0 11 531396.0834538663 21 189681.7781418 31 0.0 0 LINE 5 1058 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531463.4189746374 20 189655.7308904651 30 0.0 11 531619.8187998175 21 189778.5858759885 31 0.0 0 LINE 5 1059 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531596.6289551386 20 189500.2419092503 30 0.0 11 531343.389093251 21 189952.207039958 31 0.0 0 LINE 5 105A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531589.5539236847 20 189825.3454190738 30 0.0 11 531419.862832838 21 189747.5972843849 31 0.0 0 LINE 5 105B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531618.0734580644 20 189771.8641140451 30 0.0 11 531588.7417066297 21 189825.5881220773 31 0.0 0 LINE 5 105C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531860.484132561 20 189944.1697091979 30 0.0 11 531597.0958568579 21 189806.4287117634 31 0.0 0 LINE 5 105D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531801.6355198837 20 189909.2625706889 30 0.0 11 531742.489346984 21 190005.6966494571 31 0.0 0 LINE 5 105E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531814.9279010593 20 190042.9721235435 30 0.0 11 531151.7309556583 21 189680.9756981938 31 0.0 0 LINE 5 105F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531317.3126143089 20 189849.3600093366 30 0.0 11 531030.1549381406 21 190181.6614336764 31 0.0 0 LINE 5 1060 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531258.3992373407 20 189812.4975481947 30 0.0 11 531418.9099127025 21 189921.3361498332 31 0.0 0 LINE 5 1061 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531218.5597509931 20 189873.2035078246 30 0.0 11 531272.0820399069 21 189908.8547391015 31 0.0 0 LINE 5 1062 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531228.6072996558 20 189819.7590338899 30 0.0 11 531223.2377165169 21 189888.3769841649 31 0.0 0 LINE 5 1063 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531232.3984328154 20 189870.0973495005 30 0.0 11 530950.3934155348 21 190158.3164813777 31 0.0 0 LINE 5 1064 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531034.8668555523 20 189808.1214573949 30 0.0 11 531306.4089261723 21 190111.7274489819 31 0.0 0 LINE 5 1065 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531313.8950552069 20 190100.7158702 30 0.0 11 531145.5943331574 21 190270.1580097362 31 0.0 0 LINE 5 1066 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531497.3699611719 20 190152.1236482572 30 0.0 11 531296.0072010822 21 190103.5446327226 31 0.0 0 LINE 5 1067 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531476.0315914901 20 190067.5857371085 30 0.0 11 531436.7348178098 21 190143.3952572212 31 0.0 0 LINE 5 1068 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530928.7867488221 20 189884.8131776398 30 0.0 11 530992.320475658 21 189948.7315361369 31 0.0 0 LINE 5 1069 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530808.066177742 20 189943.2696648143 30 0.0 11 531148.6955089044 21 190270.255609867 31 0.0 0 LINE 5 106A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531367.9748330986 20 189915.001320673 30 0.0 11 531084.4178561316 21 190230.3276074982 31 0.0 0 LINE 5 106B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531581.3258303478 20 190436.6834793387 30 0.0 11 531080.8863389146 21 190224.3124880759 31 0.0 0 LINE 5 106C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531580.9503335561 20 190340.6131659256 30 0.0 11 531488.5618751509 21 190413.0969605477 31 0.0 0 LINE 5 106D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531524.0056442154 20 190315.868227209 30 0.0 11 531519.7068285743 21 190425.6276052329 31 0.0 0 LINE 5 106E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531355.1726899743 20 190228.6976334198 30 0.0 11 531525.6280817838 21 190337.105155134 31 0.0 0 LINE 5 106F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531547.8417943295 20 190069.8351397915 30 0.0 11 531351.9926151177 21 190341.7414312368 31 0.0 0 LINE 5 1070 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531474.9241055158 20 190011.1869115315 30 0.0 11 531564.7840285096 21 190092.8732614688 31 0.0 0 LINE 5 1071 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531617.2260846627 20 190005.2728544797 30 0.0 11 531501.9071692126 21 189969.3663271401 31 0.0 0 LINE 5 1072 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531508.6342192977 20 189969.0178824923 30 0.0 11 531474.6847081646 21 190013.3467848832 31 0.0 0 LINE 5 1073 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531746.2476896815 20 189728.5988211656 30 0.0 11 531453.5300653147 21 190209.0506510619 31 0.0 0 LINE 5 1074 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531440.8930514517 20 190212.4174961294 30 0.0 11 531461.7297555117 21 190224.8909213187 31 0.0 0 LINE 5 1075 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531255.9901226361 20 190256.7368100196 30 0.0 11 531236.5152538514 21 190297.6619448278 31 0.0 0 LINE 5 1076 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531253.9671818987 20 190241.3344272003 30 0.0 11 531255.1991211752 21 190265.3683357099 31 0.0 0 LINE 5 1077 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531201.7348821424 20 190204.1826203831 30 0.0 11 531259.0532499064 21 190247.5008277345 31 0.0 0 LINE 5 1078 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531449.3497836877 20 190136.151715123 30 0.0 11 531736.5174682032 21 190344.9304718819 31 0.0 0 LINE 5 1079 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531803.2745210516 20 190026.9244423737 30 0.0 11 531797.309994369 21 190230.8633370709 31 0.0 0 LINE 5 107A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531827.2245172675 20 190222.350860722 30 0.0 11 531492.3658312936 21 190139.2789631173 31 0.0 0 LINE 5 107B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531559.4466285263 20 190029.6520512927 30 0.0 11 531589.6207758007 21 190048.4007730151 31 0.0 0 LINE 5 107C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531605.2898829422 20 190233.9244870974 30 0.0 11 531563.2543504202 21 190317.2602789646 31 0.0 0 LINE 5 107D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531582.6712865889 20 190287.9597893974 30 0.0 11 531510.2612374601 21 190329.3042814985 31 0.0 0 LINE 5 107E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531572.753809075 20 190279.3624263534 30 0.0 11 531571.8133977135 21 190359.5076897454 31 0.0 0 LINE 5 107F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531677.3906608113 20 190404.6452770142 30 0.0 11 531564.11525354 21 190349.5023658073 31 0.0 0 LINE 5 1080 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531879.5088061571 20 189844.6153308284 30 0.0 11 531788.7603984353 21 190098.4141547363 31 0.0 0 LINE 5 1081 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531286.5767746124 20 189997.9950281009 30 0.0 11 531317.2146401164 21 190033.652161122 31 0.0 0 LINE 5 1082 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531357.0204719137 20 189983.7740461333 30 0.0 11 531315.3486359122 21 190034.0160179524 31 0.0 0 LINE 5 1083 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531339.4154425268 20 189937.4531168776 30 0.0 11 531426.721170738 21 189994.5552434192 31 0.0 0 LINE 5 1084 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531491.9298855079 20 189858.3179334316 30 0.0 11 531357.7897810734 21 190125.0859294983 31 0.0 0 LINE 5 1085 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531262.0638475986 20 190148.4590845882 30 0.0 11 531313.7937707388 21 190193.8857155916 31 0.0 0 LINE 5 1086 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531334.0604031822 20 190169.3253506072 30 0.0 11 531294.5360511213 21 190214.6066662988 31 0.0 0 LINE 5 1087 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531325.4643597094 20 190168.9101447634 30 0.0 11 531379.7237300438 21 190215.2177753232 31 0.0 0 LINE 5 1088 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531379.7130712649 20 190211.5003537553 30 0.0 11 531343.8711037515 21 190254.7084914091 31 0.0 0 LINE 5 1089 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531292.2300249293 20 190205.8704149363 30 0.0 11 531350.6165499698 21 190256.8321799389 31 0.0 0 LINE 5 108A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531738.3557628839 20 189874.7143102527 30 0.0 11 531680.1862810891 21 189971.2590249253 31 0.0 0 LINE 5 108B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531118.8134760765 20 189898.157348651 30 0.0 11 530923.3711423917 21 190076.5278730174 31 0.0 0 LINE 5 108C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531549.0232186045 20 190408.9283136724 30 0.0 11 531815.5912827789 21 190918.3242959899 31 0.0 0 LINE 5 108D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531725.3179468167 20 190263.1451353913 30 0.0 11 531858.3226310664 21 190368.7038944124 31 0.0 0 LINE 5 108E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532023.1126640984 20 189917.6702009027 30 0.0 11 531560.0017468874 21 190514.6625615866 31 0.0 0 LINE 5 108F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531752.6335439978 20 190378.0479479378 30 0.0 11 532027.0884013829 21 190720.947159359 31 0.0 0 LINE 5 1090 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531706.8490401603 20 190430.3299356158 30 0.0 11 531839.8883803324 21 190289.2269516705 31 0.0 0 LINE 5 1091 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531760.4259942967 20 190479.3392020101 30 0.0 11 531804.1551633149 21 190432.1862012669 31 0.0 0 LINE 5 1092 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531709.2673430877 20 190460.8985557431 30 0.0 11 531776.1512396244 21 190477.1404739515 31 0.0 0 LINE 5 1093 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531759.5661330731 20 190465.1822965296 30 0.0 11 531999.1325695614 21 190789.5355303038 31 0.0 0 LINE 5 1094 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531666.8870233325 20 190650.3047366494 30 0.0 11 532009.9057406248 21 190430.6462430029 31 0.0 0 LINE 5 1095 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532000.2286936998 20 190421.5001095026 30 0.0 11 532140.6677263311 21 190614.6649349926 31 0.0 0 LINE 5 1096 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532080.2335795344 20 190248.5694326226 30 0.0 11 532000.1690734311 21 190439.6101527941 31 0.0 0 LINE 5 1097 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531993.374854094 20 190256.1553575474 30 0.0 11 532061.948672143 21 190307.0370953283 31 0.0 0 LINE 5 1098 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531754.1490246187 20 190815.97404762 30 0.0 11 531827.379987234 21 190763.4448451408 31 0.0 0 LINE 5 1099 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531825.5130731995 20 190338.500300852 30 0.0 11 532091.5924045128 21 190668.7078352868 31 0.0 0 LINE 5 109A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532343.8663683539 20 190262.8020174649 30 0.0 11 532103.326302272 21 190636.37358738 31 0.0 0 LINE 5 109B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532473.8057340179 20 190090.674340814 30 0.0 11 532186.8019124103 21 190502.1917741612 31 0.0 0 LINE 5 109C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532279.6383763485 20 190196.11274643 30 0.0 11 532336.463625641 21 190298.8766446244 31 0.0 0 LINE 5 109D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532246.1302706473 20 190248.3833546964 30 0.0 11 532353.799973734 21 190270.1281452764 31 0.0 0 LINE 5 109E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532133.1547478067 20 190401.1570765797 30 0.0 11 532267.3541937391 21 190250.1678714276 31 0.0 0 LINE 5 109F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532031.7148287482 20 190209.3461047226 30 0.0 11 532244.2452321987 21 190422.3211352275 31 0.0 0 LINE 5 10A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532047.5686717147 20 190119.5293704757 30 0.0 11 531987.5720785385 21 190225.1128650848 31 0.0 0 LINE 5 10A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531910.4851815169 20 190158.168030588 30 0.0 11 532008.9166929821 21 190088.1753987119 31 0.0 0 LINE 5 10A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532002.4149168784 20 190089.9365131366 30 0.0 11 532048.4679687842 21 190121.5076598298 31 0.0 0 LINE 5 10A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531701.8104183642 20 189935.3453690496 30 0.0 11 531701.8198704416 21 189935.3534495803 31 0.0 0 LINE 5 10A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531813.0607339144 20 190030.4526695709 30 0.0 11 532129.4420644395 21 190300.9253790891 31 0.0 0 LINE 5 10A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532130.7508814489 20 190313.9375565826 30 0.0 11 532146.3871067527 21 190295.356301773 31 0.0 0 LINE 5 10A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532145.0206820415 20 190503.5415319083 30 0.0 11 532182.3169910715 21 190529.2926970463 31 0.0 0 LINE 5 10A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532129.4927986443 20 190503.0827041237 30 0.0 11 532153.4156540405 21 190505.6986976858 31 0.0 0 LINE 5 10A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532084.48793898 20 190548.722954936 30 0.0 11 532136.3912738704 21 190499.0449296283 31 0.0 0 LINE 5 10A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532056.8092401119 20 190293.4285500489 30 0.0 11 532297.8757637227 21 190037.9355843721 31 0.0 0 LINE 5 10AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532207.5227721233 20 189994.9465784494 30 0.0 11 532066.7553249823 21 190251.4614745323 31 0.0 0 LINE 5 10AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531969.2268888711 20 190167.7590414535 30 0.0 11 531992.5469677952 21 190140.9603913208 31 0.0 0 LINE 5 10AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532178.1955524762 20 190155.0732369392 30 0.0 11 532253.7626618632 21 190209.85874761 31 0.0 0 LINE 5 10AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532227.9330378915 20 190186.0183066627 30 0.0 11 532257.2029016576 21 190264.0942781078 31 0.0 0 LINE 5 10AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532217.8643400956 20 190194.4380653439 30 0.0 11 532296.8342970701 21 190208.1454908176 31 0.0 0 LINE 5 10AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532391.6274120264 20 190070.4273729366 30 0.0 11 532285.7295209613 21 190214.1498124604 31 0.0 0 LINE 5 10B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531894.4661772635 20 190432.0901979454 30 0.0 11 531934.5522845409 21 190407.5297838349 31 0.0 0 LINE 5 10B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531891.6592800405 20 190360.280225479 30 0.0 11 531934.6139546222 21 190409.4299312725 31 0.0 0 LINE 5 10B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531843.1238733045 20 190370.2742156616 30 0.0 11 531913.4162201869 21 190293.1903068104 31 0.0 0 LINE 5 10B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531789.3193321156 20 190207.0930159958 30 0.0 11 532031.2859184319 21 190382.0527326439 31 0.0 0 LINE 5 10B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532039.096682347 20 190480.2807871166 30 0.0 11 532092.1903968702 21 190436.4558942987 31 0.0 0 LINE 5 10B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532071.1757363024 20 190412.5324338467 30 0.0 11 532109.5756333829 21 190458.7711606978 31 0.0 0 LINE 5 10B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532069.3952158915 20 190420.9522976431 30 0.0 11 532123.761975346 21 190374.7707928645 31 0.0 0 LINE 5 10B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532120.0904140471 20 190374.1885778235 30 0.0 11 532157.0308076825 21 190416.4614664497 31 0.0 0 LINE 5 10B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532100.5834589982 20 190459.6547015916 30 0.0 11 532160.2028778269 21 190410.1409388884 31 0.0 0 LINE 5 10B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531769.1561834484 20 190581.7882006832 30 0.0 11 531914.0816828643 21 190803.171012523 31 0.0 0 LINE 5 10BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531719.4153004631 20 189040.0434887144 30 0.0 11 531322.9694125037 21 189229.0260951112 31 0.0 0 LINE 5 10BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531968.8214497981 20 188995.9724442154 30 0.0 11 531365.6109342521 21 189366.7655952858 31 0.0 0 LINE 5 10BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531684.4393783764 20 189323.3329337703 30 0.0 11 531352.3449747928 21 188808.9261875 31 0.0 0 LINE 5 10BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531476.1160381618 20 188976.8223097931 30 0.0 11 531268.1767972716 21 189094.2831279027 31 0.0 0 LINE 5 10BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531647.4109409196 20 188919.6673788751 30 0.0 11 531416.1677844149 21 188743.6164943205 31 0.0 0 LINE 5 10BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531466.3846967644 20 189459.5185089535 30 0.0 11 531268.9033481682 21 189091.2666828764 31 0.0 0 LINE 5 10C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531669.5210069521 20 188973.8165935606 30 0.0 11 531290.3979437241 21 189163.819039014 31 0.0 0 LINE 5 10C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531194.0533733342 20 188433.5445984078 30 0.0 11 531295.2640665268 21 189168.8164507826 31 0.0 0 LINE 5 10C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531499.0396327037 20 188680.1597014088 30 0.0 11 531241.3553360876 21 188965.0451001069 31 0.0 0 LINE 5 10C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531310.3338233292 20 188991.3747021521 30 0.0 11 531265.7140145608 21 188999.3251636938 31 0.0 0 LINE 5 10C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531324.6517658388 20 188997.4014930081 30 0.0 11 531301.800692387 21 188989.8533227177 31 0.0 0 LINE 5 10C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531346.6567294156 20 189057.6032493413 30 0.0 11 531320.0511396683 21 188990.8649172865 31 0.0 0 LINE 5 10C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531567.9455156609 20 189030.3499374114 30 0.0 11 531541.6673532669 21 188991.3682991808 31 0.0 0 LINE 5 10C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531600.301193957 20 188966.180934773 30 0.0 11 531540.8226630274 21 188993.0714908561 31 0.0 0 LINE 5 10C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531886.7588520884 20 189321.9919267621 30 0.0 11 531608.349415042 21 188896.1120560258 31 0.0 0 LINE 5 10C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531756.9861162266 20 188869.2808768581 30 0.0 11 531407.9373381911 21 188939.3426849193 31 0.0 0 LINE 5 10CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531294.8779524876 20 189527.3186458787 30 0.0 11 531058.9344860326 21 189579.1778047209 31 0.0 0 LINE 5 10CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531203.525372206 20 189082.6444684779 30 0.0 11 531314.0853586686 21 189591.3148192839 31 0.0 0 LINE 5 10CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531096.1896724 20 189100.4302733887 30 0.0 11 531269.7773097273 21 189835.7798042393 31 0.0 0 LINE 5 10CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531151.2142742812 20 189631.5412952697 30 0.0 11 530754.7683863218 21 189820.5239016666 31 0.0 0 LINE 5 10CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531171.1721781701 20 189698.109373953 30 0.0 11 531108.6900636548 21 189514.5187873819 31 0.0 0 LINE 5 10CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531102.0876062626 20 189720.4637947992 30 0.0 11 531081.8710946612 21 189659.4151391157 31 0.0 0 LINE 5 10D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531156.2856576337 20 189724.9175859754 30 0.0 11 531088.6930151012 21 189711.9372085358 31 0.0 0 LINE 5 10D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531108.7451913958 20 189707.9404608063 30 0.0 11 530756.1735946894 21 189903.6197058668 31 0.0 0 LINE 5 10D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531056.6520987661 20 189822.3268650833 30 0.0 11 530895.3149307944 21 189572.6253398407 31 0.0 0 LINE 5 10D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530907.9150119798 20 189568.3201163484 30 0.0 11 530699.9757710894 21 189685.7809344579 31 0.0 0 LINE 5 10D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530906.8933548907 20 189377.7820440888 30 0.0 11 530900.4533912059 21 189584.8216750027 31 0.0 0 LINE 5 10D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530982.7706124859 20 189420.7311560924 30 0.0 11 530899.2645509212 21 189438.5653211523 31 0.0 0 LINE 5 10D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530863.1775169132 20 189980.745130767 30 0.0 11 530700.7023219861 21 189682.7644894318 31 0.0 0 LINE 5 10D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531101.31998077 20 189565.3144001159 30 0.0 11 530722.196917542 21 189755.3168455691 31 0.0 0 LINE 5 10D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530654.6957032442 20 189221.5155091609 30 0.0 11 530727.0630403447 21 189760.3142573377 31 0.0 0 LINE 5 10D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530747.2416806323 20 189247.3009350145 30 0.0 11 530652.8930014143 21 189317.2141273253 31 0.0 0 LINE 5 10DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530756.0350379258 20 189308.7638222205 30 0.0 11 530649.051045308 21 189283.8634968476 31 0.0 0 LINE 5 10DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530795.4192782982 20 189494.645936663 30 0.0 11 530735.984569425 21 189301.57924678 31 0.0 0 LINE 5 10DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530999.6047073716 20 189350.8857676001 30 0.0 11 530685.5640125669 21 189467.7975904928 31 0.0 0 LINE 5 10DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531036.8657076219 20 189436.7241149764 30 0.0 11 530981.8713730649 21 189328.4509017923 31 0.0 0 LINE 5 10DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531086.4521717799 20 189415.375078614 30 0.0 11 531034.7194828299 21 189436.3834052333 31 0.0 0 LINE 5 10DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531381.1803599318 20 189249.8553472654 30 0.0 11 530840.3943797157 21 189404.9942916577 31 0.0 0 LINE 5 10E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530833.8034017388 20 189416.2898117606 30 0.0 11 530827.288728647 21 189392.8950771704 31 0.0 0 LINE 5 10E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530742.1327971468 20 189582.8725087071 30 0.0 11 530697.5129883786 21 189590.8229702489 31 0.0 0 LINE 5 10E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530756.4507396567 20 189588.8992995633 30 0.0 11 530733.5996662051 21 189581.3511292729 31 0.0 0 LINE 5 10E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530778.4557032334 20 189649.1010558965 30 0.0 11 530751.8501134863 21 189582.3627238419 31 0.0 0 LINE 5 10E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530909.5881846175 20 189428.3169625748 30 0.0 11 530784.2463905739 21 189096.1373681236 31 0.0 0 LINE 5 10E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531108.5813818942 20 189115.914939105 30 0.0 11 530910.3346308408 21 189067.6979914053 31 0.0 0 LINE 5 10E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530926.4599834396 20 189041.102617044 30 0.0 11 530917.9558640805 21 189386.0068931815 31 0.0 0 LINE 5 10E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531041.426258261 20 189350.3283994556 30 0.0 11 531031.3309967528 21 189316.2684607437 31 0.0 0 LINE 5 10E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530856.5678735057 20 189252.0623850323 30 0.0 11 530765.0790922604 21 189270.5459752372 31 0.0 0 LINE 5 10E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530798.4733508944 20 189259.5751234313 30 0.0 11 530739.440772385 21 189318.4626171501 31 0.0 0 LINE 5 10EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530804.1397268244 20 189271.4141772521 30 0.0 11 530726.6028294479 21 189251.1120304952 31 0.0 0 LINE 5 10EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530711.0135881931 20 189137.3537963988 30 0.0 11 530734.2142790415 21 189261.1834636557 31 0.0 0 LINE 5 10EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531304.5651187085 20 189090.643348688 30 0.0 11 531035.799416155 21 189110.9931312904 31 0.0 0 LINE 5 10ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530999.7444894787 20 189621.8477439666 30 0.0 11 530973.4663270845 21 189582.8661057361 31 0.0 0 LINE 5 10EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531032.1001677749 20 189557.6787413281 30 0.0 11 530972.6216368453 21 189584.5692974113 31 0.0 0 LINE 5 10EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531072.1108657749 20 189586.9141580743 30 0.0 11 531040.1483888599 21 189487.6098625809 31 0.0 0 LINE 5 10F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531188.7850900446 20 189460.7786834135 30 0.0 11 530896.0297265131 21 189519.5411584004 31 0.0 0 LINE 5 10F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530848.1576575035 20 189605.6691081451 30 0.0 11 530818.0399273344 21 189543.7620319594 31 0.0 0 LINE 5 10F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530847.0879069723 20 189530.7173856346 30 0.0 11 530792.9614754305 21 189556.8497671789 31 0.0 0 LINE 5 10F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530845.2135190155 20 189539.1168516337 30 0.0 11 530814.9155711146 21 189474.5373636352 31 0.0 0 LINE 5 10F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530818.4976435953 20 189475.531392542 30 0.0 11 530767.3449581734 21 189498.6612989157 31 0.0 0 LINE 5 10F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530800.7760247072 20 189561.3854770761 30 0.0 11 530767.0820439746 21 189491.5943353683 31 0.0 0 LINE 5 10F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531238.1855210372 20 189218.7990321386 30 0.0 11 531129.6891580291 21 189249.3458774341 31 0.0 0 LINE 5 10F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530672.9130626553 20 189260.0114279406 30 0.0 11 530252.2199106406 21 188868.1440122411 31 0.0 0 LINE 5 10F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530684.471856032 20 189192.2221138704 30 0.0 11 530519.5811621016 21 189035.7594543587 31 0.0 0 LINE 5 10F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530860.1522721009 20 189128.5806677993 30 0.0 11 530793.5540958264 21 188972.3834189265 31 0.0 0 LINE 5 10FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531272.1169317574 20 188932.8263748838 30 0.0 11 530573.8535816081 21 189221.4435853778 31 0.0 0 LINE 5 10FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530756.5744089849 20 189071.8318840867 30 0.0 11 530499.3980613915 21 188619.3786656358 31 0.0 0 LINE 5 10FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530694.0402449708 20 189102.1486345439 30 0.0 11 530865.3193356496 21 189011.1926495405 31 0.0 0 LINE 5 10FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530660.9563868377 20 189037.5122938518 30 0.0 11 530718.0005073976 21 189007.8203082046 31 0.0 0 LINE 5 10FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530665.2013767399 20 189091.7270989238 30 0.0 11 530667.2381379603 21 189022.9295181036 31 0.0 0 LINE 5 10FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530674.3810425642 20 189042.0878760805 30 0.0 11 530437.7811339434 21 188827.1015365688 31 0.0 0 LINE 5 1100 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530906.5493413559 20 188952.519278251 30 0.0 11 530631.0793766138 21 188635.0148490799 31 0.0 0 LINE 5 1101 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531083.9260207276 20 188855.8237667776 30 0.0 11 530966.2296031682 21 188885.7406319248 31 0.0 0 LINE 5 1102 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531010.3881229036 20 188977.7951032612 30 0.0 11 531103.9336384209 21 188901.3950542242 31 0.0 0 LINE 5 1103 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531100.5147283493 20 188907.198989996 30 0.0 11 531082.2562417648 21 188854.4330107956 31 0.0 0 LINE 5 1104 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531170.0449162952 20 189237.9965705819 30 0.0 11 531170.0396251662 21 189237.9853171069 31 0.0 0 LINE 5 1105 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531107.7686870358 20 189105.5439277551 30 0.0 11 530790.0936627911 21 188558.1746075611 31 0.0 0 LINE 5 1106 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530770.2701002741 20 188834.3343962393 30 0.0 11 531228.8502984493 21 188636.032638733 31 0.0 0 LINE 5 1107 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531455.2532802372 20 188641.247114639 30 0.0 11 530938.8815154797 21 188837.4798149403 31 0.0 0 LINE 5 1108 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531016.6839955069 20 188918.6094828753 30 0.0 11 531048.6985048241 21 188903.2125700951 31 0.0 0 LINE 5 1109 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530596.0115345955 20 188896.9408068378 30 0.0 11 530776.2852085942 21 188888.5968132422 31 0.0 0 LINE 5 110A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530810.499412421 20 188942.4644181304 30 0.0 11 530774.4691225146 21 188888.034501198 31 0.0 0 LINE 5 110B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530931.1429369639 20 189081.6941781546 30 0.0 11 530848.8341201208 21 188861.8370460586 31 0.0 0 LINE 5 110C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531203.0140174917 20 188919.6828447229 30 0.0 11 531154.1005040535 21 189123.1156930919 31 0.0 0 LINE 5 110D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530792.987268706 20 188939.2580701113 30 0.0 11 530893.48422323 21 188879.0039768547 31 0.0 0 LINE 5 110E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531682.2218760266 20 189319.8980726093 30 0.0 11 531672.7338951584 21 189517.8227310418 31 0.0 0 LINE 5 110F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528393.7599560187 20 187524.6938483252 30 0.0 11 530003.6132568962 21 189942.2237126069 31 0.0 0 LINE 5 1110 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528674.734682812 20 188311.2132533978 30 0.0 11 528559.3309317352 21 188037.4355296202 31 0.0 0 LINE 5 1111 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529022.3447486716 20 187884.9339930147 30 0.0 11 528621.9671427173 21 188233.4860521839 31 0.0 0 LINE 5 1112 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528790.496679948 20 187830.6395476078 30 0.0 11 528886.1965418544 21 188042.1536712512 31 0.0 0 LINE 5 1113 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529017.9036586692 20 188125.0850155283 30 0.0 11 528771.9057892071 21 188328.2578044422 31 0.0 0 LINE 5 1114 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529180.9709087853 20 188540.5938421276 30 0.0 11 529006.0636934473 21 188684.6353220643 31 0.0 0 LINE 5 1115 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528854.9383508704 20 187993.2720995656 30 0.0 11 529032.4021209982 21 188160.2722698406 31 0.0 0 LINE 5 1116 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528690.2652093164 20 188107.9072833756 30 0.0 11 528862.7144473831 21 188341.1823277175 31 0.0 0 LINE 5 1117 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529891.4941110528 20 189786.6610053253 30 0.0 11 532033.4775431653 21 192553.6794256942 31 0.0 0 LINE 5 1118 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530424.1573235889 20 189057.2601955194 30 0.0 11 530615.1814091358 21 188886.4997984614 31 0.0 0 LINE 5 1119 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529791.779404945 20 189319.6821134301 30 0.0 11 530003.6689285722 21 189704.3723750401 31 0.0 0 LINE 5 111A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529597.6850152232 20 189461.4597606462 30 0.0 11 529894.5596331585 21 189249.4055132699 31 0.0 0 LINE 5 111B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529779.842494701 20 189420.5689342099 30 0.0 11 529831.8626403138 21 189382.7595418249 31 0.0 0 LINE 5 111C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529655.0159155208 20 189570.2254684934 30 0.0 11 530034.0293144771 21 189421.025811471 31 0.0 0 LINE 5 111D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530026.3030274082 20 189410.1813897105 30 0.0 11 530126.7485781536 21 189626.8527145978 31 0.0 0 LINE 5 111E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530138.2307661828 20 189255.9802805821 30 0.0 11 530022.7433686064 21 189427.9382489995 31 0.0 0 LINE 5 111F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530051.5441219289 20 189246.6309410291 30 0.0 11 530108.9874280879 21 189309.8099433867 31 0.0 0 LINE 5 1120 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529675.5633810097 20 189679.5496308565 30 0.0 11 529757.5681154661 21 189642.1689603781 31 0.0 0 LINE 5 1121 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529702.9854214259 20 189829.8454059539 30 0.0 11 530127.917123712 21 189623.9784637252 31 0.0 0 LINE 5 1122 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529870.9296487201 20 189294.9701512054 30 0.0 11 530068.1511336619 21 189670.3884675232 31 0.0 0 LINE 5 1123 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530394.1384051356 20 189320.9117378102 30 0.0 11 530061.2839424964 21 189671.6111535061 31 0.0 0 LINE 5 1124 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530582.040160884 20 189150.9830491771 30 0.0 11 530193.7565299102 21 189525.4204246993 31 0.0 0 LINE 5 1125 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530344.0149637483 20 189243.063587853 30 0.0 11 530379.9011146352 21 189354.8746423326 31 0.0 0 LINE 5 1126 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530301.0336818742 20 189287.8700499391 30 0.0 11 530402.4682670551 21 189330.0200891955 31 0.0 0 LINE 5 1127 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530160.6542056199 20 189415.9203584347 30 0.0 11 530321.5122062477 21 189293.7240614566 31 0.0 0 LINE 5 1128 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529972.8374165564 20 189026.1966783911 30 0.0 11 530265.5573080922 21 189458.1619515941 31 0.0 0 LINE 5 1129 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530175.1575922121 20 189329.8815589349 30 0.0 11 530194.0910912162 21 189314.6737587161 31 0.0 0 LINE 5 112A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530152.5025848808 20 189518.6672716123 30 0.0 11 530184.1168749776 21 189551.1430138658 31 0.0 0 LINE 5 112B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530137.3563490113 20 189515.2151382539 30 0.0 11 530160.3221415125 21 189522.4067171776 31 0.0 0 LINE 5 112C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530084.3770351425 20 189551.2936940677 30 0.0 11 530144.9052914925 21 189512.5872016605 31 0.0 0 LINE 5 112D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530106.5758562604 20 189295.4645403759 30 0.0 11 530463.5683009287 21 189048.0505566158 31 0.0 0 LINE 5 112E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530431.8429333872 20 189046.5774025137 30 0.0 11 530515.4704058857 21 189229.6641527433 31 0.0 0 LINE 5 112F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530380.3564014845 20 188954.2573887482 30 0.0 11 530124.4476774383 21 189256.2120495064 31 0.0 0 LINE 5 1130 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530252.4199769282 20 189183.1866620482 30 0.0 11 530315.9699360793 21 189251.5477832537 31 0.0 0 LINE 5 1131 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530295.2366096555 20 189223.1635398347 30 0.0 11 530308.8600722086 21 189305.4252168782 31 0.0 0 LINE 5 1132 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530283.7300963471 20 189229.477901484 30 0.0 11 530358.560215857 21 189258.1937652501 31 0.0 0 LINE 5 1133 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530478.1896499934 20 189141.3998736121 30 0.0 11 530346.5041401216 21 189261.9379565754 31 0.0 0 LINE 5 1134 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529920.4884380986 20 189400.1249218689 30 0.0 11 529964.5664900084 21 189383.7775894323 31 0.0 0 LINE 5 1135 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529931.6173131438 20 189329.1270419157 30 0.0 11 529964.2596465282 21 189385.6538118503 31 0.0 0 LINE 5 1136 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529882.0654487507 20 189329.549276416 30 0.0 11 529965.9340981221 21 189267.5090258793 31 0.0 0 LINE 5 1137 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529860.8233238849 20 189159.0447172158 30 0.0 11 530064.4005868218 21 189377.4824185364 31 0.0 0 LINE 5 1138 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530053.0738443868 20 189475.3673694956 30 0.0 11 530113.6384535762 21 189442.6337191324 31 0.0 0 LINE 5 1139 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530097.6453030549 20 189415.0988856449 30 0.0 11 530126.3815590909 21 189467.8890319381 31 0.0 0 LINE 5 113A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530094.2705849351 20 189423.0156802548 30 0.0 11 530156.5398193389 21 189388.2159911196 31 0.0 0 LINE 5 113B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530153.0500824229 20 189386.934947412 30 0.0 11 530181.1210737556 21 189435.5519119445 31 0.0 0 LINE 5 113C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530117.3882154891 20 189467.0174726847 30 0.0 11 530185.4552303947 21 189429.9638725852 31 0.0 0 LINE 5 113D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529633.0482007297 20 189917.753207084 30 0.0 11 529865.8300288423 21 190673.7845134428 31 0.0 0 LINE 5 113E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.7877707331 20 190050.3400571805 30 0.0 11 529803.1800083046 21 189984.5373966304 31 0.0 0 LINE 5 113F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529690.468046342 20 189886.8937312946 30 0.0 11 529835.0780648242 21 190359.728321133 31 0.0 0 LINE 5 1140 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529771.0299817181 20 189990.2071443399 30 0.0 11 529852.6219251565 21 189998.1979528455 31 0.0 0 LINE 5 1141 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529786.091352851 20 189911.9225946936 30 0.0 11 529778.7158427058 21 189999.461330864 31 0.0 0 LINE 5 1142 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529678.12740668 20 189748.3520551558 30 0.0 11 530014.0117758446 21 190142.7941897908 31 0.0 0 LINE 5 1143 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530132.8866705972 20 189698.1563884737 30 0.0 11 530202.777203116 21 189787.1120784594 31 0.0 0 LINE 5 1144 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530262.8900021763 20 189732.12793098 30 0.0 11 529693.1011346465 21 190228.3257209733 31 0.0 0 LINE 5 1145 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529908.5101230068 20 190131.5293901852 30 0.0 11 530125.3000962972 21 190582.6184565757 31 0.0 0 LINE 5 1146 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529853.4818453089 20 190173.9736557676 30 0.0 11 530011.2903512204 21 190061.2527900251 31 0.0 0 LINE 5 1147 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529896.5732127627 20 190232.416210965 30 0.0 11 529948.5933583757 21 190194.6068185801 31 0.0 0 LINE 5 1148 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529849.9447807383 20 190204.4331025739 30 0.0 11 529912.426864935 21 190233.2990804276 31 0.0 0 LINE 5 1149 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529898.4664877692 20 190218.360150213 30 0.0 11 529958.5477179953 21 190345.4488586622 31 0.0 0 LINE 5 114A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529771.7466335826 20 190382.0727452485 30 0.0 11 530512.071249634 21 190087.5854839669 31 0.0 0 LINE 5 114B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530143.0337454699 20 190222.0286664657 30 0.0 11 530272.5447482439 21 190505.4522987187 31 0.0 0 LINE 5 114C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529800.495504817 20 190503.9870758497 30 0.0 11 529882.500239273 21 190466.6064053712 31 0.0 0 LINE 5 114D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529987.6603667819 20 190106.8174279606 30 0.0 11 530206.9770089463 21 190524.2946848936 31 0.0 0 LINE 5 114E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530195.3235001076 20 189991.9189582468 30 0.0 11 530441.7331030244 21 190342.1924138142 31 0.0 0 LINE 5 114F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529944.2322428545 20 189687.3531936067 30 0.0 11 530293.1197923231 21 190128.7091115361 31 0.0 0 LINE 5 1150 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530223.3065743222 20 190107.3118171309 30 0.0 11 530663.2321954126 21 189814.3623448716 31 0.0 0 LINE 5 1151 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530243.7940378211 20 189737.4826935213 30 0.0 11 530432.9675583755 21 189813.9027659494 31 0.0 0 LINE 5 1152 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530435.3740718211 20 189782.8939022669 30 0.0 11 530241.1783954999 21 190068.0593262615 31 0.0 0 LINE 5 1153 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530369.1506949899 20 189995.0339388033 30 0.0 11 530514.4874132149 21 190153.0233038265 31 0.0 0 LINE 5 1154 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530554.2853607679 20 189986.7113306505 30 0.0 11 530458.5247020654 21 190122.4572681574 31 0.0 0 LINE 5 1155 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530099.3082621901 20 189602.6786171054 30 0.0 11 530305.7932890129 21 189775.9213665038 31 0.0 0 LINE 5 1156 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530037.2191561604 20 190211.9721986242 30 0.0 11 530081.2972080702 21 190195.6248661874 31 0.0 0 LINE 5 1157 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530048.3480312057 20 190140.974318671 30 0.0 11 530080.9903645901 21 190197.5010886054 31 0.0 0 LINE 5 1158 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529998.7961668124 20 190141.3965531712 30 0.0 11 530082.6648161838 21 190079.3563026345 31 0.0 0 LINE 5 1159 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530078.5121304261 20 189745.4989626146 30 0.0 11 530148.8456116325 21 189833.577177656 31 0.0 0 LINE 5 115A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529885.3325268359 20 190334.6202251309 30 0.0 11 529999.4182105816 21 190659.536911753 31 0.0 0 LINE 5 115B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530543.8561078087 20 190046.7631956589 30 0.0 11 530885.6216848795 21 189962.0778141541 31 0.0 0 LINE 5 115C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530217.6887113289 20 189493.3847411613 30 0.0 11 530635.4718868977 21 190165.2105370837 31 0.0 0 LINE 5 115D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530547.8292868897 20 189554.7386399882 30 0.0 11 530729.0204895633 21 189707.5601312849 31 0.0 0 LINE 5 115E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530524.7775013762 20 189638.8254976219 30 0.0 11 530596.3074582908 21 189592.1909071853 31 0.0 0 LINE 5 115F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530567.889837774 20 189349.5276480384 30 0.0 11 530683.9924030411 21 189331.9287256953 31 0.0 0 LINE 5 1160 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530605.2697539877 20 189399.1033628598 30 0.0 11 530663.0541326525 21 189305.6872696934 31 0.0 0 LINE 5 1161 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530504.9687196564 20 189599.6951843686 30 0.0 11 530706.8746037114 21 189455.3898307983 31 0.0 0 LINE 5 1162 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530415.4768326146 20 189540.5554919245 30 0.0 11 530493.6519406615 21 189633.4862080975 31 0.0 0 LINE 5 1163 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530404.1021717828 20 189682.5253705288 30 0.0 11 530372.6508416777 21 189565.9125719136 31 0.0 0 LINE 5 1164 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530372.0443083815 20 189572.621277741 30 0.0 11 530417.6443064328 21 189540.3992189759 31 0.0 0 LINE 5 1165 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530122.6772955924 20 189800.8264032089 30 0.0 11 530122.6881558121 21 189800.8203457863 31 0.0 0 LINE 5 1166 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530250.5013500226 20 189729.5309445075 30 0.0 11 530614.0162237905 21 189526.7759952493 31 0.0 0 LINE 5 1167 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530581.7610652955 20 189592.2842723292 30 0.0 11 530425.8919601132 21 189277.4914096943 31 0.0 0 LINE 5 1168 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530354.1996803542 20 189347.2906557087 30 0.0 11 530545.8603971944 21 189568.3823464327 31 0.0 0 LINE 5 1169 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530433.4968575933 20 189630.7708719959 30 0.0 11 530416.4651855908 21 189599.5953065837 31 0.0 0 LINE 5 116A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530494.1742757037 20 189430.4035020564 30 0.0 11 530571.7937496105 21 189378.5666669773 31 0.0 0 LINE 5 116B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530540.4667486668 20 189394.5089099479 30 0.0 11 530623.8482308888 21 189394.1762472761 31 0.0 0 LINE 5 116C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530544.8656291073 20 189406.875027464 30 0.0 11 530585.145662588 21 189337.5809691292 31 0.0 0 LINE 5 116D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530488.9207428889 20 189200.8594292581 30 0.0 11 530586.919627916 21 189350.0798081888 31 0.0 0 LINE 5 116E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530407.9016811688 20 189813.1407639047 30 0.0 11 530656.0048411988 21 189646.9975927352 31 0.0 0 LINE 5 116F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529599.7443129627 20 189141.9164963533 30 0.0 11 529073.0465794991 21 189156.8615358623 31 0.0 0 LINE 5 1170 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529397.9785832684 20 189142.0982707312 30 0.0 11 529627.9073701178 21 189899.0021408969 31 0.0 0 LINE 5 1171 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529440.8580157359 20 189273.1131639067 30 0.0 11 529294.3072642183 21 189292.6214168864 31 0.0 0 LINE 5 1172 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529333.1202366099 20 189148.6359144085 30 0.0 11 529477.7302550919 21 189621.470504247 31 0.0 0 LINE 5 1173 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529324.1287595416 20 189279.3380187785 30 0.0 11 529260.9644783164 21 189331.6005467687 31 0.0 0 LINE 5 1174 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529267.8552350962 20 189222.8702752408 30 0.0 11 529322.9340814623 21 189291.308197208 31 0.0 0 LINE 5 1175 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529285.220690443 20 189230.6266191861 30 0.0 11 529086.5249493996 21 189239.2437692679 31 0.0 0 LINE 5 1176 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529256.3618522856 20 189111.4712087769 30 0.0 11 529208.0640394783 21 189541.7345497636 31 0.0 0 LINE 5 1177 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529082.044641571 20 189295.137497983 30 0.0 11 529265.2378484767 21 189330.9158113016 31 0.0 0 LINE 5 1178 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529090.0583594282 20 189235.0592643627 30 0.0 11 529082.5629886751 21 189295.808256935 31 0.0 0 LINE 5 1179 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528792.6523966713 20 189233.7003870718 30 0.0 11 529086.9472625145 21 189275.3716972314 31 0.0 0 LINE 5 117A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528860.8155782081 20 189239.6542274844 30 0.0 11 528852.6389035224 21 189352.4857093842 31 0.0 0 LINE 5 117B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528772.0540770689 20 189340.5320141246 30 0.0 11 529635.8297696164 21 189445.595253 31 0.0 0 LINE 5 117C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529289.216465819 20 189473.3841425907 30 0.0 11 529328.7527121662 21 189910.7863063088 31 0.0 0 LINE 5 117D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529358.572360176 20 189477.7872034763 30 0.0 11 529164.7094688229 21 189472.6202442182 31 0.0 0 LINE 5 117E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529355.5426843992 20 189550.3352514977 30 0.0 11 529291.2728503051 21 189548.0915653369 31 0.0 0 LINE 5 117F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529378.5419250274 20 189501.0574678744 30 0.0 11 529342.8949609663 21 189559.9348784515 31 0.0 0 LINE 5 1180 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529346.1109909713 20 189539.7427780762 30 0.0 11 529407.1643398471 21 189938.3272563772 31 0.0 0 LINE 5 1181 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529542.725968138 20 189604.5678193184 30 0.0 11 529145.0952981153 21 189692.8941715661 31 0.0 0 LINE 5 1182 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.4339834579 20 189679.5831878522 30 0.0 11 529183.3674982138 21 189915.3729674253 31 0.0 0 LINE 5 1183 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528966.4009061653 20 189614.3684809313 30 0.0 11 529158.3170448564 21 189692.311265146 31 0.0 0 LINE 5 1184 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529033.0284363266 20 189558.1300895361 30 0.0 11 529020.7513625082 21 189642.6321203984 31 0.0 0 LINE 5 1185 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529598.6615891 20 189783.2636048686 30 0.0 11 529509.7764530662 21 189798.1472734654 31 0.0 0 LINE 5 1186 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529648.1818643421 20 189846.6063273694 30 0.0 11 529180.7911350706 21 189913.644045867 31 0.0 0 LINE 5 1187 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529209.7837831938 20 189497.1726082335 30 0.0 11 529256.2925069518 21 189918.6843695926 31 0.0 0 LINE 5 1188 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528915.0275073097 20 189863.6918634366 30 0.0 11 529197.3740694625 21 189907.0042125853 31 0.0 0 LINE 5 1189 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528630.6392415507 20 189668.1399893563 30 0.0 11 528867.6389683824 21 189709.7115438169 31 0.0 0 LINE 5 118A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529011.1539890148 20 189125.1746906123 30 0.0 11 528968.8246504097 21 189686.1789647126 31 0.0 0 LINE 5 118B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529101.5053739744 20 189840.1004521793 30 0.0 11 529091.814488364 21 189901.7571293312 31 0.0 0 LINE 5 118C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529112.1295733161 20 189828.7667822493 30 0.0 11 529097.1151838522 21 189847.5740824715 31 0.0 0 LINE 5 118D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529176.2263413235 20 189829.0392131988 30 0.0 11 529104.4020878985 21 189830.8109330373 31 0.0 0 LINE 5 118E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528613.6534800922 20 189380.0428021393 30 0.0 11 528496.9060559934 21 189575.3968549445 31 0.0 0 LINE 5 118F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528790.8784877498 20 189334.2893465018 30 0.0 11 528582.4828990723 21 189388.0899835995 31 0.0 0 LINE 5 1190 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529227.5216962489 20 189612.0593604654 30 0.0 11 529181.840168628 21 189623.1637727485 31 0.0 0 LINE 5 1191 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529178.583755367 20 189559.4320979504 30 0.0 11 529183.1439911666 21 189624.5473949048 31 0.0 0 LINE 5 1192 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529219.8949335223 20 189532.065108598 30 0.0 11 529115.6713294665 21 189527.5503116321 31 0.0 0 LINE 5 1193 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529142.1308924119 20 189378.8470075555 30 0.0 11 529095.5635214133 21 189673.7880377656 31 0.0 0 LINE 5 1194 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529159.7048485519 20 189748.5921076506 30 0.0 11 529091.1913892631 21 189755.335226266 31 0.0 0 LINE 5 1195 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529089.0468866706 20 189723.5649724518 30 0.0 11 529094.7548927941 21 189783.3979952963 31 0.0 0 LINE 5 1196 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529096.2725740104 20 189728.2397774477 30 0.0 11 529025.1904553542 21 189734.2237831711 31 0.0 0 LINE 5 1197 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529027.3666452278 20 189731.2098929347 30 0.0 11 529031.2918264516 21 189787.2115245815 31 0.0 0 LINE 5 1198 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529101.7222307826 20 189777.6450789907 30 0.0 11 529024.5734288724 21 189785.003758375 31 0.0 0 LINE 5 1199 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529681.4765692738 20 190017.5958356645 30 0.0 11 529618.3122880486 21 190069.8583636548 31 0.0 0 LINE 5 119A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529625.2030448283 20 189961.1280921271 30 0.0 11 529680.2818911949 21 190029.5660140943 31 0.0 0 LINE 5 119B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529640.7646787354 20 189969.1431576651 30 0.0 11 529442.068937692 21 189977.7603077468 31 0.0 0 LINE 5 119C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529623.2038416172 20 189765.1496793769 30 0.0 11 529565.4118492106 21 190279.9923666497 31 0.0 0 LINE 5 119D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529439.3924513033 20 190033.3953148692 30 0.0 11 529622.5856582088 21 190069.1736281878 31 0.0 0 LINE 5 119E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529447.4061691604 20 189973.3170812488 30 0.0 11 529439.9107984073 21 190034.0660738211 31 0.0 0 LINE 5 119F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529150.0002064036 20 189971.958203958 30 0.0 11 529444.2950722467 21 190013.6295141177 31 0.0 0 LINE 5 11A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529234.2783157637 20 190088.9390749303 30 0.0 11 529879.2664644778 21 190171.3895907363 31 0.0 0 LINE 5 11A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529646.5642755513 20 190211.6419594768 30 0.0 11 529670.4577492668 21 190475.9831164549 31 0.0 0 LINE 5 11A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529715.9201699082 20 190216.0450203624 30 0.0 11 529522.0572785551 21 190210.8780611042 31 0.0 0 LINE 5 11A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529712.8904941317 20 190288.5930683839 30 0.0 11 529648.6206600372 21 190286.3493822232 31 0.0 0 LINE 5 11A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529735.8897347596 20 190239.3152847607 30 0.0 11 529700.2427706988 21 190298.1926953377 31 0.0 0 LINE 5 11A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529703.4588007035 20 190278.0005949622 30 0.0 11 529764.5121495793 21 190676.5850732634 31 0.0 0 LINE 5 11A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529792.6337321126 20 190366.5769540622 30 0.0 11 529502.4431078476 21 190431.151988452 31 0.0 0 LINE 5 11A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529502.7817931904 20 190417.8410047382 30 0.0 11 529540.715307946 21 190653.6307843117 31 0.0 0 LINE 5 11A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529323.7487158978 20 190352.6262978175 30 0.0 11 529515.6648545887 21 190430.5690820322 31 0.0 0 LINE 5 11A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529433.1144004612 20 190090.1837804841 30 0.0 11 529378.0991722405 21 190380.8899372845 31 0.0 0 LINE 5 11AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529567.131592926 20 190235.4304251197 30 0.0 11 529614.7390158634 21 190694.1570997866 31 0.0 0 LINE 5 11AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529179.290859914 20 190439.6790580357 30 0.0 11 529539.3947473728 21 190386.1536617259 31 0.0 0 LINE 5 11AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529236.7986886044 20 190349.5859306546 30 0.0 11 529269.5934678258 21 190462.342439048 31 0.0 0 LINE 5 11AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529297.4897753574 20 190362.6856109918 30 0.0 11 529236.9844176113 21 190454.3627758919 31 0.0 0 LINE 5 11AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529368.5017987471 20 189863.4325074985 30 0.0 11 529349.6696075257 21 190181.6308220653 31 0.0 0 LINE 5 11AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529385.9158724497 20 190087.9554098637 30 0.0 11 529107.8956361627 21 190262.3863000119 31 0.0 0 LINE 5 11B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529190.5207611801 20 190184.8997290861 30 0.0 11 529277.6501320874 21 190327.1649891366 31 0.0 0 LINE 5 11B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529266.1013483288 20 190305.8058681578 30 0.0 11 529300.8217879958 21 190381.6153221281 31 0.0 0 LINE 5 11B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529279.1713942825 20 190304.6038239317 30 0.0 11 529233.2048132479 21 190370.2637131008 31 0.0 0 LINE 5 11B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529121.1132686136 20 190345.3750432046 30 0.0 11 529245.2927747905 21 190366.6237795077 31 0.0 0 LINE 5 11B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529192.5917265354 20 189879.9855184976 30 0.0 11 529151.473581988 21 190023.4573339458 31 0.0 0 LINE 5 11B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529584.8695059813 20 190350.3171773516 30 0.0 11 529539.1879783602 21 190361.4215896345 31 0.0 0 LINE 5 11B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529535.9315650991 20 190297.6899148364 30 0.0 11 529540.4918008986 21 190362.805211791 31 0.0 0 LINE 5 11B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529577.2427432546 20 190270.3229254841 30 0.0 11 529473.0191391987 21 190265.8081285183 31 0.0 0 LINE 5 11B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529499.4787021441 20 190117.1048244416 30 0.0 11 529452.9113311455 21 190412.0458546517 31 0.0 0 LINE 5 11B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529517.0526582841 20 190486.8499245364 30 0.0 11 529448.5391989954 21 190493.5930431521 31 0.0 0 LINE 5 11BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529446.3946964027 20 190461.822789338 30 0.0 11 529452.1027025263 21 190521.6558121825 31 0.0 0 LINE 5 11BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529289.7172643801 20 189986.7411276527 30 0.0 11 529280.6825980962 21 190099.0930094734 31 0.0 0 LINE 5 11BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529222.9041325545 20 190423.7023349991 30 0.0 11 528709.3237252108 21 190682.1166628364 31 0.0 0 LINE 5 11BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529163.3485840849 20 190389.3201673407 30 0.0 11 528959.3591667059 21 190489.6088624351 31 0.0 0 LINE 5 11BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529164.681216433 20 190202.4724583925 30 0.0 11 528995.0771133086 21 190210.678909631 31 0.0 0 LINE 5 11BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529136.4969689673 20 190064.9659453543 30 0.0 11 529183.7428766971 21 191350.1385539917 31 0.0 0 LINE 5 11C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529075.492698009 20 190279.8947185111 30 0.0 11 528649.9905491098 21 190388.6682855325 31 0.0 0 LINE 5 11C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529082.2046651557 20 190349.065351906 30 0.0 11 529056.3943639352 21 190156.8588315621 31 0.0 0 LINE 5 11C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529010.1017019967 20 190357.6421176554 30 0.0 11 529002.0689515459 21 190293.8367838478 31 0.0 0 LINE 5 11C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529062.4162329431 20 190372.4898407178 30 0.0 11 528998.6082292791 21 190346.6868526846 31 0.0 0 LINE 5 11C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529019.0547880857 20 190346.6421365833 30 0.0 11 528635.3045711425 21 190470.4680981078 31 0.0 0 LINE 5 11C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528986.4090745275 20 190551.0779274919 30 0.0 11 528835.8111172078 21 190172.6179566959 31 0.0 0 LINE 5 11C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528849.0058062867 20 190170.8298920155 30 0.0 11 528622.2811080334 21 190245.8744314231 31 0.0 0 LINE 5 11C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528884.8396085598 20 189983.6889307637 30 0.0 11 528838.4947543224 21 190185.5776040143 31 0.0 0 LINE 5 11C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528950.9821621563 20 190040.4969147609 30 0.0 11 528865.6036683856 21 190041.8506366036 31 0.0 0 LINE 5 11C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528818.9183331026 20 190634.7907043113 30 0.0 11 528790.0524771059 21 190549.4159225766 31 0.0 0 LINE 5 11CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528764.2819378928 20 190693.7773339177 30 0.0 11 528623.5771128351 21 190243.0553556253 31 0.0 0 LINE 5 11CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529039.3431507226 20 190205.2713146913 30 0.0 11 528630.6398575692 21 190318.3944534166 31 0.0 0 LINE 5 11CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528662.360593598 20 189841.5344313142 30 0.0 11 528634.4480423454 21 190324.238339472 31 0.0 0 LINE 5 11CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528642.1873241249 20 189641.292104649 30 0.0 11 528650.3809379063 21 190127.5994357825 31 0.0 0 LINE 5 11CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528753.425410089 20 189824.8044275578 30 0.0 11 528647.3405610826 21 189875.1584992957 31 0.0 0 LINE 5 11CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528750.170429287 20 189886.8077721141 30 0.0 11 528650.0186687917 21 189841.694295748 31 0.0 0 LINE 5 11D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528752.8755982489 20 190076.7971426593 30 0.0 11 528731.887199553 21 189875.8824381668 31 0.0 0 LINE 5 11D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528947.1272669612 20 189980.1131455051 30 0.0 11 528650.2833384174 21 190029.2173010918 31 0.0 0 LINE 5 11D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528942.591557104 20 189876.9953841607 30 0.0 11 529048.8655200789 21 189768.3325097931 31 0.0 0 LINE 5 11D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529284.0550368516 20 190057.307597568 30 0.0 11 529284.0426462572 21 190057.3086510901 31 0.0 0 LINE 5 11D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529069.2172349707 20 189964.3602476667 30 0.0 11 528814.3343133004 21 189997.5317432476 31 0.0 0 LINE 5 11D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528805.6839475577 20 190007.3399509129 30 0.0 11 528803.8150157145 21 189983.1271099848 31 0.0 0 LINE 5 11D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528683.5378083801 20 190153.0575385689 30 0.0 11 528638.2227412406 21 190152.2317883801 31 0.0 0 LINE 5 11D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528696.420491177 20 190161.7386773015 30 0.0 11 528675.4597844933 21 190149.9151749459 31 0.0 0 LINE 5 11D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528706.3716819392 20 190225.0588454159 30 0.0 11 528693.1703564675 21 190154.4359923367 31 0.0 0 LINE 5 11D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528877.7138260937 20 190033.7914588225 30 0.0 11 528830.8379358486 21 189685.6645060741 31 0.0 0 LINE 5 11DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528920.0980527489 20 189798.5942733324 30 0.0 11 528894.1033295456 21 189993.8972962386 31 0.0 0 LINE 5 11DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529224.660609378 20 190237.173797853 30 0.0 11 528810.2420405034 21 189672.5104535883 31 0.0 0 LINE 5 11DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528859.7685753607 20 189850.6117725274 30 0.0 11 528766.4324096041 21 189851.0593911296 31 0.0 0 LINE 5 11DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528801.3176274221 20 189846.7515289162 30 0.0 11 528732.0141848773 21 189893.1154706532 31 0.0 0 LINE 5 11DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528804.5882927735 20 189859.4626956493 30 0.0 11 528732.4391360198 21 189824.5535736687 31 0.0 0 LINE 5 11DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528735.7271808159 20 189657.3973491444 30 0.0 11 528737.95990904 21 189835.9065026335 31 0.0 0 LINE 5 11E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528928.7545163261 20 190241.1008184592 30 0.0 11 528910.5083181793 21 190197.7743116633 31 0.0 0 LINE 5 11E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528972.9053949298 20 190184.3976374539 30 0.0 11 528909.3502903563 21 190199.2820699479 31 0.0 0 LINE 5 11E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.3677672739 20 190119.6171140234 30 0.0 11 528846.7750420871 21 190120.6734324097 31 0.0 0 LINE 5 11E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528783.1552386387 20 190195.9215508423 30 0.0 11 528744.2071778071 21 190033.8158718843 31 0.0 0 LINE 5 11E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528943.273818483 20 190435.7833200833 30 0.0 11 528696.4510643113 21 190531.1367562146 31 0.0 0 LINE 5 11E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528976.0769089332 20 189434.0576018465 30 0.0 11 529140.8150301299 21 189457.1353655681 31 0.0 0 LINE 5 11E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528884.5132737517 20 189395.1880814658 30 0.0 11 528971.8021976204 21 189232.6095664005 31 0.0 0 LINE 5 11E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528963.8167557576 20 190199.7062129303 30 0.0 11 528942.2151172271 21 190084.5386704732 31 0.0 0 LINE 5 11E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529538.7347799715 20 189605.4543884852 30 0.0 11 529721.0447377914 21 189683.0898924534 31 0.0 0 LINE 5 11E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532093.4400750394 20 190602.6288740622 30 0.0 11 532537.709917907 21 190944.7038226986 31 0.0 0 LINE 5 11EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532113.3938232591 20 190608.2493097254 30 0.0 11 531485.2645507479 21 191089.1072229474 31 0.0 0 LINE 5 11EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532002.1664151241 20 190689.6864734899 30 0.0 11 532109.8523286888 21 190790.9852332279 31 0.0 0 LINE 5 11EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532093.3699689512 20 190762.8054165837 30 0.0 11 532114.2129493946 21 190842.0939303852 31 0.0 0 LINE 5 11ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532172.0125192354 20 190749.7415389612 30 0.0 11 532087.3610531503 21 190773.2268060422 31 0.0 0 LINE 5 11EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532153.3819682775 20 190745.9176035789 30 0.0 11 532309.7817934577 21 190868.7725891024 31 0.0 0 LINE 5 11EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532246.303823139 20 190665.9402739241 30 0.0 11 532034.6666925351 21 191043.6557042007 31 0.0 0 LINE 5 11F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532280.8315229687 20 190916.7940833162 30 0.0 11 532111.1404321221 21 190839.0459486273 31 0.0 0 LINE 5 11F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532309.3510573484 20 190863.3127782874 30 0.0 11 532280.0193059137 21 190917.0367863198 31 0.0 0 LINE 5 11F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532551.761731845 20 191035.6183734401 30 0.0 11 532288.373456142 21 190897.8773760057 31 0.0 0 LINE 5 11F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532492.9131191679 20 191000.7112349314 30 0.0 11 532433.7669462679 21 191097.1453136996 31 0.0 0 LINE 5 11F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532506.2055003433 20 191134.4207877858 30 0.0 11 531880.4091661065 21 190762.0070556545 31 0.0 0 LINE 5 11F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532008.590213593 20 190940.8086735789 30 0.0 11 531721.4325374245 21 191273.1100979186 31 0.0 0 LINE 5 11F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531949.6768366249 20 190903.9462124372 30 0.0 11 532110.1875119865 21 191012.7848140758 31 0.0 0 LINE 5 11F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531909.8373502772 20 190964.652172067 30 0.0 11 531963.3596391908 21 191000.303403344 31 0.0 0 LINE 5 11F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531919.8848989398 20 190911.2076981324 30 0.0 11 531914.5153158007 21 190979.8256484073 31 0.0 0 LINE 5 11F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531923.6760320993 20 190961.5460137429 30 0.0 11 531641.6710148187 21 191249.7651456203 31 0.0 0 LINE 5 11FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531726.1444548365 20 190899.5701216376 30 0.0 11 531997.6865254563 21 191203.1761132243 31 0.0 0 LINE 5 11FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532005.1726544908 20 191192.1645344424 30 0.0 11 531836.8719324415 21 191361.6066739787 31 0.0 0 LINE 5 11FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532188.6475604557 20 191243.5723124995 30 0.0 11 531987.2848003661 21 191194.9932969649 31 0.0 0 LINE 5 11FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532167.309190774 20 191159.034401351 30 0.0 11 532128.0124170939 21 191234.8439214637 31 0.0 0 LINE 5 11FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531630.7610581088 20 190956.806285408 30 0.0 11 531694.2947849448 21 191020.7246439053 31 0.0 0 LINE 5 11FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531499.3437770261 20 191034.7183290566 30 0.0 11 531839.9731081884 21 191361.7042741094 31 0.0 0 LINE 5 1200 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532059.2524323825 20 191006.4499849154 30 0.0 11 531775.6954554155 21 191321.7762717404 31 0.0 0 LINE 5 1201 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532216.6329280467 20 191506.1016118414 30 0.0 11 531772.1639381984 21 191315.7611523182 31 0.0 0 LINE 5 1202 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532441.2418068305 20 191623.2923990452 30 0.0 11 531955.262167516 21 191389.2169487265 31 0.0 0 LINE 5 1203 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532272.2279328401 20 191432.061830168 30 0.0 11 532179.8394744348 21 191504.5456247899 31 0.0 0 LINE 5 1204 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532215.2832434994 20 191407.3168914513 30 0.0 11 532210.9844278584 21 191517.0762694753 31 0.0 0 LINE 5 1205 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532046.4502892583 20 191320.1462976625 30 0.0 11 532216.905681068 21 191428.5538193766 31 0.0 0 LINE 5 1206 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532239.1193936134 20 191161.2838040338 30 0.0 11 532043.2702144016 21 191433.1900954792 31 0.0 0 LINE 5 1207 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532166.2017047998 20 191102.635575774 30 0.0 11 532256.0616277937 21 191184.3219257113 31 0.0 0 LINE 5 1208 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532308.5036839469 20 191096.7215187221 30 0.0 11 532193.1847684965 21 191060.8149913824 31 0.0 0 LINE 5 1209 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532199.9118185815 20 191060.4665467347 30 0.0 11 532165.9623074486 21 191104.7954491255 31 0.0 0 LINE 5 120A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532437.5252889657 20 190820.0474854079 30 0.0 11 532144.8076645989 21 191300.4993153043 31 0.0 0 LINE 5 120B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532132.1706507358 20 191303.8661603718 30 0.0 11 532153.0073547956 21 191316.3395855612 31 0.0 0 LINE 5 120C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531947.2677219202 20 191348.1854742621 30 0.0 11 531927.7928531354 21 191389.1106090703 31 0.0 0 LINE 5 120D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531945.2447811827 20 191332.7830914429 30 0.0 11 531946.4767204593 21 191356.8169999523 31 0.0 0 LINE 5 120E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531893.0124814265 20 191295.6312846257 30 0.0 11 531950.3308491905 21 191338.9494919771 31 0.0 0 LINE 5 120F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532140.6273829715 20 191227.6003793653 30 0.0 11 532496.6227987491 21 191476.4468156583 31 0.0 0 LINE 5 1210 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532486.9862212213 20 191446.1845371221 30 0.0 11 532344.3388213688 21 191588.191690398 31 0.0 0 LINE 5 1211 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532494.5521203357 20 191118.373106616 30 0.0 11 532476.0061814613 21 191480.6445697622 31 0.0 0 LINE 5 1212 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532555.6789127965 20 191365.8405141135 30 0.0 11 532183.6434305776 21 191230.7276273598 31 0.0 0 LINE 5 1213 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532250.7242278104 20 191121.100715535 30 0.0 11 532280.8983750848 21 191139.8494372576 31 0.0 0 LINE 5 1214 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532296.5674822263 20 191325.3731513396 30 0.0 11 532254.5319497042 21 191408.7089432071 31 0.0 0 LINE 5 1215 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532273.9488858729 20 191379.4084536399 30 0.0 11 532201.5388367442 21 191420.752945741 31 0.0 0 LINE 5 1216 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532264.031408359 20 191370.8110905958 30 0.0 11 532263.0909969975 21 191450.9563539879 31 0.0 0 LINE 5 1217 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532414.1618065546 20 191522.577755367 30 0.0 11 532255.3928528242 21 191440.9510300498 31 0.0 0 LINE 5 1218 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532685.3559009919 20 191001.6618268656 30 0.0 11 532521.9230479188 21 190934.6835698601 31 0.0 0 LINE 5 1219 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532584.1101927998 20 190947.9789637227 30 0.0 11 532480.0379977193 21 191189.8628189787 31 0.0 0 LINE 5 121A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531977.8543738964 20 191089.4436923433 30 0.0 11 532008.4922394006 21 191125.1008253645 31 0.0 0 LINE 5 121B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532048.2980711977 20 191075.2227103755 30 0.0 11 532006.6262351963 21 191125.4646821949 31 0.0 0 LINE 5 121C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532030.6930418108 20 191028.9017811203 30 0.0 11 532117.998770022 21 191086.0039076615 31 0.0 0 LINE 5 121D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532183.2074847922 20 190949.7665976741 30 0.0 11 532049.0673803575 21 191216.5345937405 31 0.0 0 LINE 5 121E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531953.3414468827 20 191239.9077488307 30 0.0 11 532005.0713700226 21 191285.334379834 31 0.0 0 LINE 5 121F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532025.3380024663 20 191260.7740148495 30 0.0 11 531985.8136504054 21 191306.0553305413 31 0.0 0 LINE 5 1220 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532016.7419589933 20 191260.358809006 30 0.0 11 532071.0013293279 21 191306.6664395658 31 0.0 0 LINE 5 1221 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532070.9906705489 20 191302.9490179977 30 0.0 11 532035.1487030354 21 191346.1571556514 31 0.0 0 LINE 5 1222 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531983.5076242133 20 191297.3190791788 30 0.0 11 532041.8941492539 21 191348.2808441813 31 0.0 0 LINE 5 1223 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532429.633362168 20 190966.1629744953 30 0.0 11 532371.4638803732 21 191062.7076891677 31 0.0 0 LINE 5 1224 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531810.0910753604 20 190989.6060128932 30 0.0 11 531614.6487416758 21 191167.9765372598 31 0.0 0 LINE 5 1225 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531796.2678138876 20 190690.6548548851 30 0.0 11 530764.4896246664 21 191480.5220505232 31 0.0 0 LINE 5 1226 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531281.3914890426 20 191081.1013010658 30 0.0 11 531389.0774026074 21 191182.4000608037 31 0.0 0 LINE 5 1227 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531441.4991432304 20 191042.7926367183 30 0.0 11 531048.3177917206 21 191342.6143030769 31 0.0 0 LINE 5 1228 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531372.5950428699 20 191154.2202441596 30 0.0 11 531393.4380233133 21 191233.5087579612 31 0.0 0 LINE 5 1229 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531451.2375931538 20 191141.1563665371 30 0.0 11 531366.5861270688 21 191164.6416336182 31 0.0 0 LINE 5 122A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531433.92164784 20 191138.5943822833 30 0.0 11 531590.3214730201 21 191261.4493678067 31 0.0 0 LINE 5 122B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531567.1316283411 20 190983.1054010685 30 0.0 11 531313.8917664535 21 191435.0705317762 31 0.0 0 LINE 5 122C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531560.0565968872 20 191308.2089108923 30 0.0 11 531390.3655060405 21 191230.4607762033 31 0.0 0 LINE 5 122D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531588.5761312669 20 191254.7276058633 30 0.0 11 531559.2443798324 21 191308.4516138957 31 0.0 0 LINE 5 122E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531830.9868057637 20 191427.0332010161 30 0.0 11 531567.5985300605 21 191289.2922035817 31 0.0 0 LINE 5 122F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531772.1381930866 20 191392.1260625073 30 0.0 11 531712.9920201865 21 191488.5601412755 31 0.0 0 LINE 5 1230 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531785.4305742621 20 191525.8356153619 30 0.0 11 531122.2336288609 21 191163.8391900123 31 0.0 0 LINE 5 1231 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531287.8152875113 20 191332.2235011548 30 0.0 11 531000.6576113431 21 191664.5249254946 31 0.0 0 LINE 5 1232 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531228.9019105434 20 191295.3610400128 30 0.0 11 531389.412585905 21 191404.1996416514 31 0.0 0 LINE 5 1233 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531189.0624241958 20 191356.0669996431 30 0.0 11 531242.5847131093 21 191391.7182309199 31 0.0 0 LINE 5 1234 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531199.1099728586 20 191302.6225257084 30 0.0 11 531193.7403897194 21 191371.2404759832 31 0.0 0 LINE 5 1235 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531202.901106018 20 191352.9608413188 30 0.0 11 530920.8960887374 21 191641.1799731962 31 0.0 0 LINE 5 1236 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530791.3001046506 20 191134.8743590273 30 0.0 11 531243.4633766599 21 191657.8057239712 31 0.0 0 LINE 5 1237 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531284.3977284094 20 191583.5793620181 30 0.0 11 531116.0970063601 21 191753.0215015545 31 0.0 0 LINE 5 1238 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531467.8726343744 20 191634.9871400754 30 0.0 11 531266.5098742847 21 191586.4081245408 31 0.0 0 LINE 5 1239 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531446.5342646923 20 191550.4492289268 30 0.0 11 531407.2374910125 21 191626.2587490396 31 0.0 0 LINE 5 123A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530855.7335500447 20 191403.5462717947 30 0.0 11 530919.2672768807 21 191467.4646302917 31 0.0 0 LINE 5 123B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530778.5688509447 20 191426.1331566325 30 0.0 11 531119.1981821072 21 191753.1191016854 31 0.0 0 LINE 5 123C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531338.4775063013 20 191397.8648124914 30 0.0 11 531054.9205293343 21 191713.1910993164 31 0.0 0 LINE 5 123D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531377.5029102171 20 191845.5685987614 30 0.0 11 531051.3890121169 21 191707.1759798942 31 0.0 0 LINE 5 123E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531518.344467532 20 191552.6986316098 30 0.0 11 531322.4952883203 21 191824.604923055 31 0.0 0 LINE 5 123F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531445.4267787183 20 191494.0504033497 30 0.0 11 531535.2867017123 21 191575.7367532872 31 0.0 0 LINE 5 1240 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531587.7287578654 20 191488.136346298 30 0.0 11 531472.4098424151 21 191452.2298189583 31 0.0 0 LINE 5 1241 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531479.1368925001 20 191451.8813743105 30 0.0 11 531445.1873813673 21 191496.2102767015 31 0.0 0 LINE 5 1242 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531716.7503628843 20 191211.4623129839 30 0.0 11 531424.0327385175 21 191691.9141428803 31 0.0 0 LINE 5 1243 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531411.3957246545 20 191695.2809879477 30 0.0 11 531432.2324287142 21 191707.7544131372 31 0.0 0 LINE 5 1244 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531226.4927958389 20 191739.600301838 30 0.0 11 531207.017927054 21 191780.5254366461 31 0.0 0 LINE 5 1245 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531224.4698551012 20 191724.1979190188 30 0.0 11 531225.7017943778 21 191748.2318275282 31 0.0 0 LINE 5 1246 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531172.2375553451 20 191687.0461122015 30 0.0 11 531229.5559231091 21 191730.3643195529 31 0.0 0 LINE 5 1247 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531419.8524568902 20 191619.0152069412 30 0.0 11 531707.0201414058 21 191827.7939637002 31 0.0 0 LINE 5 1248 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531773.7771942542 20 191509.787934192 30 0.0 11 531767.8126675716 21 191713.7268288893 31 0.0 0 LINE 5 1249 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531797.7271904702 20 191705.2143525404 30 0.0 11 531462.8685044961 21 191622.1424549358 31 0.0 0 LINE 5 124A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531529.949301729 20 191512.5155431109 30 0.0 11 531560.1234490032 21 191531.2642648336 31 0.0 0 LINE 5 124B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531850.0114793597 20 191327.4788226467 30 0.0 11 531759.2630716378 21 191581.2776465546 31 0.0 0 LINE 5 124C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531257.0794478149 20 191480.858519919 30 0.0 11 531287.7173133191 21 191516.5156529402 31 0.0 0 LINE 5 124D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531327.5231451162 20 191466.6375379514 30 0.0 11 531285.8513091147 21 191516.8795097707 31 0.0 0 LINE 5 124E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531309.9181157294 20 191420.3166086959 30 0.0 11 531397.2238439407 21 191477.4187352375 31 0.0 0 LINE 5 124F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531462.4325587107 20 191341.18142525 30 0.0 11 531328.292454276 21 191607.9494213166 31 0.0 0 LINE 5 1250 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531708.8584360867 20 191357.5778020711 30 0.0 11 531650.6889542918 21 191454.1225167437 31 0.0 0 LINE 5 1251 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531059.8805382769 20 191405.2619729084 30 0.0 11 530893.8738155942 21 191559.3913648357 31 0.0 0 LINE 5 1252 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531695.8206200191 20 191746.0086272095 30 0.0 11 531828.8253042691 21 191851.5673862307 31 0.0 0 LINE 5 1253 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531993.615337301 20 191400.533692721 30 0.0 11 531530.5044200901 21 191997.5260534049 31 0.0 0 LINE 5 1254 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531723.1362172004 20 191860.9114397561 30 0.0 11 532005.3993839649 21 192197.3802678644 31 0.0 0 LINE 5 1255 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531677.3517133629 20 191913.1934274341 30 0.0 11 531810.391053535 21 191772.0904434886 31 0.0 0 LINE 5 1256 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.9286674994 20 191962.2026938285 30 0.0 11 531774.6578365174 21 191915.0496930851 31 0.0 0 LINE 5 1257 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531679.7700162902 20 191943.7620475613 30 0.0 11 531746.6539128269 21 191960.0039657696 31 0.0 0 LINE 5 1258 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531730.0688062759 20 191948.045788348 30 0.0 11 531969.6352427643 21 192272.3990221221 31 0.0 0 LINE 5 1259 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531637.389696535 20 192133.1682284677 30 0.0 11 531980.4084138274 21 191913.5097348211 31 0.0 0 LINE 5 125A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531970.7313669026 20 191904.3636013212 30 0.0 11 532111.1703995337 21 192097.5284268109 31 0.0 0 LINE 5 125B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532050.7362527369 20 191731.4329244408 30 0.0 11 531970.6717466338 21 191922.4736446127 31 0.0 0 LINE 5 125C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531963.8775272967 20 191739.018849366 30 0.0 11 532032.4513453455 21 191789.9005871466 31 0.0 0 LINE 5 125D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531734.6458126212 20 192378.6164578516 30 0.0 11 532111.7612289476 21 192094.4824889581 31 0.0 0 LINE 5 125E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531796.0157464022 20 191821.3637926705 30 0.0 11 532062.0950777154 21 192151.5713271051 31 0.0 0 LINE 5 125F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532314.3690415566 20 191745.6655092834 30 0.0 11 532055.593819006 21 192154.0985609112 31 0.0 0 LINE 5 1260 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532444.3084072207 20 191573.5378326324 30 0.0 11 532157.3045856129 21 191985.0552659795 31 0.0 0 LINE 5 1261 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532250.1410495512 20 191678.9762382483 30 0.0 11 532306.9662988436 21 191781.7401364429 31 0.0 0 LINE 5 1262 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532216.6329438502 20 191731.2468465146 30 0.0 11 532324.3026469366 21 191752.9916370946 31 0.0 0 LINE 5 1263 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532103.6574210093 20 191884.0205683982 30 0.0 11 532237.8568669417 21 191733.0313632459 31 0.0 0 LINE 5 1264 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532002.2175019509 20 191692.209596541 30 0.0 11 532214.7479054014 21 191905.1846270458 31 0.0 0 LINE 5 1265 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532018.0713449173 20 191602.3928622941 30 0.0 11 531958.0747517411 21 191707.9763569033 31 0.0 0 LINE 5 1266 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531880.9878547196 20 191641.0315224062 30 0.0 11 531979.4193661846 21 191571.0388905303 31 0.0 0 LINE 5 1267 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531972.917590081 20 191572.800004955 30 0.0 11 532018.9706419868 21 191604.3711516482 31 0.0 0 LINE 5 1268 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531672.3130915669 20 191418.2088608678 30 0.0 11 531672.3225436441 21 191418.2169413986 31 0.0 0 LINE 5 1269 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531783.5634071171 20 191513.3161613891 30 0.0 11 532099.9447376423 21 191783.7888709074 31 0.0 0 LINE 5 126A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532101.2535546515 20 191796.8010484009 30 0.0 11 532116.8897799552 21 191778.2197935914 31 0.0 0 LINE 5 126B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532115.5233552441 20 191986.4050237265 30 0.0 11 532152.8196642743 21 192012.1561888647 31 0.0 0 LINE 5 126C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532099.995471847 20 191985.9461959419 30 0.0 11 532123.9183272432 21 191988.5621895042 31 0.0 0 LINE 5 126D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532054.9906121824 20 192031.5864467543 30 0.0 11 532106.893947073 21 191981.9084214466 31 0.0 0 LINE 5 126E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532027.3119133144 20 191776.2920418672 30 0.0 11 532268.3784369255 21 191520.7990761905 31 0.0 0 LINE 5 126F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532178.0254453258 20 191477.8100702677 30 0.0 11 532037.2579981849 21 191734.3249663507 31 0.0 0 LINE 5 1270 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531939.7295620738 20 191650.6225332717 30 0.0 11 531963.0496409979 21 191623.823883139 31 0.0 0 LINE 5 1271 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532148.6982256789 20 191637.9367287575 30 0.0 11 532224.2653350659 21 191692.7222394283 31 0.0 0 LINE 5 1272 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532198.4357110942 20 191668.8817984812 30 0.0 11 532227.7055748605 21 191746.9577699262 31 0.0 0 LINE 5 1273 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532188.3670132983 20 191677.3015571623 30 0.0 11 532267.336970273 21 191691.0089826361 31 0.0 0 LINE 5 1274 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532362.1300852291 20 191553.2908647549 30 0.0 11 532256.2321941641 21 191697.0133042788 31 0.0 0 LINE 5 1275 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531864.9688504661 20 191914.9536897637 30 0.0 11 531905.0549577436 21 191890.3932756532 31 0.0 0 LINE 5 1276 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531862.1619532432 20 191843.1437172973 30 0.0 11 531905.1166278249 21 191892.2934230909 31 0.0 0 LINE 5 1277 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531813.6265465071 20 191853.1377074801 30 0.0 11 531883.9188933896 21 191776.0537986287 31 0.0 0 LINE 5 1278 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531759.8220053184 20 191689.9565078141 30 0.0 11 532001.7885916345 21 191864.9162244624 31 0.0 0 LINE 5 1279 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532009.5993555495 20 191963.144278935 30 0.0 11 532062.6930700728 21 191919.319386117 31 0.0 0 LINE 5 127A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532041.6784095048 20 191895.395925665 30 0.0 11 532080.0783065855 21 191941.6346525161 31 0.0 0 LINE 5 127B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532039.8978890943 20 191903.8157894616 30 0.0 11 532094.2646485485 21 191857.6342846829 31 0.0 0 LINE 5 127C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532090.5930872497 20 191857.0520696418 30 0.0 11 532127.5334808851 21 191899.3249582679 31 0.0 0 LINE 5 127D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532071.0861322011 20 191942.51819341 30 0.0 11 532130.7055510295 21 191893.0044307067 31 0.0 0 LINE 5 127E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531739.658856651 20 192064.6516925016 30 0.0 11 531884.5843560669 21 192286.0345043412 31 0.0 0 LINE 5 127F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531726.566720581 20 190667.1991249742 30 0.0 11 531616.5188179025 21 190751.1164965218 31 0.0 0 LINE 5 1280 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531689.9179736658 20 190522.9069805326 30 0.0 11 531293.4720857064 21 190711.8895869297 31 0.0 0 LINE 5 1281 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531647.4488907804 20 190599.3061460694 30 0.0 11 531294.8772940742 21 190794.98539113 31 0.0 0 LINE 5 1282 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531654.9420515791 20 190806.1964255886 30 0.0 11 531464.5204324898 21 190511.2376294206 31 0.0 0 LINE 5 1283 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531506.7950860217 20 190920.7104162707 30 0.0 11 531461.9685388102 21 190842.5268395827 31 0.0 0 LINE 5 1284 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531464.5931598749 20 190989.1469239503 30 0.0 11 531239.4060213708 21 190574.130174695 31 0.0 0 LINE 5 1285 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531640.0236801546 20 190456.680085379 30 0.0 11 531260.9006169267 21 190646.6825308323 31 0.0 0 LINE 5 1286 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531212.7647778893 20 190266.6331710364 30 0.0 11 531265.7667397293 21 190651.6799426009 31 0.0 0 LINE 5 1287 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531538.4481888635 20 190513.2134292297 30 0.0 11 531512.1700264695 21 190474.2317909991 31 0.0 0 LINE 5 1288 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531570.8038671595 20 190449.0444265913 30 0.0 11 531511.32533623 21 190475.9349826742 31 0.0 0 LINE 5 1289 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531532.3049148279 20 190937.4342044066 30 0.0 11 531029.4371592352 21 191062.0412965392 31 0.0 0 LINE 5 128A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531174.0280454086 20 190565.5079602962 30 0.0 11 531255.8981468314 21 190942.1803400939 31 0.0 0 LINE 5 128B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531066.6923456027 20 190583.2937652071 30 0.0 11 531240.2799829301 21 191318.6432960578 31 0.0 0 LINE 5 128C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531121.7169474838 20 191114.404787088 30 0.0 11 530725.2710595243 21 191303.3873934849 31 0.0 0 LINE 5 128D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531141.6748513727 20 191180.9728657711 30 0.0 11 531079.1927368576 21 190997.3822792003 31 0.0 0 LINE 5 128E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531072.5902794654 20 191203.3272866175 30 0.0 11 531052.3737678636 21 191142.278630934 31 0.0 0 LINE 5 128F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531126.7883308363 20 191207.7810777936 30 0.0 11 531059.1956883039 21 191194.8007003539 31 0.0 0 LINE 5 1290 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530935.1011591012 20 191270.8061954971 30 0.0 11 530726.6762678921 21 191386.4831976849 31 0.0 0 LINE 5 1291 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530953.2732856884 20 190903.5946479108 30 0.0 11 530869.7672241239 21 190921.4288129707 31 0.0 0 LINE 5 1292 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530833.6801901157 20 191463.6086225853 30 0.0 11 530751.3796565852 21 191262.9827624679 31 0.0 0 LINE 5 1293 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531071.8226539727 20 191048.1778919344 30 0.0 11 530692.6995907446 21 191238.1803373874 31 0.0 0 LINE 5 1294 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530970.1073805743 20 190833.7492594184 30 0.0 11 530656.0666857695 21 190950.6610823109 31 0.0 0 LINE 5 1295 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531007.3683808244 20 190919.5876067948 30 0.0 11 530952.3740462676 21 190811.3143936106 31 0.0 0 LINE 5 1296 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531056.9548449825 20 190898.2385704325 30 0.0 11 531005.2221560326 21 190919.2468970518 31 0.0 0 LINE 5 1297 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531351.6830331344 20 190732.7188390835 30 0.0 11 530810.8970529181 21 190887.8577834759 31 0.0 0 LINE 5 1298 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530804.3060749416 20 190899.153303579 30 0.0 11 530797.7914018496 21 190875.7585689889 31 0.0 0 LINE 5 1299 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530880.0908578202 20 190911.1804543932 30 0.0 11 530754.7490637765 21 190579.0008599418 31 0.0 0 LINE 5 129A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531079.0840550969 20 190598.7784309232 30 0.0 11 530880.8373040431 21 190550.5614832236 31 0.0 0 LINE 5 129B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530896.9626566423 20 190523.9661088623 30 0.0 11 530888.458537283 21 190868.8703849999 31 0.0 0 LINE 5 129C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531275.0677919114 20 190573.5068405064 30 0.0 11 531006.3020893577 21 190593.8566231087 31 0.0 0 LINE 5 129D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530970.2471626816 20 191104.7112357848 30 0.0 11 530943.9690002872 21 191065.7295975544 31 0.0 0 LINE 5 129E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531002.6028409777 20 191040.5422331465 30 0.0 11 530943.124310048 21 191067.4327892296 31 0.0 0 LINE 5 129F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531042.6135389779 20 191069.7776498928 30 0.0 11 531010.6510620626 21 190970.4733543993 31 0.0 0 LINE 5 12A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531208.6881942397 20 190701.6625239569 30 0.0 11 531100.1918312319 21 190732.2093692526 31 0.0 0 LINE 5 12A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530830.6549453034 20 190611.4441596177 30 0.0 11 530764.056769029 21 190455.2469107448 31 0.0 0 LINE 5 12A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531242.6196049599 20 190415.6898667019 30 0.0 11 530544.3562548107 21 190704.3070771961 31 0.0 0 LINE 5 12A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530727.0770821876 20 190554.695375905 30 0.0 11 530469.9007345941 21 190102.2421574541 31 0.0 0 LINE 5 12A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530664.5429181734 20 190585.0121263624 30 0.0 11 530835.8220088523 21 190494.0561413587 31 0.0 0 LINE 5 12A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530691.5892971918 20 190658.1596607209 30 0.0 11 530637.7408111629 21 190505.793009922 31 0.0 0 LINE 5 12A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530644.8837157669 20 190524.9513678989 30 0.0 11 530408.283807146 21 190309.9650283871 31 0.0 0 LINE 5 12A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530877.0520145585 20 190435.3827700694 30 0.0 11 530601.5820498165 21 190117.8783408983 31 0.0 0 LINE 5 12A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531054.4286939304 20 190338.687258596 30 0.0 11 530936.7322763709 21 190368.6041237431 31 0.0 0 LINE 5 12A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530980.8907961061 20 190460.6585950796 30 0.0 11 531074.4363116233 21 190384.2585460425 31 0.0 0 LINE 5 12AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531071.0174015519 20 190390.0624818143 30 0.0 11 531052.7589149675 21 190337.296502614 31 0.0 0 LINE 5 12AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531140.5475894979 20 190720.8600624002 30 0.0 11 531140.5422983688 21 190720.8488089252 31 0.0 0 LINE 5 12AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531078.2713602384 20 190588.4074195735 30 0.0 11 530552.7345483289 21 189682.8822585834 31 0.0 0 LINE 5 12AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530740.7727734767 20 190317.1978880576 30 0.0 11 531066.8566840048 21 190154.7626582723 31 0.0 0 LINE 5 12AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531172.6815375744 20 190253.818759882 30 0.0 11 530909.3841886824 21 190320.3433067586 31 0.0 0 LINE 5 12AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530987.1866687095 20 190401.4729746934 30 0.0 11 531019.2011780268 21 190386.0760619135 31 0.0 0 LINE 5 12B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530566.5142077983 20 190379.8042986561 30 0.0 11 530746.7878817967 21 190371.4603050605 31 0.0 0 LINE 5 12B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530781.0020856237 20 190425.3279099487 30 0.0 11 530744.9717957172 21 190370.8979930163 31 0.0 0 LINE 5 12B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530901.6456101665 20 190564.5576699728 30 0.0 11 530819.3367933233 21 190344.7005378771 31 0.0 0 LINE 5 12B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531173.5166906944 20 190402.5463365411 30 0.0 11 531124.6031772562 21 190605.9791849102 31 0.0 0 LINE 5 12B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530763.4899419086 20 190422.1215619297 30 0.0 11 530863.9868964326 21 190361.8674686729 31 0.0 0 LINE 5 12B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531652.7245492292 20 190802.7615644275 30 0.0 11 531643.2365683611 21 191000.68622286 31 0.0 0 LINE 5 12B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528736.092904392 20 189686.6373637899 30 0.0 11 528620.6891533154 21 189412.8596400124 31 0.0 0 LINE 5 12B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528883.5141672747 20 189434.6341329915 30 0.0 11 528683.3253642974 21 189608.9101625759 31 0.0 0 LINE 5 12B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528709.7858504974 20 189222.7317666962 30 0.0 11 528856.699215057 21 189525.0171630695 31 0.0 0 LINE 5 12B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528945.836060306 20 189561.5091656175 30 0.0 11 528833.2640107872 21 189703.6819148343 31 0.0 0 LINE 5 12BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529194.1836177331 20 189955.6672653194 30 0.0 11 529067.4219150274 21 190060.0594324565 31 0.0 0 LINE 5 12BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528825.4410240728 20 189476.1355913837 30 0.0 11 529002.9047942007 21 189643.1357616589 31 0.0 0 LINE 5 12BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528660.7678825191 20 189590.7707751939 30 0.0 11 528833.2171205858 21 189824.0458195359 31 0.0 0 LINE 5 12BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530606.7976766392 20 190323.4935651079 30 0.0 11 530953.6176210528 21 190051.2345594849 31 0.0 0 LINE 5 12BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530952.1102433072 20 189920.7174612524 30 0.0 11 530840.126610297 21 189582.7534186109 31 0.0 0 LINE 5 12BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531395.6742002643 20 190631.2880820697 30 0.0 11 531358.5835637108 21 190314.4144565366 31 0.0 0 LINE 5 12C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529420.8840551164 20 188885.5709871339 30 0.0 11 529215.7566812801 21 189003.180972715 31 0.0 0 LINE 5 12C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529578.2053426957 20 190618.865623553 30 0.0 11 529786.5781078201 21 190957.2416225101 31 0.0 0 LINE 5 12C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528306.4601697287 20 191394.6659840302 30 0.0 11 530681.24822964 21 190279.6287509912 31 0.0 0 LINE 5 12C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530786.8875049436 20 191256.1992820703 30 0.0 11 530934.3568216041 21 191452.1553284745 31 0.0 0 LINE 5 12C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530810.6600446865 20 191279.9374053675 30 0.0 11 530574.7165782317 21 191331.7965642098 31 0.0 0 LINE 5 12C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530611.9717645991 20 190853.0490328778 30 0.0 11 530785.5594019265 21 191588.3985637284 31 0.0 0 LINE 5 12C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530666.9963664804 20 191384.1600547587 30 0.0 11 530270.5504785207 21 191573.1426611555 31 0.0 0 LINE 5 12C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530686.9542703694 20 191450.7281334419 30 0.0 11 530624.4721558542 21 191267.1375468709 31 0.0 0 LINE 5 12C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530617.8696984619 20 191473.0825542882 30 0.0 11 530597.6531868602 21 191412.0338986045 31 0.0 0 LINE 5 12C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530624.5272835949 20 191460.5592202951 30 0.0 11 530271.9556868885 21 191656.2384653555 31 0.0 0 LINE 5 12CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530572.4341909653 20 191574.9456245721 30 0.0 11 530411.0970229937 21 191325.2440993296 31 0.0 0 LINE 5 12CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530423.6971041789 20 191320.9388758374 30 0.0 11 530215.7578632887 21 191438.3996939469 31 0.0 0 LINE 5 12CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530422.6754470898 20 191130.4008035777 30 0.0 11 530416.2354834049 21 191337.4404344914 31 0.0 0 LINE 5 12CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530498.5527046849 20 191173.3499155815 30 0.0 11 530415.0466431205 21 191191.1840806411 31 0.0 0 LINE 5 12CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530378.9596091123 20 191733.363890256 30 0.0 11 530216.4844141852 21 191435.3832489207 31 0.0 0 LINE 5 12CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530617.1020729691 20 191317.9331596048 30 0.0 11 530237.9790097414 21 191507.9356050581 31 0.0 0 LINE 5 12D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530170.4777954436 20 190974.1342686499 30 0.0 11 530242.845132544 21 191512.9330168268 31 0.0 0 LINE 5 12D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530263.0237728314 20 190999.9196945033 30 0.0 11 530168.6750936133 21 191069.8328868142 31 0.0 0 LINE 5 12D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530271.8171301251 20 191061.3825817094 30 0.0 11 530164.8331375071 21 191036.4822563365 31 0.0 0 LINE 5 12D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530311.2013704974 20 191247.264696152 30 0.0 11 530251.7666616241 21 191054.1980062689 31 0.0 0 LINE 5 12D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530515.3867995707 20 191103.5045270889 30 0.0 11 530201.3461047661 21 191220.4163499817 31 0.0 0 LINE 5 12D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530552.647799821 20 191189.3428744654 30 0.0 11 530497.6534652642 21 191081.0696612813 31 0.0 0 LINE 5 12D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530602.234263979 20 191167.9938381031 30 0.0 11 530550.5015750291 21 191189.0021647223 31 0.0 0 LINE 5 12D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531277.3814127393 20 190896.6993731198 30 0.0 11 530356.1764719148 21 191157.6130511465 31 0.0 0 LINE 5 12D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530349.5854939382 20 191168.9085712497 30 0.0 11 530343.0708208462 21 191145.5138366594 31 0.0 0 LINE 5 12D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530257.914889346 20 191335.4912681963 30 0.0 11 530213.295080578 21 191343.4417297378 31 0.0 0 LINE 5 12DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530272.2328318559 20 191341.5180590523 30 0.0 11 530249.3817584041 21 191333.969888762 31 0.0 0 LINE 5 12DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530294.2377954327 20 191401.7198153854 30 0.0 11 530267.6322056853 21 191334.9814833307 31 0.0 0 LINE 5 12DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530425.3702768167 20 191180.9357220638 30 0.0 11 530300.0284827732 21 190848.7561276125 31 0.0 0 LINE 5 12DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530624.3634740933 20 190868.5336985939 30 0.0 11 530426.1167230396 21 190820.3167508943 31 0.0 0 LINE 5 12DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530442.2420756388 20 190793.721376533 30 0.0 11 530433.7379562795 21 191138.6256526705 31 0.0 0 LINE 5 12DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530557.2083504603 20 191102.9471589445 30 0.0 11 530547.1130889521 21 191068.8872202327 31 0.0 0 LINE 5 12E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530372.3499657048 20 191004.6811445212 30 0.0 11 530280.8611844596 21 191023.1647347263 31 0.0 0 LINE 5 12E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530314.2554430935 20 191012.1938829203 30 0.0 11 530255.222864584 21 191071.0813766387 31 0.0 0 LINE 5 12E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530319.9218190236 20 191024.032936741 30 0.0 11 530242.384921647 21 191003.7307899842 31 0.0 0 LINE 5 12E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530226.7956803922 20 190889.9725558877 30 0.0 11 530249.9963712407 21 191013.8022231446 31 0.0 0 LINE 5 12E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530843.0219665133 20 190748.4988920565 30 0.0 11 530551.5815083543 21 190863.6118907793 31 0.0 0 LINE 5 12E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530515.5265816781 20 191374.4665034555 30 0.0 11 530489.2484192839 21 191335.4848652249 31 0.0 0 LINE 5 12E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530547.8822599742 20 191310.297500817 30 0.0 11 530488.4037290445 21 191337.1880569003 31 0.0 0 LINE 5 12E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530587.8929579744 20 191339.5329175635 30 0.0 11 530555.9304810591 21 191240.2286220699 31 0.0 0 LINE 5 12E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530704.5671822437 20 191213.3974429023 30 0.0 11 530411.8118187123 21 191272.1599178894 31 0.0 0 LINE 5 12E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530363.9397497025 20 191358.287867634 30 0.0 11 530333.8220195336 21 191296.3807914483 31 0.0 0 LINE 5 12EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530362.8699991715 20 191283.3361451236 30 0.0 11 530308.7435676297 21 191309.4685266677 31 0.0 0 LINE 5 12EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530360.9956112147 20 191291.7356111226 30 0.0 11 530330.6976633138 21 191227.1561231241 31 0.0 0 LINE 5 12EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530334.2797357945 20 191228.1501520307 30 0.0 11 530283.1270503726 21 191251.2800584046 31 0.0 0 LINE 5 12ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530316.5581169064 20 191314.0042365652 30 0.0 11 530282.8641361738 21 191244.2130948573 31 0.0 0 LINE 5 12EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530753.9676132364 20 190971.4177916275 30 0.0 11 530645.4712502283 21 191001.964636923 31 0.0 0 LINE 5 12EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530188.6951548543 20 191012.6301874295 30 0.0 11 529846.2858622457 21 190650.5201306966 31 0.0 0 LINE 5 12F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530200.2539482312 20 190944.8408733593 30 0.0 11 530035.3632543009 21 190788.3782138476 31 0.0 0 LINE 5 12F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530375.9343643 20 190881.1994272883 30 0.0 11 530309.3361880256 21 190725.0021784153 31 0.0 0 LINE 5 12F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530671.8834682779 20 190733.3985119153 30 0.0 11 530089.6356738072 21 190974.0623448668 31 0.0 0 LINE 5 12F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530209.82233717 20 190854.7673940329 30 0.0 11 530381.1014278488 21 190763.8114090294 31 0.0 0 LINE 5 12F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530176.738479037 20 190790.1310533407 30 0.0 11 530233.7825995969 21 190760.4390676936 31 0.0 0 LINE 5 12F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530180.983468939 20 190844.3458584129 30 0.0 11 530183.0202301594 21 190775.5482775925 31 0.0 0 LINE 5 12F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530190.1631347634 20 190794.7066355697 30 0.0 11 529953.5632261425 21 190579.7202960579 31 0.0 0 LINE 5 12F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530422.331433555 20 190705.13803774 30 0.0 11 530242.3648234194 21 190452.4459640357 31 0.0 0 LINE 5 12F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530685.8270084943 20 190990.6153300706 30 0.0 11 530685.8217173655 21 190990.6040765957 31 0.0 0 LINE 5 12F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530658.1253966024 20 190512.595404907 30 0.0 11 530294.1637362402 21 190689.0570376765 31 0.0 0 LINE 5 12FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530111.7936267947 20 190649.5595663267 30 0.0 11 530292.0673007933 21 190641.2155727311 31 0.0 0 LINE 5 12FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530326.2815046201 20 190695.0831776194 30 0.0 11 530290.2512147138 21 190640.653260687 31 0.0 0 LINE 5 12FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530446.9250291631 20 190834.3129376435 30 0.0 11 530364.6162123198 21 190614.4558055476 31 0.0 0 LINE 5 12FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529939.939415788 20 190809.8789550084 30 0.0 11 530130.9635013352 21 190639.1185579506 31 0.0 0 LINE 5 12FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529654.0128583817 20 191008.5990400711 30 0.0 11 529538.5254608057 21 191180.5570084886 31 0.0 0 LINE 5 12FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529909.9204973347 20 191073.5304972992 30 0.0 11 529577.0660346956 21 191424.229912995 31 0.0 0 LINE 5 1300 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530097.8222530831 20 190903.6018086659 30 0.0 11 529709.5386221093 21 191278.0391841883 31 0.0 0 LINE 5 1301 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529859.7970559477 20 190995.6823473421 30 0.0 11 529895.6832068345 21 191107.4934018215 31 0.0 0 LINE 5 1302 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529816.8157740735 20 191040.488809428 30 0.0 11 529918.2503592541 21 191082.6388486844 31 0.0 0 LINE 5 1303 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.4362978191 20 191168.5391179237 30 0.0 11 529837.294298447 21 191046.3428209456 31 0.0 0 LINE 5 1304 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529488.6195087556 20 190778.8154378799 30 0.0 11 529781.3394002914 21 191210.780711083 31 0.0 0 LINE 5 1305 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529690.9396844112 20 191082.5003184239 30 0.0 11 529709.8731834154 21 191067.2925182051 31 0.0 0 LINE 5 1306 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529622.3579484594 20 191048.0832998647 30 0.0 11 529979.350393128 21 190800.6693161047 31 0.0 0 LINE 5 1307 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529947.6250255865 20 190799.1961620026 30 0.0 11 530031.2524980849 21 190982.2829122324 31 0.0 0 LINE 5 1308 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529909.4806381238 20 190695.8884812792 30 0.0 11 529640.2297696372 21 191008.8308089954 31 0.0 0 LINE 5 1309 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529768.2020691272 20 190935.8054215372 30 0.0 11 529831.7520282783 21 191004.1665427424 31 0.0 0 LINE 5 130A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529811.0187018545 20 190975.7822993236 30 0.0 11 529824.6421644078 21 191058.0439763673 31 0.0 0 LINE 5 130B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529799.5121885463 20 190982.096660973 30 0.0 11 529874.3423080562 21 191010.812524739 31 0.0 0 LINE 5 130C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529993.9717421925 20 190894.018633101 30 0.0 11 529862.2862323207 21 191014.5567160643 31 0.0 0 LINE 5 130D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530063.611379089 20 191307.3573994773 30 0.0 11 530244.8025817625 21 191460.1788907737 31 0.0 0 LINE 5 130E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530040.5595935753 20 191391.4442571109 30 0.0 11 530112.0895504901 21 191344.8096666741 31 0.0 0 LINE 5 130F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530083.6719299731 20 191102.1464075275 30 0.0 11 530199.7744952403 21 191084.5474851844 31 0.0 0 LINE 5 1310 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530121.0518461871 20 191151.7221223488 30 0.0 11 530178.8362248517 21 191058.3060291823 31 0.0 0 LINE 5 1311 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530020.7508118557 20 191352.3139438574 30 0.0 11 530222.6566959106 21 191208.0085902876 31 0.0 0 LINE 5 1312 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529931.2589248137 20 191293.1742514133 30 0.0 11 530009.4340328605 21 191386.1049675863 31 0.0 0 LINE 5 1313 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529919.8842639817 20 191435.1441300177 30 0.0 11 529888.4329338768 21 191318.5313314026 31 0.0 0 LINE 5 1314 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529887.8264005807 20 191325.2400372301 30 0.0 11 529933.4263986319 21 191293.0179784648 31 0.0 0 LINE 5 1315 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529766.283442222 20 191482.1497039964 30 0.0 11 530129.7983159895 21 191279.3947547383 31 0.0 0 LINE 5 1316 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530097.5431574947 20 191344.9030318181 30 0.0 11 529941.6740523123 21 191030.1101691833 31 0.0 0 LINE 5 1317 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529869.9817725534 20 191099.9094151975 30 0.0 11 530061.6424893936 21 191321.0011059216 31 0.0 0 LINE 5 1318 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529949.2789497925 20 191383.3896314849 30 0.0 11 529932.2472777902 21 191352.2140660729 31 0.0 0 LINE 5 1319 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530009.9563679029 20 191183.0222615452 30 0.0 11 530087.5758418096 21 191131.1854264664 31 0.0 0 LINE 5 131A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530056.2488408661 20 191147.127669437 30 0.0 11 530139.6303230878 21 191146.7950067648 31 0.0 0 LINE 5 131B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530060.6477213065 20 191159.4937869528 30 0.0 11 530100.927754787 21 191090.1997286182 31 0.0 0 LINE 5 131C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530004.702835088 20 190953.4781887471 30 0.0 11 530102.7017201151 21 191102.6985676777 31 0.0 0 LINE 5 131D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529923.683773368 20 191565.7595233935 30 0.0 11 530171.786933398 21 191399.6163522243 31 0.0 0 LINE 5 131E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530467.8923355064 20 191673.3362207413 30 0.0 11 530355.9087024962 21 191335.3721780998 31 0.0 0 LINE 5 131F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 531840.7935770436 20 189057.792002755 30 0.0 11 531982.1822814013 21 189216.3451605004 31 0.0 0 LINE 5 1320 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 532397.1314996439 20 186862.2401610883 30 0.0 11 532751.6338472817 21 186400.5866240799 31 0.0 0 LINE 5 1321 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529390.5920680657 20 178053.3126901525 30 0.0 11 530115.1553102974 21 178218.3674452636 31 0.0 0 LINE 5 1322 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529588.7373599372 20 178091.3637877734 30 0.0 11 529220.8203963338 21 178791.6550297485 31 0.0 0 LINE 5 1323 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529522.027867812 20 178212.0012265017 30 0.0 11 529662.3119211489 21 178258.6711213384 31 0.0 0 LINE 5 1324 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529651.2157191435 20 178109.9595009088 30 0.0 11 529420.4224018896 21 178547.2455074355 31 0.0 0 LINE 5 1325 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529635.5138608472 20 178240.0261699392 30 0.0 11 529687.7454499261 21 178303.2160374569 31 0.0 0 LINE 5 1326 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529701.3864531909 20 178195.1249762844 30 0.0 11 529634.440434588 21 178252.0078302338 31 0.0 0 LINE 5 1327 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529682.8737538791 20 178199.4838608876 30 0.0 11 529876.420257985 21 178245.2441442418 31 0.0 0 LINE 5 1328 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529733.5857718822 20 178087.8633627716 30 0.0 11 529700.2622754637 21 178519.5446872525 31 0.0 0 LINE 5 1329 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529870.3293648365 20 178300.9853595905 30 0.0 11 529683.6765661495 21 178301.741337488 31 0.0 0 LINE 5 132A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529873.7351080664 20 178240.4707767044 30 0.0 11 529869.6943259762 21 178301.5468993824 31 0.0 0 LINE 5 132B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530166.1098490548 20 178294.9608130672 30 0.0 11 529869.2240375089 21 178280.6506399475 31 0.0 0 LINE 5 132C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530098.0406759726 20 178288.0142161451 30 0.0 11 530084.8929137669 21 178400.3749640314 31 0.0 0 LINE 5 132D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530166.28914748 20 178403.7599636211 30 0.0 11 529351.949710317 21 178348.293701919 31 0.0 0 LINE 5 132E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529633.3820592434 20 178437.1764218828 30 0.0 11 529512.4457275377 21 178859.3827355189 31 0.0 0 LINE 5 132F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529564.4324633867 20 178428.4827311594 30 0.0 11 529755.8193743748 21 178459.7967601896 31 0.0 0 LINE 5 1330 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529553.7906139416 20 178500.3099491722 30 0.0 11 529617.3392258458 21 178510.169950549 31 0.0 0 LINE 5 1331 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529540.4498922314 20 178447.5909756185 30 0.0 11 529564.4116247705 21 178512.1129943156 31 0.0 0 LINE 5 1332 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529565.0429286165 20 178491.6761349184 30 0.0 11 529430.2582499482 21 178871.7158540896 31 0.0 0 LINE 5 1333 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529359.7546940634 20 178518.4432037213 30 0.0 11 529733.7382635378 21 178679.8370821898 31 0.0 0 LINE 5 1334 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529735.9041441907 20 178666.6991235893 30 0.0 11 529654.3858264684 21 178891.1774868423 31 0.0 0 LINE 5 1335 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529923.9961336309 20 178636.2490944916 30 0.0 11 529720.8609436733 21 178676.7827410348 31 0.0 0 LINE 5 1336 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529869.1091454615 20 178568.5039620335 30 0.0 11 529865.3064953427 21 178653.8084731304 31 0.0 0 LINE 5 1337 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529297.2528540473 20 178610.462173554 30 0.0 11 529381.7643390703 21 178641.7655263754 31 0.0 0 LINE 5 1338 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529210.7412612053 20 178736.3848983364 30 0.0 11 529657.2409238578 21 178889.9628940308 31 0.0 0 LINE 5 1339 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529706.9376248931 20 178475.4520136958 30 0.0 11 529582.1354664721 21 178880.7415985645 31 0.0 0 LINE 5 133A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530059.7092555507 20 178862.7149028401 30 0.0 11 529576.4032417384 21 178876.7673218856 31 0.0 0 LINE 5 133B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530312.7701853247 20 178874.6729484941 30 0.0 11 529773.4183123891 21 178866.4825009502 31 0.0 0 LINE 5 133C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530079.0449972051 20 178772.167551013 30 0.0 11 530025.6681078049 21 178876.7640873191 31 0.0 0 LINE 5 133D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530016.9737908839 20 178773.6423330408 30 0.0 11 530059.1953704929 21 178875.0471608128 31 0.0 0 LINE 5 133E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529827.1402371451 20 178765.487534809 30 0.0 11 530027.3700867477 21 178792.2314815871 31 0.0 0 LINE 5 133F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529935.2167503272 20 178540.3694703332 30 0.0 11 529871.7571494588 21 178869.4026166622 31 0.0 0 LINE 5 1340 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529844.4046062384 20 178517.7916381525 30 0.0 11 529960.2714997501 21 178554.1554734086 31 0.0 0 LINE 5 1341 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529971.0478116974 20 178452.6277842837 30 0.0 11 529851.3161161499 21 178468.5039314089 31 0.0 0 LINE 5 1342 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529857.2739883265 20 178465.3609430782 30 0.0 11 529845.0949802163 21 178519.8521593871 31 0.0 0 LINE 5 1343 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529971.8629280645 20 178147.3501551373 30 0.0 11 529908.1362417926 21 178706.3282208272 31 0.0 0 LINE 5 1344 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529898.0838949129 20 178714.6936309961 30 0.0 11 529922.23314985 21 178717.2564532717 31 0.0 0 LINE 5 1345 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529748.9219505447 20 178832.6088930304 30 0.0 11 529748.4472840071 21 178877.9289974535 31 0.0 0 LINE 5 1346 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529740.6139858995 20 178819.4824537115 30 0.0 11 529751.8312643767 21 178840.7737452691 31 0.0 0 LINE 5 1347 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529677.6053795027 20 178807.7187209904 30 0.0 11 529747.8204193533 21 178822.9407625761 31 0.0 0 LINE 5 1348 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529873.7097927802 20 178641.9345159805 30 0.0 11 530301.3177057517 21 178718.1497223015 31 0.0 0 LINE 5 1349 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530279.8565997225 20 178694.7383990443 30 0.0 11 530210.0881816244 21 178883.5416831849 31 0.0 0 LINE 5 134A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530148.9711179213 20 178394.0948102993 30 0.0 11 530284.3736267778 21 178730.6222615631 31 0.0 0 LINE 5 134B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530308.4283792124 20 178592.96658897 30 0.0 11 529914.0577438836 21 178626.6963115775 31 0.0 0 LINE 5 134C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529928.8617689076 20 178499.0298163773 30 0.0 11 529964.1210211301 21 178503.3632748896 31 0.0 0 LINE 5 134D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530056.2992316162 20 178665.127754665 30 0.0 11 530053.1740083323 21 178758.4126579452 31 0.0 0 LINE 5 134E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530058.4809445885 20 178723.6653914825 30 0.0 11 530010.1477911528 21 178791.6101375701 31 0.0 0 LINE 5 134F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530045.868844705 20 178720.0313925719 30 0.0 11 530078.6936574002 21 178793.1523833286 31 0.0 0 LINE 5 1350 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530245.8754076924 20 178794.6613581359 30 0.0 11 530067.5037911571 21 178787.3081704402 31 0.0 0 LINE 5 1351 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530273.0675218956 20 178208.0096468544 30 0.0 11 530096.6192585914 21 178215.9086817285 31 0.0 0 LINE 5 1352 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530158.6363406193 20 178201.8413428505 30 0.0 11 530165.8416213736 21 178465.0654016896 31 0.0 0 LINE 5 1353 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529667.9501122793 20 178584.9671873393 30 0.0 11 529710.7353059648 21 178604.4489002836 31 0.0 0 LINE 5 1354 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529725.8966288471 20 178542.4612814524 30 0.0 11 529709.1949448264 21 178605.5631942513 31 0.0 0 LINE 5 1355 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529690.4566796745 20 178507.8263922591 30 0.0 11 529793.675196943 21 178522.9551968021 31 0.0 0 LINE 5 1356 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529795.5983844062 20 178371.9284360456 30 0.0 11 529785.9759576364 21 178670.3679445664 31 0.0 0 LINE 5 1357 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529708.9335792827 20 178731.8027120526 30 0.0 11 529774.9635139324 21 178751.2863329311 31 0.0 0 LINE 5 1358 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529783.0333527766 20 178720.4833197699 30 0.0 11 529766.195812011 21 178778.1814061991 31 0.0 0 LINE 5 1359 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529775.0586125864 20 178723.7187298189 30 0.0 11 529843.7540392793 21 178742.9388824889 31 0.0 0 LINE 5 135A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529842.1822544748 20 178739.5700801422 30 0.0 11 529827.8150230222 21 178793.839523249 31 0.0 0 LINE 5 135B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529760.4321706216 20 178771.2229377899 30 0.0 11 529834.828413398 21 178792.9320800863 31 0.0 0 LINE 5 135C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530026.101377302 20 178283.255303252 30 0.0 11 530013.8863797965 21 178395.3060256032 31 0.0 0 LINE 5 135D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529473.7643035521 20 178564.8684743813 30 0.0 11 529371.3688412569 21 178808.8539638275 31 0.0 0 LINE 5 135E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529032.4566797877 20 178870.0605803373 30 0.0 11 529172.7407331247 21 178916.7304751739 31 0.0 0 LINE 5 135F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529161.6445311194 20 178768.0188547444 30 0.0 11 528930.8512138653 21 179205.304861271 31 0.0 0 LINE 5 1360 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.9426728229 20 178898.0855237747 30 0.0 11 529198.1742619019 21 178961.2753912924 31 0.0 0 LINE 5 1361 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529211.8152651667 20 178853.1843301198 30 0.0 11 529144.8692465639 21 178910.0671840692 31 0.0 0 LINE 5 1362 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529195.0257614894 20 178858.1359249845 30 0.0 11 529388.5722655955 21 178903.8962083386 31 0.0 0 LINE 5 1363 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529250.5651757271 20 178661.0646291282 30 0.0 11 529210.6910874394 21 179177.6040410879 31 0.0 0 LINE 5 1364 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529380.7581768124 20 178959.044713426 30 0.0 11 529194.1053781251 21 178959.8006913236 31 0.0 0 LINE 5 1365 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529384.1639200421 20 178898.53013054 30 0.0 11 529380.123137952 21 178959.6062532179 31 0.0 0 LINE 5 1366 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.5386610307 20 178953.0201669028 30 0.0 11 529379.6528494846 21 178938.7099937831 31 0.0 0 LINE 5 1367 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529608.4694879482 20 178946.0735699806 30 0.0 11 529595.3217257426 21 179058.4343178669 31 0.0 0 LINE 5 1368 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.7179594558 20 179061.8193174565 30 0.0 11 528922.8004795738 21 179012.0193788653 31 0.0 0 LINE 5 1369 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529143.8108712193 20 179095.2357757184 30 0.0 11 528987.872384487 21 179724.1392376596 31 0.0 0 LINE 5 136A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529074.8612753623 20 179086.5420849948 30 0.0 11 529266.2481863507 21 179117.8561140251 31 0.0 0 LINE 5 136B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529064.2194259175 20 179158.3693030075 30 0.0 11 529127.7680378215 21 179168.2293043844 31 0.0 0 LINE 5 136C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529050.8787042071 20 179105.6503294541 30 0.0 11 529074.8404367462 21 179170.1723481511 31 0.0 0 LINE 5 136D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529075.4717405924 20 179149.735488754 30 0.0 11 529028.4832144465 21 179282.2246296349 31 0.0 0 LINE 5 136E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528870.1835060391 20 179176.5025575568 30 0.0 11 529244.1670755135 21 179337.8964360254 31 0.0 0 LINE 5 136F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529246.3329561665 20 179324.7584774249 30 0.0 11 529164.8146384443 21 179549.2368406779 31 0.0 0 LINE 5 1370 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529434.4249456065 20 179294.3084483272 30 0.0 11 529231.2897556491 21 179334.8420948704 31 0.0 0 LINE 5 1371 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529379.5379574373 20 179226.5633158691 30 0.0 11 529375.7353073186 21 179311.8678269659 31 0.0 0 LINE 5 1372 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528804.6219794623 20 179283.2325338339 30 0.0 11 528889.1334644851 21 179314.5358866552 31 0.0 0 LINE 5 1373 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529217.3664368688 20 179133.5113675314 30 0.0 11 529092.5642784479 21 179538.8009524001 31 0.0 0 LINE 5 1374 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529589.4738091809 20 179430.2269048485 30 0.0 11 529536.0969197806 21 179534.8234411546 31 0.0 0 LINE 5 1375 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529527.4026028597 20 179431.7016868763 30 0.0 11 529569.6241824687 21 179533.1065146484 31 0.0 0 LINE 5 1376 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529337.5690491209 20 179423.5468886444 30 0.0 11 529537.7988987233 21 179450.2908354228 31 0.0 0 LINE 5 1377 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529445.6455623029 20 179198.4288241688 30 0.0 11 529373.454971783 21 179620.5635239094 31 0.0 0 LINE 5 1378 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529354.8334182141 20 179175.850991988 30 0.0 11 529470.7003117257 21 179212.2148272441 31 0.0 0 LINE 5 1379 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529481.4766236733 20 179110.6871381193 30 0.0 11 529361.7449281256 21 179126.5632852444 31 0.0 0 LINE 5 137A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529367.7028003022 20 179123.4202969139 30 0.0 11 529355.523792192 21 179177.9115132226 31 0.0 0 LINE 5 137B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529482.2917400402 20 178805.4095089728 30 0.0 11 529418.5650537684 21 179364.3875746627 31 0.0 0 LINE 5 137C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529408.5127068887 20 179372.7529848317 30 0.0 11 529432.6619618259 21 179375.3158071073 31 0.0 0 LINE 5 137D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529259.3507625205 20 179490.6682468659 30 0.0 11 529255.8735480284 21 179568.0055555123 31 0.0 0 LINE 5 137E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529251.0427978754 20 179477.541807547 30 0.0 11 529262.2600763525 21 179498.8330991046 31 0.0 0 LINE 5 137F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529188.0341914784 20 179465.778074826 30 0.0 11 529258.249231329 21 179481.0001164117 31 0.0 0 LINE 5 1380 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529384.1386047561 20 179299.9938698159 30 0.0 11 529732.453511002 21 179368.7730410141 31 0.0 0 LINE 5 1381 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529659.3999298971 20 179052.1541641347 30 0.0 11 529739.685557499 21 179239.7197962464 31 0.0 0 LINE 5 1382 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529763.253681698 20 179219.4248595483 30 0.0 11 529424.4865558593 21 179284.7556654132 31 0.0 0 LINE 5 1383 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529439.2905808833 20 179157.0891702127 30 0.0 11 529474.549833106 21 179161.4226287252 31 0.0 0 LINE 5 1384 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529566.728043592 20 179323.1871085005 30 0.0 11 529563.6028203082 21 179416.4720117807 31 0.0 0 LINE 5 1385 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529568.9097565642 20 179381.7247453179 30 0.0 11 529520.5766031286 21 179449.6694914057 31 0.0 0 LINE 5 1386 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529556.2976566809 20 179378.0907464075 30 0.0 11 529589.1224693758 21 179451.2117371642 31 0.0 0 LINE 5 1387 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529703.8933669607 20 179447.8056638777 30 0.0 11 529577.9326031328 21 179445.3675242758 31 0.0 0 LINE 5 1388 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529651.9679774769 20 178854.6875987086 30 0.0 11 529676.2704333494 21 179123.124755525 31 0.0 0 LINE 5 1389 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529178.378924255 20 179243.0265411749 30 0.0 11 529221.1641179405 21 179262.5082541191 31 0.0 0 LINE 5 138A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529236.3254408228 20 179200.5206352878 30 0.0 11 529219.623756802 21 179263.6225480869 31 0.0 0 LINE 5 138B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529200.8854916501 20 179165.8857460946 30 0.0 11 529304.1040089189 21 179181.0145506376 31 0.0 0 LINE 5 138C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529306.027196382 20 179029.9877898812 30 0.0 11 529296.4047696122 21 179328.427298402 31 0.0 0 LINE 5 138D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529219.3623912584 20 179389.8620658881 30 0.0 11 529285.392325908 21 179409.3456867667 31 0.0 0 LINE 5 138E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529293.4621647522 20 179378.5426736056 30 0.0 11 529276.6246239869 21 179436.2407600347 31 0.0 0 LINE 5 138F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529285.4874245623 20 179381.7780836545 30 0.0 11 529354.1828512551 21 179400.9982363247 31 0.0 0 LINE 5 1390 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529352.6110664505 20 179397.6294339777 30 0.0 11 529338.243834998 21 179451.8988770846 31 0.0 0 LINE 5 1391 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529270.8609825975 20 179429.2822916254 30 0.0 11 529345.2572253737 21 179450.9914339217 31 0.0 0 LINE 5 1392 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529536.5301892779 20 178941.3146570876 30 0.0 11 529524.3151917721 21 179053.3653794388 31 0.0 0 LINE 5 1393 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528984.1931155279 20 179222.9278282168 30 0.0 11 528881.7976532325 21 179466.913317663 31 0.0 0 LINE 5 1394 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528256.2762777142 20 179214.9213572008 30 0.0 11 530103.7181598913 21 179877.1135497176 31 0.0 0 LINE 5 1395 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529654.1600247581 20 179483.0418736856 30 0.0 11 529835.6988509518 21 179619.8379238862 31 0.0 0 LINE 5 1396 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529687.9234379178 20 179299.2651771761 30 0.0 11 529852.9724886179 21 179339.161398821 31 0.0 0 LINE 5 1397 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529812.9763927825 20 178860.6350568236 30 0.0 11 529635.628069068 21 179631.6345729913 31 0.0 0 LINE 5 1398 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529760.9940699366 20 179392.0524657283 30 0.0 11 530158.5156557565 21 179578.7617488612 31 0.0 0 LINE 5 1399 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529741.4176915706 20 179458.7337407407 30 0.0 11 529802.8474606397 21 179274.78836411 31 0.0 0 LINE 5 139A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529810.6291420638 20 179480.6921862162 30 0.0 11 529830.4957305616 21 179419.5287628033 31 0.0 0 LINE 5 139B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529756.457483715 20 179485.4562664032 30 0.0 11 529823.9746865969 21 179472.0890363976 31 0.0 0 LINE 5 139C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529803.899951935 20 179468.2071818381 30 0.0 11 530157.5863137912 21 179661.8642374505 31 0.0 0 LINE 5 139D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529794.8493942628 20 179677.7989024762 30 0.0 11 530016.551838801 21 179331.6720833669 31 0.0 0 LINE 5 139E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530003.9273105937 20 179327.439084107 30 0.0 11 530212.5357747149 21 179443.7072241541 31 0.0 0 LINE 5 139F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530003.8578455762 20 179136.8982854884 30 0.0 11 530011.4833042558 21 179343.8976436545 31 0.0 0 LINE 5 13A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529928.2277777098 20 179180.2812000585 30 0.0 11 530011.8345964161 21 179197.6368800278 31 0.0 0 LINE 5 13A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529868.044136958 20 180083.1249647489 30 0.0 11 530211.7919622313 21 179440.6949891383 31 0.0 0 LINE 5 13A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529810.5083008496 20 179325.540939631 30 0.0 11 530190.7131860163 21 179513.3692432622 31 0.0 0 LINE 5 13A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530249.0655645315 20 179039.0310878337 30 0.0 11 530185.8757603917 21 179518.3944386658 31 0.0 0 LINE 5 13A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530294.6453275093 20 178828.2357818487 30 0.0 11 530207.136287022 21 179322.2600316574 31 0.0 0 LINE 5 13A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530162.7597095563 20 179005.505079643 30 0.0 11 530257.5071957045 21 179074.8768433358 31 0.0 0 LINE 5 13A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530154.3184601428 20 179067.0173137474 30 0.0 11 530261.1581083423 21 179041.5047589406 31 0.0 0 LINE 5 13A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530115.9993088026 20 179253.1219120244 30 0.0 11 530174.3274578325 21 179059.7180382476 31 0.0 0 LINE 5 13A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529943.3485241449 20 179121.6943172797 30 0.0 11 530225.6990278078 21 179225.6449261795 31 0.0 0 LINE 5 13A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529919.992444411 20 179033.5303585037 30 0.0 11 529909.9177026341 21 179154.5508737263 31 0.0 0 LINE 5 13AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529811.8359642482 20 179126.1964533755 30 0.0 11 529871.7432927308 21 179021.321084674 31 0.0 0 LINE 5 13AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529866.583463484 20 179025.6513016039 30 0.0 11 529921.639794042 21 179034.9476104859 31 0.0 0 LINE 5 13AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529528.8460521422 20 179011.6896635413 30 0.0 11 529528.8580247461 21 179011.6930241212 31 0.0 0 LINE 5 13AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529669.7627948629 20 179051.2434616328 30 0.0 11 530070.5115597969 21 179163.7292843079 31 0.0 0 LINE 5 13AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530077.1671128554 20 179174.9868763492 30 0.0 11 530083.5477105241 21 179151.5552194418 31 0.0 0 LINE 5 13AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530169.790140668 20 179341.0418955059 30 0.0 11 530214.4547457032 21 179348.7367139115 31 0.0 0 LINE 5 13B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530155.5069449908 20 179347.150578423 30 0.0 11 530178.3144196068 21 179339.4716765309 31 0.0 0 LINE 5 13B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530133.8470841208 20 179407.477357839 30 0.0 11 530160.0700644021 21 179340.5877646542 31 0.0 0 LINE 5 13B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530001.4524453501 20 179187.4478071817 30 0.0 11 530112.8405056052 21 178854.307559915 31 0.0 0 LINE 5 13B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530012.787356849 20 178853.2658569171 30 0.0 11 529992.8426168967 21 179145.18634855 31 0.0 0 LINE 5 13B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529869.1699363119 20 179110.215485955 30 0.0 11 529879.0699900083 21 179076.0982957604 31 0.0 0 LINE 5 13B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530053.4625753887 20 179010.8925017714 30 0.0 11 530145.0557017851 21 179028.851883651 31 0.0 0 LINE 5 13B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530111.5991667361 20 179018.0724420342 30 0.0 11 530170.9679931944 21 179076.6209235426 31 0.0 0 LINE 5 13B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530106.0006793766 20 179029.9437499166 30 0.0 11 530183.4200463617 21 179009.1979254373 31 0.0 0 LINE 5 13B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530211.5666022765 20 178844.3956620246 30 0.0 11 530175.8663950519 21 179019.3127799945 31 0.0 0 LINE 5 13B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529912.4058616428 20 179381.4916903172 30 0.0 11 529938.4603670565 21 179342.3602108463 31 0.0 0 LINE 5 13BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529879.6832537396 20 179317.5090227454 30 0.0 11 529939.3147966758 21 179344.0585375256 31 0.0 0 LINE 5 13BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529839.8406267025 20 179346.9730791118 30 0.0 11 529871.2339191949 21 179247.487380539 31 0.0 0 LINE 5 13BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529722.446007878 20 179221.5078008555 30 0.0 11 530015.5330712783 21 179278.5928655428 31 0.0 0 LINE 5 13BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530063.8975621379 20 179364.4452664547 30 0.0 11 530093.660291165 21 179302.3667378539 31 0.0 0 LINE 5 13BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530064.538088384 20 179289.4886470033 30 0.0 11 530118.8132780433 21 179315.310648166 31 0.0 0 LINE 5 13BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530066.4605446687 20 179297.8772417078 30 0.0 11 530096.3881850598 21 179233.1253131048 31 0.0 0 LINE 5 13C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530092.811863561 20 179234.139838246 30 0.0 11 530144.0961623568 21 179256.9764424545 31 0.0 0 LINE 5 13C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530111.0248303785 20 179319.8910332636 30 0.0 11 530144.3186036829 21 179249.9080892157 31 0.0 0 LINE 5 13C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529861.6016424258 20 179569.9884220753 30 0.0 11 530086.1388329739 21 179709.9769923934 31 0.0 0 LINE 5 13C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529622.5161699437 20 178175.7189232008 30 0.0 11 529077.4038483118 21 177670.6570250304 31 0.0 0 LINE 5 13C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529774.3187212543 20 177482.138466658 30 0.0 11 528687.2778214917 21 179514.0567645756 31 0.0 0 LINE 5 13C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529417.3393448741 20 178156.7481172629 30 0.0 11 529299.651861507 21 178067.2643144636 31 0.0 0 LINE 5 13C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529428.6886676548 20 177992.5128970265 30 0.0 11 529197.8953504009 21 178429.7989035533 31 0.0 0 LINE 5 13C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529330.1661889128 20 178078.8680238525 30 0.0 11 529248.5245953539 21 178071.4015350011 31 0.0 0 LINE 5 13C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529330.0669757164 20 177999.1478521863 30 0.0 11 529320.8798790198 21 178086.5150413052 31 0.0 0 LINE 5 13C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529336.9143225266 20 178016.8914074236 30 0.0 11 529189.9238064542 21 177882.9211085918 31 0.0 0 LINE 5 13CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529400.4528063577 20 177912.0405350285 30 0.0 11 529062.8618736286 21 178183.1338463775 31 0.0 0 LINE 5 13CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529147.3409759589 20 177919.4023998922 30 0.0 11 529252.0380194656 21 178073.9286689897 31 0.0 0 LINE 5 13CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529195.3798063321 20 177882.4445238005 30 0.0 11 529147.2356998853 21 177920.2435409268 31 0.0 0 LINE 5 13CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528985.4169776725 20 177671.8079557215 30 0.0 11 529164.7529224974 21 177908.8408332845 31 0.0 0 LINE 5 13CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529029.5609383942 20 177724.08585033 30 0.0 11 528944.2152067236 21 177798.3415396893 31 0.0 0 LINE 5 13CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528895.4917239208 20 177733.0512087936 30 0.0 11 529395.5462928345 21 178370.1010164841 31 0.0 0 LINE 5 13D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529168.6027359841 20 178191.8725241933 30 0.0 11 528888.2709667337 21 178529.9521993433 31 0.0 0 LINE 5 13D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529214.6858789368 20 178243.8914723069 30 0.0 11 529080.8407019511 21 178103.5526440751 31 0.0 0 LINE 5 13D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529161.3904520156 20 178293.2067404935 30 0.0 11 529117.3919810326 21 178246.304925462 31 0.0 0 LINE 5 13D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529212.4426651124 20 178274.4734394976 30 0.0 11 529145.6528736322 21 178291.0980982021 31 0.0 0 LINE 5 13D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529162.1692304324 20 178279.0451431864 30 0.0 11 528924.464112137 21 178604.7649222723 31 0.0 0 LINE 5 13D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529255.9069136356 20 178463.6338263879 30 0.0 11 528911.6359587691 21 178245.9432113415 31 0.0 0 LINE 5 13D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528921.2604722176 20 178236.7418127482 30 0.0 11 528781.9298895611 21 178430.7076871426 31 0.0 0 LINE 5 13D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528840.2666205454 20 178064.2721146709 30 0.0 11 528921.423797634 21 178254.8512176915 31 0.0 0 LINE 5 13D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528927.1673621965 20 178071.3605236999 30 0.0 11 528858.8860398547 21 178122.6341112539 31 0.0 0 LINE 5 13D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529169.5950389337 20 178629.8001218609 30 0.0 11 529096.0644715597 21 178577.691133574 31 0.0 0 LINE 5 13DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529160.0579374052 20 178709.6349629289 30 0.0 11 528781.3216274457 21 178427.6651825823 31 0.0 0 LINE 5 13DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529095.4979343949 20 178152.7428659879 30 0.0 11 528831.3138803026 21 178484.4686743191 31 0.0 0 LINE 5 13DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528628.0581488629 20 178204.8741762493 30 0.0 11 528837.8295044756 21 178486.9586376026 31 0.0 0 LINE 5 13DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528424.0543547561 20 177877.8356717893 30 0.0 11 528562.8268120758 21 178074.4044123051 31 0.0 0 LINE 5 13DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529216.8899173546 20 177748.886168231 30 0.0 11 528791.3587558008 21 178116.9089922682 31 0.0 0 LINE 5 13DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528790.12447374 20 178129.9284512769 30 0.0 11 528774.3821003199 21 178111.4370410781 31 0.0 0 LINE 5 13E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528776.9406634209 20 178319.6110330121 30 0.0 11 528726.5995712288 21 178356.5059315515 31 0.0 0 LINE 5 13E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528792.4656647689 20 178319.063293216 30 0.0 11 528768.558181954 21 178321.8162367464 31 0.0 0 LINE 5 13E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528837.7311428057 20 178364.4450779506 30 0.0 11 528785.5441805669 21 178315.0650886479 31 0.0 0 LINE 5 13E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528755.2984108906 20 177649.3990332462 30 0.0 11 528534.7752388648 21 177705.6368993211 31 0.0 0 LINE 5 13E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528913.2431451212 20 177741.8952113882 30 0.0 11 528727.5188711966 21 177633.1306766926 31 0.0 0 LINE 5 13E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528996.851259631 20 177534.4409062467 30 0.0 11 529089.8929912046 21 177684.5729166937 31 0.0 0 LINE 5 13E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529066.5130080652 20 177625.4342248347 30 0.0 11 528845.1307561178 21 177768.0130442476 31 0.0 0 LINE 5 13E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529027.0818980847 20 178246.7260845622 30 0.0 11 528986.8558042628 21 178222.3956239463 31 0.0 0 LINE 5 13E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529029.4775335915 20 178174.901215971 30 0.0 11 528986.8050162779 21 178224.2960933789 31 0.0 0 LINE 5 13E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529078.0693745433 20 178184.6171070637 30 0.0 11 529007.3367636004 21 178107.936987194 31 0.0 0 LINE 5 13EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529130.9385857497 20 178021.1304743279 30 0.0 11 528889.9778635624 21 178197.4729300951 31 0.0 0 LINE 5 13EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528882.7297250409 20 178295.7441018924 30 0.0 11 528829.3859203152 21 178252.2239657511 31 0.0 0 LINE 5 13EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528850.2632399967 20 178228.1805583032 30 0.0 11 528812.1287559493 21 178274.6384218255 31 0.0 0 LINE 5 13ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528852.0919470814 20 178236.5900879977 30 0.0 11 528797.4616232942 21 178190.7206685541 31 0.0 0 LINE 5 13EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528801.1297903722 20 178190.1174380736 30 0.0 11 528764.4320756943 21 178232.6011706328 31 0.0 0 LINE 5 13EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528821.1258424423 20 178275.4704550611 30 0.0 11 528761.2238634208 21 178226.2989113819 31 0.0 0 LINE 5 13F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529090.8056720976 20 178811.7223970167 30 0.0 11 528921.4179963483 21 178657.3388480305 31 0.0 0 LINE 5 13F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529053.9482432962 20 178755.0734565325 30 0.0 11 528795.8177370931 21 178958.6398040954 31 0.0 0 LINE 5 13F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528880.2968394233 20 178694.9083576101 30 0.0 11 528984.9938829302 21 178849.4346267077 31 0.0 0 LINE 5 13F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528928.3356697966 20 178657.9504815182 30 0.0 11 528880.1915633499 21 178695.7494986447 31 0.0 0 LINE 5 13F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528718.372841137 20 178447.3139134394 30 0.0 11 528897.7087859617 21 178684.3467910024 31 0.0 0 LINE 5 13F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528695.6708666394 20 178589.6934914857 30 0.0 11 529094.9695538866 21 179102.887760648 31 0.0 0 LINE 5 13F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528901.5585994485 20 178967.3784819112 30 0.0 11 528732.141915289 21 179171.6947379631 31 0.0 0 LINE 5 13F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528947.6417424012 20 179019.3974300246 30 0.0 11 528813.7965654157 21 178879.0586017929 31 0.0 0 LINE 5 13F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528894.34631548 20 179068.7126982114 30 0.0 11 528850.347844497 21 179021.8108831797 31 0.0 0 LINE 5 13F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528945.3985285767 20 179049.9793972156 30 0.0 11 528878.6087370967 21 179066.6040559201 31 0.0 0 LINE 5 13FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528895.1250938969 20 179054.5511009042 30 0.0 11 528657.4199756015 21 179380.27087999 31 0.0 0 LINE 5 13FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528895.9212925059 20 179180.2384345977 30 0.0 11 528644.5918222334 21 179021.4491690592 31 0.0 0 LINE 5 13FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528654.216335682 20 179012.2477704661 30 0.0 11 528514.8857530255 21 179206.2136448606 31 0.0 0 LINE 5 13FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528586.5761248556 20 178871.1360494124 30 0.0 11 528654.3796610985 21 179030.3571754095 31 0.0 0 LINE 5 13FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528835.808251877 20 178730.7567791569 30 0.0 11 528591.8419033192 21 178898.1400689717 31 0.0 0 LINE 5 13FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528828.4537978593 20 178928.2488237058 30 0.0 11 528564.269743767 21 179259.9746320368 31 0.0 0 LINE 5 1400 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528269.2197572814 20 178811.8149971797 30 0.0 11 528562.3417837797 21 179027.729923469 31 0.0 0 LINE 5 1401 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528373.5205664697 20 178788.4641264325 30 0.0 11 528317.2847204717 21 178891.5517462234 31 0.0 0 LINE 5 1402 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528407.3274474087 20 178840.5419954112 30 0.0 11 528299.7840299943 21 178862.902993846 31 0.0 0 LINE 5 1403 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528949.8457808189 20 178524.3921259489 30 0.0 11 528712.1583839063 21 178736.7821449431 31 0.0 0 LINE 5 1404 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528735.5919425773 20 178724.2733405178 30 0.0 11 528343.5785116573 21 178635.7446258223 31 0.0 0 LINE 5 1405 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528456.8048605814 20 178639.042180561 30 0.0 11 528418.2993716642 21 178801.3636480728 31 0.0 0 LINE 5 1406 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528425.1672519241 20 178778.0737645175 30 0.0 11 528396.3449656503 21 178856.3160680103 31 0.0 0 LINE 5 1407 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528435.2839998973 20 178786.435727325 30 0.0 11 528356.3938325171 21 178800.5951449837 31 0.0 0 LINE 5 1408 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528294.4449571226 20 178703.9188960649 30 0.0 11 528367.5328099538 21 178806.5357773142 31 0.0 0 LINE 5 1409 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528813.4200762677 20 178412.1139766217 30 0.0 11 528683.1105900724 21 178484.8759271629 31 0.0 0 LINE 5 140A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528760.037761549 20 179022.23204228 30 0.0 11 528719.8116677272 21 178997.9015816641 31 0.0 0 LINE 5 140B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528762.4333970562 20 178950.4071736888 30 0.0 11 528719.7608797423 21 178999.8020510967 31 0.0 0 LINE 5 140C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528811.0252380077 20 178960.1230647815 30 0.0 11 528740.292627065 21 178883.4429449118 31 0.0 0 LINE 5 140D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528863.8944492142 20 178796.6364320458 30 0.0 11 528622.9337270268 21 178972.978887813 31 0.0 0 LINE 5 140E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528615.6855885053 20 179071.2500596103 30 0.0 11 528562.3417837797 21 179027.729923469 31 0.0 0 LINE 5 140F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528604.542523008 20 178870.2673164959 30 0.0 11 528545.0846194137 21 179050.1443795434 31 0.0 0 LINE 5 1410 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528807.0383873775 20 178556.2992887536 30 0.0 11 528721.42228723 21 178629.6099560472 31 0.0 0 LINE 5 1411 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528311.4140469933 20 178831.2318750209 30 0.0 11 527764.9983652827 21 178652.4227521558 31 0.0 0 LINE 5 1412 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528293.4167632091 20 178764.8609884605 30 0.0 11 528078.0430157141 21 178692.1722434146 31 0.0 0 LINE 5 1413 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528426.0905374633 20 178633.2877697826 30 0.0 11 528300.0214083799 21 178519.5359683435 31 0.0 0 LINE 5 1414 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528503.0450711533 20 178515.8978525081 30 0.0 11 527848.7885761961 21 179224.2979558424 31 0.0 0 LINE 5 1415 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528308.2547575839 20 178625.3173770244 30 0.0 11 527929.8019000886 21 178402.4784166646 31 0.0 0 LINE 5 1416 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528264.2492173824 20 178679.1052888522 30 0.0 11 528381.4511659365 21 178524.5956730775 31 0.0 0 LINE 5 1417 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528207.0669986657 20 178634.3549584659 30 0.0 11 528246.3532710626 21 178583.4409672331 31 0.0 0 LINE 5 1418 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528233.7008313366 20 178681.767024288 30 0.0 11 528206.6393295455 21 178618.4825029276 31 0.0 0 LINE 5 1419 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528221.171590992 20 178632.8657273165 30 0.0 11 527861.7172574328 21 178450.1372953824 31 0.0 0 LINE 5 141A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528053.8908279912 20 178754.8365498442 30 0.0 11 528213.902859453 21 178380.2596631688 31 0.0 0 LINE 5 141B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528224.5211522193 20 178388.2938933077 30 0.0 11 528010.8207720457 21 178281.6734487079 31 0.0 0 LINE 5 141C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528381.8699628479 20 178280.8362153252 30 0.0 11 528206.6694766406 21 178391.3426474184 31 0.0 0 LINE 5 141D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528388.7284378934 20 178367.7554063139 30 0.0 11 528327.2234748795 21 178308.5231576142 31 0.0 0 LINE 5 141E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527795.7539910907 20 178699.4383652264 30 0.0 11 528013.7273650271 21 178280.5878456312 31 0.0 0 LINE 5 141F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528335.2273462379 20 178546.9086936534 30 0.0 11 527965.6217953812 21 178338.9977436644 31 0.0 0 LINE 5 1420 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528324.307153484 20 178023.1710512262 30 0.0 11 527964.202594872 21 178345.8270295297 31 0.0 0 LINE 5 1421 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528451.1721830445 20 177866.9365657112 30 0.0 11 528114.1337485903 21 178217.6031442749 31 0.0 0 LINE 5 1422 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528400.6852306725 20 178075.5073020777 30 0.0 11 528289.9497653272 21 178036.4280947665 31 0.0 0 LINE 5 1423 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528354.6640913282 20 178117.1854062772 30 0.0 11 528315.4415328623 21 178014.5833020709 31 0.0 0 LINE 5 1424 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528222.6390442239 20 178253.8333692926 30 0.0 11 528349.4000127607 21 178096.5473615973 31 0.0 0 LINE 5 1425 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528428.5654308189 20 178322.2134059058 30 0.0 11 528183.4244803492 21 178147.7615489016 31 0.0 0 LINE 5 1426 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528498.0472897094 20 178245.8844032025 30 0.0 11 528785.7765094022 21 178228.4478699931 31 0.0 0 LINE 5 1427 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528753.2729735434 20 178602.3532546211 30 0.0 11 528753.2634433724 21 178602.3452663433 31 0.0 0 LINE 5 1428 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528526.2577362868 20 178397.1155255769 30 0.0 11 528322.1082209895 21 178240.946939484 31 0.0 0 LINE 5 1429 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528309.0585253266 20 178241.8043823055 30 0.0 11 528324.8032623659 21 178223.3149845974 31 0.0 0 LINE 5 142A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528119.700557502 20 178259.033853847 30 0.0 11 528088.1451886887 21 178226.5008571775 31 0.0 0 LINE 5 142B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528122.7167284986 20 178274.2728957545 30 0.0 11 528116.1869921529 21 178251.1102323525 31 0.0 0 LINE 5 142C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528085.1330619262 20 178326.1953176414 30 0.0 11 528125.5601604262 21 178266.8024554597 31 0.0 0 LINE 5 142D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528341.4937854892 20 178311.3453024235 30 0.0 11 528553.6807481992 21 178031.4052781823 31 0.0 0 LINE 5 142E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528537.3680729672 20 178174.4241490659 30 0.0 11 528381.2428563006 21 178294.6069810829 31 0.0 0 LINE 5 142F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528444.1633946261 20 178700.1838262611 30 0.0 11 528548.3477819184 21 178007.5561802428 31 0.0 0 LINE 5 1430 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528457.909674054 20 178168.7824377468 30 0.0 11 528391.3999235287 21 178103.2973762012 31 0.0 0 LINE 5 1431 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528419.1776495675 20 178124.8365042053 30 0.0 11 528337.3406876953 21 178108.8585846446 31 0.0 0 LINE 5 1432 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528412.535768426 20 178136.1571237316 30 0.0 11 528385.9785806686 21 178060.5339566718 31 0.0 0 LINE 5 1433 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528506.1565314453 20 177944.3045508276 30 0.0 11 528381.8900450846 21 178072.4776498863 31 0.0 0 LINE 5 1434 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528231.5376889895 20 178494.3534429387 30 0.0 11 528249.142879486 21 178450.7625355663 31 0.0 0 LINE 5 1435 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528302.8256281043 20 178485.2660585849 30 0.0 11 528247.2586261313 21 178451.0154244339 31 0.0 0 LINE 5 1436 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528470.8068808959 20 178560.9105217073 30 0.0 11 528258.2996718624 21 178351.1501406726 31 0.0 0 LINE 5 1437 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528160.1300526372 20 178359.6639282912 30 0.0 11 528246.7934186207 21 178217.2396902225 31 0.0 0 LINE 5 1438 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528104.5825630481 20 178642.6588122643 30 0.0 11 527862.3107208053 21 178536.2722331519 31 0.0 0 LINE 5 1439 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528974.2490269006 20 177943.2169498362 30 0.0 11 529074.8116481313 21 178075.7250287029 31 0.0 0 LINE 5 143A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528936.7151588525 20 177851.0977463463 30 0.0 11 529113.2393739193 21 177797.3359449813 31 0.0 0 LINE 5 143B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528285.5873183847 20 178489.7153869756 30 0.0 11 528351.4611522887 21 178392.8090836222 31 0.0 0 LINE 5 143C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529252.4513196267 20 178461.4487730904 30 0.0 11 529327.0124102068 21 178645.0375417232 31 0.0 0 LINE 5 143D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530338.2961201331 20 180788.7547084909 30 0.0 11 530435.1516274485 21 181525.5409562457 31 0.0 0 LINE 5 143E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530235.1318529886 20 180967.1210590397 30 0.0 11 530240.08671063 21 181114.8814870659 31 0.0 0 LINE 5 143F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530375.6883102297 20 181052.8292676401 30 0.0 11 529885.4674530158 21 180988.268304624 31 0.0 0 LINE 5 1440 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530248.2643181117 20 181083.2761554827 30 0.0 11 530207.1473563143 21 181154.2021289139 31 0.0 0 LINE 5 1441 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530313.2478625071 20 181129.4546631625 30 0.0 11 530236.6556469487 21 181086.430704766 31 0.0 0 LINE 5 1442 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530302.7309378077 20 181113.6080797556 30 0.0 11 530327.0365308518 21 181310.9997992657 31 0.0 0 LINE 5 1443 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530425.0157447808 20 181122.3984354473 30 0.0 11 530008.6308414541 21 181241.0695507227 31 0.0 0 LINE 5 1444 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530272.6495276417 20 181324.6466285585 30 0.0 11 530207.1171655377 21 181149.8743530758 31 0.0 0 LINE 5 1445 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530330.580248871 20 181306.824020257 30 0.0 11 530271.9023948822 21 181324.2461364468 31 0.0 0 LINE 5 1446 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530381.021937737 20 181599.9243260485 30 0.0 11 530291.3346635938 21 181316.5479702797 31 0.0 0 LINE 5 1447 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530363.8961214457 20 181533.6795228619 30 0.0 11 530253.9629897674 21 181560.3723660222 31 0.0 0 LINE 5 1448 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530279.057127295 20 181637.8777809726 30 0.0 11 530048.2555749861 21 180854.9627992806 31 0.0 0 LINE 5 1449 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530062.6450814385 20 181149.7461893054 30 0.0 11 529624.7179966677 21 181182.9672071196 31 0.0 0 LINE 5 144A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530046.8518474741 20 181082.0690086005 30 0.0 11 530083.9544910923 21 181272.418455535 31 0.0 0 LINE 5 144B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529975.7995744307 20 181097.0347261711 30 0.0 11 529988.6233627915 21 181160.0521535555 31 0.0 0 LINE 5 144C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530020.6039639803 20 181066.2153863765 30 0.0 11 529968.4198112056 21 181111.0937745181 31 0.0 0 LINE 5 144D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529987.8038513251 20 181104.588180371 30 0.0 11 529584.6093016989 21 181110.1786099761 31 0.0 0 LINE 5 144E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529891.407447771 20 180921.3739107299 30 0.0 11 529869.9416690375 21 181328.1304897638 31 0.0 0 LINE 5 144F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529883.0140692269 20 181325.5988206547 30 0.0 11 529644.197247677 21 181327.1145507522 31 0.0 0 LINE 5 1450 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529976.892035066 20 181491.4081337029 30 0.0 11 529868.3336776149 21 181314.9939479675 31 0.0 0 LINE 5 1451 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530021.3585201078 20 181416.4100260595 30 0.0 11 529940.0430461289 21 181442.4698313734 31 0.0 0 LINE 5 1452 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529656.6301186837 20 180661.1742274603 30 0.0 11 529783.4049957184 21 180984.8427226674 31 0.0 0 LINE 5 1453 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529635.2797641427 20 180857.3255297743 30 0.0 11 529646.3277984724 21 181329.3701150071 31 0.0 0 LINE 5 1454 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530052.2973304801 20 181232.0162702387 30 0.0 11 529628.8914339743 21 181255.737002807 31 0.0 0 LINE 5 1455 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529811.6546990779 20 181697.3242248847 30 0.0 11 529630.6275680862 21 181248.9813300898 31 0.0 0 LINE 5 1456 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529888.3275670068 20 181938.7866450614 30 0.0 11 529708.694419197 21 181430.1615783586 31 0.0 0 LINE 5 1457 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529903.2812325341 20 181684.009864405 30 0.0 11 529786.6576949632 21 181670.2811276199 31 0.0 0 LINE 5 1458 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529880.3412750034 20 181626.3143881118 30 0.0 11 529799.9115781909 21 181701.1252479569 31 0.0 0 LINE 5 1459 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529822.0603907441 20 181445.464678714 30 0.0 11 529866.519758919 21 181642.5194831281 31 0.0 0 LINE 5 145A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530070.7006040116 20 181468.6318969595 30 0.0 11 529740.1085727789 21 181523.3935734394 31 0.0 0 LINE 5 145B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530060.3345732529 20 181375.631093596 30 0.0 11 530066.4740637235 21 181496.9149432353 31 0.0 0 LINE 5 145C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530165.4248362273 20 181471.7605166045 30 0.0 11 530108.9547541151 21 181364.9950690455 31 0.0 0 LINE 5 145D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530113.9712455618 20 181369.490559017 30 0.0 11 530058.6420695524 21 181376.9941032111 31 0.0 0 LINE 5 145E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530451.983915835 20 181366.5037393104 30 0.0 11 529905.6668498683 21 181500.873497438 31 0.0 0 LINE 5 145F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529894.3310124588 20 181494.3521053083 30 0.0 11 529900.3146067254 21 181517.8882726195 31 0.0 0 LINE 5 1460 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529731.9521605782 20 181395.4258543422 30 0.0 11 529689.2881019887 21 181410.7201434047 31 0.0 0 LINE 5 1461 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529741.3762525003 20 181383.0762722773 30 0.0 11 529725.3059075305 21 181400.9896875065 31 0.0 0 LINE 5 1462 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529730.5252408357 20 181319.9040835115 30 0.0 11 529740.6359545888 21 181391.0352007434 31 0.0 0 LINE 5 1463 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529954.0963399314 20 181446.2263190318 30 0.0 11 530031.1308153276 21 181873.6873985594 31 0.0 0 LINE 5 1464 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530045.6316110478 20 181845.4314955982 30 0.0 11 529844.349988987 21 181845.5760181434 31 0.0 0 LINE 5 1465 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530282.1062332428 20 181618.2810391656 30 0.0 11 530013.5500333215 21 181862.1296240347 31 0.0 0 LINE 5 1466 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530150.9915726047 20 181836.8800974799 30 0.0 11 529982.3986712572 21 181478.7707205962 31 0.0 0 LINE 5 1467 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530107.2600731355 20 181448.3154505321 30 0.0 11 530115.4416801651 21 181482.8850185999 31 0.0 0 LINE 5 1468 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529995.7589939005 20 181625.5055781762 30 0.0 11 529907.1951239718 21 181654.9721888375 31 0.0 0 LINE 5 1469 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529941.6226574095 20 181647.8812763107 30 0.0 11 529861.1212243257 21 181626.1533791875 31 0.0 0 LINE 5 146A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529940.6503530184 20 181634.7921344092 30 0.0 11 529883.4805572988 21 181690.9683044021 31 0.0 0 LINE 5 146B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529940.1267632553 20 181848.2680882116 30 0.0 11 529885.0748283349 21 181678.4452763864 31 0.0 0 LINE 5 146C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530499.7067164951 20 181670.0269107118 30 0.0 11 530431.0198845195 21 181507.3047441572 31 0.0 0 LINE 5 146D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530465.7497934597 20 181560.5761427814 30 0.0 11 530221.4121484268 21 181658.7491352089 31 0.0 0 LINE 5 146E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529936.0586576352 20 181233.4894753265 30 0.0 11 529932.6486109173 21 181280.3774430722 31 0.0 0 LINE 5 146F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529996.04332569 20 181273.0671257869 30 0.0 11 529931.068716294 21 181279.3199476997 31 0.0 0 LINE 5 1470 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530016.2143186337 20 181227.8045961354 30 0.0 11 530037.8743831275 21 181329.8525487859 31 0.0 0 LINE 5 1471 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530180.1685787403 20 181279.2053078991 30 0.0 11 529896.9632612126 21 181373.8281353093 31 0.0 0 LINE 5 1472 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529812.5960530011 20 181322.917106081 30 0.0 11 529817.2569814127 21 181391.6036367747 31 0.0 0 LINE 5 1473 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529848.9453069127 20 181388.47346972 30 0.0 11 529788.9909870235 21 181392.7221734328 31 0.0 0 LINE 5 1474 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529843.1416998106 20 181382.1187467608 30 0.0 11 529848.9754071669 21 181453.2133581997 31 0.0 0 LINE 5 1475 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529851.5886507226 20 181450.5694416274 30 0.0 11 529795.7074865813 21 181455.9439452276 31 0.0 0 LINE 5 1476 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529793.514654658 20 181384.9006469958 30 0.0 11 529798.9941570257 21 181462.2056458788 31 0.0 0 LINE 5 1477 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530343.3747185888 20 181464.5652553773 30 0.0 11 530234.0562590772 21 181492.0251343554 31 0.0 0 LINE 5 1478 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529887.4667406315 20 181044.4103591459 30 0.0 11 529623.1064784813 21 181033.123129424 31 0.0 0 LINE 5 1479 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529387.0340056964 20 180728.3098706004 30 0.0 11 528799.8257840726 21 180655.4140875558 31 0.0 0 LINE 5 147A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529486.5268066528 20 180641.3842100841 30 0.0 11 529452.9622144351 21 180884.3232757525 31 0.0 0 LINE 5 147B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530403.7387025317 20 180950.4231390571 30 0.0 11 529098.342956821 21 180757.7100933105 31 0.0 0 LINE 5 147C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529461.139821917 20 180852.7179441691 30 0.0 11 529420.0228601196 21 180923.6439176005 31 0.0 0 LINE 5 147D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529526.1233663122 20 180898.896451849 30 0.0 11 529449.5311507541 21 180855.8724934527 31 0.0 0 LINE 5 147E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529515.649079774 20 180884.8716507115 30 0.0 11 529539.954672818 21 181082.2633702215 31 0.0 0 LINE 5 147F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529719.7424303435 20 180868.5123586221 30 0.0 11 529221.5063452594 21 181010.5113394093 31 0.0 0 LINE 5 1480 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529485.5250314471 20 181094.088417245 30 0.0 11 529419.992669343 21 180919.3161417624 31 0.0 0 LINE 5 1481 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529543.4557526762 20 181076.2658089434 30 0.0 11 529484.7778986873 21 181093.6879251331 31 0.0 0 LINE 5 1482 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529593.8974415423 20 181369.3661147352 30 0.0 11 529504.210167399 21 181085.9897589662 31 0.0 0 LINE 5 1483 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529576.7716252509 20 181303.1213115482 30 0.0 11 529466.8384935727 21 181329.8141547087 31 0.0 0 LINE 5 1484 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529491.9326311002 20 181407.3195696592 30 0.0 11 529276.8016459199 21 180683.033535298 31 0.0 0 LINE 5 1485 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529275.5205852436 20 180919.1879779918 30 0.0 11 528837.5935004729 21 180952.4089958063 31 0.0 0 LINE 5 1486 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529259.7273512793 20 180851.5107972869 30 0.0 11 529296.8299948975 21 181041.8602442213 31 0.0 0 LINE 5 1487 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529188.6750782359 20 180866.4765148574 30 0.0 11 529201.498866597 21 180929.4939422421 31 0.0 0 LINE 5 1488 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529233.4794677856 20 180835.6571750629 30 0.0 11 529181.2953150109 21 180880.5355632046 31 0.0 0 LINE 5 1489 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529200.6793551305 20 180874.0299690574 30 0.0 11 528797.4848055041 21 180879.6203986625 31 0.0 0 LINE 5 148A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529104.2829515762 20 180690.8156994162 30 0.0 11 529082.8171728428 21 181097.5722784504 31 0.0 0 LINE 5 148B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529095.8895730323 20 181095.0406093412 30 0.0 11 528857.0727514823 21 181096.5563394386 31 0.0 0 LINE 5 148C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529189.7675388713 20 181260.8499223896 30 0.0 11 529081.2091814203 21 181084.435736654 31 0.0 0 LINE 5 148D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529234.2340239129 20 181185.851814746 30 0.0 11 529152.9185499342 21 181211.9116200599 31 0.0 0 LINE 5 148E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528974.9826614881 20 180670.418543214 30 0.0 11 528974.9780985168 21 180760.5411873043 31 0.0 0 LINE 5 148F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528848.1552679479 20 180626.7673184608 30 0.0 11 528859.2033022775 21 181098.8119036936 31 0.0 0 LINE 5 1490 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529265.1728342852 20 181001.4580589253 30 0.0 11 528841.7669377794 21 181025.1787914937 31 0.0 0 LINE 5 1491 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529048.6929366448 20 181521.8496197857 30 0.0 11 528843.5030718915 21 181018.4231187765 31 0.0 0 LINE 5 1492 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529116.1567363395 20 181453.4516530914 30 0.0 11 528999.5331987682 21 181439.7229163066 31 0.0 0 LINE 5 1493 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529093.2167788087 20 181395.7561767984 30 0.0 11 529012.7870819961 21 181470.5670366435 31 0.0 0 LINE 5 1494 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529034.9358945496 20 181214.9064674006 30 0.0 11 529079.3952627241 21 181411.9612718146 31 0.0 0 LINE 5 1495 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529283.5761078168 20 181238.073685646 30 0.0 11 528952.9840765841 21 181292.8353621259 31 0.0 0 LINE 5 1496 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529273.2100770582 20 181145.0728822825 30 0.0 11 529279.3495675287 21 181266.3567319217 31 0.0 0 LINE 5 1497 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529378.3003400324 20 181241.2023052909 30 0.0 11 529321.8302579203 21 181134.4368577321 31 0.0 0 LINE 5 1498 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529326.8467493671 20 181138.9323477035 30 0.0 11 529271.5175733577 21 181146.4358918976 31 0.0 0 LINE 5 1499 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529664.8594196403 20 181135.9455279969 30 0.0 11 529118.5423536736 21 181270.3152861244 31 0.0 0 LINE 5 149A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529107.2065162641 20 181263.7938939947 30 0.0 11 529113.1901105305 21 181287.3300613058 31 0.0 0 LINE 5 149B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528944.8276643835 20 181164.8676430287 30 0.0 11 528902.163605794 21 181180.1619320912 31 0.0 0 LINE 5 149C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528954.2517563056 20 181152.5180609637 30 0.0 11 528938.1814113358 21 181170.431476193 31 0.0 0 LINE 5 149D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528943.4007446409 20 181089.3458721978 30 0.0 11 528953.5114583941 21 181160.4769894299 31 0.0 0 LINE 5 149E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529166.9718437365 20 181215.6681077183 30 0.0 11 529223.4415039462 21 181566.1891852296 31 0.0 0 LINE 5 149F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529494.9817370479 20 181387.7228278521 30 0.0 11 529346.9736344345 21 181528.1516351163 31 0.0 0 LINE 5 14A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529374.1904109175 20 181543.2044757688 30 0.0 11 529195.2741750626 21 181248.2125092826 31 0.0 0 LINE 5 14A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529320.1355769406 20 181217.7572392189 30 0.0 11 529328.3171839703 21 181252.3268072863 31 0.0 0 LINE 5 14A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529208.6344977056 20 181394.9473668628 30 0.0 11 529120.0706277772 21 181424.4139775238 31 0.0 0 LINE 5 14A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529154.4981612148 20 181417.3230649972 30 0.0 11 529073.996728131 21 181395.595167874 31 0.0 0 LINE 5 14A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529153.5258568235 20 181404.2339230956 30 0.0 11 529096.3560611041 21 181460.4100930885 31 0.0 0 LINE 5 14A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529139.4093974719 20 181566.8543061548 30 0.0 11 529097.9503321401 21 181447.8870650729 31 0.0 0 LINE 5 14A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529677.5761621105 20 181312.1744703976 30 0.0 11 529434.287652232 21 181428.1909238953 31 0.0 0 LINE 5 14A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529148.9341614404 20 181002.931264013 30 0.0 11 529145.5241147225 21 181049.8192317587 31 0.0 0 LINE 5 14A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529208.9188294952 20 181042.5089144736 30 0.0 11 529143.9442200992 21 181048.7617363862 31 0.0 0 LINE 5 14A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529229.089822439 20 180997.2463848219 30 0.0 11 529250.7498869326 21 181099.2943374726 31 0.0 0 LINE 5 14AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529393.0440825455 20 181048.6470965855 30 0.0 11 529109.8387650178 21 181143.2699239959 31 0.0 0 LINE 5 14AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529025.4715568064 20 181092.3588947676 30 0.0 11 529030.132485218 21 181161.0454254612 31 0.0 0 LINE 5 14AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529061.8208107179 20 181157.9152584065 30 0.0 11 529001.8664908287 21 181162.1639621192 31 0.0 0 LINE 5 14AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529056.0172036158 20 181151.5605354473 30 0.0 11 529061.8509109723 21 181222.6551468862 31 0.0 0 LINE 5 14AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529064.4641545279 20 181220.0112303138 30 0.0 11 529008.5829903865 21 181225.3857339141 31 0.0 0 LINE 5 14AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529006.3901584631 20 181154.3424356824 30 0.0 11 529011.869660831 21 181231.6474345654 31 0.0 0 LINE 5 14B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529556.2502223941 20 181234.0070440637 30 0.0 11 529446.9317628824 21 181261.4669230418 31 0.0 0 LINE 5 14B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529100.3422444369 20 180813.8521478327 30 0.0 11 528835.9819822866 21 180802.5649181105 31 0.0 0 LINE 5 14B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529045.3514116085 20 181479.3920862135 30 0.0 11 528875.2749760494 21 182028.5885954034 31 0.0 0 LINE 5 14B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529273.1578980983 20 181500.2911526591 30 0.0 11 529293.0655504569 21 181668.9226533226 31 0.0 0 LINE 5 14B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529727.9161891624 20 181465.2266305704 30 0.0 11 528978.5941736404 21 181562.118928557 31 0.0 0 LINE 5 14B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529211.5230500173 20 181601.0380815575 30 0.0 11 529164.4210874387 21 182037.7150136904 31 0.0 0 LINE 5 14B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529142.1935067098 20 181605.8382328055 30 0.0 11 529336.0236311505 21 181599.5612135245 31 0.0 0 LINE 5 14B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.6385750521 20 181678.3677420495 30 0.0 11 529209.8945070248 21 181675.7560551536 31 0.0 0 LINE 5 14B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529122.3575251194 20 181629.222470229 30 0.0 11 529158.3410628242 21 181687.894785142 31 0.0 0 LINE 5 14B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529155.0094566439 20 181667.7214322521 30 0.0 11 529096.2395799927 21 182066.648993784 31 0.0 0 LINE 5 14BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528958.7689201024 20 181733.6713150126 30 0.0 11 529356.8988662861 21 181819.7192097903 31 0.0 0 LINE 5 14BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529356.4839619108 20 181806.4103837885 30 0.0 11 529319.9013057859 21 182042.4135214028 31 0.0 0 LINE 5 14BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529535.1406554567 20 181740.1715234809 30 0.0 11 529343.6739983511 21 181819.2120265032 31 0.0 0 LINE 5 14BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529468.1921718079 20 181684.3155929165 30 0.0 11 529480.9529403677 21 181768.745934306 31 0.0 0 LINE 5 14BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528903.8575074511 20 181912.684482759 30 0.0 11 528992.8264165814 21 181927.0589116806 31 0.0 0 LINE 5 14BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529291.0906535335 20 181624.3712904532 30 0.0 11 529246.996455296 21 182046.1424701601 31 0.0 0 LINE 5 14C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529712.0754532269 20 181936.1278735951 30 0.0 11 529278.1139804708 21 182031.483426149 31 0.0 0 LINE 5 14C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529925.5796502365 20 181905.6625871589 30 0.0 11 529431.9139545944 21 181995.1722096143 31 0.0 0 LINE 5 14C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529713.5411507648 20 181843.550632553 30 0.0 11 529681.3926029392 21 181956.4930895919 31 0.0 0 LINE 5 14C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529652.9260736845 20 181856.9976421366 30 0.0 11 529713.9554234051 21 181948.3268234142 31 0.0 0 LINE 5 14C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529465.0973098047 20 181885.696672062 30 0.0 11 529666.720024011 21 181873.2262078698 31 0.0 0 LINE 5 14C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529528.3837332418 20 181678.1482808087 30 0.0 11 529528.9621030175 21 181979.0256669608 31 0.0 0 LINE 5 14C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529602.9486020106 20 181625.6271380842 30 0.0 11 529485.9619619313 21 181658.2092124433 31 0.0 0 LINE 5 14C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529478.4882745172 20 181556.3851261245 30 0.0 11 529597.6412726829 21 181576.1409858726 31 0.0 0 LINE 5 14C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529591.7886059378 20 181572.8061832562 30 0.0 11 529602.1916801686 21 181627.6641538704 31 0.0 0 LINE 5 14C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529487.5869661725 20 181251.2420300496 30 0.0 11 529487.587972784 21 181251.2544245436 31 0.0 0 LINE 5 14CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529499.4347171412 20 181397.1243871717 30 0.0 11 529533.1281695744 21 181811.994709275 31 0.0 0 LINE 5 14CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529524.8827278017 20 181822.1456922354 30 0.0 11 529549.0718544475 21 181819.9914582276 31 0.0 0 LINE 5 14CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529401.3310440504 20 181966.6734615757 30 0.0 11 529409.6269396648 21 182011.2303385892 31 0.0 0 LINE 5 14CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529390.6421172938 20 181955.4008163437 30 0.0 11 529405.7639595057 21 181974.1218291566 31 0.0 0 LINE 5 14CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529326.5479602904 20 181956.0402892964 30 0.0 11 529398.3811817222 21 181957.4006826129 31 0.0 0 LINE 5 14CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529486.9021456546 20 181755.4714014451 30 0.0 11 529837.9909134975 21 181744.2285632496 31 0.0 0 LINE 5 14D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529804.2198961672 20 181650.0413236167 30 0.0 11 529523.542947489 21 181732.7203207542 31 0.0 0 LINE 5 14D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529513.3862834716 20 181604.6003171262 30 0.0 11 529548.8181221356 21 181602.0354508805 31 0.0 0 LINE 5 14D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.5307986297 20 181742.9275861688 30 0.0 11 529685.4990405129 21 181835.0567994266 31 0.0 0 LINE 5 14D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529683.9882674731 20 181799.9390878854 30 0.0 11 529649.7025155847 21 181875.946123477 31 0.0 0 LINE 5 14D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.9115523811 20 181798.8119082378 30 0.0 11 529717.253377332 21 181864.2074958406 31 0.0 0 LINE 5 14D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529881.572860625 20 181833.3672292052 30 0.0 11 529705.1447701149 21 181860.6368429481 31 0.0 0 LINE 5 14D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529274.0109237178 20 181739.3577341212 30 0.0 11 529319.7552911159 21 181750.200371683 31 0.0 0 LINE 5 14D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529322.6466951995 20 181686.4510941786 30 0.0 11 529318.4594131879 21 181751.5914374181 31 0.0 0 LINE 5 14D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529281.1794788938 20 181659.3211196363 30 0.0 11 529385.3755203517 21 181654.2095661979 31 0.0 0 LINE 5 14D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529358.0648502905 20 181505.6602194628 30 0.0 11 529406.3204206742 21 181800.3297483763 31 0.0 0 LINE 5 14DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529342.608506431 20 181875.4998933934 30 0.0 11 529411.1594564413 21 181881.850563048 31 0.0 0 LINE 5 14DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529413.1219933337 20 181850.0685497743 30 0.0 11 529407.7567111777 21 181909.9332781541 31 0.0 0 LINE 5 14DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529405.9231944706 20 181854.7846556055 30 0.0 11 529477.0384147157 21 181860.3615155338 31 0.0 0 LINE 5 14DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529474.8450016534 20 181857.3601365404 30 0.0 11 529471.2405749233 21 181913.3833272983 31 0.0 0 LINE 5 14DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529400.7565436811 20 181904.2203542361 30 0.0 11 529477.9462196996 21 181911.1371247718 31 0.0 0 LINE 5 14DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529079.6029298196 20 181757.1795881796 30 0.0 11 529026.3082474618 21 182016.3579564733 31 0.0 0 LINE 5 14E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530304.0548154939 20 181048.7539546006 30 0.0 11 530588.3653885961 21 180362.1664057763 31 0.0 0 LINE 5 14E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530387.586207844 20 180865.0913584818 30 0.0 11 529834.2934995411 21 180781.9679262921 31 0.0 0 LINE 5 14E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530250.5880801642 20 180849.7596601176 30 0.0 11 530293.6298891184 21 180708.320283045 31 0.0 0 LINE 5 14E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530408.542233124 20 180803.3646145163 30 0.0 11 529429.5724630821 21 180667.1618954379 31 0.0 0 LINE 5 14E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530293.3458882066 20 180740.9651845166 30 0.0 11 530271.9939805481 21 180661.812204194 31 0.0 0 LINE 5 14E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530368.0695185732 20 180713.1857914608 30 0.0 11 530282.9497682542 21 180734.9126546915 31 0.0 0 LINE 5 14E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530353.8084333581 20 180725.7691677678 30 0.0 11 530428.3909564597 21 180541.4007864436 31 0.0 0 LINE 5 14E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530474.1995392441 20 180748.9386734418 30 0.0 11 530102.7367198838 21 180526.5098193058 31 0.0 0 LINE 5 14E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530379.3916276373 20 180514.1382142453 30 0.0 11 530270.8443368462 21 180665.9845985361 31 0.0 0 LINE 5 14E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530430.7327140616 20 180546.3516690988 30 0.0 11 530378.566280631 21 180514.3316143769 31 0.0 0 LINE 5 14EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530555.3395872043 20 180276.3048576078 30 0.0 11 530395.3428708616 21 180526.7984042543 31 0.0 0 LINE 5 14EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530521.6466092081 20 180335.8569420938 30 0.0 11 530422.3727951547 21 180281.6120238077 31 0.0 0 LINE 5 14EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530466.6778245934 20 180213.2463200424 30 0.0 11 530042.9464715477 21 180903.4193199609 31 0.0 0 LINE 5 14ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530131.2651613216 20 180628.7038626293 30 0.0 11 529716.8712397313 21 180483.2341223061 31 0.0 0 LINE 5 14EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530098.4884788015 20 180689.9844966847 30 0.0 11 530183.6084302914 21 180515.7314853186 31 0.0 0 LINE 5 14EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530033.7335854979 20 180657.1332866572 30 0.0 11 530062.4356391981 21 180599.58471747 31 0.0 0 LINE 5 14F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530069.0309937571 20 180698.501849582 30 0.0 11 530030.2454078206 21 180641.642955409 31 0.0 0 LINE 5 14F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530047.2841766509 20 180652.9453499921 30 0.0 11 529659.2848141497 21 180543.156496049 31 0.0 0 LINE 5 14F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529906.7395476128 20 180804.9550288512 30 0.0 11 529991.3169604977 21 180406.5101073454 31 0.0 0 LINE 5 14F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530003.2881671689 20 180412.339962063 30 0.0 11 529773.0067559511 21 180349.0450701636 31 0.0 0 LINE 5 14F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530136.8940016724 20 180276.4897439913 30 0.0 11 529986.3626820854 21 180418.7824132492 31 0.0 0 LINE 5 14F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530160.4269277974 20 180360.44321819 30 0.0 11 530088.6310933923 21 180314.2190045845 31 0.0 0 LINE 5 14F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529656.0831902319 20 180747.808326711 30 0.0 11 529775.6486375952 21 180347.4180243195 31 0.0 0 LINE 5 14F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530142.5703661036 20 180546.5598761695 30 0.0 11 529739.7428308468 21 180414.0260948585 31 0.0 0 LINE 5 14F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530030.6034768476 20 180034.8140560444 30 0.0 11 529739.6706909495 21 180421.000911799 31 0.0 0 LINE 5 14F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530167.1778184791 20 179821.435804477 30 0.0 11 529861.9841355233 21 180266.2102890804 31 0.0 0 LINE 5 14FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530115.6586507159 20 180071.3969923189 30 0.0 11 529999.4572098697 21 180054.4632132203 31 0.0 0 LINE 5 14FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530078.5632398818 20 180121.1859482354 30 0.0 11 530020.2448667559 21 180028.1022856727 31 0.0 0 LINE 5 14FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529975.4466945978 20 180280.7799861815 30 0.0 11 530069.4085769443 21 180101.9549431169 31 0.0 0 LINE 5 14FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530221.6070836974 20 180322.7768728894 30 0.0 11 529916.4653748503 21 180184.2905203223 31 0.0 0 LINE 5 14FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530563.4482295682 20 180520.1388637834 30 0.0 11 530070.5480235035 21 180248.9065734364 31 0.0 0 LINE 5 14FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530057.9102858542 20 180252.2707006923 30 0.0 11 530069.7834853323 21 180231.0862321789 31 0.0 0 LINE 5 1500 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529875.4556045341 20 180305.7831659003 30 0.0 11 529838.2060363652 21 180279.9644354035 31 0.0 0 LINE 5 1501 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529881.3609942497 20 180320.1516055526 30 0.0 11 529870.4764736164 21 180298.6882963201 31 0.0 0 LINE 5 1502 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529854.5243826426 20 180378.3604207361 30 0.0 11 529882.7065439429 21 180312.2723873586 31 0.0 0 LINE 5 1503 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530103.1777825322 20 180314.2290691114 30 0.0 11 530288.257365063 21 179921.2878100911 31 0.0 0 LINE 5 1504 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530464.5492722588 20 180232.9642966499 30 0.0 11 530268.2836737723 21 179927.8997465798 31 0.0 0 LINE 5 1505 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530394.5016180104 20 179987.8726226491 30 0.0 11 530138.940988989 21 180290.1219519965 31 0.0 0 LINE 5 1506 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530189.8361350755 20 180151.8493923363 30 0.0 11 530111.9210931672 21 180100.4578906554 31 0.0 0 LINE 5 1507 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530143.3388728079 20 180116.2204799576 30 0.0 11 530059.9568527525 21 180116.3653020212 31 0.0 0 LINE 5 1508 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530139.0108783557 20 180128.6115846532 30 0.0 11 530098.3346968596 21 180059.5493237822 31 0.0 0 LINE 5 1509 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530256.6557167706 20 179825.3268424936 30 0.0 11 530096.6323345037 21 180072.058116419 31 0.0 0 LINE 5 150A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530688.1274518463 20 180239.3206435547 30 0.0 11 530579.6530818914 21 180378.7110859745 31 0.0 0 LINE 5 150B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530626.9910246668 20 180336.2478352728 30 0.0 11 530416.4020727649 21 180178.1620529922 31 0.0 0 LINE 5 150C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530030.676524334 20 180515.0421419232 30 0.0 11 530039.5222749266 21 180468.8700439159 31 0.0 0 LINE 5 150D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530098.862731711 20 180492.3443019127 30 0.0 11 530037.7224595286 21 180469.4824392266 31 0.0 0 LINE 5 150E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530106.6272602049 20 180541.2858756927 30 0.0 11 530153.9694919473 21 180448.3253672619 31 0.0 0 LINE 5 150F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530278.2990380709 20 180534.0863436747 30 0.0 11 530029.2485366401 21 180369.3666451558 31 0.0 0 LINE 5 1510 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529934.5768977602 20 180396.698668686 30 0.0 11 529956.8621806169 21 180331.5608922397 31 0.0 0 LINE 5 1511 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529986.6596079763 20 180342.7885919839 30 0.0 11 529929.8495715699 21 180323.1622902407 31 0.0 0 LINE 5 1512 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529979.4086186403 20 180347.4240545212 30 0.0 11 530003.4501558765 21 180280.2639443032 31 0.0 0 LINE 5 1513 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530005.289772253 20 180283.4942923202 30 0.0 11 529952.7054835665 21 180263.83513725 31 0.0 0 LINE 5 1514 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529932.1939634152 20 180331.8883243654 30 0.0 11 529957.5012727588 21 180258.637878003 31 0.0 0 LINE 5 1515 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529486.6508263606 20 180674.9791019966 30 0.0 11 529282.7583007949 21 180545.4162611162 31 0.0 0 LINE 5 1516 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529735.3611681152 20 180295.211299418 30 0.0 11 529455.1550969702 21 180733.9066311564 31 0.0 0 LINE 5 1517 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529646.6994055041 20 180232.1527618527 30 0.0 11 529251.3825813411 21 180876.0442192342 31 0.0 0 LINE 5 1518 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529311.2867422323 20 180647.6103044398 30 0.0 11 528896.8928206421 21 180502.1405641166 31 0.0 0 LINE 5 1519 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529278.5100597123 20 180708.8909384949 30 0.0 11 529363.6300112022 21 180534.6379271289 31 0.0 0 LINE 5 151A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529213.7551664087 20 180676.0397284676 30 0.0 11 529242.4572201087 21 180618.4911592803 31 0.0 0 LINE 5 151B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529249.0525746678 20 180717.4082913922 30 0.0 11 529210.2669887313 21 180660.5493972194 31 0.0 0 LINE 5 151C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529227.3057575616 20 180671.8517918025 30 0.0 11 528839.3063950604 21 180562.0629378591 31 0.0 0 LINE 5 151D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529109.7181942716 20 180716.2489171899 30 0.0 11 529171.3385414084 21 180425.4165491558 31 0.0 0 LINE 5 151E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529183.3097480795 20 180431.2464038735 30 0.0 11 528953.028336862 21 180367.951511974 31 0.0 0 LINE 5 151F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529316.9155825832 20 180295.3961858016 30 0.0 11 529166.3842629962 21 180437.6888550596 31 0.0 0 LINE 5 1520 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529340.4485087083 20 180379.3496600005 30 0.0 11 529268.6526743031 21 180333.1254463949 31 0.0 0 LINE 5 1521 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528860.8199180713 20 180692.1987855913 30 0.0 11 528955.670218506 21 180366.3244661299 31 0.0 0 LINE 5 1522 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529322.5919470144 20 180565.4663179799 30 0.0 11 528919.7644117577 21 180432.9325366689 31 0.0 0 LINE 5 1523 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529248.2253256548 20 180006.770937361 30 0.0 11 528919.6922718605 21 180439.9073536093 31 0.0 0 LINE 5 1524 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529295.6802316267 20 180090.3034341293 30 0.0 11 529179.4787907807 21 180073.3696550306 31 0.0 0 LINE 5 1525 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529258.5848207927 20 180140.0923900456 30 0.0 11 529200.2664476667 21 180047.0087274829 31 0.0 0 LINE 5 1526 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529155.4682755085 20 180299.686427992 30 0.0 11 529249.4301578551 21 180120.8613849271 31 0.0 0 LINE 5 1527 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529401.6286646083 20 180341.6833146997 30 0.0 11 529096.4869557612 21 180203.1969621326 31 0.0 0 LINE 5 1528 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529367.5377231179 20 180428.8292367399 30 0.0 11 529404.8688565344 21 180313.2703686059 31 0.0 0 LINE 5 1529 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529417.7557216468 20 180448.6471933713 30 0.0 11 529366.2558188828 21 180427.0745044187 31 0.0 0 LINE 5 152A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529743.4698104789 20 180539.0453055938 30 0.0 11 529250.5696044141 21 180267.8130152466 31 0.0 0 LINE 5 152B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529237.9318667649 20 180271.1771425025 30 0.0 11 529249.8050662433 21 180249.9926739893 31 0.0 0 LINE 5 152C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529055.4771854449 20 180324.6896077105 30 0.0 11 529018.227617276 21 180298.8708772138 31 0.0 0 LINE 5 152D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529061.3825751605 20 180339.058047363 30 0.0 11 529050.4980545273 21 180317.5947381304 31 0.0 0 LINE 5 152E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529034.5459635536 20 180397.2668625465 30 0.0 11 529062.7281248536 21 180331.178829169 31 0.0 0 LINE 5 152F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529283.1993634429 20 180333.1355109217 30 0.0 11 529428.495189928 21 180009.1864854411 31 0.0 0 LINE 5 1530 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529644.5708531695 20 180251.8707384601 30 0.0 11 529537.9671151138 21 180077.9101355026 31 0.0 0 LINE 5 1531 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529568.1531303601 20 180070.417110919 30 0.0 11 529318.9625698996 21 180309.0283938069 31 0.0 0 LINE 5 1532 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529431.6815314825 20 180370.7724530625 30 0.0 11 529448.5343991409 21 180339.4998679173 31 0.0 0 LINE 5 1533 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529369.8577159862 20 180170.7558341468 30 0.0 11 529291.9426740779 21 180119.3643324658 31 0.0 0 LINE 5 1534 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529323.3604537187 20 180135.1269217678 30 0.0 11 529239.9784336633 21 180135.2717438316 31 0.0 0 LINE 5 1535 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529319.0324592666 20 180147.5180264635 30 0.0 11 529278.3562777705 21 180078.4557655923 31 0.0 0 LINE 5 1536 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529347.5005444616 20 179986.7877196253 30 0.0 11 529276.6539154145 21 180090.9645582292 31 0.0 0 LINE 5 1537 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529801.379483573 20 180372.1177002053 30 0.0 11 529596.4236536755 21 180197.0684948025 31 0.0 0 LINE 5 1538 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529210.6981052448 20 180533.9485837334 30 0.0 11 529219.5438558373 21 180487.776485726 31 0.0 0 LINE 5 1539 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529278.8843126219 20 180511.2507437229 30 0.0 11 529217.7440404395 21 180488.388881037 31 0.0 0 LINE 5 153A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529286.648841116 20 180560.1923175028 30 0.0 11 529333.9910728581 21 180467.2318090721 31 0.0 0 LINE 5 153B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529458.3206189816 20 180552.9927854849 30 0.0 11 529209.2701175509 21 180388.2730869662 31 0.0 0 LINE 5 153C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529114.5984786709 20 180415.6051104964 30 0.0 11 529136.8837615276 21 180350.46733405 31 0.0 0 LINE 5 153D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529166.6811888871 20 180361.6950337942 30 0.0 11 529109.8711524805 21 180342.0687320508 31 0.0 0 LINE 5 153E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529159.4301995511 20 180366.3304963314 30 0.0 11 529183.4717367871 21 180299.1703861135 31 0.0 0 LINE 5 153F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529185.3113531638 20 180302.4007341305 30 0.0 11 529132.7270644774 21 180282.7415790602 31 0.0 0 LINE 5 1540 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529112.215544326 20 180350.7947661756 30 0.0 11 529137.5228536697 21 180277.5443198133 31 0.0 0 LINE 5 1541 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529663.9524871362 20 180416.2079580638 30 0.0 11 529565.4709759887 21 180361.3812993516 31 0.0 0 LINE 5 1542 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529234.0052739636 20 180046.9156515399 30 0.0 11 529211.9176295402 21 179472.4115735709 31 0.0 0 LINE 5 1543 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529289.9946326802 20 180006.9883611616 30 0.0 11 529283.3608963961 21 179779.775909238 31 0.0 0 LINE 5 1544 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529459.4550720368 20 180085.7093986373 30 0.0 11 529522.3434504139 21 179927.9819454036 31 0.0 0 LINE 5 1545 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529889.6290109534 20 180237.3174666211 30 0.0 11 529190.9426539895 21 179949.7257856779 31 0.0 0 LINE 5 1546 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529426.0056714986 20 179972.4400921852 30 0.0 11 529562.597765681 21 179470.2487059042 31 0.0 0 LINE 5 1547 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529360.2828528293 20 179949.8538544857 30 0.0 11 529545.8787654194 21 180006.1004129726 31 0.0 0 LINE 5 1548 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529382.3886989727 20 179880.6893421017 30 0.0 11 529443.7775062827 21 179899.848153108 31 0.0 0 LINE 5 1549 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529347.1775158107 20 179922.1313209226 30 0.0 11 529397.1246658042 21 179874.7758805751 31 0.0 0 LINE 5 154A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529388.6836782065 20 179893.3988098539 30 0.0 11 529372.4531559766 21 179574.1258653627 31 0.0 0 LINE 5 154B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529616.4842112671 20 179993.5565345598 30 0.0 11 529644.9627958351 21 179574.1739714516 31 0.0 0 LINE 5 154C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529810.4509426742 20 180050.0314443105 30 0.0 11 529705.8888757529 21 179988.2719131615 31 0.0 0 LINE 5 154D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529672.3072657123 20 180084.689110929 30 0.0 11 529792.5123713107 21 180096.4561646946 31 0.0 0 LINE 5 154E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529785.9958672843 20 180098.1619758782 30 0.0 11 529810.2472230898 21 180047.8679142512 31 0.0 0 LINE 5 154F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529602.0926766144 20 180381.7833834248 30 0.0 11 529602.0968578984 21 180381.7716721647 31 0.0 0 LINE 5 1550 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529651.3061089158 20 180243.9426441503 30 0.0 11 529811.9088096871 21 179631.7846855943 31 0.0 0 LINE 5 1551 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529603.1557238958 20 179813.6619840299 30 0.0 11 530068.185463361 21 179996.3275982037 31 0.0 0 LINE 5 1552 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530011.1804052058 20 180078.5598368081 30 0.0 11 529720.5177057797 21 179934.7647016076 31 0.0 0 LINE 5 1553 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529718.4984998654 20 180047.1531873395 30 0.0 11 529752.0581562893 21 180058.8040753184 31 0.0 0 LINE 5 1554 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529435.4333691352 20 179735.2093099271 30 0.0 11 529569.1663452307 21 179856.3856726004 31 0.0 0 LINE 5 1555 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529555.4541606357 20 179918.709878119 30 0.0 11 529568.2748068141 21 179854.7065291475 31 0.0 0 LINE 5 1556 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529542.8570141844 20 180102.5062273532 30 0.0 11 529639.4839479853 21 179888.5549816735 31 0.0 0 LINE 5 1557 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530296.9455510268 20 180360.090818716 30 0.0 11 530207.6100940128 21 180500.4133324969 31 0.0 0 LINE 5 1558 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530370.2956111029 20 180292.9007332187 30 0.0 11 530482.0169150562 21 180439.7662500494 31 0.0 0 LINE 5 1559 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529849.8873611541 20 180179.2781143133 30 0.0 11 529671.7765252076 21 180289.0687592285 31 0.0 0 LINE 5 155A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529545.2950098589 20 179904.0897720795 30 0.0 11 529659.0471003351 21 179932.2083697526 31 0.0 0 LINE 5 155B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529907.5884870807 20 180800.9556676964 30 0.0 11 529761.3216142649 21 180934.635113062 31 0.0 0 LINE 5 155C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528841.0342824628 20 177209.4097422151 30 0.0 11 528278.3732090686 21 180058.8817655076 31 0.0 0 LINE 5 155D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528485.8015310987 20 177965.2994590461 30 0.0 11 528596.9717934894 21 177689.7755207768 31 0.0 0 LINE 5 155E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529032.856454134 20 177908.0484599054 30 0.0 11 528503.1768036521 21 177872.9737800619 31 0.0 0 LINE 5 155F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528906.7072705641 20 177706.0885696858 30 0.0 11 528825.4591571875 21 177923.5636996254 31 0.0 0 LINE 5 1560 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528860.3990250182 20 178075.2330047576 30 0.0 11 528542.6989520168 21 178045.8936531997 31 0.0 0 LINE 5 1561 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528683.1105900724 20 178484.8759271629 30 0.0 11 528457.5160371857 21 178463.7198493692 31 0.0 0 LINE 5 1562 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528837.7525704118 20 177866.8596032536 30 0.0 11 528845.8741515778 21 178110.4093651077 31 0.0 0 LINE 5 1563 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528640.1476426235 20 177832.0636059231 30 0.0 11 528597.9887555746 21 178119.0803550255 31 0.0 0 LINE 5 1564 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528308.5306784712 20 179869.5117948136 30 0.0 11 527876.8658865468 21 183341.9964196203 31 0.0 0 LINE 5 1565 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529200.5279966597 20 179727.7499392975 30 0.0 11 529456.3896473957 21 179741.3193956278 31 0.0 0 LINE 5 1566 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528567.0355326954 20 179468.0301035344 30 0.0 11 528446.0992009897 21 179890.2364171706 31 0.0 0 LINE 5 1567 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528329.4294157617 20 179431.7414473565 30 0.0 11 528689.4728478268 21 179490.6504418413 31 0.0 0 LINE 5 1568 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528487.4440873934 20 179531.1636308236 30 0.0 11 528550.9926992977 21 179541.0236322006 31 0.0 0 LINE 5 1569 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528293.4081675153 20 179549.2968853729 30 0.0 11 528667.3917369897 21 179710.6907638414 31 0.0 0 LINE 5 156A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528669.5576176427 20 179697.5528052409 30 0.0 11 528588.0392999204 21 179922.0311684939 31 0.0 0 LINE 5 156B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528857.6496070828 20 179667.1027761433 30 0.0 11 528654.5144171252 21 179707.6364226865 31 0.0 0 LINE 5 156C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528802.7626189134 20 179599.3576436852 30 0.0 11 528798.9599687946 21 179684.662154782 31 0.0 0 LINE 5 156D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528230.9063274992 20 179641.3158552055 30 0.0 11 528315.4178125222 21 179672.619208027 31 0.0 0 LINE 5 156E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528144.3947346573 20 179767.238579988 30 0.0 11 528590.8943973097 21 179920.8165756824 31 0.0 0 LINE 5 156F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528640.591098345 20 179506.3056953474 30 0.0 11 528515.7889399241 21 179911.5952802161 31 0.0 0 LINE 5 1570 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528993.3627290027 20 179893.5685844917 30 0.0 11 528510.0567151904 21 179907.6210035374 31 0.0 0 LINE 5 1571 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529246.4236587767 20 179905.5266301457 30 0.0 11 528707.0717858409 21 179897.3361826018 31 0.0 0 LINE 5 1572 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529012.6984706571 20 179803.0212326646 30 0.0 11 528959.3215812568 21 179907.6177689707 31 0.0 0 LINE 5 1573 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528950.6272643358 20 179804.4960146925 30 0.0 11 528992.8488439449 21 179905.9008424644 31 0.0 0 LINE 5 1574 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528760.793710597 20 179796.3412164605 30 0.0 11 528961.0235601997 21 179823.0851632388 31 0.0 0 LINE 5 1575 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528902.3510568863 20 179387.5366045096 30 0.0 11 528805.4106229107 21 179900.2562983138 31 0.0 0 LINE 5 1576 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528831.7373683648 20 179745.5473126478 30 0.0 11 528855.8866233021 21 179748.1101349233 31 0.0 0 LINE 5 1577 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528682.5754239966 20 179863.462574682 30 0.0 11 528682.1007574591 21 179908.782679105 31 0.0 0 LINE 5 1578 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528674.2674593516 20 179850.3361353631 30 0.0 11 528685.4847378287 21 179871.6274269207 31 0.0 0 LINE 5 1579 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528611.2588529547 20 179838.572402642 30 0.0 11 528681.4738928051 21 179853.7944442277 31 0.0 0 LINE 5 157A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528807.3632662322 20 179672.788197632 30 0.0 11 529234.9711792036 21 179749.003403953 31 0.0 0 LINE 5 157B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529213.5100731744 20 179725.592080696 30 0.0 11 529143.7416550763 21 179914.3953648365 31 0.0 0 LINE 5 157C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529242.0818526643 20 179623.8202706216 30 0.0 11 528847.7112173356 21 179657.5499932291 31 0.0 0 LINE 5 157D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528989.9527050682 20 179695.9814363166 30 0.0 11 528986.8274817843 21 179789.2663395969 31 0.0 0 LINE 5 157E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528992.1344180404 20 179754.519073134 30 0.0 11 528943.8012646047 21 179822.4638192218 31 0.0 0 LINE 5 157F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528979.5223181569 20 179750.8850742235 30 0.0 11 529012.3471308522 21 179824.0060649801 31 0.0 0 LINE 5 1580 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529179.5288811444 20 179825.5150397874 30 0.0 11 529001.157264609 21 179818.1618520918 31 0.0 0 LINE 5 1581 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528601.6035857312 20 179615.8208689909 30 0.0 11 528644.3887794168 21 179635.3025819352 31 0.0 0 LINE 5 1582 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528659.5501022991 20 179573.3149631039 30 0.0 11 528642.8484182783 21 179636.4168759029 31 0.0 0 LINE 5 1583 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528624.1101531263 20 179538.6800739106 30 0.0 11 528727.328670395 21 179553.8088784535 31 0.0 0 LINE 5 1584 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528729.2518578581 20 179402.7821176971 30 0.0 11 528719.6294310883 21 179701.221626218 31 0.0 0 LINE 5 1585 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528642.5870527347 20 179762.6563937042 30 0.0 11 528708.6169873843 21 179782.1400145828 31 0.0 0 LINE 5 1586 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528716.6868262284 20 179751.3370014214 30 0.0 11 528699.849285463 21 179809.0350878508 31 0.0 0 LINE 5 1587 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528708.7120860384 20 179754.5724114705 30 0.0 11 528777.4075127313 21 179773.7925641406 31 0.0 0 LINE 5 1588 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528775.8357279267 20 179770.4237617937 30 0.0 11 528761.4684964741 21 179824.6932049007 31 0.0 0 LINE 5 1589 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528694.0856440736 20 179802.0766194414 30 0.0 11 528768.4818868498 21 179823.7857617378 31 0.0 0 LINE 5 158A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528032.8196453648 20 179780.2768232606 30 0.0 11 527664.9026817615 21 180480.5680652355 31 0.0 0 LINE 5 158B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527966.1101532396 20 179900.9142619889 30 0.0 11 528106.3942065767 21 179947.5841568255 31 0.0 0 LINE 5 158C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528095.2980045713 20 179798.8725363961 30 0.0 11 527864.5046873172 21 180236.1585429227 31 0.0 0 LINE 5 158D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528079.5961462748 20 179928.9392054262 30 0.0 11 528131.8277353538 21 179992.1290729441 31 0.0 0 LINE 5 158E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528145.4687386187 20 179884.0380117714 30 0.0 11 528078.5227200158 21 179940.9208657209 31 0.0 0 LINE 5 158F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528184.2186491791 20 179691.9183107798 30 0.0 11 528144.3445608914 21 180208.4577227396 31 0.0 0 LINE 5 1590 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528542.1229614001 20 179976.9272516323 30 0.0 11 528528.9751991945 21 180089.2879995186 31 0.0 0 LINE 5 1591 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528610.3714329076 20 180092.6729991083 30 0.0 11 527856.4539530258 21 180042.873060517 31 0.0 0 LINE 5 1592 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528077.4643446711 20 180126.0894573699 30 0.0 11 527913.1918958154 21 180598.8407671337 31 0.0 0 LINE 5 1593 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528008.5147488142 20 180117.3957666466 30 0.0 11 528199.9016598025 21 180148.7097956767 31 0.0 0 LINE 5 1594 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527997.8728993692 20 180189.2229846591 30 0.0 11 528061.4215112735 21 180199.0829860361 31 0.0 0 LINE 5 1595 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527984.5321776591 20 180136.5040111058 30 0.0 11 528008.4939101981 21 180201.0260298027 31 0.0 0 LINE 5 1596 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528009.1252140441 20 180180.5891704056 30 0.0 11 527962.1366878985 21 180313.0783112867 31 0.0 0 LINE 5 1597 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527803.836979491 20 180207.3562392084 30 0.0 11 528536.4916803161 21 180520.438294822 31 0.0 0 LINE 5 1598 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528179.9864296183 20 180355.6121590764 30 0.0 11 528072.0206366862 21 180647.9226835457 31 0.0 0 LINE 5 1599 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527738.2754529142 20 180314.0862154856 30 0.0 11 527822.7869379371 21 180345.389568307 31 0.0 0 LINE 5 159A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528151.0199103206 20 180164.3650491832 30 0.0 11 528012.2358912885 21 180615.0601186566 31 0.0 0 LINE 5 159B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528379.2990357547 20 180229.2825058204 30 0.0 11 528307.1084452349 21 180651.417205561 31 0.0 0 LINE 5 159C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528415.9452134922 20 179836.2631906246 30 0.0 11 528352.2185272204 21 180395.2412563144 31 0.0 0 LINE 5 159D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528317.7920782079 20 180330.8475514675 30 0.0 11 528836.3191207583 21 180433.2372557007 31 0.0 0 LINE 5 159E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528593.0534033489 20 180083.0078457863 30 0.0 11 528673.3390309509 21 180270.5734778979 31 0.0 0 LINE 5 159F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528696.9071551498 20 180250.2785411998 30 0.0 11 528358.1400293112 21 180315.6093470646 31 0.0 0 LINE 5 15A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528500.3815170438 20 180354.0407901521 30 0.0 11 528492.0712026886 21 180568.5503232738 31 0.0 0 LINE 5 15A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528637.5468404127 20 180478.6593455293 30 0.0 11 528473.9315714308 21 180507.4188145933 31 0.0 0 LINE 5 15A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528585.6214509289 20 179885.5412803603 30 0.0 11 528609.9239068013 21 180153.9784371766 31 0.0 0 LINE 5 15A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528112.0323977069 20 180273.8802228265 30 0.0 11 528154.8175913925 21 180293.3619357707 31 0.0 0 LINE 5 15A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528169.9789142748 20 180231.3743169395 30 0.0 11 528153.277230254 21 180294.4762297385 31 0.0 0 LINE 5 15A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528134.5389651021 20 180196.7394277462 30 0.0 11 528237.7574823708 21 180211.8682322892 31 0.0 0 LINE 5 15A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528470.1836627297 20 179972.1683387392 30 0.0 11 528457.968665224 21 180084.2190610903 31 0.0 0 LINE 5 15A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527917.8465889796 20 180253.7815098684 30 0.0 11 527769.6882990085 21 180564.6440479685 31 0.0 0 LINE 5 15A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528587.8134982101 20 180513.8955553372 30 0.0 11 528889.8979239679 21 180694.7831536562 31 0.0 0 LINE 5 15A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528746.6298662342 20 179891.4887384752 30 0.0 11 528569.28154252 21 180662.4882546429 31 0.0 0 LINE 5 15AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528937.5113190281 20 180167.75196714 30 0.0 11 528958.2724492294 21 180403.8740448904 31 0.0 0 LINE 5 15AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528861.8812511615 20 180211.1348817101 30 0.0 11 528945.4880698681 21 180228.4905616793 31 0.0 0 LINE 5 15AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529096.4131830083 20 180036.3587612945 30 0.0 11 529191.1606691565 21 180105.7305249874 31 0.0 0 LINE 5 15AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529087.9719335948 20 180097.870995399 30 0.0 11 529194.8115817942 21 180072.3584405921 31 0.0 0 LINE 5 15AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528875.4199148993 20 180169.4182922914 30 0.0 11 529120.3480046597 21 180209.4214413092 31 0.0 0 LINE 5 15AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528853.6459178629 20 180064.3840401553 30 0.0 11 528843.571176086 21 180185.404555378 31 0.0 0 LINE 5 15B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528745.4894377002 20 180157.0501350272 30 0.0 11 528805.3967661827 21 180052.1747663256 31 0.0 0 LINE 5 15B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528800.2369369359 20 180056.5049832557 30 0.0 11 528855.293267494 21 180065.8012921374 31 0.0 0 LINE 5 15B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528462.4995255942 20 180042.543345193 30 0.0 11 528462.5114981981 21 180042.5467057729 31 0.0 0 LINE 5 15B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528603.4162683148 20 180082.0971432843 30 0.0 11 529004.1650332488 21 180194.5829659595 31 0.0 0 LINE 5 15B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528935.105918802 20 180218.3014888331 30 0.0 11 529046.4939790572 21 179885.1612415667 31 0.0 0 LINE 5 15B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528946.4408303008 20 179884.1195385687 30 0.0 11 528926.4960903486 21 180176.0400302016 31 0.0 0 LINE 5 15B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528802.8234097638 20 180141.0691676066 30 0.0 11 528812.7234634602 21 180106.951977412 31 0.0 0 LINE 5 15B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528987.1160488407 20 180041.746183423 30 0.0 11 529078.7091752371 21 180059.7055653025 31 0.0 0 LINE 5 15B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529045.2526401881 20 180048.9261236859 30 0.0 11 529104.6214666463 21 180107.4746051942 31 0.0 0 LINE 5 15B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529039.6541528286 20 180060.7974315682 30 0.0 11 529117.0735198138 21 180040.0516070889 31 0.0 0 LINE 5 15BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.2200757285 20 179875.2493436762 30 0.0 11 529109.5198685039 21 180050.1664616459 31 0.0 0 LINE 5 15BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528656.0994813299 20 180252.361482507 30 0.0 11 528949.1865447303 21 180309.4465471946 31 0.0 0 LINE 5 15BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528556.1696433956 20 179206.5726048524 30 0.0 11 528172.098326215 21 178845.8468364899 31 0.0 0 LINE 5 15BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528412.9488724005 20 179064.4555633811 30 0.0 11 528042.393364479 21 179763.3542192984 31 0.0 0 LINE 5 15BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528350.9928183259 20 179187.6017989144 30 0.0 11 528233.3053349589 21 179098.1179961152 31 0.0 0 LINE 5 15BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528362.3421411069 20 179023.3665786782 30 0.0 11 528131.5488238528 21 179460.6525852049 31 0.0 0 LINE 5 15C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528263.8196623647 20 179109.7217055041 30 0.0 11 528182.1780688058 21 179102.2552166527 31 0.0 0 LINE 5 15C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528263.7204491684 20 179030.0015338379 30 0.0 11 528254.5333524718 21 179117.3687229567 31 0.0 0 LINE 5 15C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528270.5677959786 20 179047.7450890754 30 0.0 11 528123.5772799061 21 178913.7747902436 31 0.0 0 LINE 5 15C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528334.1062798096 20 178942.8942166801 30 0.0 11 527996.5153470805 21 179213.9875280292 31 0.0 0 LINE 5 15C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528080.9944494109 20 178950.2560815439 30 0.0 11 528185.6914929178 21 179104.7823506414 31 0.0 0 LINE 5 15C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528129.0332797841 20 178913.2982054521 30 0.0 11 528080.8891733374 21 178951.0972225784 31 0.0 0 LINE 5 15C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527919.0704511244 20 178702.6616373729 30 0.0 11 528098.4063959493 21 178939.6945149362 31 0.0 0 LINE 5 15C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527963.2144118462 20 178754.9395319815 30 0.0 11 527877.8686801754 21 178829.1952213407 31 0.0 0 LINE 5 15C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527829.1451973728 20 178763.9048904451 30 0.0 11 528367.6663100075 21 179447.3825729228 31 0.0 0 LINE 5 15C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528102.2562094361 20 179222.726205845 30 0.0 11 527821.9244401856 21 179560.8058809949 31 0.0 0 LINE 5 15CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528148.3393523888 20 179274.7451539584 30 0.0 11 528014.4941754031 21 179134.4063257267 31 0.0 0 LINE 5 15CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528095.0439254675 20 179324.060422145 30 0.0 11 528051.0454544846 21 179277.1586071135 31 0.0 0 LINE 5 15CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528146.0961385644 20 179305.3271211492 30 0.0 11 528079.3063470841 21 179321.9517798538 31 0.0 0 LINE 5 15CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528095.8227038843 20 179309.8988248382 30 0.0 11 527858.117585589 21 179635.618603924 31 0.0 0 LINE 5 15CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528189.5603870874 20 179494.4875080394 30 0.0 11 527845.2894322208 21 179276.7968929931 31 0.0 0 LINE 5 15CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527854.9139456695 20 179267.5954944 30 0.0 11 527715.583363013 21 179461.5613687941 31 0.0 0 LINE 5 15D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527773.9200939974 20 179095.1257963224 30 0.0 11 527855.0772710858 21 179285.7048993431 31 0.0 0 LINE 5 15D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527860.8208356485 20 179102.2142053516 30 0.0 11 527792.5395133066 21 179153.4877929055 31 0.0 0 LINE 5 15D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528103.2485123857 20 179660.6538035126 30 0.0 11 528029.7179450116 21 179608.5448152255 31 0.0 0 LINE 5 15D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528093.7114108572 20 179740.4886445803 30 0.0 11 527714.9751008977 21 179458.5188642339 31 0.0 0 LINE 5 15D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528029.1514078468 20 179183.5965476397 30 0.0 11 527764.9673537545 21 179515.3223559707 31 0.0 0 LINE 5 15D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527561.7116223148 20 179235.727857901 30 0.0 11 527731.416867063 21 179465.5009430376 31 0.0 0 LINE 5 15D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527497.8881053979 20 178896.5468150255 30 0.0 11 527636.6605627178 21 179093.1155555411 31 0.0 0 LINE 5 15D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528150.5433908066 20 178779.7398498826 30 0.0 11 527725.0122292528 21 179147.7626739199 31 0.0 0 LINE 5 15D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527710.5941368728 20 179350.4647146638 30 0.0 11 527660.2530446807 21 179387.3596132032 31 0.0 0 LINE 5 15D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527726.1191382208 20 179349.9169748675 30 0.0 11 527702.2116554058 21 179352.6699183981 31 0.0 0 LINE 5 15DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527771.3846162575 20 179395.2987596021 30 0.0 11 527719.1976540189 21 179345.9187702994 31 0.0 0 LINE 5 15DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527688.9518843426 20 178680.2527148979 30 0.0 11 527468.4287123164 21 178736.4905809727 31 0.0 0 LINE 5 15DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527846.8966185731 20 178772.7488930398 30 0.0 11 527661.1723446485 21 178663.9843583443 31 0.0 0 LINE 5 15DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527960.7353715366 20 179277.5797662137 30 0.0 11 527920.5092777147 21 179253.2493055979 31 0.0 0 LINE 5 15DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527963.1310070435 20 179205.7548976227 30 0.0 11 527920.45848973 21 179255.1497750304 31 0.0 0 LINE 5 15DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528011.7228479952 20 179215.4707887154 30 0.0 11 527940.9902370524 21 179138.7906688454 31 0.0 0 LINE 5 15E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528064.5920592017 20 179051.9841559795 30 0.0 11 527823.6313370143 21 179228.3266117468 31 0.0 0 LINE 5 15E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527816.3831984929 20 179326.5977835442 30 0.0 11 527763.0393937672 21 179283.0776474026 31 0.0 0 LINE 5 15E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527783.9167134486 20 179259.0342399549 30 0.0 11 527745.7822294013 21 179305.4921034771 31 0.0 0 LINE 5 15E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527785.7454205332 20 179267.4437696493 30 0.0 11 527731.1150967461 21 179221.5743502057 31 0.0 0 LINE 5 15E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527734.7832638241 20 179220.9711197252 30 0.0 11 527698.085549146 21 179263.4548522845 31 0.0 0 LINE 5 15E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527754.7793158943 20 179306.3241367128 30 0.0 11 527694.8773368726 21 179257.1525930337 31 0.0 0 LINE 5 15E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527996.7755258292 20 179885.2276632219 30 0.0 11 527915.1339322702 21 179877.7611743706 31 0.0 0 LINE 5 15E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527996.6763126328 20 179805.5074915559 30 0.0 11 527987.4892159362 21 179892.8746806747 31 0.0 0 LINE 5 15E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528002.0619858726 20 179822.162828514 30 0.0 11 527855.0714698003 21 179688.1925296822 31 0.0 0 LINE 5 15E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528133.4243398228 20 179665.1097987787 30 0.0 11 527729.4712105449 21 179989.493485747 31 0.0 0 LINE 5 15EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527813.9503128752 20 179725.7620392616 30 0.0 11 527918.647356382 21 179880.2883083592 31 0.0 0 LINE 5 15EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527861.9891432484 20 179688.8041631699 30 0.0 11 527813.8450368016 21 179726.6031802962 31 0.0 0 LINE 5 15EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527652.026314589 20 179478.1675950908 30 0.0 11 527831.3622594136 21 179715.2004726541 31 0.0 0 LINE 5 15ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527629.3243400914 20 179620.5471731373 30 0.0 11 528028.6230273386 21 180133.7414422995 31 0.0 0 LINE 5 15EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527835.2120729005 20 179998.2321635629 30 0.0 11 527665.7953887408 21 180202.5484196148 31 0.0 0 LINE 5 15EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527881.2952158531 20 180050.2511116761 30 0.0 11 527747.4500388677 21 179909.9122834445 31 0.0 0 LINE 5 15F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527827.999788932 20 180099.566379863 30 0.0 11 527784.0013179489 21 180052.6645648313 31 0.0 0 LINE 5 15F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527879.0520020287 20 180080.8330788671 30 0.0 11 527812.2622105485 21 180097.4577375718 31 0.0 0 LINE 5 15F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527828.7785673487 20 180085.4047825559 30 0.0 11 527591.0734490533 21 180411.1245616417 31 0.0 0 LINE 5 15F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527829.5747659578 20 180211.0921162493 30 0.0 11 527578.2452956853 21 180052.3028507109 31 0.0 0 LINE 5 15F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527587.8698091339 20 180043.1014521177 30 0.0 11 527448.5392264774 21 180237.0673265123 31 0.0 0 LINE 5 15F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527769.4617253289 20 179761.6104608084 30 0.0 11 527470.9605082231 21 179966.4096719633 31 0.0 0 LINE 5 15F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527762.1072713112 20 179959.1025053575 30 0.0 11 527472.4656967936 21 180317.9957862653 31 0.0 0 LINE 5 15F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527343.0535079231 20 179830.5261404157 30 0.0 11 527590.952526175 21 180062.8786122959 31 0.0 0 LINE 5 15F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527447.3543171115 20 179807.1752696685 30 0.0 11 527391.1184711135 21 179910.2628894595 31 0.0 0 LINE 5 15F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527481.1611980505 20 179859.2531386474 30 0.0 11 527373.6177806362 21 179881.6141370817 31 0.0 0 LINE 5 15FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527883.4992542709 20 179555.2458076005 30 0.0 11 527645.8118573582 21 179767.6358265945 31 0.0 0 LINE 5 15FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527737.5594578391 20 179726.7548728622 30 0.0 11 527417.4122622993 21 179654.4557690584 31 0.0 0 LINE 5 15FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527530.6386112234 20 179657.7533237969 30 0.0 11 527492.133122306 21 179820.0747913089 31 0.0 0 LINE 5 15FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527499.0010025659 20 179796.7849077535 30 0.0 11 527470.1787162922 21 179875.0272112465 31 0.0 0 LINE 5 15FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527509.1177505392 20 179805.1468705611 30 0.0 11 527430.2275831589 21 179819.3062882198 31 0.0 0 LINE 5 15FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527368.2787077643 20 179722.6300393009 30 0.0 11 527441.3665605957 21 179825.2469205501 31 0.0 0 LINE 5 1600 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527747.0735497196 20 179442.9676582734 30 0.0 11 527616.7640635243 21 179515.7296088145 31 0.0 0 LINE 5 1601 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527693.6912350009 20 180053.0857239316 30 0.0 11 527653.4651411791 21 180028.7552633158 31 0.0 0 LINE 5 1602 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527696.0868705079 20 179981.2608553404 30 0.0 11 527653.4143531943 21 180030.6557327483 31 0.0 0 LINE 5 1603 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527744.6787114596 20 179990.9767464331 30 0.0 11 527673.9461005169 21 179914.2966265633 31 0.0 0 LINE 5 1604 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527797.5479226662 20 179827.4901136973 30 0.0 11 527537.2927043674 21 180019.8184956274 31 0.0 0 LINE 5 1605 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527549.3390619573 20 180102.1037412619 30 0.0 11 527495.9952572316 21 180058.5836051206 31 0.0 0 LINE 5 1606 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527516.8725769129 20 180034.5401976727 30 0.0 11 527478.7380928657 21 180080.9980611951 31 0.0 0 LINE 5 1607 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527740.6918608296 20 179587.1529704054 30 0.0 11 527655.0757606819 21 179660.4636376987 31 0.0 0 LINE 5 1608 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527385.2477976351 20 179849.943018257 30 0.0 11 527098.8476690628 21 179756.2214112595 31 0.0 0 LINE 5 1609 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527367.2505138509 20 179783.5721316966 30 0.0 11 527151.8767663561 21 179710.8833866505 31 0.0 0 LINE 5 160A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527499.9242881051 20 179651.9989130187 30 0.0 11 527373.8551590216 21 179538.2471115796 31 0.0 0 LINE 5 160B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527576.8788217952 20 179534.6089957443 30 0.0 11 526615.348353887 21 180575.7118171535 31 0.0 0 LINE 5 160C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527382.0885082257 20 179644.0285202604 30 0.0 11 527003.6356507306 21 179421.1895599007 31 0.0 0 LINE 5 160D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527338.0829680242 20 179697.8164320882 30 0.0 11 527455.2849165784 21 179543.3068163136 31 0.0 0 LINE 5 160E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527280.9007493075 20 179653.0661017021 30 0.0 11 527320.1870217045 21 179602.1521104691 31 0.0 0 LINE 5 160F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527307.5345819786 20 179700.4781675243 30 0.0 11 527280.4730801873 21 179637.1936461638 31 0.0 0 LINE 5 1610 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527295.0053416338 20 179651.5768705524 30 0.0 11 526935.5510080746 21 179468.8484386185 31 0.0 0 LINE 5 1611 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527092.8716803185 20 179855.1358713125 30 0.0 11 527287.7366100949 21 179398.970806405 31 0.0 0 LINE 5 1612 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527298.354902861 20 179407.0050365438 30 0.0 11 527084.6545226875 21 179300.3845919441 31 0.0 0 LINE 5 1613 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527455.7037134897 20 179299.5473585614 30 0.0 11 527280.5032272824 21 179410.0537906542 31 0.0 0 LINE 5 1614 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527462.5621885354 20 179386.46654955 30 0.0 11 527401.0572255213 21 179327.2343008504 31 0.0 0 LINE 5 1615 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526919.5354947839 20 179622.1715367483 30 0.0 11 527087.5611156689 21 179299.2989888672 31 0.0 0 LINE 5 1616 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527409.0610968798 20 179565.6198368894 30 0.0 11 527039.455546023 21 179357.7088869003 31 0.0 0 LINE 5 1617 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527398.1409041258 20 179041.8821944623 30 0.0 11 527038.0363455138 21 179364.5381727657 31 0.0 0 LINE 5 1618 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527525.0059336864 20 178885.6477089472 30 0.0 11 527187.9674992323 21 179236.314287511 31 0.0 0 LINE 5 1619 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527474.5189813144 20 179094.2184453138 30 0.0 11 527363.7835159692 21 179055.1392380027 31 0.0 0 LINE 5 161A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527428.49784197 20 179135.8965495132 30 0.0 11 527389.2752835042 21 179033.2944453069 31 0.0 0 LINE 5 161B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527296.4727948656 20 179272.5445125288 30 0.0 11 527423.2337634025 21 179115.2585048334 31 0.0 0 LINE 5 161C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527502.3991814606 20 179340.924549142 30 0.0 11 527257.2582309912 21 179166.4726921377 31 0.0 0 LINE 5 161D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527571.8810403514 20 179264.5955464387 30 0.0 11 527723.8586542512 21 179262.4553722551 31 0.0 0 LINE 5 161E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527686.9264469953 20 179633.2069362727 30 0.0 11 527686.9169168243 21 179633.1989479949 31 0.0 0 LINE 5 161F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527600.0914869286 20 179415.8266688129 30 0.0 11 527395.9419716314 21 179259.6580827202 31 0.0 0 LINE 5 1620 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527382.8922759684 20 179260.5155255418 30 0.0 11 527398.6370130078 21 179242.0261278335 31 0.0 0 LINE 5 1621 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527193.5343081437 20 179277.7449970831 30 0.0 11 527161.9789393307 21 179245.2120004136 31 0.0 0 LINE 5 1622 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527196.5504791403 20 179292.9840389905 30 0.0 11 527190.0207427949 21 179269.8213755883 31 0.0 0 LINE 5 1623 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527158.9668125681 20 179344.9064608775 30 0.0 11 527199.393911068 21 179285.5135986958 31 0.0 0 LINE 5 1624 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527415.3275361311 20 179330.0564456594 30 0.0 11 527627.5144988411 21 179050.1164214183 31 0.0 0 LINE 5 1625 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527611.2018236088 20 179193.135292302 30 0.0 11 527455.0766069426 21 179313.318124319 31 0.0 0 LINE 5 1626 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527517.997145268 20 179718.8949694971 30 0.0 11 527622.1815325604 21 179026.267323479 31 0.0 0 LINE 5 1627 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527531.7434246959 20 179187.4935809829 30 0.0 11 527465.2336741706 21 179122.0085194374 31 0.0 0 LINE 5 1628 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527493.0114002093 20 179143.5476474413 30 0.0 11 527411.1744383372 21 179127.5697278805 31 0.0 0 LINE 5 1629 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527486.3695190679 20 179154.8682669677 30 0.0 11 527459.8123313106 21 179079.2450999079 31 0.0 0 LINE 5 162A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527579.9902820873 20 178963.0156940637 30 0.0 11 527455.7237957266 21 179091.1887931223 31 0.0 0 LINE 5 162B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527305.3714396315 20 179513.0645861748 30 0.0 11 527322.9766301279 21 179469.4736788026 31 0.0 0 LINE 5 162C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527376.6593787462 20 179503.977201821 30 0.0 11 527321.0923767731 21 179469.7265676699 31 0.0 0 LINE 5 162D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527544.6406315378 20 179579.6216649434 30 0.0 11 527332.1334225043 21 179369.8612839087 31 0.0 0 LINE 5 162E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527233.9638032789 20 179378.3750715273 30 0.0 11 527320.6271692625 21 179235.9508334586 31 0.0 0 LINE 5 162F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527178.4163136899 20 179661.3699555005 30 0.0 11 526916.167627152 21 179585.7363974202 31 0.0 0 LINE 5 1630 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527907.9025003525 20 178974.0706314878 30 0.0 11 528008.4651215832 21 179106.5787103545 31 0.0 0 LINE 5 1631 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527870.3686323044 20 178881.9514279978 30 0.0 11 528046.8928473712 21 178828.1896266328 31 0.0 0 LINE 5 1632 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527359.4210690266 20 179508.4265302118 30 0.0 11 527425.2949029307 21 179411.5202268584 31 0.0 0 LINE 5 1633 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528186.1047930786 20 179492.302454742 30 0.0 11 528260.6658836588 21 179675.8912233747 31 0.0 0 LINE 5 1634 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529294.8928599667 20 182000.5817697426 30 0.0 11 529368.8051009005 21 182556.3946378973 31 0.0 0 LINE 5 1635 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529305.0816559066 20 182018.6352957792 30 0.0 11 528520.6037537193 21 181916.8259805211 31 0.0 0 LINE 5 1636 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529168.7853264406 20 181997.9747406915 30 0.0 11 529173.7401840819 21 182145.7351687175 31 0.0 0 LINE 5 1637 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529181.9177915637 20 182114.1298371344 30 0.0 11 529140.8008297662 21 182185.0558105655 31 0.0 0 LINE 5 1638 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529246.9013359591 20 182160.3083448142 30 0.0 11 529170.3091204007 21 182117.2843864177 31 0.0 0 LINE 5 1639 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529236.3844112596 20 182144.4617614073 30 0.0 11 529260.6900043037 21 182341.8534809173 31 0.0 0 LINE 5 163A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529358.6692182326 20 182153.2521170987 30 0.0 11 528942.2843149059 21 182271.9232323746 31 0.0 0 LINE 5 163B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529206.3030010937 20 182355.5003102103 30 0.0 11 529140.7706389897 21 182180.7280347275 31 0.0 0 LINE 5 163C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529264.233722323 20 182337.6777019085 30 0.0 11 529205.5558683341 21 182355.0998180983 31 0.0 0 LINE 5 163D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529314.675411189 20 182630.7780077002 30 0.0 11 529224.9881370458 21 182347.4016519313 31 0.0 0 LINE 5 163E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529297.5495948976 20 182564.5332045134 30 0.0 11 529187.6164632194 21 182591.2260476738 31 0.0 0 LINE 5 163F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529212.7106007468 20 182668.7314626243 30 0.0 11 529031.4484553348 21 181963.4250934025 31 0.0 0 LINE 5 1640 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528996.2985548904 20 182180.5998709571 30 0.0 11 528558.3714701195 21 182213.8208887712 31 0.0 0 LINE 5 1641 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528980.5053209261 20 182112.922690252 30 0.0 11 529017.6079645442 21 182303.2721371866 31 0.0 0 LINE 5 1642 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528909.4530478827 20 182127.8884078224 30 0.0 11 528922.2768362436 21 182190.9058352073 31 0.0 0 LINE 5 1643 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528954.2574374323 20 182097.0690680281 30 0.0 11 528902.0732846576 21 182141.9474561697 31 0.0 0 LINE 5 1644 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528921.4573247771 20 182135.4418620226 30 0.0 11 528518.2627751507 21 182141.0322916278 31 0.0 0 LINE 5 1645 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528825.0609212229 20 181952.2275923816 30 0.0 11 528803.5951424895 21 182358.9841714154 31 0.0 0 LINE 5 1646 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528816.6675426789 20 182356.4525023064 30 0.0 11 528577.850721129 21 182357.9682324038 31 0.0 0 LINE 5 1647 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528910.5455085181 20 182522.2618153545 30 0.0 11 528801.987151067 21 182345.8476296189 31 0.0 0 LINE 5 1648 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528955.0119935594 20 182447.2637077112 30 0.0 11 528873.6965195808 21 182473.323513025 31 0.0 0 LINE 5 1649 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528717.0630321416 20 181925.5737602287 30 0.0 11 528717.0584691702 21 182015.6964043191 31 0.0 0 LINE 5 164A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528568.9332375947 20 181888.1792114258 30 0.0 11 528579.9812719242 21 182360.2237966586 31 0.0 0 LINE 5 164B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528985.9508039319 20 182262.8699518902 30 0.0 11 528562.5449074261 21 182286.5906844586 31 0.0 0 LINE 5 164C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528745.3081725296 20 182728.1779065364 30 0.0 11 528564.2810415382 21 182279.8350117414 31 0.0 0 LINE 5 164D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528821.9810404587 20 182969.6403267128 30 0.0 11 528642.3478926489 21 182461.0152600103 31 0.0 0 LINE 5 164E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528836.9347059861 20 182714.8635460567 30 0.0 11 528720.311168415 21 182701.1348092714 31 0.0 0 LINE 5 164F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528813.9947484554 20 182657.1680697636 30 0.0 11 528733.5650516428 21 182731.9789296086 31 0.0 0 LINE 5 1650 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528755.7138641961 20 182476.3183603657 30 0.0 11 528800.1732323709 21 182673.3731647797 31 0.0 0 LINE 5 1651 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529004.3540774635 20 182499.4855786111 30 0.0 11 528673.7620462308 21 182554.2472550911 31 0.0 0 LINE 5 1652 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528993.9880467048 20 182406.4847752476 30 0.0 11 529000.1275371754 21 182527.768624887 31 0.0 0 LINE 5 1653 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529099.0783096793 20 182502.614198256 30 0.0 11 529042.608227567 21 182395.8487506972 31 0.0 0 LINE 5 1654 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529047.6247190138 20 182400.3442406685 30 0.0 11 528992.2955430044 21 182407.8477848628 31 0.0 0 LINE 5 1655 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529385.637389287 20 182397.357420962 30 0.0 11 528839.3203233203 21 182531.7271790895 31 0.0 0 LINE 5 1656 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528827.9844859108 20 182525.2057869599 30 0.0 11 528833.9680801772 21 182548.7419542709 31 0.0 0 LINE 5 1657 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528665.6056340302 20 182426.2795359938 30 0.0 11 528622.9415754407 21 182441.5738250564 31 0.0 0 LINE 5 1658 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528675.0297259523 20 182413.9299539289 30 0.0 11 528658.9593809825 21 182431.8433691579 31 0.0 0 LINE 5 1659 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528664.1787142876 20 182350.7577651632 30 0.0 11 528674.2894280408 21 182421.8888823951 31 0.0 0 LINE 5 165A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528887.7498133832 20 182477.0800006834 30 0.0 11 528964.7842887796 21 182904.5410802109 31 0.0 0 LINE 5 165B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529215.7597066946 20 182649.1347208173 30 0.0 11 528947.2035067732 21 182892.9833056864 31 0.0 0 LINE 5 165C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529084.6450460566 20 182867.7337791315 30 0.0 11 528916.0521447092 21 182509.6244022478 31 0.0 0 LINE 5 165D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529040.9135465872 20 182479.1691321838 30 0.0 11 529049.095153617 21 182513.7387002515 31 0.0 0 LINE 5 165E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528929.4124673524 20 182656.3592598277 30 0.0 11 528840.8485974237 21 182685.825870489 31 0.0 0 LINE 5 165F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528875.2761308614 20 182678.7349579624 30 0.0 11 528794.7746977778 21 182657.0070608392 31 0.0 0 LINE 5 1660 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528874.3038264703 20 182665.6458160607 30 0.0 11 528817.1340307507 21 182721.8219860538 31 0.0 0 LINE 5 1661 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529410.8461557705 20 182845.4371980838 30 0.0 11 529364.6733579714 21 182538.1584258087 31 0.0 0 LINE 5 1662 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529399.4032669115 20 182591.429824433 30 0.0 11 529155.0656218786 21 182689.6028168605 31 0.0 0 LINE 5 1663 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528869.7121310872 20 182264.3431569781 30 0.0 11 528866.3020843692 21 182311.2311247239 31 0.0 0 LINE 5 1664 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528929.6967991418 20 182303.9208074386 30 0.0 11 528864.7221897459 21 182310.1736293514 31 0.0 0 LINE 5 1665 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528949.8677920855 20 182258.6582777871 30 0.0 11 528971.5278565793 21 182360.7062304376 31 0.0 0 LINE 5 1666 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529113.8220521923 20 182310.0589895508 30 0.0 11 528830.6167346646 21 182404.6818169607 31 0.0 0 LINE 5 1667 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528746.2495264531 20 182353.7707877327 30 0.0 11 528750.9104548647 21 182422.4573184263 31 0.0 0 LINE 5 1668 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528782.5987803646 20 182419.3271513715 30 0.0 11 528722.6444604755 21 182423.5758550844 31 0.0 0 LINE 5 1669 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528776.7951732625 20 182412.9724284125 30 0.0 11 528782.6288806188 21 182484.0670398513 31 0.0 0 LINE 5 166A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528785.2421241746 20 182481.4231232787 30 0.0 11 528729.3609600332 21 182486.7976268792 31 0.0 0 LINE 5 166B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528727.1681281097 20 182415.7543286476 30 0.0 11 528732.6476304777 21 182493.0593275304 31 0.0 0 LINE 5 166C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529277.0281920406 20 182495.4189370289 30 0.0 11 529167.7097325291 21 182522.878816007 31 0.0 0 LINE 5 166D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528821.1202140835 20 182075.2640407977 30 0.0 11 528556.7599519333 21 182063.9768110757 31 0.0 0 LINE 5 166E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529022.0789531999 20 181853.5018650219 30 0.0 11 527686.7491531824 21 181680.2031497812 31 0.0 0 LINE 5 166F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528381.6608302458 20 181767.4165293778 30 0.0 11 528386.6156878871 21 181915.1769574041 31 0.0 0 LINE 5 1670 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528522.2172874869 20 181853.1247379782 30 0.0 11 528031.996430273 21 181788.563774962 31 0.0 0 LINE 5 1671 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528394.7932953689 20 181883.5716258208 30 0.0 11 528353.6763335714 21 181954.497599252 31 0.0 0 LINE 5 1672 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528459.7768397642 20 181929.7501335006 30 0.0 11 528383.1846242059 21 181886.7261751042 31 0.0 0 LINE 5 1673 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528449.302553226 20 181915.7253323631 30 0.0 11 528473.60814627 21 182113.117051873 31 0.0 0 LINE 5 1674 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528653.3959037955 20 181899.3660402736 30 0.0 11 528155.1598187115 21 182041.3650210609 31 0.0 0 LINE 5 1675 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528419.1785048989 20 182124.9420988967 30 0.0 11 528353.6461427949 21 181950.169823414 31 0.0 0 LINE 5 1676 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528477.1092261283 20 182107.1194905949 30 0.0 11 528418.4313721394 21 182124.5416067849 31 0.0 0 LINE 5 1677 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528527.5509149943 20 182400.2197963869 30 0.0 11 528437.8636408509 21 182116.8434406178 31 0.0 0 LINE 5 1678 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528510.4250987028 20 182333.9749932 30 0.0 11 528400.4919670246 21 182360.6678363602 31 0.0 0 LINE 5 1679 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528425.5861045521 20 182438.1732513108 30 0.0 11 528210.4551193718 21 181713.8872169497 31 0.0 0 LINE 5 167A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528209.1740586957 20 181950.0416596434 30 0.0 11 527771.2469739247 21 181983.2626774577 31 0.0 0 LINE 5 167B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528193.3808247313 20 181882.3644789384 30 0.0 11 528230.4834683494 21 182072.7139258729 31 0.0 0 LINE 5 167C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528122.328551688 20 181897.330196509 30 0.0 11 528135.1523400488 21 181960.3476238937 31 0.0 0 LINE 5 167D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528167.1329412375 20 181866.5108567147 30 0.0 11 528114.9487884628 21 181911.3892448562 31 0.0 0 LINE 5 167E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528134.3328285824 20 181904.883650709 30 0.0 11 527731.1382789561 21 181910.4740803142 31 0.0 0 LINE 5 167F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527996.1768338681 20 181460.0353403722 30 0.0 11 527948.1823344532 21 182149.6768160842 31 0.0 0 LINE 5 1680 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528029.5430464843 20 182125.8942909927 30 0.0 11 527797.7082417475 21 182127.3657074069 31 0.0 0 LINE 5 1681 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528123.4210123233 20 182291.7036040411 30 0.0 11 528014.8626548722 21 182115.2894183054 31 0.0 0 LINE 5 1682 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528167.8874973648 20 182216.7054963975 30 0.0 11 528086.572023386 21 182242.7653017115 31 0.0 0 LINE 5 1683 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527852.4579638684 20 181696.0038806513 30 0.0 11 527852.453400897 21 181786.1265247416 31 0.0 0 LINE 5 1684 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527781.8087413998 20 181657.6210001123 30 0.0 11 527782.4804644517 21 182093.9906394431 31 0.0 0 LINE 5 1685 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528198.8263077372 20 182032.3117405768 30 0.0 11 527775.4204112313 21 182056.0324731452 31 0.0 0 LINE 5 1686 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527910.8695471963 20 182377.3371982609 30 0.0 11 527777.1565453434 21 182049.2768004279 31 0.0 0 LINE 5 1687 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528217.2295812688 20 182268.9273672976 30 0.0 11 527886.6375500361 21 182323.6890437774 31 0.0 0 LINE 5 1688 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528206.8635505101 20 182175.9265639341 30 0.0 11 528213.0030409806 21 182297.2104135735 31 0.0 0 LINE 5 1689 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528311.9538134844 20 182272.0559869425 30 0.0 11 528255.4837313723 21 182165.2905393836 31 0.0 0 LINE 5 168A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528260.5002228191 20 182169.786029355 30 0.0 11 528205.1710468096 21 182177.2895735493 31 0.0 0 LINE 5 168B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528598.5128930922 20 182166.7992096486 30 0.0 11 528052.1958271254 21 182301.1689677762 31 0.0 0 LINE 5 168C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528040.859989716 20 182294.6475756465 30 0.0 11 528046.8435839823 21 182318.1837429574 31 0.0 0 LINE 5 168D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527878.4811378353 20 182195.7213246802 30 0.0 11 527671.7558010316 21 182303.4826875344 31 0.0 0 LINE 5 168E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527887.9052297575 20 182183.3717426153 30 0.0 11 527871.8348847878 21 182201.2851578445 31 0.0 0 LINE 5 168F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527877.0542180927 20 182120.1995538495 30 0.0 11 527887.164931846 21 182191.3306710815 31 0.0 0 LINE 5 1690 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528100.6253171885 20 182246.5217893698 30 0.0 11 528157.0949773981 21 182597.0428668813 31 0.0 0 LINE 5 1691 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528428.6352104999 20 182418.5765095037 30 0.0 11 528280.6271078863 21 182559.005316768 31 0.0 0 LINE 5 1692 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528307.8438843695 20 182574.0581574205 30 0.0 11 528128.9276485144 21 182279.0661909342 31 0.0 0 LINE 5 1693 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528253.7890503926 20 182248.6109208704 30 0.0 11 528261.9706574223 21 182283.180488938 31 0.0 0 LINE 5 1694 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528611.2296355624 20 182343.028152049 30 0.0 11 528367.9411256838 21 182459.0446055469 31 0.0 0 LINE 5 1695 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528082.5876348925 20 182033.7849456645 30 0.0 11 528079.1775881745 21 182080.6729134102 31 0.0 0 LINE 5 1696 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528142.5723029471 20 182073.3625961251 30 0.0 11 528077.5976935512 21 182079.6154180378 31 0.0 0 LINE 5 1697 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528162.7432958909 20 182028.1000664736 30 0.0 11 528184.4033603846 21 182130.1480191241 31 0.0 0 LINE 5 1698 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528326.6975559975 20 182079.5007782372 30 0.0 11 528043.4922384698 21 182174.1236056473 31 0.0 0 LINE 5 1699 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528489.9036958461 20 182264.8607257154 30 0.0 11 528380.5852363343 21 182292.3206046936 31 0.0 0 LINE 5 169A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527996.0297969854 20 181841.1454156097 30 0.0 11 527769.6354557385 21 181833.4185997619 31 0.0 0 LINE 5 169B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528206.8113715502 20 182531.1448343106 30 0.0 11 528226.7190239089 21 182699.7763349743 31 0.0 0 LINE 5 169C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528661.5696626142 20 182496.080312222 30 0.0 11 527912.2476470924 21 182592.9726102086 31 0.0 0 LINE 5 169D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528145.1765234692 20 182631.8917632092 30 0.0 11 528108.1456837993 21 183069.5131572405 31 0.0 0 LINE 5 169E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528075.8469801618 20 182636.6919144571 30 0.0 11 528269.6771046024 21 182630.4148951759 31 0.0 0 LINE 5 169F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528079.2920485041 20 182709.2214237011 30 0.0 11 528143.5479804768 21 182706.6097368051 31 0.0 0 LINE 5 16A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528056.0109985714 20 182660.0761518805 30 0.0 11 528091.9945362762 21 182718.7484667934 31 0.0 0 LINE 5 16A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528088.6629300958 20 182698.5751139037 30 0.0 11 528029.8930534446 21 183097.5026754358 31 0.0 0 LINE 5 16A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527892.4223935542 20 182764.5249966642 30 0.0 11 528290.552339738 21 182850.572891442 31 0.0 0 LINE 5 16A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528290.1374353627 20 182837.2640654401 30 0.0 11 528256.5027161783 21 183054.2493831048 31 0.0 0 LINE 5 16A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528468.7941289087 20 182771.0252051323 30 0.0 11 528277.3274718031 21 182850.0657081549 31 0.0 0 LINE 5 16A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528401.8456452598 20 182715.1692745681 30 0.0 11 528414.6064138194 21 182799.5996159577 31 0.0 0 LINE 5 16A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527788.3542460773 20 183007.16342335 30 0.0 11 528210.7738302006 21 183067.2709162053 31 0.0 0 LINE 5 16A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528224.7441269853 20 182655.224972105 30 0.0 11 528180.649928748 21 183076.9961518119 31 0.0 0 LINE 5 16A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529484.7651123115 20 182728.031229721 30 0.0 11 528171.209505827 21 183064.0007175021 31 0.0 0 LINE 5 16A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528398.7507832566 20 182916.5503537137 30 0.0 11 528600.373497463 21 182904.0798895212 31 0.0 0 LINE 5 16AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528462.0372066938 20 182709.0019624602 30 0.0 11 528462.6155764694 21 183009.8793486124 31 0.0 0 LINE 5 16AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528536.6020754626 20 182656.4808197359 30 0.0 11 528419.6154353832 21 182689.0628940951 31 0.0 0 LINE 5 16AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528412.1417479692 20 182587.2388077762 30 0.0 11 528531.2947461346 21 182606.9946675243 31 0.0 0 LINE 5 16AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528525.4420793897 20 182603.6598649078 30 0.0 11 528535.8451536205 21 182658.517835522 31 0.0 0 LINE 5 16AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528421.2404396244 20 182282.0957117013 30 0.0 11 528421.2414462359 21 182282.1081061951 31 0.0 0 LINE 5 16AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528433.0881905932 20 182427.9780688233 30 0.0 11 528466.7816430264 21 182842.8483909267 31 0.0 0 LINE 5 16B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528458.5362012535 20 182852.9993738869 30 0.0 11 528482.7253278994 21 182850.8451398792 31 0.0 0 LINE 5 16B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528420.5556191065 20 182786.3250830966 30 0.0 11 528771.6443869495 21 182775.0822449014 31 0.0 0 LINE 5 16B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528737.8733696192 20 182680.8950052683 30 0.0 11 528457.1964209409 21 182763.5740024058 31 0.0 0 LINE 5 16B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528447.0397569236 20 182635.4539987776 30 0.0 11 528482.4715955876 21 182632.8891325321 31 0.0 0 LINE 5 16B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528604.1842720816 20 182773.7812678206 30 0.0 11 528619.1525139648 21 182865.9104810782 31 0.0 0 LINE 5 16B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528617.6417409251 20 182830.7927695371 30 0.0 11 528583.3559890368 21 182906.7998051287 31 0.0 0 LINE 5 16B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528604.5650258331 20 182829.6655898895 30 0.0 11 528650.9068507839 21 182895.0611774923 31 0.0 0 LINE 5 16B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528815.2263340769 20 182864.2209108569 30 0.0 11 528638.798243567 21 182891.4905245996 31 0.0 0 LINE 5 16B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528207.6643971698 20 182770.2114157729 30 0.0 11 528253.4087645679 21 182781.0540533346 31 0.0 0 LINE 5 16B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528256.3001686514 20 182717.3047758302 30 0.0 11 528252.1128866399 21 182782.4451190698 31 0.0 0 LINE 5 16BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528214.8329523457 20 182690.174801288 30 0.0 11 528319.0289938037 21 182685.0632478495 31 0.0 0 LINE 5 16BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528291.7183237425 20 182536.5139011146 30 0.0 11 528339.9738941262 21 182831.183430028 31 0.0 0 LINE 5 16BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528276.2619798829 20 182906.3535750451 30 0.0 11 528344.8129298933 21 182912.7042446996 31 0.0 0 LINE 5 16BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528346.7754667857 20 182880.9222314257 30 0.0 11 528341.4101846297 21 182940.7869598057 31 0.0 0 LINE 5 16BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528339.5766679224 20 182885.6383372573 30 0.0 11 528410.6918881676 21 182891.2151971855 31 0.0 0 LINE 5 16BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528408.4984751054 20 182888.213818192 30 0.0 11 528404.8940483753 21 182944.2370089496 31 0.0 0 LINE 5 16C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528334.410017133 20 182935.0740358879 30 0.0 11 528411.5996931515 21 182941.9908064232 31 0.0 0 LINE 5 16C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528989.1832316477 20 181787.7273625354 30 0.0 11 528851.974849362 21 181769.6573331517 31 0.0 0 LINE 5 16C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529064.9186347733 20 181659.5575442809 30 0.0 11 528650.5247131833 21 181514.0878039578 31 0.0 0 LINE 5 16C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528980.9376501028 20 181683.7990316437 30 0.0 11 528592.9382876016 21 181574.0101777006 31 0.0 0 LINE 5 16C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528840.3930210647 20 181835.8087105029 30 0.0 11 528913.2932495596 21 181492.3751053638 31 0.0 0 LINE 5 16C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528654.593928897 20 181812.577808336 30 0.0 11 528677.9227151468 21 181725.5269109787 31 0.0 0 LINE 5 16C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528576.4161301284 20 181831.3605113784 30 0.0 11 528709.3021110472 21 181378.271705971 31 0.0 0 LINE 5 16C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529076.2238395554 20 181577.4135578212 30 0.0 11 528673.3963042988 21 181444.8797765102 31 0.0 0 LINE 5 16C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528907.1951827109 20 181141.4120527991 30 0.0 11 528673.3241644014 21 181451.8545934505 31 0.0 0 LINE 5 16C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528964.3299977859 20 181545.8958235747 30 0.0 11 528973.1757483785 21 181499.7237255672 31 0.0 0 LINE 5 16CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529032.516205163 20 181523.1979835643 30 0.0 11 528971.3759329806 21 181500.3361208781 31 0.0 0 LINE 5 16CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528660.8951822511 20 181842.4229195187 30 0.0 11 528216.4117742468 21 181576.2699427678 31 0.0 0 LINE 5 16CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528669.0146415672 20 181326.0649810698 30 0.0 11 528461.5209524132 21 181650.9205861786 31 0.0 0 LINE 5 16CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528580.3528789561 20 181263.0064435044 30 0.0 11 528185.0360547931 21 181906.897900886 31 0.0 0 LINE 5 16CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528244.9402156842 20 181678.4639860913 30 0.0 11 527830.546294094 21 181532.9942457681 31 0.0 0 LINE 5 16CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528212.1635331643 20 181739.7446201465 30 0.0 11 528297.2834846542 21 181565.4916087805 31 0.0 0 LINE 5 16D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528147.4086398607 20 181706.8934101192 30 0.0 11 528176.1106935607 21 181649.3448409319 31 0.0 0 LINE 5 16D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528182.7060481197 20 181748.2619730439 30 0.0 11 528143.9204621834 21 181691.403078871 31 0.0 0 LINE 5 16D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528274.1019821601 20 181410.2033416521 30 0.0 11 528202.306147755 21 181363.9791280465 31 0.0 0 LINE 5 16D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527794.473391523 20 181723.0524672429 30 0.0 11 527877.5480466762 21 181522.7459140839 31 0.0 0 LINE 5 16D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528256.2454204663 20 181596.3199996316 30 0.0 11 527853.4178852097 21 181463.7862183204 31 0.0 0 LINE 5 16D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528335.2821380603 20 181372.5369963514 30 0.0 11 528030.1404292131 21 181234.0506437841 31 0.0 0 LINE 5 16D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528301.1911965698 20 181459.6829183916 30 0.0 11 528338.5223299863 21 181344.1240502575 31 0.0 0 LINE 5 16D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528351.4091950987 20 181479.500875023 30 0.0 11 528299.9092923348 21 181457.9281860703 31 0.0 0 LINE 5 16D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528677.1232839307 20 181569.8989872454 30 0.0 11 528184.2230778662 21 181298.6666968981 31 0.0 0 LINE 5 16D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528171.5853402168 20 181302.0308241542 30 0.0 11 528183.4585396952 21 181280.8463556411 31 0.0 0 LINE 5 16DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528216.8528368949 20 181363.9891925735 30 0.0 11 528362.1486633801 21 181040.0401670928 31 0.0 0 LINE 5 16DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528578.2243266215 20 181282.7244201118 30 0.0 11 528471.6205885658 21 181108.7638171541 31 0.0 0 LINE 5 16DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528501.806603812 20 181101.2707925706 30 0.0 11 528252.6160433516 21 181339.8820754586 31 0.0 0 LINE 5 16DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528735.032957025 20 181402.9713818568 30 0.0 11 528530.0771271274 21 181227.9221764542 31 0.0 0 LINE 5 16DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528144.3515786968 20 181564.8022653851 30 0.0 11 528153.1973292892 21 181518.6301673776 31 0.0 0 LINE 5 16DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528212.5377860739 20 181542.1044253746 30 0.0 11 528151.3975138914 21 181519.2425626885 31 0.0 0 LINE 5 16E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528220.302314568 20 181591.0459991545 30 0.0 11 528267.6445463101 21 181498.0854907237 31 0.0 0 LINE 5 16E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528597.6059605881 20 181447.0616397155 30 0.0 11 528499.1244494406 21 181392.2349810032 31 0.0 0 LINE 5 16E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528393.1085454885 20 181116.5630802888 30 0.0 11 528455.9969238659 21 180958.8356270552 31 0.0 0 LINE 5 16E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528823.2824844054 20 181268.1711482727 30 0.0 11 528124.5961274414 21 180980.5794673295 31 0.0 0 LINE 5 16E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528359.6591449503 20 181003.2937738368 30 0.0 11 528496.251239133 21 180501.1023875558 31 0.0 0 LINE 5 16E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528293.9363262813 20 180980.7075361373 30 0.0 11 528479.5322388713 21 181036.9540946242 31 0.0 0 LINE 5 16E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528261.5482504279 20 181051.651746213 30 0.0 11 528330.7781392561 21 180905.6295622267 31 0.0 0 LINE 5 16E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528322.3371516584 20 180924.2524915057 30 0.0 11 528306.1066294286 21 180604.9795470143 31 0.0 0 LINE 5 16E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528550.137684719 20 181024.4102162114 30 0.0 11 528578.6162692871 21 180605.0276531032 31 0.0 0 LINE 5 16E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528744.1044161262 20 181080.8851259622 30 0.0 11 528639.5423492048 21 181019.1255948131 31 0.0 0 LINE 5 16EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528605.9607391642 20 181115.5427925806 30 0.0 11 528726.1658447626 21 181127.3098463461 31 0.0 0 LINE 5 16EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528719.6493407362 20 181129.0156575297 30 0.0 11 528743.9006965419 21 181078.7215959029 31 0.0 0 LINE 5 16EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528535.7461500664 20 181412.6370650762 30 0.0 11 528535.7503313503 21 181412.6253538163 31 0.0 0 LINE 5 16ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528584.9595823676 20 181274.796325802 30 0.0 11 528850.6481789077 21 180262.0898888091 31 0.0 0 LINE 5 16EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528536.8091973477 20 180844.5156656816 30 0.0 11 528882.5862303128 21 180959.2072697967 31 0.0 0 LINE 5 16EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528887.8023072455 20 181104.0651430399 30 0.0 11 528654.1711792317 21 180965.6183832592 31 0.0 0 LINE 5 16F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528652.1519733174 20 181078.006868991 30 0.0 11 528685.7116297412 21 181089.6577569701 31 0.0 0 LINE 5 16F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528369.086842587 20 180766.0629915787 30 0.0 11 528502.8198186826 21 180887.2393542519 31 0.0 0 LINE 5 16F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528489.1076340876 20 180949.5635597706 30 0.0 11 528501.9282802661 21 180885.5602107991 31 0.0 0 LINE 5 16F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528476.5104876363 20 181133.3599090048 30 0.0 11 528573.1374214369 21 180919.4086633252 31 0.0 0 LINE 5 16F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528783.5408346061 20 181210.1317959648 30 0.0 11 528605.4299986597 21 181319.9224408801 31 0.0 0 LINE 5 16F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528478.9484833108 20 180934.9434537312 30 0.0 11 528592.700573787 21 180963.0620514041 31 0.0 0 LINE 5 16F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528841.2419605326 20 181831.809349348 30 0.0 11 528694.9750877169 21 181965.4887947136 31 0.0 0 LINE 5 16F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527559.6352817407 20 178984.0106022821 30 0.0 11 527670.8055441313 21 178708.4866640128 31 0.0 0 LINE 5 16F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527841.850379535 20 178909.2222632197 30 0.0 11 527577.010554294 21 178891.6849232979 31 0.0 0 LINE 5 16F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527868.0342853392 20 178636.461298328 30 0.0 11 527759.1126306393 21 178954.417381277 31 0.0 0 LINE 5 16FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527796.601578126 20 179043.1395445016 30 0.0 11 527616.5327026586 21 179064.6047964356 31 0.0 0 LINE 5 16FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527694.8464714251 20 179497.7635815927 30 0.0 11 527531.3497878276 21 179482.4309926053 31 0.0 0 LINE 5 16FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527771.4060438636 20 178897.713284905 30 0.0 11 527779.5276250298 21 179141.2630467593 31 0.0 0 LINE 5 16FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527573.8011160755 20 178862.9172875747 30 0.0 11 527531.6422290265 21 179149.9340366772 31 0.0 0 LINE 5 16FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528437.3553301 20 180754.5273863803 30 0.0 11 528875.2647654894 21 180805.9507894455 31 0.0 0 LINE 5 16FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528966.2110071292 20 180712.3251185517 30 0.0 11 529125.0585334791 21 180393.6913294563 31 0.0 0 LINE 5 1700 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528779.8311440291 20 181528.9781279204 30 0.0 11 528976.924057618 21 181278.1016776676 31 0.0 0 LINE 5 1701 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528610.0466290963 20 178898.6744360602 30 0.0 11 528381.6542351669 21 178837.4677158369 31 0.0 0 LINE 5 1702 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527499.6368574303 20 180238.8424938624 30 0.0 11 527408.8582457727 21 180625.7233147637 31 0.0 0 LINE 5 1703 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526325.5493438983 20 179990.7231208413 30 0.0 11 528521.0807331772 21 180775.9064331124 31 0.0 0 LINE 5 1704 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527907.5126679384 20 181542.9682871881 30 0.0 11 527873.9480757209 21 181785.9073528567 31 0.0 0 LINE 5 1705 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527907.6366876462 20 181576.5631791007 30 0.0 11 527703.7441620805 21 181447.0003382203 31 0.0 0 LINE 5 1706 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528067.6852667896 20 181133.7368389568 30 0.0 11 527435.8092670268 21 182162.9355310014 31 0.0 0 LINE 5 1707 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527732.2726035179 20 181549.194381544 30 0.0 11 527317.8786819276 21 181403.7246412206 31 0.0 0 LINE 5 1708 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527699.4959209979 20 181610.4750155991 30 0.0 11 527784.6158724877 21 181436.2220042331 31 0.0 0 LINE 5 1709 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527634.7410276944 20 181577.6238055718 30 0.0 11 527663.4430813943 21 181520.0752363844 31 0.0 0 LINE 5 170A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527486.3805875073 20 181827.0284917456 30 0.0 11 527592.3244026941 21 181327.0006262598 31 0.0 0 LINE 5 170B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527604.2956093652 20 181332.8304809776 30 0.0 11 527374.0141981476 21 181269.5355890781 31 0.0 0 LINE 5 170C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527737.901443869 20 181196.9802629057 30 0.0 11 527587.3701242818 21 181339.2729321637 31 0.0 0 LINE 5 170D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527761.4343699937 20 181280.9337371047 30 0.0 11 527689.6385355888 21 181234.7095234988 31 0.0 0 LINE 5 170E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527281.8057793569 20 181593.7828626954 30 0.0 11 527376.6560797916 21 181267.9085432339 31 0.0 0 LINE 5 170F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527743.5778082999 20 181467.0503950839 30 0.0 11 527340.7502730433 21 181334.516613773 31 0.0 0 LINE 5 1710 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527669.2111869405 20 180908.3550144651 30 0.0 11 527340.678133146 21 181341.4914307134 31 0.0 0 LINE 5 1711 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527716.6660929125 20 180991.8875112333 30 0.0 11 527600.4646520663 21 180974.9537321347 31 0.0 0 LINE 5 1712 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527679.5706820783 20 181041.6764671496 30 0.0 11 527621.2523089522 21 180948.592804587 31 0.0 0 LINE 5 1713 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527576.4541367941 20 181201.2705050961 30 0.0 11 527670.4160191407 21 181022.4454620314 31 0.0 0 LINE 5 1714 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527822.614525894 20 181243.2673918037 30 0.0 11 527517.4728170468 21 181104.7810392368 31 0.0 0 LINE 5 1715 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527788.5235844035 20 181330.413313844 30 0.0 11 527825.8547178198 21 181214.8544457102 31 0.0 0 LINE 5 1716 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527838.7415829323 20 181350.2312704753 30 0.0 11 527787.2416801685 21 181328.658581523 31 0.0 0 LINE 5 1717 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528508.8212567543 20 181633.8112238231 30 0.0 11 527671.5554656998 21 181169.3970923505 31 0.0 0 LINE 5 1718 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527658.9177280506 20 181172.7612196068 30 0.0 11 527670.7909275288 21 181151.5767510934 31 0.0 0 LINE 5 1719 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527476.4630467304 20 181226.2736848147 30 0.0 11 527439.2134785617 21 181200.4549543179 31 0.0 0 LINE 5 171A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527482.3684364462 20 181240.642124467 30 0.0 11 527471.4839158129 21 181219.1788152345 31 0.0 0 LINE 5 171B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527455.5318248391 20 181298.8509396505 30 0.0 11 527483.7139861392 21 181232.7629062729 31 0.0 0 LINE 5 171C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527704.1852247286 20 181234.7195880258 30 0.0 11 527849.4810512137 21 180910.7705625452 31 0.0 0 LINE 5 171D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528065.5567144552 20 181153.4548155641 30 0.0 11 527958.9529763994 21 180979.4942126066 31 0.0 0 LINE 5 171E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527989.1389916457 20 180972.0011880231 30 0.0 11 527739.9484311853 21 181210.612470911 31 0.0 0 LINE 5 171F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527852.6673927681 20 181272.3565301665 30 0.0 11 527869.5202604264 21 181241.0839450215 31 0.0 0 LINE 5 1720 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527790.8435772719 20 181072.3399112507 30 0.0 11 527712.9285353634 21 181020.9484095699 31 0.0 0 LINE 5 1721 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527744.3463150042 20 181036.710998872 30 0.0 11 527660.964294949 21 181036.8558209355 31 0.0 0 LINE 5 1722 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527740.0183205521 20 181049.1021035675 30 0.0 11 527699.3421390562 21 180980.0398426965 31 0.0 0 LINE 5 1723 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527768.4864057471 20 180888.3717967293 30 0.0 11 527697.6397767001 21 180992.5486353334 31 0.0 0 LINE 5 1724 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528305.2549142606 20 181222.4813618912 30 0.0 11 528017.4095149611 21 181098.6525719066 31 0.0 0 LINE 5 1725 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527631.6839665303 20 181435.5326608375 30 0.0 11 527640.529717123 21 181389.3605628302 31 0.0 0 LINE 5 1726 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527699.8701739076 20 181412.834820827 30 0.0 11 527638.7299017251 21 181389.9729581412 31 0.0 0 LINE 5 1727 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527707.6347024016 20 181461.7763946069 30 0.0 11 527754.9769341437 21 181368.8158861762 31 0.0 0 LINE 5 1728 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527879.3064802673 20 181454.5768625892 30 0.0 11 527630.2559788366 21 181289.8571640703 31 0.0 0 LINE 5 1729 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527535.5843399566 20 181317.1891876006 30 0.0 11 527557.8696228134 21 181252.0514111541 31 0.0 0 LINE 5 172A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527587.6670501727 20 181263.2791108984 30 0.0 11 527530.8570137664 21 181243.6528091551 31 0.0 0 LINE 5 172B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527580.4160608368 20 181267.9145734355 30 0.0 11 527604.4575980728 21 181200.7544632176 31 0.0 0 LINE 5 172C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527606.2972144495 20 181203.9848112346 30 0.0 11 527553.712925763 21 181184.3256561642 31 0.0 0 LINE 5 172D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527533.2014056115 20 181252.3788432797 30 0.0 11 527558.5087149551 21 181179.1283969175 31 0.0 0 LINE 5 172E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528084.9383484219 20 181317.7920351681 30 0.0 11 527986.4568372743 21 181262.9653764555 31 0.0 0 LINE 5 172F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527654.9911352492 20 180948.4997286438 30 0.0 11 527667.4434421974 21 180450.2901774473 31 0.0 0 LINE 5 1730 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527710.9804939659 20 180908.5724382659 30 0.0 11 527704.3467576817 21 180681.3599863421 31 0.0 0 LINE 5 1731 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527880.4409333225 20 180987.2934757415 30 0.0 11 527943.3293116995 21 180829.5660225076 31 0.0 0 LINE 5 1732 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528194.5290345232 20 181091.1185565957 30 0.0 11 527611.9285152752 21 180851.309862782 31 0.0 0 LINE 5 1733 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527781.268714115 20 180851.4379315898 30 0.0 11 527966.864626705 21 180907.6844900767 31 0.0 0 LINE 5 1734 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527803.3745602582 20 180782.2734192058 30 0.0 11 527864.7633675682 21 180801.4322302122 31 0.0 0 LINE 5 1735 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527768.1633770963 20 180823.7153980267 30 0.0 11 527818.1105270899 21 180776.3599576792 31 0.0 0 LINE 5 1736 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527809.669539492 20 180794.9828869581 30 0.0 11 527793.4390172622 21 180475.7099424668 31 0.0 0 LINE 5 1737 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528037.4700725527 20 180895.1406116638 30 0.0 11 528087.9867389572 21 180589.0534814345 31 0.0 0 LINE 5 1738 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528023.0785379001 20 181283.3674605286 30 0.0 11 528023.0827191841 21 181283.3557492687 31 0.0 0 LINE 5 1739 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528340.439197865 20 180924.8250785686 30 0.0 11 527957.9105047284 21 180793.3770014409 31 0.0 0 LINE 5 173A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527856.4192304206 20 180636.7933870313 30 0.0 11 527990.1522065163 21 180757.9697497044 31 0.0 0 LINE 5 173B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527976.4400219213 20 180820.2939552231 30 0.0 11 527989.2606680998 21 180756.2906062517 31 0.0 0 LINE 5 173C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527963.8428754701 20 181004.0903044574 30 0.0 11 528060.4698092707 21 180790.1390587778 31 0.0 0 LINE 5 173D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527621.5138579452 20 180629.3340164016 30 0.0 11 527877.3755086813 21 180642.9034727321 31 0.0 0 LINE 5 173E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527667.4095200623 20 180807.1107072498 30 0.0 11 527128.0576471266 21 180798.9202597059 31 0.0 0 LINE 5 173F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527433.6843319427 20 180704.6053097688 30 0.0 11 527380.3074425424 21 180809.2018460748 31 0.0 0 LINE 5 1740 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527371.6131256215 20 180706.0800917967 30 0.0 11 527413.8347052304 21 180807.4849195685 31 0.0 0 LINE 5 1741 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527181.7795718828 20 180697.9252935647 30 0.0 11 527382.0094214852 21 180724.6692403429 31 0.0 0 LINE 5 1742 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527379.8248971851 20 180601.3707391883 30 0.0 11 527655.9570404891 21 180650.5874810572 31 0.0 0 LINE 5 1743 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527634.49593446 20 180627.1761578001 30 0.0 11 527564.727516362 21 180815.9794419407 31 0.0 0 LINE 5 1744 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527680.2763528484 20 180527.0181601985 30 0.0 11 527085.8869598081 21 180596.2012948931 31 0.0 0 LINE 5 1745 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527410.9385663538 20 180597.5655134207 30 0.0 11 527407.81334307 21 180690.8504167008 31 0.0 0 LINE 5 1746 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527413.120279326 20 180656.1031502381 30 0.0 11 527364.7871258904 21 180724.0478963259 31 0.0 0 LINE 5 1747 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527400.5081794425 20 180652.4691513277 30 0.0 11 527433.3329921378 21 180725.5901420843 31 0.0 0 LINE 5 1748 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527600.5147424299 20 180727.0991168916 30 0.0 11 527422.1431258947 21 180719.7459291959 31 0.0 0 LINE 5 1749 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527358.4971803137 20 181069.3360442441 30 0.0 11 527379.258310515 21 181305.4581219943 31 0.0 0 LINE 5 174A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527517.3990442939 20 180937.9428383985 30 0.0 11 527612.146530442 21 181007.3146020915 31 0.0 0 LINE 5 174B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527508.9577948804 20 180999.4550725032 30 0.0 11 527615.7974430798 21 180973.9425176962 31 0.0 0 LINE 5 174C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527296.4057761851 20 181071.0023693953 30 0.0 11 527541.3338659454 21 181111.0055184133 31 0.0 0 LINE 5 174D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527356.0917800875 20 181119.8855659372 30 0.0 11 527467.4798403427 21 180786.7453186707 31 0.0 0 LINE 5 174E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527367.4266915865 20 180785.7036156728 30 0.0 11 527347.4819516342 21 181077.6241073057 31 0.0 0 LINE 5 174F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527408.1019101263 20 180943.3302605271 30 0.0 11 527499.6950365228 21 180961.2896424068 31 0.0 0 LINE 5 1750 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527466.2385014737 20 180950.5102007901 30 0.0 11 527525.6073279321 21 181009.0586822982 31 0.0 0 LINE 5 1751 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527460.6400141142 20 180962.3815086723 30 0.0 11 527538.0593810993 21 180941.635684193 31 0.0 0 LINE 5 1752 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527566.2059370142 20 180776.8334207803 30 0.0 11 527530.5057297896 21 180951.7505387501 31 0.0 0 LINE 5 1753 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527077.0853426155 20 181153.9455596111 30 0.0 11 527370.172406016 21 181211.0306242986 31 0.0 0 LINE 5 1754 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527387.1968684147 20 181613.9091956559 30 0.0 11 527546.0443947647 21 181295.2754065605 31 0.0 0 LINE 5 1755 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529864.0625938844 20 179850.1100024555 30 0.0 11 530689.4088798159 21 179901.2472741166 31 0.0 0 LINE 5 1756 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526146.3666421647 20 183861.9215044605 30 0.0 11 526295.0595649951 21 183266.6983786453 31 0.0 0 LINE 5 1757 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526156.7676960638 20 183757.2998493608 30 0.0 11 526872.0452317546 21 184095.1589363041 31 0.0 0 LINE 5 1758 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526280.1281120633 20 183818.8283446044 30 0.0 11 526320.8011047294 21 183676.6896715689 31 0.0 0 LINE 5 1759 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526172.6945403687 20 183694.0884457485 30 0.0 11 526619.3832154593 21 183906.1116386753 31 0.0 0 LINE 5 175A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526303.3104941537 20 183704.2550264607 30 0.0 11 526364.2262575479 21 183649.3882056604 31 0.0 0 LINE 5 175B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526255.6535841598 20 183640.3477925701 30 0.0 11 526315.3269201439 21 183704.818882624 31 0.0 0 LINE 5 175C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526260.794374798 20 183658.6587778636 30 0.0 11 526298.2976688607 21 183463.3442732338 31 0.0 0 LINE 5 175D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526147.1218396106 20 183612.73058267 30 0.0 11 526579.828602082 21 183627.6998522125 31 0.0 0 LINE 5 175E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526354.247191199 20 183467.0635497783 30 0.0 11 526362.9256044818 21 183653.5160206742 31 0.0 0 LINE 5 175F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526293.6425841297 20 183466.2296248381 30 0.0 11 526354.8351812499 21 183467.6741797741 31 0.0 0 LINE 5 1760 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526441.1573141331 20 183292.5913131285 30 0.0 11 526423.5172909697 21 183982.9678032511 31 0.0 0 LINE 5 1761 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526500.3735382098 20 183698.0161894802 30 0.0 11 526927.332856658 21 183800.9215245747 31 0.0 0 LINE 5 1762 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526494.6144850082 20 183767.2726717287 30 0.0 11 526517.7762170607 21 183574.729034389 31 0.0 0 LINE 5 1763 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526566.8286919588 20 183774.8559771781 30 0.0 11 526573.9822678175 21 183710.9461027097 31 0.0 0 LINE 5 1764 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526514.7235287358 20 183790.4225115961 30 0.0 11 526578.1702533896 21 183763.7435188542 31 0.0 0 LINE 5 1765 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526557.7250167089 20 183763.9802964612 30 0.0 11 526943.1435876271 21 183882.5114018416 31 0.0 0 LINE 5 1766 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526593.1821208949 20 183967.9472765855 30 0.0 11 526738.5555161251 21 183587.449878167 31 0.0 0 LINE 5 1767 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526725.3374610824 20 183585.8436353218 30 0.0 11 526953.0738168576 21 183657.7597249765 31 0.0 0 LINE 5 1768 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526686.9306696731 20 183399.2137364918 30 0.0 11 526736.0505498801 21 183600.4452431444 31 0.0 0 LINE 5 1769 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526621.5764646847 20 183456.9269267728 30 0.0 11 526706.9655038702 21 183457.1051075179 31 0.0 0 LINE 5 176A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526687.7712547906 20 184026.4867210937 30 0.0 11 526715.4590134472 21 183940.72263176 31 0.0 0 LINE 5 176B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526817.252760931 20 184107.5751165661 30 0.0 11 526951.7391244286 21 183654.9587585502 31 0.0 0 LINE 5 176C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526535.4923129867 20 183622.9021839629 30 0.0 11 526945.7142486438 21 183730.3879497893 31 0.0 0 LINE 5 176D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526907.4315473432 20 183254.0098220853 30 0.0 11 526941.9868780364 21 183736.2837096106 31 0.0 0 LINE 5 176E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526816.1450377863 20 183238.5351007249 30 0.0 11 526922.9130617307 21 183287.4239214544 31 0.0 0 LINE 5 176F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526820.2533152976 20 183300.4877575854 30 0.0 11 526919.7745033624 21 183253.9997590661 31 0.0 0 LINE 5 1770 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526820.164002127 20 183490.4963649759 30 0.0 11 526838.3844023372 21 183289.3117523006 31 0.0 0 LINE 5 1771 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526590.6611682273 20 183392.0731721455 30 0.0 11 526922.0915035857 21 183441.5086364376 31 0.0 0 LINE 5 1772 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526571.9585185818 20 183483.7618569228 30 0.0 11 526603.371210842 21 183366.4558115051 31 0.0 0 LINE 5 1773 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526501.4775952947 20 183359.9989028833 30 0.0 11 526522.4218541533 21 183478.9487620135 31 0.0 0 LINE 5 1774 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526519.0287964525 20 183473.1296748034 30 0.0 11 526573.9878772992 21 183482.9846393319 31 0.0 0 LINE 5 1775 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526196.4405248281 20 183372.1430748632 30 0.0 11 526757.6198582386 21 183412.0845848348 31 0.0 0 LINE 5 1776 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526766.4044345876 20 183421.7727726658 30 0.0 11 526767.9398491217 21 183397.536496668 31 0.0 0 LINE 5 1777 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526890.5451039946 20 183565.7949545252 30 0.0 11 526935.8445084186 21 183564.3454263059 31 0.0 0 LINE 5 1778 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526877.7831560563 20 183574.6526275019 30 0.0 11 526898.5791011399 21 183562.5416778816 31 0.0 0 LINE 5 1779 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526868.7046423821 20 183638.1037935833 30 0.0 11 526880.9324460784 21 183567.3058897442 31 0.0 0 LINE 5 177A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526694.7455424822 20 183449.2134150571 30 0.0 11 526718.8337582751 21 183114.217383739 31 0.0 0 LINE 5 177B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526797.9205867572 20 183062.9766257928 30 0.0 11 526965.7571857292 21 183122.9233535809 31 0.0 0 LINE 5 177C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526644.3091041178 20 183148.8166298903 30 0.0 11 526677.8083660316 21 183409.5486689271 31 0.0 0 LINE 5 177D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526549.6285343083 20 183400.1772286422 30 0.0 11 526552.4613872791 21 183364.7658085349 31 0.0 0 LINE 5 177E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526689.3727600271 20 183265.9906037531 30 0.0 11 526803.5007252154 21 183264.9666445346 31 0.0 0 LINE 5 177F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526768.5595068004 20 183261.1394582676 30 0.0 11 526838.494677635 21 183306.5448998165 31 0.0 0 LINE 5 1780 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526765.464147099 20 183273.8944478745 30 0.0 11 526837.1258694434 21 183237.9953508338 31 0.0 0 LINE 5 1781 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526831.5368826524 20 183070.9002346203 30 0.0 11 526831.7619163459 21 183249.4232088129 31 0.0 0 LINE 5 1782 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526646.5637345624 20 183657.2058092401 30 0.0 11 526664.2117238904 21 183613.6322116076 31 0.0 0 LINE 5 1783 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526601.6364027762 20 183601.1158308463 30 0.0 11 526665.3903993997 21 183615.1238843356 31 0.0 0 LINE 5 1784 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526568.5371013311 20 183637.9940329533 30 0.0 11 526579.2708064839 21 183534.2263568313 31 0.0 0 LINE 5 1785 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526428.2985359867 20 183538.715750499 30 0.0 11 526726.8775057319 21 183535.6612179669 31 0.0 0 LINE 5 1786 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526791.5272269688 20 183610.0263459667 30 0.0 11 526808.1904199362 21 183543.2288778073 31 0.0 0 LINE 5 1787 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526777.0726188523 20 183536.4738519391 30 0.0 11 526835.4334266978 21 183550.8470236224 31 0.0 0 LINE 5 1788 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526780.6436278328 20 183544.3040661218 30 0.0 11 526796.9304441347 21 183474.8546922448 31 0.0 0 LINE 5 1789 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526793.6313980108 20 183476.56806068 30 0.0 11 526848.4617921767 21 183488.6186901389 31 0.0 0 LINE 5 178A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526828.72588772 20 183556.9008460126 30 0.0 11 526847.2574595743 21 183481.6501407461 31 0.0 0 LINE 5 178B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526634.7260185561 20 183852.0697490888 30 0.0 11 526882.8381198066 21 183944.016119175 31 0.0 0 LINE 5 178C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526958.3758547891 20 184280.0246811046 30 0.0 11 526999.0488474554 21 184137.8860080692 31 0.0 0 LINE 5 178D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526850.9422830945 20 184155.2847822487 30 0.0 11 527297.6309581853 21 184367.3079751753 31 0.0 0 LINE 5 178E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526981.5582368797 20 184165.4513629608 30 0.0 11 527042.4740002738 21 184110.5845421606 31 0.0 0 LINE 5 178F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526933.9013268857 20 184101.5441290703 30 0.0 11 526993.5746628696 21 184166.0152191241 31 0.0 0 LINE 5 1790 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526939.5611466158 20 184118.1083122997 30 0.0 11 526977.0644406785 21 183922.79380767 31 0.0 0 LINE 5 1791 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526740.309918598 20 184070.9843235278 30 0.0 11 527258.076344808 21 184088.8961887127 31 0.0 0 LINE 5 1792 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527032.4949339247 20 183928.2598862781 30 0.0 11 527041.1733472075 21 184114.7123571743 31 0.0 0 LINE 5 1793 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526971.8903268556 20 183927.4259613383 30 0.0 11 527033.0829239759 21 183928.8705162743 31 0.0 0 LINE 5 1794 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527013.9204027358 20 183633.0017334758 30 0.0 11 527012.2254621887 21 183930.2273940919 31 0.0 0 LINE 5 1795 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527009.8694960516 20 183701.3044251353 30 0.0 11 527122.6870704073 21 183709.6708002807 31 0.0 0 LINE 5 1796 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527122.6138772766 20 183628.2042443963 30 0.0 11 527104.861432775 21 184383.5561167509 31 0.0 0 LINE 5 1797 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527178.6212809359 20 184159.2125259804 30 0.0 11 527813.577229433 21 184288.3144994509 31 0.0 0 LINE 5 1798 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527172.862227734 20 184228.4690082291 30 0.0 11 527196.0239597866 21 184035.925370889 31 0.0 0 LINE 5 1799 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527245.0764346846 20 184236.052313678 30 0.0 11 527252.2300105434 21 184172.14243921 31 0.0 0 LINE 5 179A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527192.9712714617 20 184251.6188480962 30 0.0 11 527256.4179961154 21 184224.9398553542 31 0.0 0 LINE 5 179B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527235.9727594348 20 184225.1766329612 30 0.0 11 527370.3370712806 21 184266.4988514751 31 0.0 0 LINE 5 179C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527271.4298636206 20 184429.1436130856 30 0.0 11 527416.803258851 21 184048.6462146672 31 0.0 0 LINE 5 179D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527403.5852038083 20 184047.0399718219 30 0.0 11 527631.3215595834 21 184118.9560614766 31 0.0 0 LINE 5 179E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527365.1784123991 20 183860.4100729922 30 0.0 11 527414.298292606 21 184061.6415796445 31 0.0 0 LINE 5 179F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527299.8242074107 20 183918.1232632729 30 0.0 11 527385.2132465961 21 183918.301444018 31 0.0 0 LINE 5 17A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527380.8466232018 20 184490.1155273246 30 0.0 11 527408.5343818584 21 184404.3514379912 31 0.0 0 LINE 5 17A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527213.7400557126 20 184084.0985204632 30 0.0 11 527623.9619913699 21 184191.5842862895 31 0.0 0 LINE 5 17A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527494.3927805122 20 183699.7314372251 30 0.0 11 527601.1608044566 21 183748.6202579545 31 0.0 0 LINE 5 17A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527498.5010580233 20 183761.6840940857 30 0.0 11 527598.0222460883 21 183715.1960955663 31 0.0 0 LINE 5 17A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527498.4117448529 20 183951.6927014761 30 0.0 11 527516.6321450631 21 183750.5080888008 31 0.0 0 LINE 5 17A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527268.9089109532 20 183853.2695086456 30 0.0 11 527693.7275002586 21 183907.4760789607 31 0.0 0 LINE 5 17A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527250.2062613076 20 183944.9581934229 30 0.0 11 527281.6189535678 21 183827.6521480053 31 0.0 0 LINE 5 17A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527179.7253380207 20 183821.1952393834 30 0.0 11 527200.6695968792 21 183940.1450985137 31 0.0 0 LINE 5 17A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527197.2765391785 20 183934.3260113036 30 0.0 11 527252.235620025 21 183944.180975832 31 0.0 0 LINE 5 17A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526874.6882675539 20 183833.3394113636 30 0.0 11 527435.8676009643 21 183873.280921335 31 0.0 0 LINE 5 17AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527444.6521773135 20 183882.969109166 30 0.0 11 527446.1875918474 21 183858.7328331681 31 0.0 0 LINE 5 17AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527568.7928467203 20 184026.9912910253 30 0.0 11 527646.2080503886 21 184027.1825246443 31 0.0 0 LINE 5 17AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527556.0308987824 20 184035.8489640022 30 0.0 11 527576.8268438658 21 184023.7380143818 31 0.0 0 LINE 5 17AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527546.9523851079 20 184099.3001300833 30 0.0 11 527559.1801888044 21 184028.5022262444 31 0.0 0 LINE 5 17AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527372.9932852081 20 183910.4097515571 30 0.0 11 527426.9250448026 21 183559.489228346 31 0.0 0 LINE 5 17AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527113.6925585766 20 183645.9169350216 30 0.0 11 527297.6811319859 21 183557.7418069882 31 0.0 0 LINE 5 17B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527276.4040582523 20 183535.0564137323 30 0.0 11 527356.0561087577 21 183870.7450054275 31 0.0 0 LINE 5 17B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527227.8762770341 20 183861.3735651424 30 0.0 11 527230.7091300049 21 183825.962145035 31 0.0 0 LINE 5 17B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527388.414985323 20 183727.0003715881 30 0.0 11 527481.7484679412 21 183726.1629810347 31 0.0 0 LINE 5 17B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527446.8072495261 20 183722.3357947676 30 0.0 11 527516.7424203608 21 183767.7412363167 31 0.0 0 LINE 5 17B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527443.7118898248 20 183735.0907843745 30 0.0 11 527515.3736121694 21 183699.1916873341 31 0.0 0 LINE 5 17B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527507.0987654129 20 183584.6688198411 30 0.0 11 527510.0096590718 21 183710.619545313 31 0.0 0 LINE 5 17B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526916.7194524115 20 183661.7243328356 30 0.0 11 527183.8830550492 21 183626.0490480191 31 0.0 0 LINE 5 17B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527324.8114772883 20 184118.4021457402 30 0.0 11 527342.4594666163 21 184074.8285481079 31 0.0 0 LINE 5 17B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527279.8841455021 20 184062.3121673466 30 0.0 11 527343.6381421257 21 184076.3202208358 31 0.0 0 LINE 5 17B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527246.7848440569 20 184099.1903694535 30 0.0 11 527257.5185492098 21 183995.4226933316 31 0.0 0 LINE 5 17BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527106.5462787125 20 183999.912086999 30 0.0 11 527405.1252484577 21 183996.857554467 31 0.0 0 LINE 5 17BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527469.7749696947 20 184071.2226824668 30 0.0 11 527486.438162662 21 184004.4252143077 31 0.0 0 LINE 5 17BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527455.3203615782 20 183997.6701884394 30 0.0 11 527513.6811694236 21 184012.0433601225 31 0.0 0 LINE 5 17BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527458.8913705585 20 184005.500402622 30 0.0 11 527475.1781868609 21 183936.0510287449 31 0.0 0 LINE 5 17BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527471.8791407367 20 183937.7643971802 30 0.0 11 527526.7095349025 21 183949.815026639 31 0.0 0 LINE 5 17BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527506.9736304459 20 184018.0971825126 30 0.0 11 527525.5052023 21 183942.8464772463 31 0.0 0 LINE 5 17C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527008.1685822724 20 183773.3808903472 30 0.0 11 527120.6368161418 21 183780.828501626 31 0.0 0 LINE 5 17C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527312.973761282 20 184313.2660855889 30 0.0 11 527561.0858625324 21 184405.2124556752 31 0.0 0 LINE 5 17C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527335.8734279835 20 185040.8666845549 30 0.0 11 527919.0477671159 21 183166.9809628446 31 0.0 0 LINE 5 17C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527544.4143172993 20 183632.8616138635 30 0.0 11 527673.3810309673 21 183445.6796394856 31 0.0 0 LINE 5 17C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527359.3700625528 20 183606.9296638141 30 0.0 11 527392.2242523522 21 183440.3358468486 31 0.0 0 LINE 5 17C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526915.8269966726 20 183500.6085807193 30 0.0 11 527693.6597362677 21 183645.0693403355 31 0.0 0 LINE 5 17C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527448.9719851374 20 183529.9862193265 30 0.0 11 527643.2933316129 21 183069.7323576719 31 0.0 0 LINE 5 17C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527516.4241439892 20 183546.7144378046 30 0.0 11 527330.0369680068 21 183493.1482288574 31 0.0 0 LINE 5 17C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527535.4248805666 20 183476.6332690318 30 0.0 11 527473.4732808892 21 183459.3808779063 31 0.0 0 LINE 5 17C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527542.4841681129 20 183530.5538725857 30 0.0 11 527526.2629878082 21 183463.6649435127 31 0.0 0 LINE 5 17CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527523.236772931 20 183483.8863626044 30 0.0 11 527721.4676373326 21 183085.4501236723 31 0.0 0 LINE 5 17CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527733.0237619601 20 183484.0319248232 30 0.0 11 527377.7980020232 21 183277.2218469782 31 0.0 0 LINE 5 17CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527374.1047094388 20 183290.0146803263 30 0.0 11 527481.4129521734 21 183076.6588443756 31 0.0 0 LINE 5 17CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527183.7386016345 20 183298.1722389731 30 0.0 11 527390.2276942121 21 183281.7668573049 31 0.0 0 LINE 5 17CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527230.2927904696 20 183371.8926021298 30 0.0 11 527244.0838495338 21 183287.6244204047 31 0.0 0 LINE 5 17CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528134.8774861161 20 183393.6977037461 30 0.0 11 527478.4350058732 21 183077.5298510543 31 0.0 0 LINE 5 17D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527380.4186075985 20 183483.339926926 30 0.0 11 527551.9385165398 21 183095.5047207027 31 0.0 0 LINE 5 17D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527214.3653902986 20 183070.3577530247 30 0.0 11 527557.1645236159 21 183100.1244745444 31 0.0 0 LINE 5 17D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526863.0108382376 20 183020.7490917978 30 0.0 11 527360.3044246794 21 183087.2087069777 31 0.0 0 LINE 5 17D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527295.0972429494 20 183181.1983438331 30 0.0 11 527099.3917540238 21 183131.1324575882 31 0.0 0 LINE 5 17D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527171.1168625928 20 183359.2724053633 30 0.0 11 527262.9884432511 21 183072.7638563169 31 0.0 0 LINE 5 17D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527084.0237982917 20 183386.3498542505 30 0.0 11 527205.3628897168 21 183391.2783853459 31 0.0 0 LINE 5 17D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527181.1974413807 20 183490.4753190934 30 0.0 11 527073.8736295296 21 183435.073781426 31 0.0 0 LINE 5 17D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527078.4189700695 20 183440.0451490341 30 0.0 11 527085.3698454549 21 183384.6438293321 31 0.0 0 LINE 5 17D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527078.8063363808 20 183778.070793482 30 0.0 11 527078.8091857135 21 183778.0586890183 31 0.0 0 LINE 5 17D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527112.3427896616 20 183635.6020684094 30 0.0 11 527207.7160715952 21 183230.4396688804 31 0.0 0 LINE 5 17DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527218.6809989879 20 183223.312247723 30 0.0 11 527194.9996156784 21 183217.9320380072 31 0.0 0 LINE 5 17DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527380.6546446571 20 183123.7239312546 30 0.0 11 527386.4465854053 21 183078.7729513362 31 0.0 0 LINE 5 17DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527387.3641206894 20 183137.7349489587 30 0.0 11 527378.7239987938 21 183115.2739889114 31 0.0 0 LINE 5 17DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527448.5559520536 20 183156.8145103248 30 0.0 11 527380.6135250315 21 183133.4545235604 31 0.0 0 LINE 5 17DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527234.3446664419 20 183298.4297236824 30 0.0 11 526896.7764445693 21 183201.283339818 31 0.0 0 LINE 5 17DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526899.9827787879 20 183301.2905252701 30 0.0 11 527192.4867734056 21 183308.8257239823 31 0.0 0 LINE 5 17E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527162.7971416081 20 183433.8713913096 30 0.0 11 527128.2904609601 21 183425.4284818214 31 0.0 0 LINE 5 17E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526882.6827136528 20 183103.0669733985 30 0.0 11 527058.9575892087 21 183131.310046931 31 0.0 0 LINE 5 17E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527431.9935369405 20 183379.1591894488 30 0.0 11 527391.7913556132 21 183354.7892375719 31 0.0 0 LINE 5 17E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527369.457562608 20 183414.568266419 30 0.0 11 527393.4518823327 21 183353.8634867969 31 0.0 0 LINE 5 17E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527400.5863184767 20 183453.1242789833 30 0.0 11 527299.8576946609 21 183425.9822934587 31 0.0 0 LINE 5 17E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527280.2173434821 20 183575.7388883725 30 0.0 11 527324.8098717205 21 183280.4928252855 31 0.0 0 LINE 5 17E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527408.5318940674 20 183228.5276283497 30 0.0 11 527345.2459384735 21 183201.4268612583 31 0.0 0 LINE 5 17E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527333.6156467227 20 183231.0694696553 30 0.0 11 527357.1104773119 21 183175.7470972171 31 0.0 0 LINE 5 17E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527341.9150752116 20 183228.7926635495 30 0.0 11 527275.9511290317 21 183201.640615347 31 0.0 0 LINE 5 17E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527277.1165489448 20 183205.1706483711 30 0.0 11 527297.7556320369 21 183152.9631963756 31 0.0 0 LINE 5 17EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527362.0173412369 20 183183.3340947189 30 0.0 11 527290.6842075074 21 183153.0409959863 31 0.0 0 LINE 5 17EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527622.4769279048 20 183421.9162279387 30 0.0 11 527752.8080714243 21 183191.6391279312 31 0.0 0 LINE 5 17EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526172.6398658639 20 183798.7108105307 30 0.0 11 525758.1454340727 21 184286.030813627 31 0.0 0 LINE 5 17ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525540.2138584358 20 183597.7464136007 30 0.0 11 527616.4438770662 21 184597.5557938863 31 0.0 0 LINE 5 17EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526229.3686672956 20 183925.7679148408 30 0.0 11 526144.9611678353 21 184047.147767945 31 0.0 0 LINE 5 17EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526064.799718067 20 183921.4003476109 30 0.0 11 526511.4883931579 21 184133.4235405376 31 0.0 0 LINE 5 17F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526155.2591332825 20 184016.1683851839 30 0.0 11 526151.2649311015 21 184098.0533325403 31 0.0 0 LINE 5 17F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526075.6150280776 20 184019.6515044495 30 0.0 11 526163.2934473707 21 184025.1217211256 31 0.0 0 LINE 5 17F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526093.0519312629 20 184012.0571435086 30 0.0 11 525965.44190075 21 184164.6019988687 31 0.0 0 LINE 5 17F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525985.5984568236 20 183953.0266835703 30 0.0 11 526270.7776231972 21 184278.805848628 31 0.0 0 LINE 5 17F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526003.6978839475 20 184205.5978744847 30 0.0 11 526153.6406479724 21 184094.4358023696 31 0.0 0 LINE 5 17F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525964.7341469383 20 184159.1711469766 30 0.0 11 526004.542735631 21 184205.6673505589 31 0.0 0 LINE 5 17F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525763.2000248929 20 184377.885917585 30 0.0 11 525992.4067272518 21 184188.6499438754 31 0.0 0 LINE 5 17F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525813.5569578426 20 184331.5626314666 30 0.0 11 525891.368509183 21 184413.6794007321 31 0.0 0 LINE 5 17F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525828.2052620678 20 184465.1304386105 30 0.0 11 526443.4543435843 21 183938.4848300049 31 0.0 0 LINE 5 17F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526275.019891734 20 184172.7893517072 30 0.0 11 526624.6944832488 21 184438.5174978444 31 0.0 0 LINE 5 17FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526325.0357963618 20 184124.5396230914 30 0.0 11 526190.5049777605 21 184264.2213218149 31 0.0 0 LINE 5 17FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526376.5689214775 20 184175.693657369 30 0.0 11 526331.5770466168 21 184221.6433787894 31 0.0 0 LINE 5 17FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526355.6854196749 20 184125.4826587656 30 0.0 11 526375.1302151602 21 184191.5065593739 31 0.0 0 LINE 5 17FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526362.3870306762 20 184175.5167183563 30 0.0 11 526697.9034325305 21 184399.1812927491 31 0.0 0 LINE 5 17FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526542.8303198861 20 184074.0280263877 30 0.0 11 526339.9496769996 21 184427.2292990156 31 0.0 0 LINE 5 17FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526330.3480265903 20 184418.0040453817 30 0.0 11 526530.0534350708 21 184548.9754984417 31 0.0 0 LINE 5 1800 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526161.4718436333 20 184506.245960555 30 0.0 11 526348.4341758878 21 184417.0721515127 31 0.0 0 LINE 5 1801 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526164.8650642328 20 184419.1226542814 30 0.0 11 526218.990871217 21 184485.1659490183 31 0.0 0 LINE 5 1802 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526712.5106458383 20 184153.2086076598 30 0.0 11 526663.56988205 21 184228.8848432855 31 0.0 0 LINE 5 1803 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526792.6783634435 20 184159.3482499835 30 0.0 11 526527.03949261 21 184549.7123618235 31 0.0 0 LINE 5 1804 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526239.0286861463 20 184247.4892532267 30 0.0 11 526581.6696928112 21 184497.3539504156 31 0.0 0 LINE 5 1805 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526310.9550896549 20 184712.2948244993 30 0.0 11 526583.880833825 21 184490.7385040259 31 0.0 0 LINE 5 1806 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525992.8709973916 20 184929.997010199 30 0.0 11 526183.3718907056 21 184783.0056012491 31 0.0 0 LINE 5 1807 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525830.383102649 20 184143.3497653357 30 0.0 11 526216.1373391672 21 184552.8753902649 31 0.0 0 LINE 5 1808 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526229.1974565366 20 184553.5559043262 30 0.0 11 526211.3909523055 21 184570.0690196928 31 0.0 0 LINE 5 1809 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526419.2687016282 20 184558.6761052552 30 0.0 11 526458.2672452309 21 184607.4056927582 31 0.0 0 LINE 5 180A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526418.0624437224 20 184543.1883479094 30 0.0 11 526421.8277408346 21 184566.9574238335 31 0.0 0 LINE 5 180B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526461.4818759007 20 184496.0372843275 30 0.0 11 526414.3616489805 21 184550.2733109726 31 0.0 0 LINE 5 180C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525750.5794705347 20 184608.7482925879 30 0.0 11 525816.1275078263 21 184826.6854894777 31 0.0 0 LINE 5 180D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525836.2877733857 20 184447.0196035297 30 0.0 11 525735.5049749351 21 184637.1933595237 31 0.0 0 LINE 5 180E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525625.4714226731 20 184372.2929563019 30 0.0 11 525771.5186383708 21 184272.9622200615 31 0.0 0 LINE 5 180F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525713.4256940008 20 184298.8314740285 30 0.0 11 525865.2733286215 21 184513.9619392872 31 0.0 0 LINE 5 1810 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526335.831346627 20 184311.854184065 30 0.0 11 526313.2303502487 21 184353.0768101416 31 0.0 0 LINE 5 1811 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526263.9695257499 20 184312.5095601781 30 0.0 11 526315.1312625812 21 184353.0468804205 31 0.0 0 LINE 5 1812 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526271.614012543 20 184263.5490927737 30 0.0 11 526198.0054952921 21 184337.4728996437 31 0.0 0 LINE 5 1813 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526106.0305223349 20 184217.6672843158 30 0.0 11 526292.442435946 21 184450.9253598606 31 0.0 0 LINE 5 1814 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526390.9327040018 20 184453.9955091639 30 0.0 11 526349.7161546585 21 184509.1385940667 31 0.0 0 LINE 5 1815 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526324.8082092294 20 184489.3006966659 30 0.0 11 526372.8429470729 21 184525.42874556 31 0.0 0 LINE 5 1816 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526333.1325333442 20 184487.1166666029 30 0.0 11 526289.6234289066 21 184543.6448343446 31 0.0 0 LINE 5 1817 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526288.8650342379 20 184540.0055797161 30 0.0 11 526332.868234571 21 184574.8668498478 31 0.0 0 LINE 5 1818 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526373.2923182385 20 184516.4044500072 30 0.0 11 526326.7078393501 21 184578.3396913904 31 0.0 0 LINE 5 1819 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526897.6134313817 20 184224.2046449315 30 0.0 11 526750.5592740903 21 184399.9929827601 31 0.0 0 LINE 5 181A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526842.5800905745 20 184263.4335107758 30 0.0 11 527056.9201882246 21 184512.6902832656 31 0.0 0 LINE 5 181B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526789.8404489752 20 184439.4823091223 30 0.0 11 526939.783213 21 184328.3202370075 31 0.0 0 LINE 5 181C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526750.8767119656 20 184393.0555816145 30 0.0 11 526790.6853006583 21 184439.5517851969 31 0.0 0 LINE 5 181D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526549.3425899203 20 184611.7703522228 30 0.0 11 526778.5492922794 21 184422.5343785133 31 0.0 0 LINE 5 181E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526692.5574984854 20 184628.4080760892 30 0.0 11 527188.3396056741 21 184207.6850059707 31 0.0 0 LINE 5 181F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527061.1624567615 20 184406.6737863451 30 0.0 11 527272.4860252165 21 184567.2648657181 31 0.0 0 LINE 5 1820 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527111.1783613893 20 184358.4240577295 30 0.0 11 526976.6475427879 21 184498.1057564528 31 0.0 0 LINE 5 1821 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527162.711486505 20 184409.5780920069 30 0.0 11 527117.7196116441 21 184455.5278134274 31 0.0 0 LINE 5 1822 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527141.8279847026 20 184359.3670934034 30 0.0 11 527161.2727801879 21 184425.3909940119 31 0.0 0 LINE 5 1823 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527148.5295957035 20 184409.4011529941 30 0.0 11 527484.0459975578 21 184633.065727387 31 0.0 0 LINE 5 1824 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527274.0698449415 20 184403.2704430421 30 0.0 11 527126.0922420271 21 184661.1137336536 31 0.0 0 LINE 5 1825 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527116.490591618 20 184651.8884800196 30 0.0 11 527316.1960000983 21 184782.8599330798 31 0.0 0 LINE 5 1826 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526978.3772804878 20 184725.4576938802 30 0.0 11 527134.5767409155 21 184650.9565861506 31 0.0 0 LINE 5 1827 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526827.5450292298 20 184482.4090883761 30 0.0 11 527005.1334362445 21 184719.0503836559 31 0.0 0 LINE 5 1828 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527025.1712511737 20 184481.3736878646 30 0.0 11 527367.8122578385 21 184731.2383850533 31 0.0 0 LINE 5 1829 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526932.5809737569 20 185045.0461003779 30 0.0 11 527135.858719686 21 184743.0230287044 31 0.0 0 LINE 5 182A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526904.8237453241 20 184941.8305093475 30 0.0 11 527010.2055709973 21 184993.6397609068 31 0.0 0 LINE 5 182B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526955.4196256611 20 184905.843476556 30 0.0 11 526982.3255175957 21 185012.3407716361 31 0.0 0 LINE 5 182C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526616.5256676765 20 184377.2341999736 30 0.0 11 526838.8137058941 21 184605.691738446 31 0.0 0 LINE 5 182D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526825.3214585717 20 184582.8102803995 30 0.0 11 526753.5128899614 21 184978.2282779938 31 0.0 0 LINE 5 182E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526752.0011926325 20 184864.9640085656 30 0.0 11 526915.8108504811 21 184896.5445007636 31 0.0 0 LINE 5 182F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526892.2504283604 20 184890.6714296093 30 0.0 11 526971.645669471 21 184916.1464748675 31 0.0 0 LINE 5 1830 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526900.1754142045 20 184880.2088481438 30 0.0 11 526917.6708325288 21 184958.426863686 31 0.0 0 LINE 5 1831 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526823.7113538355 20 185024.4236562697 30 0.0 11 526923.1332783114 21 184947.0457557922 31 0.0 0 LINE 5 1832 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526510.1397750775 20 184518.3029687869 30 0.0 11 526588.3675743969 21 184645.4063717812 31 0.0 0 LINE 5 1833 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527121.9739116546 20 184545.7386187029 30 0.0 11 527099.3729152762 21 184586.9612447796 31 0.0 0 LINE 5 1834 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527050.1120907775 20 184546.3939948161 30 0.0 11 527101.2738276086 21 184586.9313150585 31 0.0 0 LINE 5 1835 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527057.7565775703 20 184497.4335274115 30 0.0 11 526984.1480603196 21 184571.3573342815 31 0.0 0 LINE 5 1836 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526892.1730873623 20 184451.5517189536 30 0.0 11 527078.5850009737 21 184684.8097944985 31 0.0 0 LINE 5 1837 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527177.0752690295 20 184687.8799438017 30 0.0 11 527135.858719686 21 184743.0230287044 31 0.0 0 LINE 5 1838 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526976.7466853434 20 184707.544365911 30 0.0 11 527158.9855121005 21 184759.3131801978 31 0.0 0 LINE 5 1839 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526654.4660197752 20 184518.5584666173 30 0.0 11 526731.3448775517 21 184600.9854753612 31 0.0 0 LINE 5 183A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526950.1892693617 20 185002.0656262611 30 0.0 11 526794.7357978775 21 185555.5789665183 31 0.0 0 LINE 5 183B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526884.6421618659 20 185022.8640277708 30 0.0 11 526821.1612098639 21 185241.1291727191 31 0.0 0 LINE 5 183C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526747.5557430888 20 184895.8949132786 30 0.0 11 526639.2579063532 21 185026.6789956317 31 0.0 0 LINE 5 183D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526627.0050355719 20 184823.9927585792 30 0.0 11 527362.5387850584 21 185447.5890790977 31 0.0 0 LINE 5 183E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526744.594477287 20 185013.962813596 30 0.0 11 526538.0210973291 21 185401.533718455 31 0.0 0 LINE 5 183F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526800.2018736364 20 185055.6454778395 30 0.0 11 526640.8564858529 21 184945.1078575293 31 0.0 0 LINE 5 1840 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526757.9191734891 20 185114.6757368199 30 0.0 11 526705.3834328252 21 185077.5860933195 31 0.0 0 LINE 5 1841 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526804.1579407269 20 185086.0533429193 30 0.0 11 526742.0791783166 21 185115.7767811565 31 0.0 0 LINE 5 1842 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526755.8325669559 20 185100.647073046 30 0.0 11 526588.5271048182 21 185467.5339494677 31 0.0 0 LINE 5 1843 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526884.7942566758 20 185262.5995901697 30 0.0 11 526503.7627330624 21 185118.6319818105 31 0.0 0 LINE 5 1844 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526511.3389918514 20 185107.6822193495 30 0.0 11 526413.8858925074 21 185325.7158523542 31 0.0 0 LINE 5 1845 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526397.2989610982 20 184955.0366424418 30 0.0 11 526515.1427734561 21 185125.3883896891 31 0.0 0 LINE 5 1846 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526483.8486768585 20 184944.4947667127 30 0.0 11 526427.2806052112 21 185008.4586083068 31 0.0 0 LINE 5 1847 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526840.4035060879 20 185522.8553234135 30 0.0 11 526412.677887643 21 185322.8579613402 31 0.0 0 LINE 5 1848 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526665.1115230083 20 184990.3428613132 30 0.0 11 526473.077143995 21 185368.4407634845 31 0.0 0 LINE 5 1849 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526142.309491468 20 185023.4850477535 30 0.0 11 526479.960517171 21 185369.568792402 31 0.0 0 LINE 5 184A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525980.8306060982 20 184903.3662741616 30 0.0 11 526345.4878643996 21 185225.2156793015 31 0.0 0 LINE 5 184B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526191.356440681 20 184944.954221952 30 0.0 11 526157.0130028118 21 185057.2487276261 31 0.0 0 LINE 5 184C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526234.9505034651 20 184989.1647108225 30 0.0 11 526134.1058144044 21 185032.7072138333 31 0.0 0 LINE 5 184D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526377.0795550635 20 185115.2702679994 30 0.0 11 526214.5545125192 21 184995.3000970941 31 0.0 0 LINE 5 184E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526436.6567078091 20 184906.6268665365 30 0.0 11 526272.7679378563 21 185158.9520676018 31 0.0 0 LINE 5 184F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526357.4471082533 20 184840.4476801803 30 0.0 11 526327.8126399383 21 184553.7179558004 31 0.0 0 LINE 5 1850 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526702.7607323182 20 184570.3205013269 30 0.0 11 526702.7531557811 21 184570.3303619977 31 0.0 0 LINE 5 1851 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526507.3444309529 20 184805.8431383081 30 0.0 11 526359.9824307177 21 185016.4377554403 31 0.0 0 LINE 5 1852 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526361.3930396807 20 185029.4392917895 30 0.0 11 526342.251967972 21 185014.4935918768 31 0.0 0 LINE 5 1853 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526386.6449285419 20 185217.8952197336 30 0.0 11 526355.4807307931 21 185250.8031207893 31 0.0 0 LINE 5 1854 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526401.7422031849 20 185214.2348940512 30 0.0 11 526378.8775942331 21 185221.7419633934 31 0.0 0 LINE 5 1855 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526455.2131926328 20 185249.5806600645 30 0.0 11 526394.1577971015 21 185211.7111334264 31 0.0 0 LINE 5 1856 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526429.4944541394 20 184994.0813645118 30 0.0 11 526140.7997494224 21 184793.968666802 31 0.0 0 LINE 5 1857 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526284.3821589323 20 184804.1957133648 30 0.0 11 526411.0839343908 21 184955.0786364757 31 0.0 0 LINE 5 1858 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526813.624339175 20 184874.9987138734 30 0.0 11 526117.198523644 21 184800.3091828398 31 0.0 0 LINE 5 1859 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526282.1184163698 20 184883.8219749501 30 0.0 11 526219.5156131227 21 184953.0515150769 31 0.0 0 LINE 5 185A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526239.8562063999 20 184924.3845242305 30 0.0 11 526227.366538283 21 185006.8259606097 31 0.0 0 LINE 5 185B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526251.4485595676 20 184930.5398763398 30 0.0 11 526177.0208654439 21 184960.2832111424 31 0.0 0 LINE 5 185C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526055.79485749 20 184845.1473364929 30 0.0 11 526189.1273452085 21 184963.8610706331 31 0.0 0 LINE 5 185D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526617.0051048034 20 185096.1699463408 30 0.0 11 526572.7061751235 21 185080.4309893497 31 0.0 0 LINE 5 185E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526604.8998507491 20 185025.3320070574 30 0.0 11 526573.0388196335 21 185082.3028096171 31 0.0 0 LINE 5 185F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526673.3455933371 20 184854.2911744704 30 0.0 11 526472.7948735252 21 185075.5108393422 31 0.0 0 LINE 5 1860 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526485.4681327537 20 185173.2305774661 30 0.0 11 526339.4935442785 21 185092.6910088522 31 0.0 0 LINE 5 1861 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526770.5658452664 20 185216.7153135767 30 0.0 11 526674.5592140982 21 185463.2847288145 31 0.0 0 LINE 5 1862 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526034.838448984 20 184377.5229186959 30 0.0 11 526162.9583683656 21 184271.426179767 31 0.0 0 LINE 5 1863 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525944.3955297334 20 184418.9332707799 30 0.0 11 525883.1890116699 21 184244.8502677682 31 0.0 0 LINE 5 1864 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526610.0769078264 20 185042.3659122216 30 0.0 11 526510.4617097421 21 184980.6649727358 31 0.0 0 LINE 5 1865 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526540.7939205786 20 184077.5732577944 30 0.0 11 526721.0522125807 21 183995.2863186054 31 0.0 0 LINE 5 1866 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529002.4945046415 20 182989.4166194158 30 0.0 11 529149.9114243247 21 182978.1940307746 31 0.0 0 LINE 5 1867 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529082.1590611431 20 182845.3486731855 30 0.0 11 529038.4653913891 21 183337.8681855062 31 0.0 0 LINE 5 1868 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529117.9874533724 20 182971.3653905561 30 0.0 11 529190.5948485013 21 183009.4345963159 31 0.0 0 LINE 5 1869 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529161.3658895741 20 182904.4802136752 30 0.0 11 529121.6319291057 21 182982.8296927146 31 0.0 0 LINE 5 186A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529145.9800161928 20 182915.6603215054 30 0.0 11 529342.1620844844 21 182882.9976690538 31 0.0 0 LINE 5 186B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529149.5716516822 20 182793.1125980499 30 0.0 11 529285.810685997 21 183204.0847952215 31 0.0 0 LINE 5 186C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529358.1052558049 20 182936.7563646868 30 0.0 11 529186.2722550136 21 183009.6484671357 31 0.0 0 LINE 5 186D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529337.839644036 20 182879.6344003608 30 0.0 11 529357.7368392796 21 182937.5198242835 31 0.0 0 LINE 5 186E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529628.5345965598 20 182816.7965311425 30 0.0 11 529349.2207426371 21 182918.4318456688 31 0.0 0 LINE 5 186F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529563.0764663739 20 182836.7188986079 30 0.0 11 529594.4117381667 21 182945.4198740323 31 0.0 0 LINE 5 1870 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.7820878086 20 182917.0583723003 30 0.0 11 528898.3699407844 21 183180.8853994138 31 0.0 0 LINE 5 1871 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529192.2768187649 20 183153.9957730478 30 0.0 11 529244.0572068602 21 183590.1179566264 31 0.0 0 LINE 5 1872 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529125.3310361034 20 183172.6475614621 30 0.0 11 529313.9339647009 21 183127.4983262947 31 0.0 0 LINE 5 1873 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529143.2993213422 20 183243.00052112 30 0.0 11 529205.7155989878 21 183227.5133010033 31 0.0 0 LINE 5 1874 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529110.6058846278 20 183199.5447479236 30 0.0 11 529157.6589570039 21 183249.7768482477 31 0.0 0 LINE 5 1875 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529150.3364046958 20 183230.6864319542 30 0.0 11 529173.0367678382 21 183633.2802610981 31 0.0 0 LINE 5 1876 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528971.3791487153 20 183334.7731061746 30 0.0 11 529378.6802900167 21 183338.9533619875 31 0.0 0 LINE 5 1877 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529375.5960000428 20 183326.0002098403 30 0.0 11 529387.2477611892 21 183564.537435772 31 0.0 0 LINE 5 1878 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529537.2708909291 20 183225.1685163086 30 0.0 11 529365.6238454158 21 183341.117529533 31 0.0 0 LINE 5 1879 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529460.4528499908 20 183183.9256620372 30 0.0 11 529489.9408801077 21 183264.0616454732 31 0.0 0 LINE 5 187A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528721.379921109 20 183580.3838869297 30 0.0 11 529039.3752873129 21 183439.9840603285 31 0.0 0 LINE 5 187B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528918.2607131755 20 183593.3886842624 30 0.0 11 529389.4108538934 21 183562.3130601848 31 0.0 0 LINE 5 187C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529274.9119920447 20 183160.8419620406 30 0.0 11 529316.5842563571 21 183582.8593180066 31 0.0 0 LINE 5 187D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529750.0154457829 20 183381.516104049 30 0.0 11 529309.7609766477 21 183581.4115163893 31 0.0 0 LINE 5 187E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529988.005583848 20 183294.6626457544 30 0.0 11 529487.4641051801 21 183495.7242144426 31 0.0 0 LINE 5 187F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529732.8236843104 20 183290.5373308892 30 0.0 11 529724.0578069372 21 183407.6385141588 31 0.0 0 LINE 5 1880 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.1539762847 20 183315.9056936367 30 0.0 11 529754.3115197908 21 183393.0872929542 31 0.0 0 LINE 5 1881 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529497.9412056234 20 183381.8108317713 30 0.0 11 529692.9311665412 21 183329.0268711166 31 0.0 0 LINE 5 1882 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529510.5331576017 20 183132.4113161336 30 0.0 11 529579.2785852399 21 183460.3808246315 31 0.0 0 LINE 5 1883 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529418.0562012752 20 183146.715740923 30 0.0 11 529538.9701211892 21 183135.4334761842 31 0.0 0 LINE 5 1884 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529509.6380631061 20 183037.6396577352 30 0.0 11 529405.3659134461 21 183098.5908658569 31 0.0 0 LINE 5 1885 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529409.6444093042 20 183093.3880695214 30 0.0 11 529419.489826466 21 183148.3488614938 31 0.0 0 LINE 5 1886 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529392.3121772476 20 182755.8068495324 30 0.0 11 529549.751119872 21 183295.9277136093 31 0.0 0 LINE 5 1887 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529543.7167941479 20 183307.5301563754 30 0.0 11 529566.9777532239 21 183300.5528822005 31 0.0 0 LINE 5 1888 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529451.7724354552 20 183473.9619128789 30 0.0 11 529468.8639611219 21 183515.9382981882 31 0.0 0 LINE 5 1889 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529439.0339467371 20 183465.070535544 30 0.0 11 529457.6133766657 21 183480.3659994512 31 0.0 0 LINE 5 188A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529376.3793059448 20 183478.5933264844 30 0.0 11 529447.0171259769 21 183465.4723222404 31 0.0 0 LINE 5 188B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529493.0974417447 20 183249.8615614997 30 0.0 11 529916.9032413744 21 183154.751472073 31 0.0 0 LINE 5 188C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529888.0572707052 20 183141.4631650017 30 0.0 11 529896.7457502339 21 183342.5572290356 31 0.0 0 LINE 5 188D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529651.0735796021 20 182914.8438654025 30 0.0 11 529906.1021607946 21 183172.8070170999 31 0.0 0 LINE 5 188E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529875.041216191 20 183036.5611619992 30 0.0 11 529524.4111204172 21 183220.203281717 31 0.0 0 LINE 5 188F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529488.683131434 20 183096.7472006318 30 0.0 11 529522.8742442423 21 183087.1055443997 31 0.0 0 LINE 5 1890 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.4465953165 20 183200.6263381069 30 0.0 11 529703.6460430593 21 183287.8595707087 31 0.0 0 LINE 5 1891 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529695.1001273892 20 183253.764066248 30 0.0 11 529676.8089733075 21 183335.1152550795 31 0.0 0 LINE 5 1892 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529682.0640560481 20 183255.2911076818 30 0.0 11 529740.6163598035 21 183310.0247841765 31 0.0 0 LINE 5 1893 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529895.369820892 20 183246.7525081241 30 0.0 11 529728.0369450099 21 183308.9635329003 31 0.0 0 LINE 5 1894 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529693.5360133447 20 182695.2429836775 30 0.0 11 529533.8761624989 21 182770.7752046368 31 0.0 0 LINE 5 1895 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529585.6253156224 20 182733.8153123566 30 0.0 11 529694.0815682416 21 182973.7654373622 31 0.0 0 LINE 5 1896 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529281.3180175185 20 183276.9133290334 30 0.0 11 529328.3084743434 21 183278.3299818934 31 0.0 0 LINE 5 1897 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529318.3137405335 20 183215.3027187767 30 0.0 11 529327.3189961681 21 183279.9533415037 31 0.0 0 LINE 5 1898 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529272.2357810101 20 183197.0712297279 30 0.0 11 529373.2723181507 21 183171.0989137618 31 0.0 0 LINE 5 1899 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529316.6305635991 20 183031.0828691245 30 0.0 11 529423.1897224751 21 183310.0163325214 31 0.0 0 LINE 5 189A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529375.9058362808 20 183396.4685900099 30 0.0 11 529444.3326079678 21 183388.8962278366 31 0.0 0 LINE 5 189B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529439.860142844 20 183357.3693349594 30 0.0 11 529446.6499833035 21 183417.089264825 31 0.0 0 LINE 5 189C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529433.7575016177 20 183363.4374589976 30 0.0 11 529504.5404009335 21 183354.5911557249 31 0.0 0 LINE 5 189D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529501.7879393648 20 183352.0924976781 30 0.0 11 529509.5296659485 21 183407.695154667 31 0.0 0 LINE 5 189E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529438.6434841719 20 183412.9016860105 30 0.0 11 529515.6462087013 21 183404.1456473196 31 0.0 0 LINE 5 189F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529494.895595546 20 182860.1555962907 30 0.0 11 529526.9711199328 21 182968.2098941174 31 0.0 0 LINE 5 18A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529094.4719762004 20 183333.4875583031 30 0.0 11 529094.416596101 21 183598.0886669403 31 0.0 0 LINE 5 18A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528799.8989817682 20 183846.8871999126 30 0.0 11 528751.9949650761 21 184436.6604579644 31 0.0 0 LINE 5 18A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528708.8283584604 20 183751.1739329707 30 0.0 11 528952.9732172928 21 183774.3958920667 31 0.0 0 LINE 5 18A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528978.6545404572 20 182821.6705424059 30 0.0 11 528841.5271843571 21 184134.0700467983 31 0.0 0 LINE 5 18A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528921.0492463402 20 183767.5672518482 30 0.0 11 528993.6566414693 21 183805.636457608 31 0.0 0 LINE 5 18A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528964.4276825422 20 183700.6820749673 30 0.0 11 528924.6937220741 21 183779.0315540066 31 0.0 0 LINE 5 18A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528950.8601394615 20 183711.7422512852 30 0.0 11 529147.042207753 21 183679.0795988337 31 0.0 0 LINE 5 18A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528925.852151978 20 183508.5272844486 30 0.0 11 529088.8724789651 21 184000.2866565134 31 0.0 0 LINE 5 18A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529161.1670487729 20 183732.9582259788 30 0.0 11 528989.3340479817 21 183805.8503284278 31 0.0 0 LINE 5 18A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529140.901437004 20 183675.836261653 30 0.0 11 529160.7986322474 21 183733.7216855758 31 0.0 0 LINE 5 18AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529431.5963895281 20 183612.9983924347 30 0.0 11 529152.2825356053 21 183714.633706961 31 0.0 0 LINE 5 18AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529366.1382593417 20 183632.9207599 30 0.0 11 529397.4735311349 21 183741.6217353242 31 0.0 0 LINE 5 18AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529473.8438807766 20 183713.2602335924 30 0.0 11 528759.3426455927 21 183958.9421117921 31 0.0 0 LINE 5 18AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528995.3386117331 20 183950.19763434 30 0.0 11 529047.1189998285 21 184386.3198179183 31 0.0 0 LINE 5 18AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528928.3928290715 20 183968.8494227541 30 0.0 11 529116.9957576689 21 183923.7001875868 31 0.0 0 LINE 5 18AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528946.36111431 20 184039.202382412 30 0.0 11 529008.777391956 21 184023.7151622953 31 0.0 0 LINE 5 18B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528913.6676775958 20 183995.7466092156 30 0.0 11 528960.720749972 21 184045.9787095397 31 0.0 0 LINE 5 18B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528953.3981976639 20 184026.8882932462 30 0.0 11 528976.0985608062 21 184429.48212239 31 0.0 0 LINE 5 18B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528774.4409416834 20 184130.9749674667 30 0.0 11 529181.7420829849 21 184135.1552232796 31 0.0 0 LINE 5 18B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529178.657793011 20 184122.2020711322 30 0.0 11 529190.3095541572 21 184360.739297064 31 0.0 0 LINE 5 18B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529340.3326838975 20 184021.3703776007 30 0.0 11 529168.6856383837 21 184137.3193908248 31 0.0 0 LINE 5 18B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529263.514642959 20 183980.1275233293 30 0.0 11 529293.0026730755 21 184060.2635067652 31 0.0 0 LINE 5 18B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528759.5507635506 20 184261.0245410653 30 0.0 11 528849.5923701449 21 184257.2035358896 31 0.0 0 LINE 5 18B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528721.3225061437 20 184389.5905455545 30 0.0 11 529192.4726468614 21 184358.5149214769 31 0.0 0 LINE 5 18B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529077.9737850126 20 183957.0438233327 30 0.0 11 529119.6460493255 21 184379.0611792988 31 0.0 0 LINE 5 18B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529607.0855259606 20 184151.2387982638 30 0.0 11 529112.8227696159 21 184377.6133776814 31 0.0 0 LINE 5 18BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529535.8854772784 20 184086.7391921813 30 0.0 11 529527.1195999053 21 184203.8403754511 31 0.0 0 LINE 5 18BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529479.2157692527 20 184112.1075549288 30 0.0 11 529557.3733127589 21 184189.2891542463 31 0.0 0 LINE 5 18BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529301.0029985914 20 184178.0126930631 30 0.0 11 529495.9929595092 21 184125.2287324086 31 0.0 0 LINE 5 18BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529313.59495057 20 183928.6131774258 30 0.0 11 529382.340378208 21 184256.5826859235 31 0.0 0 LINE 5 18BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529221.1179942434 20 183942.917602215 30 0.0 11 529342.0319141572 21 183931.6353374763 31 0.0 0 LINE 5 18BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529312.699856074 20 183833.8415190274 30 0.0 11 529208.4277064143 21 183894.792727149 31 0.0 0 LINE 5 18C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529212.7062022725 20 183889.5899308134 30 0.0 11 529222.5516194342 21 183944.5507227859 31 0.0 0 LINE 5 18C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529195.3739702155 20 183552.0087108246 30 0.0 11 529352.8129128399 21 184092.1295749014 31 0.0 0 LINE 5 18C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529346.7785871158 20 184103.7320176673 30 0.0 11 529370.0395461917 21 184096.7547434928 31 0.0 0 LINE 5 18C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529254.8342284231 20 184270.163774171 30 0.0 11 529271.9257540901 21 184312.1401594801 31 0.0 0 LINE 5 18C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529242.0957397047 20 184261.272396836 30 0.0 11 529260.6751696339 21 184276.5678607432 31 0.0 0 LINE 5 18C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529179.4410989126 20 184274.7951877764 30 0.0 11 529250.0789189447 21 184261.6741835324 31 0.0 0 LINE 5 18C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529296.1592347129 20 184046.0634227918 30 0.0 11 529643.9673254191 21 183974.7655943309 31 0.0 0 LINE 5 18C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529454.1353725699 20 183711.0457266946 30 0.0 11 529600.7203160754 21 183852.9594423334 31 0.0 0 LINE 5 18C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529614.6042797779 20 183825.1282280992 30 0.0 11 529327.4729133852 21 184016.405143009 31 0.0 0 LINE 5 18C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529291.7449244022 20 183892.949061924 30 0.0 11 529325.9360372104 21 183883.3074056918 31 0.0 0 LINE 5 18CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529473.5083882844 20 183996.828199399 30 0.0 11 529506.7078360274 21 184084.0614320004 31 0.0 0 LINE 5 18CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529498.1619203571 20 184049.9659275401 30 0.0 11 529479.8707662756 21 184131.3171163717 31 0.0 0 LINE 5 18CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529485.1258490162 20 184051.4929689739 30 0.0 11 529543.6781527715 21 184106.2266454686 31 0.0 0 LINE 5 18CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529648.1988771667 20 184058.6937259326 30 0.0 11 529531.0987379779 21 184105.1653941923 31 0.0 0 LINE 5 18CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529370.9042646857 20 183531.8227899418 30 0.0 11 529497.1433612095 21 183769.9672986542 31 0.0 0 LINE 5 18CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529084.3798104866 20 184073.1151903254 30 0.0 11 529131.3702673114 21 184074.5318431856 31 0.0 0 LINE 5 18D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529121.3755335018 20 184011.5045800688 30 0.0 11 529130.3807891362 21 184076.1552027958 31 0.0 0 LINE 5 18D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529075.2975739782 20 183993.2730910198 30 0.0 11 529176.3341111189 21 183967.3007750539 31 0.0 0 LINE 5 18D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529119.6923565671 20 183827.2847304165 30 0.0 11 529226.2515154431 21 184106.2181938137 31 0.0 0 LINE 5 18D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529178.9676292489 20 184192.670451302 30 0.0 11 529247.3944009359 21 184185.0980891285 31 0.0 0 LINE 5 18D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529242.9219358122 20 184153.5711962515 30 0.0 11 529249.7117762716 21 184213.291126117 31 0.0 0 LINE 5 18D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529236.8192945857 20 184159.6393202897 30 0.0 11 529307.6021939016 21 184150.793017017 31 0.0 0 LINE 5 18D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529304.8497323328 20 184148.2943589701 30 0.0 11 529312.5914589166 21 184203.8970159591 31 0.0 0 LINE 5 18D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529241.70527714 20 184209.1035473026 30 0.0 11 529318.7080016693 21 184200.3475086117 31 0.0 0 LINE 5 18D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529297.9573885139 20 183656.3574575827 30 0.0 11 529330.0329129007 21 183764.4117554094 31 0.0 0 LINE 5 18D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528897.5337691688 20 184129.6894195952 30 0.0 11 528897.478389069 21 184394.2905282322 31 0.0 0 LINE 5 18DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529564.8081035469 20 184156.3795667532 30 0.0 11 530120.7290760145 21 184302.9901803174 31 0.0 0 LINE 5 18DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529576.0183069298 20 183927.891279077 30 0.0 11 529743.6527647668 21 183900.8434291773 31 0.0 0 LINE 5 18DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529521.6816180366 20 183475.0313137005 30 0.0 11 529650.2941202522 21 184219.5650098007 31 0.0 0 LINE 5 18DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529679.2907305889 20 183985.1940250151 30 0.0 11 530117.5734721159 21 184013.717285966 31 0.0 0 LINE 5 18DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529687.0294849822 20 184054.2573199527 30 0.0 11 529672.5303405014 21 183860.8683520123 31 0.0 0 LINE 5 18DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529759.3473827288 20 184047.7365935693 30 0.0 11 529754.0104869314 21 183983.6494400565 31 0.0 0 LINE 5 18E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529711.2346513648 20 184073.0827985901 30 0.0 11 529768.3266381497 21 184034.6411471173 31 0.0 0 LINE 5 18E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529748.3128897444 20 184038.8260773843 30 0.0 11 530149.3755702474 21 184080.6091368607 31 0.0 0 LINE 5 18E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529822.5334303282 20 184232.0902659284 30 0.0 11 529891.6037786624 21 183830.6665730242 31 0.0 0 LINE 5 18E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529878.3245604799 20 183831.6460420928 30 0.0 11 530115.6678549417 21 183858.1777639944 31 0.0 0 LINE 5 18E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529804.5617092055 20 183655.9621141555 30 0.0 11 529891.6584272959 21 183843.9010499806 31 0.0 0 LINE 5 18E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529751.5979813427 20 183725.2212505417 30 0.0 11 529835.4105477586 21 183708.8880490126 31 0.0 0 LINE 5 18E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530003.7161490814 20 184279.3533582009 30 0.0 11 530014.3010319426 21 184189.8544685236 31 0.0 0 LINE 5 18E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529699.2253891022 20 183904.7076811009 30 0.0 11 530122.488138511 21 183930.8586144009 31 0.0 0 LINE 5 18E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529992.8308329559 20 183470.8687570237 30 0.0 11 530106.5214174473 21 183900.3913899983 31 0.0 0 LINE 5 18E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529953.3300898477 20 183258.8502033253 30 0.0 11 530063.7143634662 21 183748.2713958617 31 0.0 0 LINE 5 18EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529900.2748189806 20 183473.3341383796 30 0.0 11 530014.4801315384 21 183500.6594803322 31 0.0 0 LINE 5 18EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529916.2827226056 20 183533.3237762995 30 0.0 11 530004.9389856002 21 183468.472655168 31 0.0 0 LINE 5 18EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529952.9289195793 20 183719.7650139767 30 0.0 11 529931.9111294502 21 183518.8533820108 31 0.0 0 LINE 5 18ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529742.8811912783 20 183665.3457348656 30 0.0 11 530043.46283358 21 183651.9961161206 31 0.0 0 LINE 5 18EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529687.2422269649 20 183593.0775140649 30 0.0 11 529724.7608320558 21 183708.5756517063 31 0.0 0 LINE 5 18EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529623.3457701452 20 183720.3648745762 30 0.0 11 529638.0259663806 21 183600.4806687575 31 0.0 0 LINE 5 18F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529634.9426060249 20 183606.469617366 30 0.0 11 529689.309536844 21 183593.7472855568 31 0.0 0 LINE 5 18F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529318.09148679 20 183724.2272268729 30 0.0 11 529318.1038273831 21 183724.225695042 31 0.0 0 LINE 5 18F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529463.3394359053 20 183706.1976788945 30 0.0 11 529876.4055847055 21 183654.9240051979 31 0.0 0 LINE 5 18F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529886.8974241664 20 183662.7311218112 30 0.0 11 529883.7183415998 21 183638.6552416385 31 0.0 0 LINE 5 18F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530036.5394987975 20 183780.0364676758 30 0.0 11 530080.7040672157 21 183769.8566803663 31 0.0 0 LINE 5 18F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530025.7307421312 20 183791.1942660727 30 0.0 11 530043.7929825967 21 183775.2913763358 31 0.0 0 LINE 5 18F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530029.0903345296 20 183855.2035078002 30 0.0 11 530027.4002947669 21 183783.3772860089 31 0.0 0 LINE 5 18F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529821.8954453944 20 183703.5076889587 30 0.0 11 529795.7595766237 21 183353.2126123737 31 0.0 0 LINE 5 18F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529703.0907581594 20 183390.9512902205 30 0.0 11 529797.6095269524 21 183667.8656604379 31 0.0 0 LINE 5 18F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.0361374302 20 183683.451661832 30 0.0 11 529665.9695573602 21 183648.1606338434 31 0.0 0 LINE 5 18FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529801.5681898015 20 183520.5770130863 30 0.0 11 529892.9789850213 21 183501.7115229562 31 0.0 0 LINE 5 18FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529857.9570564266 20 183504.7116257166 30 0.0 11 529935.3509598677 21 183535.7400957423 31 0.0 0 LINE 5 18FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529857.3859786731 20 183517.8244012334 30 0.0 11 529920.755485241 21 183468.7484065412 31 0.0 0 LINE 5 18FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529882.9679134057 20 183305.8861517042 30 0.0 11 529917.7020419922 21 183480.9976683616 31 0.0 0 LINE 5 18FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529814.8331984142 20 183916.8910231721 30 0.0 11 529823.7242868534 21 183870.7276341683 31 0.0 0 LINE 5 18FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529759.9097336122 20 183870.5448924621 30 0.0 11 529825.1691067379 21 183871.9632955235 31 0.0 0 LINE 5 1900 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529734.5644303138 20 183913.1263572974 30 0.0 11 529725.0345265799 21 183809.2412093268 31 0.0 0 LINE 5 1901 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529577.7783682334 20 183842.8329485435 30 0.0 11 529870.1339267547 21 183782.112616325 31 0.0 0 LINE 5 1902 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529947.940788104 20 183842.5762503987 30 0.0 11 529951.375853984 21 183773.8175122284 31 0.0 0 LINE 5 1903 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529919.539180531 20 183773.2058405635 30 0.0 11 529979.5776981694 21 183776.0251235164 31 0.0 0 LINE 5 1904 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529924.5566131975 20 183780.197959607 30 0.0 11 529927.109717592 21 183708.9101094842 31 0.0 0 LINE 5 1905 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529924.2041507862 20 183711.2289493369 30 0.0 11 529980.3298478019 21 183712.4520312043 31 0.0 0 LINE 5 1906 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529974.1670696054 20 183783.2614860843 30 0.0 11 529977.8010258291 21 183705.8477782501 31 0.0 0 LINE 5 1907 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529840.8913014926 20 184110.3672796936 30 0.0 11 530102.0983370033 21 184152.6122126289 31 0.0 0 LINE 5 1908 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528668.7913145144 20 183107.5549678178 30 0.0 11 528541.0430600417 21 183527.7503403289 31 0.0 0 LINE 5 1909 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528804.4113192836 20 182893.6556957394 30 0.0 11 528671.5138685195 21 183589.133053046 31 0.0 0 LINE 5 190A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528854.4143764418 20 183324.3966236097 30 0.0 11 528250.610854468 21 183222.7979014137 31 0.0 0 LINE 5 190B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528458.0548529516 20 183244.6009172969 30 0.0 11 528404.5920938378 21 183477.3615348441 31 0.0 0 LINE 5 190C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528531.3448267208 20 183079.5639227049 30 0.0 11 528245.4138924677 21 183131.629383617 31 0.0 0 LINE 5 190D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528807.9591497892 20 183577.2528416022 30 0.0 11 528402.8543708085 21 183474.7910999636 31 0.0 0 LINE 5 190E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528586.2414796501 20 183099.7468354818 30 0.0 11 528470.9265496374 21 183507.8371358638 31 0.0 0 LINE 5 190F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527866.6651222174 20 183086.587611023 30 0.0 11 528477.8981421178 21 183507.6131407652 31 0.0 0 LINE 5 1910 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528254.4293880732 20 183027.6427082953 30 0.0 11 528291.0664511334 21 183410.0281326049 31 0.0 0 LINE 5 1911 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528357.0203913149 20 183376.8414271265 30 0.0 11 528332.8061176764 21 183415.1533851214 31 0.0 0 LINE 5 1912 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528371.1252056358 20 183370.331442587 30 0.0 11 528350.1432728785 21 183382.1172361704 31 0.0 0 LINE 5 1913 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528430.4207266745 20 183394.6729929148 30 0.0 11 528363.1959728388 21 183369.3215660714 31 0.0 0 LINE 5 1914 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528559.5018706355 20 183212.8777008889 30 0.0 11 528512.9959012541 21 183205.9998560331 31 0.0 0 LINE 5 1915 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528533.9300921969 20 183145.716439993 30 0.0 11 528513.6841439121 21 183207.77205397 31 0.0 0 LINE 5 1916 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528989.8411163921 20 183174.0817346289 30 0.0 11 528487.6116385765 21 183092.5278840273 31 0.0 0 LINE 5 1917 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528568.0177221007 20 182964.6699830321 30 0.0 11 528384.4060132413 21 183269.6789120271 31 0.0 0 LINE 5 1918 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528742.3877054963 20 183749.6239748958 30 0.0 11 528621.5965608299 21 183958.8324620295 31 0.0 0 LINE 5 1919 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528352.40484145 20 183517.2583498101 30 0.0 11 528802.5990649035 21 183778.5899352814 31 0.0 0 LINE 5 191A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528293.1666930174 20 183608.5169334034 30 0.0 11 528953.2583603691 21 183976.1452661638 31 0.0 0 LINE 5 191B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528722.4875052028 20 183925.9917585473 30 0.0 11 528594.7392507302 21 184346.1871310584 31 0.0 0 LINE 5 191C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528785.1042229958 20 183956.1376318977 30 0.0 11 528607.3950652944 21 183878.4911678382 31 0.0 0 LINE 5 191D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528755.0313661355 20 184022.2286410237 30 0.0 11 528696.3163109133 21 183995.9953036005 31 0.0 0 LINE 5 191E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528794.8643226163 20 183985.207017528 30 0.0 11 528739.703064588 21 184026.371214784 31 0.0 0 LINE 5 191F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528750.2720030147 20 184008.8680348702 30 0.0 11 528657.0520669105 21 184401.178041452 31 0.0 0 LINE 5 1920 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528799.6205179925 20 184124.465023813 30 0.0 11 528506.43460244 21 184075.2455926983 31 0.0 0 LINE 5 1921 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528511.7510436402 20 184063.0377080264 30 0.0 11 528458.2882845263 21 184295.7983255736 31 0.0 0 LINE 5 1922 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528370.3519160148 20 183935.3189252638 30 0.0 11 528518.9061481188 21 184079.674465598 31 0.0 0 LINE 5 1923 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528453.2307839687 20 183908.2435178108 30 0.0 11 528410.0958539993 21 183981.9367846534 31 0.0 0 LINE 5 1924 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528786.1574028308 20 184374.1598480596 30 0.0 11 528456.5505614972 21 184293.2278906931 31 0.0 0 LINE 5 1925 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528639.9376703386 20 183918.1836262113 30 0.0 11 528524.6227403257 21 184326.2739265931 31 0.0 0 LINE 5 1926 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528084.9026102108 20 184016.1989552483 30 0.0 11 528531.5943328062 21 184326.0499314945 31 0.0 0 LINE 5 1927 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528166.3454298809 20 183965.2409996249 30 0.0 11 528154.3594816886 21 184082.0565156114 31 0.0 0 LINE 5 1928 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528217.6641506519 20 184000.1895122487 30 0.0 11 528127.1399110786 21 184062.4065752605 31 0.0 0 LINE 5 1929 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528381.4914746685 20 184096.4385993347 30 0.0 11 528198.839080213 21 184010.15224954 31 0.0 0 LINE 5 192A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528413.0013877898 20 183848.7173829846 30 0.0 11 528287.5926426249 21 184159.4625824032 31 0.0 0 LINE 5 192B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528501.5158683562 20 183879.0783900494 30 0.0 11 528384.4765103999 21 183846.6861963027 31 0.0 0 LINE 5 192C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528519.1842874642 20 183828.0644140476 30 0.0 11 528499.8171324582 21 183880.4336244704 31 0.0 0 LINE 5 192D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528595.6748710933 20 183498.8066472854 30 0.0 11 528345.6098893717 21 184002.7759651829 31 0.0 0 LINE 5 192E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528349.5074364252 20 184015.2595100341 30 0.0 11 528327.8380637481 21 184004.2962596118 31 0.0 0 LINE 5 192F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528410.7165820031 20 184195.2782178561 30 0.0 11 528386.5023083646 21 184233.5901758509 31 0.0 0 LINE 5 1930 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528424.8213963242 20 184188.7682333163 30 0.0 11 528403.8394635669 21 184200.5540268997 31 0.0 0 LINE 5 1931 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528484.1169173629 20 184213.1097836442 30 0.0 11 528416.8921635274 21 184187.7583568011 31 0.0 0 LINE 5 1932 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528409.4884254542 20 183967.4027798099 30 0.0 11 528079.6638097751 21 183835.989039296 31 0.0 0 LINE 5 1933 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528312.9572507023 20 183609.8065701943 30 0.0 11 528143.6786059444 21 183723.6985750834 31 0.0 0 LINE 5 1934 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528134.9109864112 20 183693.8578347845 30 0.0 11 528383.8849453777 21 183932.6951172608 31 0.0 0 LINE 5 1935 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528440.7886101574 20 183817.4568159531 30 0.0 11 528408.8288346195 21 183801.9466103597 31 0.0 0 LINE 5 1936 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528243.5765977299 20 183887.7152970022 30 0.0 11 528195.5387878738 21 183967.7415990835 31 0.0 0 LINE 5 1937 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528209.9535345455 20 183935.6830405157 30 0.0 11 528213.6376612554 21 184018.9837575135 31 0.0 0 LINE 5 1938 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528222.5171871721 20 183939.4811511292 30 0.0 11 528155.2438146322 21 183983.0522535347 31 0.0 0 LINE 5 1939 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528060.7233277694 20 183917.8614732753 30 0.0 11 528167.8135951839 21 183984.2221029732 31 0.0 0 LINE 5 193A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528426.4395500667 20 183448.0349839718 30 0.0 11 528260.2481751706 21 183660.2366414376 31 0.0 0 LINE 5 193B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528613.1980613237 20 184031.3144916184 30 0.0 11 528566.6920919425 21 184024.4366467629 31 0.0 0 LINE 5 193C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528587.6262828853 20 183964.1532307225 30 0.0 11 528567.3803346004 21 184026.2088446995 31 0.0 0 LINE 5 193D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528636.194151661 20 183954.3182081319 30 0.0 11 528541.3078292647 21 183910.9646747567 31 0.0 0 LINE 5 193E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528621.7139127892 20 183783.1067737617 30 0.0 11 528467.7144836024 21 184038.9248871805 31 0.0 0 LINE 5 193F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528499.0405333586 20 184132.3509934097 30 0.0 11 528433.0154931339 21 184112.8507930077 31 0.0 0 LINE 5 1940 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528442.9682191248 20 184082.6036251381 30 0.0 11 528425.7711037648 21 184140.1955618993 31 0.0 0 LINE 5 1941 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528447.9072965878 20 184089.6513107935 30 0.0 11 528379.7871951758 21 184068.4822838726 31 0.0 0 LINE 5 1942 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528382.936542737 20 184066.5072024408 30 0.0 11 528365.5272273391 21 184119.8785948911 31 0.0 0 LINE 5 1943 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528434.389757027 20 184137.4828767697 30 0.0 11 528360.1310789086 21 184115.3077437919 31 0.0 0 LINE 5 1944 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528476.3236267395 20 183583.4665500198 30 0.0 11 528425.7267702648 21 183684.1866009447 31 0.0 0 LINE 5 1945 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528125.6147590899 20 184028.7021100603 30 0.0 11 527552.5660905527 21 184075.1566375765 31 0.0 0 LINE 5 1946 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528083.3467968647 20 183974.4580672929 30 0.0 11 527856.6207323578 21 183990.7306343801 31 0.0 0 LINE 5 1947 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528154.8035516293 20 183801.8087856649 30 0.0 11 527994.5487521048 21 183745.6723726351 31 0.0 0 LINE 5 1948 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528288.0147642038 20 183365.5870566724 30 0.0 11 528030.3404346557 21 184075.8514723987 31 0.0 0 LINE 5 1949 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528043.0562136596 20 183840.0361402322 30 0.0 11 527535.5193539366 21 183724.884393956 31 0.0 0 LINE 5 194A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528023.2801637968 20 183906.6584704155 30 0.0 11 528071.5977713523 21 183718.842265279 31 0.0 0 LINE 5 194B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527953.2396338999 20 183887.5084735797 30 0.0 11 527969.7753182916 21 183825.3617371906 31 0.0 0 LINE 5 194C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527996.1389185524 20 183920.9287728688 30 0.0 11 527946.7059838759 21 183873.0368059822 31 0.0 0 LINE 5 194D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527965.6704341591 20 183880.6796714141 30 0.0 11 527647.3742233534 21 183910.4481971195 31 0.0 0 LINE 5 194E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528056.0681094791 20 183648.8329268226 30 0.0 11 527635.8546818722 21 183638.182139202 31 0.0 0 LINE 5 194F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528104.2585344263 20 183452.6437546761 30 0.0 11 528046.9931643914 21 183559.7331702191 31 0.0 0 LINE 5 1950 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528144.7489437926 20 183589.19175389 30 0.0 11 528151.4028743793 21 183468.5955011539 31 0.0 0 LINE 5 1951 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528153.3837633594 20 183475.0337225985 30 0.0 11 528102.1056020192 21 183452.9391290769 31 0.0 0 LINE 5 1952 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528444.5559317088 20 183646.7318726641 30 0.0 11 528444.5440535158 21 183646.7281922736 31 0.0 0 LINE 5 1953 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528304.7504013262 20 183603.4139203 30 0.0 11 527686.3268742882 21 183468.9411166398 31 0.0 0 LINE 5 1954 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527876.9014784467 20 183669.7856404972 30 0.0 11 528039.6626700543 21 183197.4211840708 31 0.0 0 LINE 5 1955 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528196.1692423678 20 183033.7410272279 30 0.0 11 527992.9132103017 21 183547.3888224487 31 0.0 0 LINE 5 1956 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528105.2861078474 20 183544.635494493 30 0.0 11 528115.501939949 21 183510.6115249354 31 0.0 0 LINE 5 1957 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527805.6390662193 20 183840.6870125336 30 0.0 11 527921.0294539186 21 183701.9308299949 31 0.0 0 LINE 5 1958 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527983.8795447074 20 183712.985091062 30 0.0 11 527919.3896683446 21 183702.8928418217 31 0.0 0 LINE 5 1959 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528168.0449598422 20 183717.7690181888 30 0.0 11 527950.1848962111 21 183630.3110709327 31 0.0 0 LINE 5 195A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528231.7146954377 20 183407.7565646374 30 0.0 11 528348.9669055398 21 183581.0464224438 31 0.0 0 LINE 5 195B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527969.7038562812 20 183723.7556854169 30 0.0 11 527992.9685127766 21 183608.912534202 31 0.0 0 LINE 5 195C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528850.3825839323 20 183323.7182158954 30 0.0 11 528990.1503365547 21 183464.1787709401 31 0.0 0 LINE 5 195D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525307.3474071975 20 184541.7665493575 30 0.0 11 528178.1351607463 21 184982.9648824393 31 0.0 0 LINE 5 195E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526077.6348797937 20 184864.5927893283 30 0.0 11 525797.6402801826 21 184765.2182856161 31 0.0 0 LINE 5 195F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525997.2138650289 20 184320.4611636129 30 0.0 11 525984.6548647781 21 184851.1522572005 31 0.0 0 LINE 5 1960 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525800.7908432205 20 184455.0695224782 30 0.0 11 526021.5188082319 21 184527.0129275369 31 0.0 0 LINE 5 1961 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526171.5682654237 20 184485.6664297445 30 0.0 11 526155.7412254004 21 184804.3255559893 31 0.0 0 LINE 5 1962 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526588.3675743969 20 184645.4063717812 30 0.0 11 526576.8066982293 21 184871.6956292857 31 0.0 0 LINE 5 1963 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525964.343985564 20 184517.1375942794 30 0.0 11 526207.3294778549 21 184498.6850303378 31 0.0 0 LINE 5 1964 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525937.9673686516 20 184716.0414479291 30 0.0 11 526226.5149961723 21 184745.9789273604 31 0.0 0 LINE 5 1965 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527987.6557398821 20 184960.8730516275 30 0.0 11 530791.2460484537 21 185189.0669865992 31 0.0 0 LINE 5 1966 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527808.157781419 20 184075.6972938018 30 0.0 11 527810.8540837077 21 183819.4902595181 31 0.0 0 LINE 5 1967 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527575.5627971427 20 184719.6434625751 30 0.0 11 528002.5221155909 21 184822.5487976695 31 0.0 0 LINE 5 1968 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527549.3928541368 20 184958.5758116922 30 0.0 11 527592.9654759936 21 184596.3563074837 31 0.0 0 LINE 5 1969 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527642.0179508916 20 184796.483250273 30 0.0 11 527649.1715267503 21 184732.5733758048 31 0.0 0 LINE 5 196A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527668.3713798277 20 184989.5745496803 30 0.0 11 527813.7447750579 21 184609.0771512619 31 0.0 0 LINE 5 196B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527800.5267200151 20 184607.4709084165 30 0.0 11 528028.2630757902 21 184679.3869980712 31 0.0 0 LINE 5 196C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527762.119928606 20 184420.8410095866 30 0.0 11 527811.2398088129 21 184622.0725162393 31 0.0 0 LINE 5 196D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527696.7657236177 20 184478.5541998675 30 0.0 11 527782.1547628032 21 184478.7323806127 31 0.0 0 LINE 5 196E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527762.9605137232 20 185048.1139941885 30 0.0 11 527790.6482723803 21 184962.3499048549 31 0.0 0 LINE 5 196F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527892.4420198638 20 185129.2023896609 30 0.0 11 528026.9283833614 21 184676.586031645 31 0.0 0 LINE 5 1970 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527610.6815719196 20 184644.5294570579 30 0.0 11 528020.9035075767 21 184752.0152228841 31 0.0 0 LINE 5 1971 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527982.6208062758 20 184275.6370951802 30 0.0 11 528017.1761369693 21 184757.9109827055 31 0.0 0 LINE 5 1972 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527983.8260365036 20 184022.296659296 30 0.0 11 527998.5376072865 21 184561.5100641322 31 0.0 0 LINE 5 1973 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527891.334296719 20 184260.1623738197 30 0.0 11 527998.1023206634 21 184309.0511945493 31 0.0 0 LINE 5 1974 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527895.4425742306 20 184322.1150306804 30 0.0 11 527994.9637622951 21 184275.6270321611 31 0.0 0 LINE 5 1975 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527895.3532610598 20 184512.1236380707 30 0.0 11 527913.57366127 21 184310.9390253954 31 0.0 0 LINE 5 1976 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527480.90823527 20 184388.0469938584 30 0.0 11 527997.2807625187 21 184463.1359095324 31 0.0 0 LINE 5 1977 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527841.5936935205 20 184443.4000457608 30 0.0 11 527843.1291080543 21 184419.1637697629 31 0.0 0 LINE 5 1978 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527965.7343629274 20 184587.42222762 30 0.0 11 528011.0337673516 21 184585.9726994008 31 0.0 0 LINE 5 1979 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527952.9724149893 20 184596.2799005969 30 0.0 11 527973.7683600728 21 184584.1689509764 31 0.0 0 LINE 5 197A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527943.8939013147 20 184659.7310666782 30 0.0 11 527956.1217050114 21 184588.9331628391 31 0.0 0 LINE 5 197B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527769.934801415 20 184470.840688152 30 0.0 11 527827.9300307166 21 184040.3829802543 31 0.0 0 LINE 5 197C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527805.4507991196 20 184062.8185162508 30 0.0 11 527997.0454664766 21 184124.5096477568 31 0.0 0 LINE 5 197D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527702.5578931418 20 184038.5925424107 30 0.0 11 527752.9976249645 21 184431.175942022 31 0.0 0 LINE 5 197E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527785.35650153 20 184287.4313081827 30 0.0 11 527878.6899841483 21 184286.5939176294 31 0.0 0 LINE 5 197F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527843.748765733 20 184282.7667313624 30 0.0 11 527913.6839365679 21 184328.1721729113 31 0.0 0 LINE 5 1980 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527840.6534060318 20 184295.5217209693 30 0.0 11 527912.3151283762 21 184259.6226239287 31 0.0 0 LINE 5 1981 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527906.7261415853 20 184092.5275077153 30 0.0 11 527906.9511752789 21 184271.0504819078 31 0.0 0 LINE 5 1982 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527721.7529934951 20 184678.8330823348 30 0.0 11 527739.4009828234 21 184635.2594847026 31 0.0 0 LINE 5 1983 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527676.8256617091 20 184622.7431039412 30 0.0 11 527740.5796583324 21 184636.7511574304 31 0.0 0 LINE 5 1984 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527643.7263602637 20 184659.6213060481 30 0.0 11 527654.4600654166 21 184555.8536299263 31 0.0 0 LINE 5 1985 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527503.4877949194 20 184560.3430235939 30 0.0 11 527802.0667646647 21 184557.2884910617 31 0.0 0 LINE 5 1986 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527866.7164859016 20 184631.6536190617 30 0.0 11 527883.379678869 21 184564.8561509022 31 0.0 0 LINE 5 1987 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527852.2618777851 20 184558.101125034 30 0.0 11 527910.6226856307 21 184572.4742967173 31 0.0 0 LINE 5 1988 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527855.8328867656 20 184565.9313392166 30 0.0 11 527872.1197030677 21 184496.4819653397 31 0.0 0 LINE 5 1989 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527868.8206569435 20 184498.1953337749 30 0.0 11 527923.6510511095 21 184510.2459632337 31 0.0 0 LINE 5 198A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527903.9151466527 20 184578.5281191074 30 0.0 11 527922.4467185071 21 184503.2774138411 31 0.0 0 LINE 5 198B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527910.2046977225 20 185240.1234589559 30 0.0 11 528625.4822334132 21 185577.9825458991 31 0.0 0 LINE 5 198C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528033.5651137221 20 185301.6519541995 30 0.0 11 528074.238106388 21 185159.5132811641 31 0.0 0 LINE 5 198D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527926.1315420274 20 185176.9120553437 30 0.0 11 528372.8202171181 21 185388.9352482703 31 0.0 0 LINE 5 198E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528056.7474958125 20 185187.0786360558 30 0.0 11 528117.6632592067 21 185132.2118152555 31 0.0 0 LINE 5 198F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528009.0905858184 20 185123.1714021653 30 0.0 11 528068.7639218026 21 185187.6424922191 31 0.0 0 LINE 5 1990 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527815.499177531 20 185092.6115966227 30 0.0 11 528333.2656037408 21 185110.5234618076 31 0.0 0 LINE 5 1991 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528085.0587549844 20 184722.9316982304 30 0.0 11 528197.8763293401 21 184731.2980733757 31 0.0 0 LINE 5 1992 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528197.8031362093 20 184649.8315174913 30 0.0 11 528180.0506917082 21 185405.1833898459 31 0.0 0 LINE 5 1993 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528253.8105398686 20 185180.8397990754 30 0.0 11 528733.1088459851 21 185324.8966353942 31 0.0 0 LINE 5 1994 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528248.0514866669 20 185250.0962813238 30 0.0 11 528271.2132187195 21 185057.552643984 31 0.0 0 LINE 5 1995 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528320.2656936174 20 185257.679586773 30 0.0 11 528327.4192694761 21 185193.7697123049 31 0.0 0 LINE 5 1996 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528268.1605303945 20 185273.2461211912 30 0.0 11 528331.6072550481 21 185246.5671284493 31 0.0 0 LINE 5 1997 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528311.1620183674 20 185246.8039060563 30 0.0 11 528445.5263302135 21 185288.12612457 31 0.0 0 LINE 5 1998 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528346.6191225535 20 185450.7708861805 30 0.0 11 528628.3189486684 21 184705.4867174532 31 0.0 0 LINE 5 1999 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528478.774462741 20 185068.6672449169 30 0.0 11 528775.4044934505 21 185164.1276033924 31 0.0 0 LINE 5 199A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528456.0358821345 20 185511.7428004195 30 0.0 11 528483.7236407914 21 185425.9787110862 31 0.0 0 LINE 5 199B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528288.9293146456 20 185105.7257935582 30 0.0 11 528745.1093170271 21 185225.2534264041 31 0.0 0 LINE 5 199C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528344.0981698862 20 184874.8967817407 30 0.0 11 528768.9167591915 21 184929.1033520555 31 0.0 0 LINE 5 199D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527949.8775264869 20 184854.9666844584 30 0.0 11 528511.0568598971 21 184894.9081944299 31 0.0 0 LINE 5 199E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528448.1825441407 20 184932.0370246522 30 0.0 11 528528.469305634 21 184409.6310701323 31 0.0 0 LINE 5 199F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528188.8818175094 20 184667.5442081165 30 0.0 11 528372.8703909186 21 184579.3690800832 31 0.0 0 LINE 5 19A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528351.5933171851 20 184556.6836868273 30 0.0 11 528431.2453676903 21 184892.3722785223 31 0.0 0 LINE 5 19A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528463.6042442558 20 184748.6276446831 30 0.0 11 528678.2731909844 21 184747.8248774162 31 0.0 0 LINE 5 19A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528582.2880243458 20 184606.2960929359 30 0.0 11 528617.9667813305 21 184768.5430947721 31 0.0 0 LINE 5 19A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527991.9087113443 20 184683.3516059304 30 0.0 11 528259.0723139821 21 184647.6763211142 31 0.0 0 LINE 5 19A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528400.0007362211 20 185140.0294188351 30 0.0 11 528417.6487255491 21 185096.4558212028 31 0.0 0 LINE 5 19A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528355.073404435 20 185083.9394404415 30 0.0 11 528418.8274010583 21 185097.9474939306 31 0.0 0 LINE 5 19A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528321.9741029895 20 185120.8176425483 30 0.0 11 528332.7078081425 21 185017.0499664265 31 0.0 0 LINE 5 19A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528083.3578412053 20 184795.0081634422 30 0.0 11 528195.8260750748 21 184802.455774721 31 0.0 0 LINE 5 19A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528388.1630202148 20 185334.8933586839 30 0.0 11 528705.0344509524 21 185469.7224833694 31 0.0 0 LINE 5 19A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528619.6035762321 20 184654.4888869583 30 0.0 11 528787.5051260328 21 184344.9983490001 31 0.0 0 LINE 5 19AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527991.0162556054 20 184522.2358538144 30 0.0 11 528768.8489952007 21 184666.6966134304 31 0.0 0 LINE 5 19AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528258.9278605673 20 184319.7995120679 30 0.0 11 528493.9558347146 21 184289.0340850979 31 0.0 0 LINE 5 19AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528305.4820494023 20 184393.5198752249 30 0.0 11 528319.2731084667 21 184309.2516934997 31 0.0 0 LINE 5 19AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528120.907951347 20 184166.6183070277 30 0.0 11 528186.1953061795 21 184069.0114987191 31 0.0 0 LINE 5 19AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528182.7230597031 20 184172.4408507259 30 0.0 11 528152.6983259142 21 184066.7804691202 31 0.0 0 LINE 5 19AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528263.2283659217 20 184381.7642178277 30 0.0 11 528292.7986475518 21 184135.3588211145 31 0.0 0 LINE 5 19B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528159.2130572247 20 184407.9771273453 30 0.0 11 528280.5521486496 21 184412.9056584408 31 0.0 0 LINE 5 19B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528256.3867003138 20 184512.1025921885 30 0.0 11 528149.0628884625 21 184456.7010545208 31 0.0 0 LINE 5 19B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528153.6082290024 20 184461.6724221288 30 0.0 11 528160.5591043877 21 184406.2711024269 31 0.0 0 LINE 5 19B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528153.9955953136 20 184799.6980665769 30 0.0 11 528153.9984446465 21 184799.6859621131 31 0.0 0 LINE 5 19B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528187.5320485945 20 184657.2293415045 30 0.0 11 528282.9053305279 21 184252.0669419752 31 0.0 0 LINE 5 19B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528309.5339253747 20 184320.0569967773 30 0.0 11 527971.965703502 21 184222.9106129128 31 0.0 0 LINE 5 19B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527975.1720377207 20 184322.9177983651 30 0.0 11 528267.6760323384 21 184330.4529970771 31 0.0 0 LINE 5 19B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528237.986400541 20 184455.4986644045 30 0.0 11 528203.4797198928 21 184447.0557549162 31 0.0 0 LINE 5 19B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528130.9300084558 20 184275.5882396961 30 0.0 11 528144.9852191297 21 184183.3153224697 31 0.0 0 LINE 5 19B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528135.6356705808 20 184217.1992720769 30 0.0 11 528191.6112669698 21 184155.3986664904 31 0.0 0 LINE 5 19BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528147.7339253272 20 184222.2887950057 30 0.0 11 528123.7204699332 21 184145.8198367432 31 0.0 0 LINE 5 19BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527957.8719725857 20 184124.6942464935 30 0.0 11 528134.1468481414 21 184152.9373200259 31 0.0 0 LINE 5 19BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528355.4066024149 20 184597.3661614674 30 0.0 11 528399.9991306533 21 184302.1200983803 31 0.0 0 LINE 5 19BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527314.8022005422 20 184741.5980162658 30 0.0 11 526970.7047902906 21 185140.6353940886 31 0.0 0 LINE 5 19BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527178.8927506483 20 184890.7223407424 30 0.0 11 527892.8909575186 21 185231.2767068576 31 0.0 0 LINE 5 19BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527304.5579262283 20 184947.3951879357 30 0.0 11 527220.1504267684 21 185068.77504104 31 0.0 0 LINE 5 19C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527139.9889769999 20 184943.0276207057 30 0.0 11 527586.6776520906 21 185155.0508136324 31 0.0 0 LINE 5 19C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527230.4483922155 20 185037.7956582788 30 0.0 11 527226.4541900343 21 185119.6806056352 31 0.0 0 LINE 5 19C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527150.8042870103 20 185041.2787775443 30 0.0 11 527238.4827063035 21 185046.7489942205 31 0.0 0 LINE 5 19C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527168.2411901958 20 185033.6844166035 30 0.0 11 527040.6311596829 21 185186.2292719635 31 0.0 0 LINE 5 19C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527060.7877157567 20 184974.6539566652 30 0.0 11 527345.9668821299 21 185300.4331217227 31 0.0 0 LINE 5 19C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527078.8871428805 20 185227.2251475794 30 0.0 11 527228.8299069052 21 185116.0630754644 31 0.0 0 LINE 5 19C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527039.9234058711 20 185180.7984200714 30 0.0 11 527079.7319945638 21 185227.2946236537 31 0.0 0 LINE 5 19C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526838.3892838256 20 185399.5131906798 30 0.0 11 527067.5959861845 21 185210.2772169702 31 0.0 0 LINE 5 19C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526888.7462167753 20 185353.1899045615 30 0.0 11 526966.5577681158 21 185435.3066738271 31 0.0 0 LINE 5 19C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526903.3945210007 20 185486.7577117054 30 0.0 11 527563.396785898 21 184919.709440807 31 0.0 0 LINE 5 19CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527350.2091506667 20 185194.4166248022 30 0.0 11 527699.8837421815 21 185460.1447709393 31 0.0 0 LINE 5 19CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527400.2250552947 20 185146.1668961864 30 0.0 11 527265.6942366933 21 185285.8485949097 31 0.0 0 LINE 5 19CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527451.7581804101 20 185197.3209304638 30 0.0 11 527406.7663055494 21 185243.270651884 31 0.0 0 LINE 5 19CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527430.8746786076 20 185147.1099318603 30 0.0 11 527450.3194740931 21 185213.1338324689 31 0.0 0 LINE 5 19CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527437.5762896092 20 185197.1439914512 30 0.0 11 527773.0926914633 21 185420.8085658439 31 0.0 0 LINE 5 19CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527618.0195788189 20 185095.6552994826 30 0.0 11 527415.1389359325 21 185448.8565721106 31 0.0 0 LINE 5 19D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527405.5372855231 20 185439.6313184767 30 0.0 11 527605.2426940034 21 185570.6027715367 31 0.0 0 LINE 5 19D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527236.6611025661 20 185527.8732336498 30 0.0 11 527423.6234348207 21 185438.6994246076 31 0.0 0 LINE 5 19D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527240.0543231658 20 185440.7499273761 30 0.0 11 527294.18013015 21 185506.7932221131 31 0.0 0 LINE 5 19D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527787.6999047709 20 185174.8358807547 30 0.0 11 527738.7591409829 21 185250.5121163805 31 0.0 0 LINE 5 19D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527867.8676223761 20 185180.9755230782 30 0.0 11 527602.2287515429 21 185571.3396349185 31 0.0 0 LINE 5 19D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527314.2179450792 20 185269.1165263216 30 0.0 11 527656.8589517441 21 185518.9812235104 31 0.0 0 LINE 5 19D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527386.1443485876 20 185733.9220975941 30 0.0 11 527608.5066100865 21 185554.6163101546 31 0.0 0 LINE 5 19D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527049.9782308985 20 185812.0857878571 30 0.0 11 527240.4791242125 21 185665.0943789074 31 0.0 0 LINE 5 19D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526905.5723615818 20 185164.9770384304 30 0.0 11 527291.3265981003 21 185574.5026633598 31 0.0 0 LINE 5 19D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527494.4579605611 20 185580.3033783502 30 0.0 11 527533.4565041639 21 185629.032965853 31 0.0 0 LINE 5 19DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527493.2517026551 20 185564.8156210044 30 0.0 11 527497.0169997674 21 185588.5846969284 31 0.0 0 LINE 5 19DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527536.6711348336 20 185517.6645574225 30 0.0 11 527489.5509079133 21 185571.9005840673 31 0.0 0 LINE 5 19DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526825.7687294675 20 185630.3755656826 30 0.0 11 526891.3167667593 21 185848.3127625726 31 0.0 0 LINE 5 19DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526911.4770323184 20 185468.6468766246 30 0.0 11 526810.6942338679 21 185658.8206326186 31 0.0 0 LINE 5 19DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527411.0206055598 20 185333.4814571598 30 0.0 11 527388.4196091816 21 185374.7040832365 31 0.0 0 LINE 5 19DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527339.1587846829 20 185334.1368332729 30 0.0 11 527390.3205215139 21 185374.6741535153 31 0.0 0 LINE 5 19E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527346.8032714759 20 185285.1763658685 30 0.0 11 527273.1947542249 21 185359.1001727385 31 0.0 0 LINE 5 19E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527181.2197812676 20 185239.2945574107 30 0.0 11 527367.6316948791 21 185472.5526329555 31 0.0 0 LINE 5 19E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527466.121962935 20 185475.6227822589 30 0.0 11 527424.9054135911 21 185530.7658671615 31 0.0 0 LINE 5 19E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527399.9974681621 20 185510.9279697606 30 0.0 11 527448.0322060059 21 185547.0560186549 31 0.0 0 LINE 5 19E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527408.3217922771 20 185508.7439396979 30 0.0 11 527364.8126878394 21 185565.2721074394 31 0.0 0 LINE 5 19E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527364.0542931707 20 185561.6328528111 30 0.0 11 527408.0574935037 21 185596.4941229428 31 0.0 0 LINE 5 19E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527448.4815771714 20 185538.0317231022 30 0.0 11 527401.8970982832 21 185599.9669644852 31 0.0 0 LINE 5 19E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528016.5909572429 20 185271.6800929167 30 0.0 11 528012.5967550619 21 185353.5650402731 31 0.0 0 LINE 5 19E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527936.946852038 20 185275.1632121824 30 0.0 11 528024.6252713311 21 185280.6334288583 31 0.0 0 LINE 5 19E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527953.3585635359 20 185269.0754004951 30 0.0 11 527825.7485330229 21 185421.620255855 31 0.0 0 LINE 5 19EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527790.870967409 20 185144.4981020443 30 0.0 11 528132.1094471575 21 185534.3175563607 31 0.0 0 LINE 5 19EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527865.0297079079 20 185461.1095822174 30 0.0 11 528014.9724719328 21 185349.9475101025 31 0.0 0 LINE 5 19EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527826.0659708985 20 185414.6828547094 30 0.0 11 527865.8745595912 21 185461.1790582917 31 0.0 0 LINE 5 19ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527624.531848853 20 185633.3976253178 30 0.0 11 527853.7385512123 21 185444.161651608 31 0.0 0 LINE 5 19EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527767.7467574182 20 185650.035349184 30 0.0 11 528263.528864607 21 185229.3122790655 31 0.0 0 LINE 5 19EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528136.3517156943 20 185428.30105944 30 0.0 11 528347.6752841493 21 185588.892138813 31 0.0 0 LINE 5 19F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528186.367620322 20 185380.0513308243 30 0.0 11 528051.8368017208 21 185519.7330295476 31 0.0 0 LINE 5 19F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528237.9007454377 20 185431.2053651018 30 0.0 11 528192.908870577 21 185477.1550865222 31 0.0 0 LINE 5 19F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528217.0172436352 20 185380.9943664984 30 0.0 11 528236.4620391206 21 185447.0182671067 31 0.0 0 LINE 5 19F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528223.7188546365 20 185431.0284260889 30 0.0 11 528559.2352564908 21 185654.693000482 31 0.0 0 LINE 5 19F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528349.2591038744 20 185424.8977161368 30 0.0 11 528201.2815009599 21 185682.7410067485 31 0.0 0 LINE 5 19F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528191.6798505507 20 185673.5157531144 30 0.0 11 528391.3852590313 21 185804.4872061746 31 0.0 0 LINE 5 19F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528022.8036675936 20 185761.7576682877 30 0.0 11 528209.7659998483 21 185672.5838592456 31 0.0 0 LINE 5 19F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527902.7342881627 20 185504.0363614708 30 0.0 11 528080.3226951775 21 185740.677656751 31 0.0 0 LINE 5 19F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528100.3605101067 20 185503.0009609594 30 0.0 11 528471.2251337772 21 185777.1470163376 31 0.0 0 LINE 5 19F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527989.6882072637 20 185927.1348780362 30 0.0 11 528192.9659531929 21 185625.1118063627 31 0.0 0 LINE 5 19FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527961.9309788312 20 185823.9192870058 30 0.0 11 528067.3128045042 21 185875.7285385648 31 0.0 0 LINE 5 19FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528012.5268591681 20 185787.9322542143 30 0.0 11 528039.4327511025 21 185894.4295492943 31 0.0 0 LINE 5 19FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527691.7149266093 20 185398.8614730684 30 0.0 11 527914.0029648269 21 185627.3190115407 31 0.0 0 LINE 5 19FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527869.2643178839 20 185537.3894388642 30 0.0 11 527810.6201234687 21 185860.3170556521 31 0.0 0 LINE 5 19FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527809.1084261395 20 185747.0527862236 30 0.0 11 527972.918083988 21 185778.6332784218 31 0.0 0 LINE 5 19FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527949.3576618674 20 185772.7602072676 30 0.0 11 528028.7529029781 21 185798.2352525258 31 0.0 0 LINE 5 1A00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527957.2826477116 20 185762.2976258021 30 0.0 11 527974.7780660359 21 185840.5156413443 31 0.0 0 LINE 5 1A01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527880.8185873425 20 185906.512433928 30 0.0 11 527980.2405118185 21 185829.1345334503 31 0.0 0 LINE 5 1A02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527585.3290340103 20 185539.930241882 30 0.0 11 527663.5568333297 21 185667.0336448759 31 0.0 0 LINE 5 1A03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528197.1631705874 20 185567.3658917978 30 0.0 11 528174.562174209 21 185608.5885178743 31 0.0 0 LINE 5 1A04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528125.3013497101 20 185568.0212679109 30 0.0 11 528176.4630865414 21 185608.5585881534 31 0.0 0 LINE 5 1A05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528132.9458365035 20 185519.0608005063 30 0.0 11 528059.3373192524 21 185592.9846073763 31 0.0 0 LINE 5 1A06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527967.3623462952 20 185473.1789920484 30 0.0 11 528153.7742599065 21 185706.4370675933 31 0.0 0 LINE 5 1A07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528252.2645279622 20 185709.5072168967 30 0.0 11 528211.0479786187 21 185764.6503017994 31 0.0 0 LINE 5 1A08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528186.1400331898 20 185744.8124043986 30 0.0 11 528234.1747710333 21 185780.9404532926 31 0.0 0 LINE 5 1A09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527729.6552787081 20 185540.1857397122 30 0.0 11 527806.5341364845 21 185622.6127484563 31 0.0 0 LINE 5 1A0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528007.2965028686 20 185884.1544039194 30 0.0 11 527851.8430313845 21 186437.6677441766 31 0.0 0 LINE 5 1A0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527941.7493953729 20 185904.9528054292 30 0.0 11 527878.2684433706 21 186123.2179503772 31 0.0 0 LINE 5 1A0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527804.6629765957 20 185777.9836909368 30 0.0 11 527696.3651398602 21 185908.7677732899 31 0.0 0 LINE 5 1A0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527684.112269079 20 185706.0815362376 30 0.0 11 528665.054318946 21 186537.7386197715 31 0.0 0 LINE 5 1A0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527801.7017107939 20 185896.0515912543 30 0.0 11 527595.1283308359 21 186283.6224961132 31 0.0 0 LINE 5 1A0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527857.3091071436 20 185937.7342554978 30 0.0 11 527697.9637193599 21 185827.1966351875 31 0.0 0 LINE 5 1A10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527815.0264069962 20 185996.7645144781 30 0.0 11 527762.4906663322 21 185959.6748709776 31 0.0 0 LINE 5 1A11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527861.265174234 20 185968.1421205775 30 0.0 11 527799.1864118238 21 185997.8655588148 31 0.0 0 LINE 5 1A12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527812.9398004629 20 185982.7358507043 30 0.0 11 527645.6343383252 21 186349.6227271258 31 0.0 0 LINE 5 1A13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527941.9014901828 20 186144.688367828 30 0.0 11 527560.8699665694 21 186000.7207594688 31 0.0 0 LINE 5 1A14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527568.4462253584 20 185989.7709970077 30 0.0 11 527470.9931260145 21 186207.8046300123 31 0.0 0 LINE 5 1A15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527454.4061946053 20 185837.1254201002 30 0.0 11 527572.250006963 21 186007.4771673475 31 0.0 0 LINE 5 1A16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527540.9559103656 20 185826.5835443709 30 0.0 11 527484.3878387183 21 185890.5473859652 31 0.0 0 LINE 5 1A19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527722.2187565154 20 185872.4316389714 30 0.0 11 527530.1843775018 21 186250.5295411427 31 0.0 0 LINE 5 1A1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527199.4167249749 20 185905.5738254118 30 0.0 11 527537.0677506778 21 186251.6575700604 31 0.0 0 LINE 5 1A1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527037.937839605 20 185785.4550518199 30 0.0 11 527402.5950979067 21 186107.3044569597 31 0.0 0 LINE 5 1A1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527248.4636741881 20 185827.0429996101 30 0.0 11 527214.1202363191 21 185939.3375052844 31 0.0 0 LINE 5 1A1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527292.057736972 20 185871.2534884808 30 0.0 11 527191.2130479115 21 185914.7959914915 31 0.0 0 LINE 5 1A1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527434.1867885707 20 185997.3590456579 30 0.0 11 527271.6617460263 21 185877.3888747525 31 0.0 0 LINE 5 1A1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527493.7639413161 20 185788.7156441948 30 0.0 11 527329.8751713632 21 186041.0408452601 31 0.0 0 LINE 5 1A20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527414.5543417604 20 185722.5364578387 30 0.0 11 527405.9648867027 21 185570.7866745304 31 0.0 0 LINE 5 1A21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527777.9499912509 20 185591.9477744219 30 0.0 11 527777.9424147139 21 185591.9576350925 31 0.0 0 LINE 5 1A22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527564.4516644597 20 185687.9319159665 30 0.0 11 527417.0896642248 21 185898.5265330985 31 0.0 0 LINE 5 1A23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527418.5002731879 20 185911.5280694478 30 0.0 11 527399.359201479 21 185896.5823695351 31 0.0 0 LINE 5 1A24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527443.7521620491 20 186099.9839973919 30 0.0 11 527412.5879643001 21 186132.8918984475 31 0.0 0 LINE 5 1A25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527458.8494366919 20 186096.3236717095 30 0.0 11 527435.98482774 21 186103.8307410518 31 0.0 0 LINE 5 1A26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527512.3204261397 20 186131.6694377228 30 0.0 11 527451.2650306086 21 186093.7999110848 31 0.0 0 LINE 5 1A27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527486.6016876462 20 185876.1701421699 30 0.0 11 527197.9069829295 21 185676.0574444601 31 0.0 0 LINE 5 1A28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527341.4893924392 20 185686.2844910231 30 0.0 11 527468.1911678976 21 185837.1674141337 31 0.0 0 LINE 5 1A29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527870.7315726819 20 185757.0874915315 30 0.0 11 527174.3057571509 21 185682.3979604978 31 0.0 0 LINE 5 1A2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527339.2256498769 20 185765.9107526084 30 0.0 11 527276.6228466298 21 185835.140292735 31 0.0 0 LINE 5 1A2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527296.9634399069 20 185806.4733018887 30 0.0 11 527284.4737717901 21 185888.914738268 31 0.0 0 LINE 5 1A2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527308.5557930746 20 185812.628653998 30 0.0 11 527234.1280989511 21 185842.3719888006 31 0.0 0 LINE 5 1A2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527112.9020909969 20 185727.2361141512 30 0.0 11 527246.2345787155 21 185845.9498482914 31 0.0 0 LINE 5 1A2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527674.1123383103 20 185978.258723999 30 0.0 11 527629.8134086306 21 185962.5197670078 31 0.0 0 LINE 5 1A2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527662.0070842561 20 185907.4207847158 30 0.0 11 527630.1460531406 21 185964.3915872753 31 0.0 0 LINE 5 1A30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527730.4528268442 20 185736.3799521287 30 0.0 11 527529.9021070324 21 185957.5996170005 31 0.0 0 LINE 5 1A31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527542.5753662606 20 186055.3193551242 30 0.0 11 527396.6007777854 21 185974.7797865106 31 0.0 0 LINE 5 1A32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527827.6730787736 20 186098.8040912351 30 0.0 11 527731.6664476053 21 186345.3735064728 31 0.0 0 LINE 5 1A33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527110.0277079166 20 185399.1501917908 30 0.0 11 527238.1476272985 21 185293.0534528619 31 0.0 0 LINE 5 1A34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527019.584788666 20 185440.5605438748 30 0.0 11 526958.3782706025 21 185266.4775408631 31 0.0 0 LINE 5 1A35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527667.1841413337 20 185924.4546898795 30 0.0 11 527567.5689432492 21 185862.7537503939 31 0.0 0 LINE 5 1A36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527615.9831795112 20 185099.2005308893 30 0.0 11 527796.2414715133 21 185016.9135917002 31 0.0 0 LINE 5 1A37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530074.9353769958 20 183884.9393605395 30 0.0 11 530627.1098105166 21 183787.5003604821 31 0.0 0 LINE 5 1A38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530092.5401323481 20 183873.9934044805 30 0.0 11 530024.122431041 21 184662.0858697672 31 0.0 0 LINE 5 1A39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530077.6837635742 20 184011.0438925107 30 0.0 11 530225.1006832576 21 183999.8213038695 31 0.0 0 LINE 5 1A3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530193.1767123051 20 183992.992663651 30 0.0 11 530265.7841074339 21 184031.0618694109 31 0.0 0 LINE 5 1A3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530236.5551485069 20 183926.10748677 30 0.0 11 530196.8211880385 21 184004.4569658093 31 0.0 0 LINE 5 1A3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530221.1692751257 20 183937.2875946002 30 0.0 11 530417.3513434172 21 183904.6249421486 31 0.0 0 LINE 5 1A3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530224.7609106149 20 183814.7398711447 30 0.0 11 530360.99994493 21 184225.7120683164 31 0.0 0 LINE 5 1A3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530433.2945147376 20 183958.3836377817 30 0.0 11 530261.4615139464 21 184031.2757402305 31 0.0 0 LINE 5 1A3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530413.0289029687 20 183901.2616734557 30 0.0 11 530432.9260982123 21 183959.1470973785 31 0.0 0 LINE 5 1A40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530703.7238554928 20 183838.4238042374 30 0.0 11 530424.4100015701 21 183940.0591187636 31 0.0 0 LINE 5 1A41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530638.2657253066 20 183858.3461717027 30 0.0 11 530669.6009970998 21 183967.0471471273 31 0.0 0 LINE 5 1A42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530745.9713467414 20 183938.6856453953 30 0.0 11 530048.9949907507 21 184149.7235543463 31 0.0 0 LINE 5 1A43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530267.4660776979 20 184175.6230461426 30 0.0 11 530319.246465793 21 184611.7452297214 31 0.0 0 LINE 5 1A44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530200.5202950364 20 184194.2748345569 30 0.0 11 530389.1232236338 21 184149.1255993895 31 0.0 0 LINE 5 1A47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530180.4056919937 20 184329.153562387 30 0.0 11 530198.7734187687 21 184654.907534193 31 0.0 0 LINE 5 1A48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530046.5684076484 20 184356.4003792694 30 0.0 11 530453.8695489496 21 184360.5806350824 31 0.0 0 LINE 5 1A49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530450.7852589756 20 184347.6274829353 30 0.0 11 530385.9506331715 21 184610.7077117975 31 0.0 0 LINE 5 1A4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530612.460149862 20 184246.7957894036 30 0.0 11 530440.8131043484 21 184362.7448026278 31 0.0 0 LINE 5 1A4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530535.6421089239 20 184205.5529351321 30 0.0 11 530565.1301390405 21 184285.688918568 31 0.0 0 LINE 5 1A4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530024.5229396512 20 184465.432338599 30 0.0 11 530114.5645462456 21 184461.6113334234 31 0.0 0 LINE 5 1A4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529993.4499721084 20 184615.0159573572 30 0.0 11 530483.024820749 21 184583.9403332796 31 0.0 0 LINE 5 1A55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530493.2454602082 20 184168.3430140179 30 0.0 11 530614.159380122 21 184157.0607492791 31 0.0 0 LINE 5 1A56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530584.827322039 20 184059.2669308301 30 0.0 11 530480.5551723789 21 184120.2181389518 31 0.0 0 LINE 5 1A57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530484.8336682371 20 184115.0153426162 30 0.0 11 530494.679085399 21 184169.9761345888 31 0.0 0 LINE 5 1A58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530467.5014361801 20 183777.4341226273 30 0.0 11 530624.9403788047 21 184317.5549867041 31 0.0 0 LINE 5 1A61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530563.872390367 20 184118.3744737268 30 0.0 11 530598.0635031751 21 184108.7328174946 31 0.0 0 LINE 5 1A66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530768.7252722775 20 183716.8702567725 30 0.0 11 530609.0654214319 21 183792.4024777319 31 0.0 0 LINE 5 1A6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530347.425039943 20 184218.6985028227 30 0.0 11 530448.4615770839 21 184192.7261868566 31 0.0 0 LINE 5 1A6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530391.819822532 20 184052.7101422193 30 0.0 11 530498.3789814079 21 184331.6436056164 31 0.0 0 LINE 5 1A71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530570.0848544786 20 183881.7828693857 30 0.0 11 530602.1603788654 21 183989.8371672121 31 0.0 0 LINE 5 1A73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529939.5685612063 20 184163.7506789629 30 0.0 11 529827.1842240089 21 185458.2877310593 31 0.0 0 LINE 5 1A74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529880.7455565422 20 184807.2457538028 30 0.0 11 530028.1624762256 21 184796.0231651615 31 0.0 0 LINE 5 1A75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529960.4101130438 20 184663.1778075725 30 0.0 11 529916.71644329 21 185155.697319893 31 0.0 0 LINE 5 1A76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529996.238505273 20 184789.1945249431 30 0.0 11 530068.8459004022 21 184827.263730703 31 0.0 0 LINE 5 1A77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530039.6169414749 20 184722.3093480621 30 0.0 11 529999.8829810068 21 184800.6588271014 31 0.0 0 LINE 5 1A78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530026.0493983941 20 184733.36952438 30 0.0 11 530222.2314666858 21 184700.7068719285 31 0.0 0 LINE 5 1A79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530001.0414109108 20 184530.1545575434 30 0.0 11 530164.0617378978 21 185021.9139296083 31 0.0 0 LINE 5 1A7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530236.3563077058 20 184754.5854990738 30 0.0 11 530064.5233069145 21 184827.4776015228 31 0.0 0 LINE 5 1A7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530216.0906959366 20 184697.4635347478 30 0.0 11 530235.9878911803 21 184755.3489586706 31 0.0 0 LINE 5 1A7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530407.4403198415 20 184689.2318219746 30 0.0 11 530227.4717945381 21 184736.2609800559 31 0.0 0 LINE 5 1A7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530070.5278706658 20 184971.8249074348 30 0.0 11 530122.3082587611 21 185407.9470910134 31 0.0 0 LINE 5 1A80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530003.5820880041 20 184990.476695849 30 0.0 11 530192.1850166016 21 184945.3274606815 31 0.0 0 LINE 5 1A81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530021.5503732429 20 185060.8296555069 30 0.0 11 530083.9666508887 21 185045.3424353904 31 0.0 0 LINE 5 1A82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529988.8569365287 20 185017.3738823104 30 0.0 11 530035.9100089048 21 185067.6059826347 31 0.0 0 LINE 5 1A83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530028.5874565967 20 185048.5155663411 30 0.0 11 530051.2878197391 21 185451.109395485 31 0.0 0 LINE 5 1A84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529590.0046100221 20 185205.4301442984 30 0.0 11 530281.0617747266 21 185224.1071918924 31 0.0 0 LINE 5 1A85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530253.8470519436 20 185143.829344227 30 0.0 11 530265.4988130901 21 185382.3665701588 31 0.0 0 LINE 5 1A88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529831.8611015576 20 185339.0029824713 30 0.0 11 529921.902708152 21 185335.1819772955 31 0.0 0 LINE 5 1A89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529796.5117650765 20 185411.2178186492 30 0.0 11 530267.6619057944 21 185380.1421945718 31 0.0 0 LINE 5 1A8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530153.1630439457 20 184978.6710964276 30 0.0 11 530194.8353082583 21 185400.6884523936 31 0.0 0 LINE 5 1A9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530159.5690694193 20 185094.7424634202 30 0.0 11 530206.5595262442 21 185096.1591162804 31 0.0 0 LINE 5 1A9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530196.5647924344 20 185033.1318531638 30 0.0 11 530205.5700480689 21 185097.7824758906 31 0.0 0 LINE 5 1A9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530150.4868329109 20 185014.9003641146 30 0.0 11 530251.5233700519 21 184988.9280481487 31 0.0 0 LINE 5 1A9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 530194.8816155 20 184848.9120035113 30 0.0 11 530301.4407743759 21 185127.8454669085 31 0.0 0 LINE 5 1A9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529970.7774168067 20 185189.3995273232 30 0.0 11 529972.6676480018 21 185415.9178013272 31 0.0 0 LINE 5 1ACD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529875.2497154139 20 184199.4087741126 30 0.0 11 529863.0202526016 21 184337.2605291638 31 0.0 0 LINE 5 1ACE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529743.980573447 20 184129.1822409128 30 0.0 11 529616.2323189746 21 184549.3776134238 31 0.0 0 LINE 5 1ACF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529771.7650712592 20 184212.0585172357 30 0.0 11 529678.5451351549 21 184604.3685238173 31 0.0 0 LINE 5 1AD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529929.6036353747 20 184346.0238967045 30 0.0 11 529583.3850811765 21 184287.767590759 31 0.0 0 LINE 5 1AD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529914.2805504444 20 184532.6416357702 30 0.0 11 529826.3178454189 21 184513.0290499321 31 0.0 0 LINE 5 1AD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529936.3648480746 20 184609.9516736181 30 0.0 11 529478.0436297417 21 184496.4183730585 31 0.0 0 LINE 5 1AD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529661.430738583 20 184121.3741085768 30 0.0 11 529546.1158085704 21 184529.4644089586 31 0.0 0 LINE 5 1AD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529232.9972191319 20 184308.7579889585 30 0.0 11 529553.0874010506 21 184529.24041386 31 0.0 0 LINE 5 1AD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529634.6911295682 20 184234.5049739838 30 0.0 11 529588.1851601869 21 184227.6271291281 31 0.0 0 LINE 5 1AD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529609.1193511298 20 184167.343713088 30 0.0 11 529588.8734028448 21 184229.3993270648 31 0.0 0 LINE 5 1AD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529943.8312827582 20 184525.0791841147 30 0.0 11 529696.7858197628 21 184980.4597351244 31 0.0 0 LINE 5 1AD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529427.594100383 20 184538.885622905 30 0.0 11 529760.9646796797 21 184732.402681762 31 0.0 0 LINE 5 1AD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529368.3559519504 20 184630.1442064984 30 0.0 11 530028.4476193018 21 184997.7725392588 31 0.0 0 LINE 5 1ADA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529797.6767641356 20 184947.6190316421 30 0.0 11 529669.928509663 21 185367.8144041533 31 0.0 0 LINE 5 1ADB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529860.2934819285 20 184977.7649049925 30 0.0 11 529682.5843242276 21 184900.118440933 31 0.0 0 LINE 5 1ADC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529830.2206250684 20 185043.8559141184 30 0.0 11 529771.5055698461 21 185017.6225766955 31 0.0 0 LINE 5 1ADD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529870.0535815491 20 185006.8342906227 30 0.0 11 529814.8923235209 21 185047.9984878788 31 0.0 0 LINE 5 1ADE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529787.3488705874 20 185190.8888152999 30 0.0 11 529732.2413258432 21 185422.8053145468 31 0.0 0 LINE 5 1ADF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529528.4200429016 20 184929.8707909057 30 0.0 11 529485.2851129321 21 185003.5640577484 31 0.0 0 LINE 5 1AE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529861.3466617636 20 185395.7871211546 30 0.0 11 529657.6942649834 21 185321.2900416619 31 0.0 0 LINE 5 1AE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529715.1269292716 20 184939.8108993062 30 0.0 11 529599.8119992587 21 185347.9011996878 31 0.0 0 LINE 5 1AE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529488.1906467225 20 184870.3446560795 30 0.0 11 529362.7819015576 21 185181.0898554979 31 0.0 0 LINE 5 1AE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529576.7051272891 20 184900.7056631444 30 0.0 11 529459.6657693327 21 184868.3134693976 31 0.0 0 LINE 5 1AE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529594.3735463972 20 184849.6916871425 30 0.0 11 529575.0063913913 21 184902.0608975654 31 0.0 0 LINE 5 1AE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529670.8641300261 20 184520.4339203804 30 0.0 11 529420.7991483043 21 185024.4032382779 31 0.0 0 LINE 5 1AE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529424.696695358 20 185036.8867831289 30 0.0 11 529403.0273226811 21 185025.9235327067 31 0.0 0 LINE 5 1AE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529484.6776843873 20 184989.0300529047 30 0.0 11 529154.8530687077 21 184857.6163123908 31 0.0 0 LINE 5 1AE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529388.1465096351 20 184631.4338432891 30 0.0 11 529218.8678648771 21 184745.3258481783 31 0.0 0 LINE 5 1AE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529210.1002453442 20 184715.4851078794 30 0.0 11 529459.0742043105 21 184954.3223903557 31 0.0 0 LINE 5 1AEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529501.6288089996 20 184469.6622570667 30 0.0 11 529335.4374341035 21 184681.8639145324 31 0.0 0 LINE 5 1AEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529688.3873202567 20 185052.9417647131 30 0.0 11 529641.8813508754 21 185046.0639198577 31 0.0 0 LINE 5 1AEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529662.8155418183 20 184985.7805038173 30 0.0 11 529642.5695935333 21 185047.8361177944 31 0.0 0 LINE 5 1AED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529711.3834105942 20 184975.9454812266 30 0.0 11 529616.4970881978 21 184932.5919478516 31 0.0 0 LINE 5 1AEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529551.5128856724 20 184605.0938231147 30 0.0 11 529500.9160291978 21 184705.8138740395 31 0.0 0 LINE 5 1AEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529229.9928105621 20 184823.4360587599 30 0.0 11 529069.7380110376 21 184767.29964573 31 0.0 0 LINE 5 1AF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529363.2040231364 20 184387.2143297671 30 0.0 11 529105.5296935886 21 185097.4787454935 31 0.0 0 LINE 5 1AF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529118.2454725926 20 184861.663413327 30 0.0 11 528610.7086128694 21 184746.5116670509 31 0.0 0 LINE 5 1AF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529098.4694227296 20 184928.2857435104 30 0.0 11 529146.7870302851 21 184740.469538374 31 0.0 0 LINE 5 1AF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529170.724510631 20 184957.6331569076 30 0.0 11 529021.8952428087 21 184894.6640790772 31 0.0 0 LINE 5 1AF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529040.859693092 20 184902.3069445089 30 0.0 11 528722.5634822862 21 184932.0754702145 31 0.0 0 LINE 5 1AF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529131.2573684122 20 184670.4601999175 30 0.0 11 528711.0439408052 21 184659.8094122968 31 0.0 0 LINE 5 1AF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529179.4477933593 20 184474.2710277709 30 0.0 11 529122.1824233242 21 184581.3604433139 31 0.0 0 LINE 5 1AF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529219.9382027254 20 184610.819026985 30 0.0 11 529226.5921333122 21 184490.2227742489 31 0.0 0 LINE 5 1AF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529228.5730222924 20 184496.6609956934 30 0.0 11 529177.2948609519 21 184474.5664021717 31 0.0 0 LINE 5 1AF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529519.7451906417 20 184668.359145759 30 0.0 11 529519.7333124487 21 184668.3554653684 31 0.0 0 LINE 5 1AFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529379.9396602592 20 184625.041193395 30 0.0 11 528356.8679548832 21 184402.5798630084 31 0.0 0 LINE 5 1AFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528952.0907373794 20 184691.4129135921 30 0.0 11 529052.0012758732 21 184341.0790658432 31 0.0 0 LINE 5 1AFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529196.5071686171 20 184329.7187022287 30 0.0 11 529068.1024692344 21 184569.0160955433 31 0.0 0 LINE 5 1AFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529180.47536678 20 184566.2627675879 30 0.0 11 529190.6911988818 21 184532.2387980305 31 0.0 0 LINE 5 1AFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528880.8283251523 20 184862.3142856285 30 0.0 11 528996.2187128513 21 184723.5581030898 31 0.0 0 LINE 5 1AFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529059.0688036402 20 184734.6123641568 30 0.0 11 528994.5789272775 21 184724.5201149165 31 0.0 0 LINE 5 1B00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529243.2342187749 20 184739.3962912836 30 0.0 11 529025.374155144 21 184651.9383440277 31 0.0 0 LINE 5 1B01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529306.9039543703 20 184429.3838377322 30 0.0 11 529424.1561644725 21 184602.6736955386 31 0.0 0 LINE 5 1B02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529044.8931152141 20 184745.3829585117 30 0.0 11 529068.1577717093 21 184630.5398072969 31 0.0 0 LINE 5 1B03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529925.571842865 20 184345.3454889904 30 0.0 11 530065.3395954874 21 184485.8060440349 31 0.0 0 LINE 5 1B04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527134.7421133008 20 185746.6815669867 30 0.0 11 526854.7475136897 21 185647.3070632744 31 0.0 0 LINE 5 1B05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527048.0415984104 20 185467.8954880649 30 0.0 11 527041.7620982851 21 185733.2410348589 31 0.0 0 LINE 5 1B06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526774.4150185317 20 185453.3134554358 30 0.0 11 527096.7080671646 21 185548.6402006319 31 0.0 0 LINE 5 1B07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527183.7589148466 20 185507.4189276198 30 0.0 11 527212.8484589074 21 185686.4143336474 31 0.0 0 LINE 5 1B08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527642.2925246087 20 185589.7842453163 30 0.0 11 527633.9139317363 21 185753.7844069439 31 0.0 0 LINE 5 1B09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527039.5332444966 20 185538.7648673743 30 0.0 11 527282.5187367876 21 185520.3123034324 31 0.0 0 LINE 5 1B0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527013.1566275844 20 185737.6687210239 30 0.0 11 527301.7042551051 21 185767.6062004553 31 0.0 0 LINE 5 1B0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528866.4052278898 20 184794.5969995048 30 0.0 11 528899.1937164198 21 184354.8994272966 31 0.0 0 LINE 5 1B0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528801.7919096823 20 184268.0094211798 30 0.0 11 528476.702491275 21 184122.8305720991 31 0.0 0 LINE 5 1B0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529625.620367733 20 184419.5556609415 30 0.0 11 529366.6037593966 21 184233.2897046201 31 0.0 0 LINE 5 1B0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527004.8945598029 20 184700.8393834953 30 0.0 11 526953.4379044082 21 184931.6240468094 31 0.0 0 LINE 5 1B0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528390.9898125458 20 185753.3602785319 30 0.0 11 528781.3753309265 21 185827.6345873771 31 0.0 0 LINE 5 1B10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528106.4157938656 20 187215.6255117142 30 0.0 11 528884.2109935742 21 184710.0395547231 31 0.0 0 LINE 5 1B11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529676.6264599539 20 185290.4940208969 30 0.0 11 529920.7713187865 21 185313.7159799931 31 0.0 0 LINE 5 1B12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529710.1858069896 20 185288.9440628221 30 0.0 11 529589.3946623234 21 185498.1525499557 31 0.0 0 LINE 5 1B13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529260.9647945109 20 185147.8370213298 30 0.0 11 529921.0564618626 21 185515.4653540902 31 0.0 0 LINE 5 1B14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529690.2856066964 20 185465.3118464734 30 0.0 11 529562.5373522235 21 185885.5072189847 31 0.0 0 LINE 5 1B15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529752.9023244892 20 185495.4577198239 30 0.0 11 529575.1931667881 21 185417.8112557643 31 0.0 0 LINE 5 1B16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529722.829467629 20 185561.5487289499 30 0.0 11 529664.1144124067 21 185535.3153915267 31 0.0 0 LINE 5 1B17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529718.0701045081 20 185548.1881227963 30 0.0 11 529624.8501684037 21 185940.498129378 31 0.0 0 LINE 5 1B18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529767.4186194858 20 185663.7851117391 30 0.0 11 529474.2327039333 21 185614.5656806243 31 0.0 0 LINE 5 1B19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529479.5491451336 20 185602.3577959528 30 0.0 11 529426.0863860198 21 185835.1184134999 31 0.0 0 LINE 5 1B1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529338.1500175083 20 185474.63901319 30 0.0 11 529486.7042496121 21 185618.9945535243 31 0.0 0 LINE 5 1B1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529421.0288854622 20 185447.5636057371 30 0.0 11 529377.8939554926 21 185521.2568725796 31 0.0 0 LINE 5 1B1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529753.9555043243 20 185913.4799359859 30 0.0 11 529424.3486629905 21 185832.5479786192 31 0.0 0 LINE 5 1B1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529607.735771832 20 185457.5037141376 30 0.0 11 529492.4208418194 21 185865.5940145193 31 0.0 0 LINE 5 1B1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529052.7007117045 20 185555.5190431744 30 0.0 11 529499.3924342998 21 185865.3700194207 31 0.0 0 LINE 5 1B1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529134.1435313744 20 185504.561087551 30 0.0 11 529122.1575831819 21 185621.3766035377 31 0.0 0 LINE 5 1B20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529185.4622521453 20 185539.5096001749 30 0.0 11 529094.9380125719 21 185601.7266631869 31 0.0 0 LINE 5 1B21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529349.289576162 20 185635.758687261 30 0.0 11 529166.6371817065 21 185549.4723374663 31 0.0 0 LINE 5 1B22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529380.7994892831 20 185388.0374709109 30 0.0 11 529255.3907441184 21 185698.7826703294 31 0.0 0 LINE 5 1B23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529469.3139698497 20 185418.3984779757 30 0.0 11 529352.2746118934 21 185386.006284229 31 0.0 0 LINE 5 1B24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529486.9823889578 20 185367.3845019738 30 0.0 11 529467.6152339519 21 185419.7537123967 31 0.0 0 LINE 5 1B25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529741.8629154026 20 184685.8712765344 30 0.0 11 529313.4079908648 21 185542.0960531091 31 0.0 0 LINE 5 1B26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529317.3055379187 20 185554.5795979603 30 0.0 11 529295.6361652416 21 185543.6163475381 31 0.0 0 LINE 5 1B27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529378.5146834967 20 185734.5983057824 30 0.0 11 529354.3004098581 21 185772.910263777 31 0.0 0 LINE 5 1B28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529392.6194978177 20 185728.0883212426 30 0.0 11 529371.6375650604 21 185739.8741148262 31 0.0 0 LINE 5 1B29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529451.9150188564 20 185752.4298715705 30 0.0 11 529384.6902650206 21 185727.0784447274 31 0.0 0 LINE 5 1B2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529377.2865269477 20 185506.7228677362 30 0.0 11 529047.4619112686 21 185375.3091272221 31 0.0 0 LINE 5 1B2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529280.7553521956 20 185149.1266581205 30 0.0 11 529111.4767074376 21 185263.0186630097 31 0.0 0 LINE 5 1B2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529102.7090879047 20 185233.1779227109 30 0.0 11 529351.6830468711 21 185472.0152051871 31 0.0 0 LINE 5 1B2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529408.5867116509 20 185356.7769038792 30 0.0 11 529376.626936113 21 185341.2666982859 31 0.0 0 LINE 5 1B2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529211.3746992233 20 185427.0353849283 30 0.0 11 529163.3368893673 21 185507.06168701 31 0.0 0 LINE 5 1B2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529177.751636039 20 185475.0031284419 30 0.0 11 529181.4357627487 21 185558.3038454395 31 0.0 0 LINE 5 1B30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529190.3152886656 20 185478.8012390553 30 0.0 11 529123.0419161259 21 185522.372341461 31 0.0 0 LINE 5 1B31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529028.5214292627 20 185457.1815612015 30 0.0 11 529135.6116966774 21 185523.5421908994 31 0.0 0 LINE 5 1B32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529339.5448717486 20 184906.714440032 30 0.0 11 529228.0462766641 21 185199.5567293637 31 0.0 0 LINE 5 1B33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529580.9961628172 20 185570.6345795445 30 0.0 11 529534.4901934361 21 185563.7567346888 31 0.0 0 LINE 5 1B34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529555.4243843787 20 185503.4733186487 30 0.0 11 529535.1784360941 21 185565.5289326257 31 0.0 0 LINE 5 1B35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529603.9922531548 20 185493.638296058 30 0.0 11 529509.1059307583 21 185450.2847626829 31 0.0 0 LINE 5 1B36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529589.5120142827 20 185322.4268616879 30 0.0 11 529435.5125850959 21 185578.2449751067 31 0.0 0 LINE 5 1B37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529466.8386348521 20 185671.6710813359 30 0.0 11 529400.8135946273 21 185652.1708809338 31 0.0 0 LINE 5 1B38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529410.7663206183 20 185621.9237130644 30 0.0 11 529393.5692052581 21 185679.5156498254 31 0.0 0 LINE 5 1B39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529415.7053980812 20 185628.9713987198 30 0.0 11 529347.5852966691 21 185607.802371799 31 0.0 0 LINE 5 1B3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529350.7346442304 20 185605.8272903669 30 0.0 11 529333.3253288324 21 185659.1986828176 31 0.0 0 LINE 5 1B3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529402.1878585207 20 185676.8029646959 30 0.0 11 529327.9291804021 21 185654.6278317182 31 0.0 0 LINE 5 1B3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529444.121728233 20 185122.7866379459 30 0.0 11 529393.5248717581 21 185223.5066888709 31 0.0 0 LINE 5 1B3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529093.4128605832 20 185568.0221979865 30 0.0 11 528595.1237850393 21 185576.7293241136 31 0.0 0 LINE 5 1B3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529051.144898358 20 185513.7781552191 30 0.0 11 528824.4188338513 21 185530.0507223063 31 0.0 0 LINE 5 1B3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529122.6016531229 20 185341.1288735912 30 0.0 11 528962.3468535983 21 185284.9924605613 31 0.0 0 LINE 5 1B40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529213.0006079433 20 185022.9166618555 30 0.0 11 528998.1385361492 21 185615.1715603249 31 0.0 0 LINE 5 1B41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528991.0782652902 20 185445.9785583417 30 0.0 11 529039.3958728458 21 185258.1623532054 31 0.0 0 LINE 5 1B42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528921.0377353934 20 185426.828561506 30 0.0 11 528937.5734197853 21 185364.6818251168 31 0.0 0 LINE 5 1B43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528963.9370200458 20 185460.2488607951 30 0.0 11 528914.5040853694 21 185412.3568939084 31 0.0 0 LINE 5 1B44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528933.4685356528 20 185419.9997593404 30 0.0 11 528615.1723248469 21 185449.7682850459 31 0.0 0 LINE 5 1B45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529023.8662109728 20 185188.1530147488 30 0.0 11 528715.9106166859 21 185150.6747967539 31 0.0 0 LINE 5 1B46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529412.354033202 20 185186.0519605904 30 0.0 11 529412.3421550092 21 185186.0482801997 31 0.0 0 LINE 5 1B47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529040.6633607615 20 184884.196908992 30 0.0 11 528925.5715025252 21 185271.9605769922 31 0.0 0 LINE 5 1B48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528773.4371677128 20 185380.00710046 30 0.0 11 528888.8275554119 21 185241.2509179212 31 0.0 0 LINE 5 1B49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528951.6776462008 20 185252.3051789882 30 0.0 11 528887.1877698381 21 185242.212929748 31 0.0 0 LINE 5 1B4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529135.8430613358 20 185257.0891061149 30 0.0 11 528917.9829977046 21 185169.6311588591 31 0.0 0 LINE 5 1B4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528775.9558829125 20 185615.017381728 30 0.0 11 528778.6521852016 21 185358.8103474443 31 0.0 0 LINE 5 1B4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528729.9180300995 20 185960.161097513 30 0.0 11 528779.0379103066 21 186161.3926041654 31 0.0 0 LINE 5 1B4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528950.4189077693 20 185814.9571831064 30 0.0 11 528984.9742384628 21 186297.2310706317 31 0.0 0 LINE 5 1B4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528951.624137997 20 185561.616747222 30 0.0 11 528966.33570878 21 186100.8301520585 31 0.0 0 LINE 5 1B4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528859.1323982127 20 185799.482461746 30 0.0 11 528965.9004221569 21 185848.3712824754 31 0.0 0 LINE 5 1B50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528863.2406757241 20 185861.4351186065 30 0.0 11 528962.7618637885 21 185814.9471200873 31 0.0 0 LINE 5 1B51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528863.1513625532 20 186051.4437259971 30 0.0 11 528881.3717627635 21 185850.2591133216 31 0.0 0 LINE 5 1B52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528448.7063367634 20 185927.3670817845 30 0.0 11 528965.078864012 21 186002.4559974586 31 0.0 0 LINE 5 1B53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528809.391795014 20 185982.7201336871 30 0.0 11 528810.9272095478 21 185958.4838576892 31 0.0 0 LINE 5 1B54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528737.7329029084 20 186010.1607760782 30 0.0 11 528795.7281322101 21 185579.7030681805 31 0.0 0 LINE 5 1B55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528773.2489006129 20 185602.138604177 30 0.0 11 528964.8435679701 21 185663.829735683 31 0.0 0 LINE 5 1B56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528671.2378729466 20 185560.6509984881 30 0.0 11 528720.795726458 21 185970.4960299483 31 0.0 0 LINE 5 1B57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528753.1546030234 20 185826.7513961091 30 0.0 11 528846.4880856416 21 185825.9140055556 31 0.0 0 LINE 5 1B58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528811.5468672264 20 185822.0868192886 30 0.0 11 528881.4820380612 21 185867.4922608376 31 0.0 0 LINE 5 1B59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528808.4515075253 20 185834.8418088954 30 0.0 11 528880.1132298697 21 185798.942711855 31 0.0 0 LINE 5 1B5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528874.5242430786 20 185631.8475956416 30 0.0 11 528874.7492767722 21 185810.370569834 31 0.0 0 LINE 5 1B5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529226.7259620609 20 185859.1195999941 30 0.0 11 529461.753936208 21 185828.3541730241 31 0.0 0 LINE 5 1B5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529273.2801508957 20 185932.8399631512 30 0.0 11 529287.0712099601 21 185848.5717814258 31 0.0 0 LINE 5 1B5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529088.7060528404 20 185705.938394954 30 0.0 11 529153.993407673 21 185608.3315866453 31 0.0 0 LINE 5 1B5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529150.5211611966 20 185711.7609386521 30 0.0 11 529120.4964274076 21 185606.1005570466 31 0.0 0 LINE 5 1B5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529231.026467415 20 185921.0843057538 30 0.0 11 529260.5967490455 21 185674.6789090408 31 0.0 0 LINE 5 1B60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529127.0111587181 20 185947.2972152716 30 0.0 11 529248.350250143 21 185952.225746367 31 0.0 0 LINE 5 1B61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529224.1848018071 20 186051.4226801147 30 0.0 11 529116.8609899559 21 185996.021142447 31 0.0 0 LINE 5 1B62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529121.4063304959 20 186000.9925100552 30 0.0 11 529128.3572058809 21 185945.5911903531 31 0.0 0 LINE 5 1B63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529155.3301500879 20 186196.5494294306 30 0.0 11 529250.7034320214 21 185791.3870299013 31 0.0 0 LINE 5 1B64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529277.3320268682 20 185859.3770847035 30 0.0 11 528939.7638049955 21 185762.2307008389 31 0.0 0 LINE 5 1B65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528942.970139214 20 185862.2378862911 30 0.0 11 529235.4741338318 21 185869.7730850032 31 0.0 0 LINE 5 1B66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529205.7845020345 20 185994.8187523307 30 0.0 11 529171.2778213867 21 185986.3758428427 31 0.0 0 LINE 5 1B67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529098.7281099492 20 185814.9083276223 30 0.0 11 529112.7833206234 21 185722.6354103959 31 0.0 0 LINE 5 1B68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529103.4337720745 20 185756.5193600031 30 0.0 11 529159.4093684629 21 185694.7187544166 31 0.0 0 LINE 5 1B69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529115.5320268205 20 185761.6088829318 30 0.0 11 529091.5185714267 21 185685.1399246696 31 0.0 0 LINE 5 1B6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528925.6700740792 20 185664.0143344197 30 0.0 11 529101.9449496349 21 185692.2574079522 31 0.0 0 LINE 5 1B6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529323.2047039083 20 186136.6862493935 30 0.0 11 529367.797232147 21 185841.4401863067 31 0.0 0 LINE 5 1B6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 529769.5900111758 20 185807.3295091061 30 0.0 11 529444.5005927685 21 185662.1506600254 31 0.0 0 LINE 5 1B6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528763.7395908349 20 183029.8856650012 30 0.0 11 528976.162882365 21 183032.3786083496 31 0.0 0 LINE 5 1B6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527025.2812095881 20 183263.6346011901 30 0.0 11 526897.1265927663 21 182483.0277155677 31 0.0 0 LINE 5 1B6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526964.2083557769 20 183286.4261005596 30 0.0 11 526885.0249361946 21 182798.3537771728 31 0.0 0 LINE 5 1B70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526777.074562552 20 183143.2710983985 30 0.0 11 526678.3375863469 21 182989.0315936426 31 0.0 0 LINE 5 1B71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526376.0911853841 20 183362.1726671961 30 0.0 11 527059.5232641422 21 182915.9150971422 31 0.0 0 LINE 5 1B72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526781.3386109241 20 183014.4930036137 30 0.0 11 526623.5488075315 21 182604.6318740274 31 0.0 0 LINE 5 1B73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526841.6122685247 20 182979.8994604785 30 0.0 11 526669.981091038 21 183070.1893105516 31 0.0 0 LINE 5 1B74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526806.8403955176 20 182916.1553230647 30 0.0 11 526750.1753566118 21 182946.5645168706 31 0.0 0 LINE 5 1B75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526849.2454166972 20 182950.2005754067 30 0.0 11 526791.2527324742 21 182913.1316652581 31 0.0 0 LINE 5 1B76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526803.0593180441 20 182929.825026326 30 0.0 11 526681.7233194259 21 182545.2802653542 31 0.0 0 LINE 5 1B77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526950.8006147146 20 182784.8000475242 30 0.0 11 526555.0614632221 21 182881.2480553835 31 0.0 0 LINE 5 1B78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526561.2464987034 20 182893.0396766159 30 0.0 11 526491.097430139 21 182664.75283978 31 0.0 0 LINE 5 1B79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526429.450063369 20 183030.6460005865 30 0.0 11 526567.1802176478 21 182875.9292060764 31 0.0 0 LINE 5 1B7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526514.0693656086 20 183051.6592852067 30 0.0 11 526465.7200294525 21 182981.2770327941 31 0.0 0 LINE 5 1B7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526945.2614984458 20 182673.699691965 30 0.0 11 526858.9467190832 21 182699.6197587514 31 0.0 0 LINE 5 1B7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526938.4648895453 20 182521.0740243328 30 0.0 11 526489.5500694043 21 182667.4421689821 31 0.0 0 LINE 5 1B7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526699.5692000325 20 183028.2482065977 30 0.0 11 526555.0552630549 21 182629.5616776445 31 0.0 0 LINE 5 1B7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526184.705617505 20 182931.6259519551 30 0.0 11 526562.0248081487 21 182629.2811126734 31 0.0 0 LINE 5 1B7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525975.5045021903 20 183074.5165478142 30 0.0 11 526410.9589320396 21 182756.1661656958 31 0.0 0 LINE 5 1B80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526223.8142669609 20 183015.5497707789 30 0.0 11 526203.4151242994 21 182899.9063416185 31 0.0 0 LINE 5 1B81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526272.4723055687 20 182976.9828819357 30 0.0 11 526177.6872562321 21 182921.4725648552 31 0.0 0 LINE 5 1B82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526428.9131914558 20 182869.1425922379 30 0.0 11 526252.9762846761 21 182968.4070682298 31 0.0 0 LINE 5 1B83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526478.2483462436 20 183113.9378498654 30 0.0 11 526330.704046688 21 182813.0714143925 31 0.0 0 LINE 5 1B84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526580.5570010577 20 183271.4185264061 30 0.0 11 526399.896323525 21 182965.1540424672 31 0.0 0 LINE 5 1B85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526402.8812421781 20 182952.4214062233 30 0.0 11 526382.0610931183 21 182964.9224447871 31 0.0 0 LINE 5 1B86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526450.9167544769 20 182768.4488967919 30 0.0 11 526423.9962748326 21 182731.9876166585 31 0.0 0 LINE 5 1B87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526465.4552706402 20 182773.9222169457 30 0.0 11 526443.6762423573 21 182763.6840354824 31 0.0 0 LINE 5 1B88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526522.8360133179 20 182745.3578990408 30 0.0 11 526457.6197868785 21 182775.5026528175 31 0.0 0 LINE 5 1B89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526466.1648483548 20 182995.8169228339 30 0.0 11 526078.9306227268 21 183192.5577152809 31 0.0 0 LINE 5 1B8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526110.1635046939 20 183198.3175948517 30 0.0 11 526052.1249617262 21 183005.5850345606 31 0.0 0 LINE 5 1B8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526395.7367372402 20 183359.4557518874 30 0.0 11 526084.9426491088 21 183172.395334799 31 0.0 0 LINE 5 1B8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526148.6610269019 20 183296.7644774479 30 0.0 11 526443.1373601789 21 183032.2846458226 31 0.0 0 LINE 5 1B8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526306.4476798011 20 183087.2896267643 30 0.0 11 526252.7504783172 21 183010.9453358622 31 0.0 0 LINE 5 1B8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526269.4450135935 20 183041.8779819008 30 0.0 11 526267.0977212187 21 182958.5288819632 31 0.0 0 LINE 5 1B8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526281.7012315749 20 183037.1815862247 30 0.0 11 526211.4541276583 21 182998.5876487597 31 0.0 0 LINE 5 1B90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526077.0975650373 20 183098.088044319 30 0.0 11 526223.9064536299 21 182996.5121949012 31 0.0 0 LINE 5 1B91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526664.7213589688 20 182917.3463248682 30 0.0 11 526618.8342611189 21 182927.568075641 31 0.0 0 LINE 5 1B92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526644.0715489711 20 182986.1804455111 30 0.0 11 526619.3925915336 21 182925.7507615153 31 0.0 0 LINE 5 1B93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526693.2233190768 20 182992.4787819791 30 0.0 11 526601.7192616864 21 183042.5781883141 31 0.0 0 LINE 5 1B94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526691.1577809463 20 183164.2890439809 30 0.0 11 526519.0682599293 21 182920.2727984166 31 0.0 0 LINE 5 1B95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526543.5586095794 20 182824.8265753773 30 0.0 11 526479.1159747663 21 182849.0486845077 31 0.0 0 LINE 5 1B96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526491.2292186234 20 182878.4972369685 30 0.0 11 526469.913795082 21 182822.2991526963 31 0.0 0 LINE 5 1B97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526495.6458991038 20 182871.1109460985 30 0.0 11 526429.2343233493 21 182897.1489668176 31 0.0 0 LINE 5 1B98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526432.5182091687 20 182898.891215551 30 0.0 11 526411.2962424721 21 182846.9179731636 31 0.0 0 LINE 5 1B99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526478.7059982679 20 182824.3817010889 30 0.0 11 526406.244637348 21 182851.8669511721 31 0.0 0 LINE 5 1B9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526831.8309248414 20 182816.4182337956 30 0.0 11 526766.5959213014 21 182559.9847257041 31 0.0 0 LINE 5 1B9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527000.2530682652 20 182306.9787163504 30 0.0 11 526860.1632714045 21 182354.2285155059 31 0.0 0 LINE 5 1B9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526958.5995454632 20 182466.2489230176 30 0.0 11 526879.4161258808 21 181978.1765996306 31 0.0 0 LINE 5 1B9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526892.7851017648 20 182352.9689788648 30 0.0 11 526813.0293333185 21 182333.9922653943 31 0.0 0 LINE 5 1B9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526867.2513936017 20 182428.4894751634 30 0.0 11 526886.42456548 21 182342.7583958494 31 0.0 0 LINE 5 1B9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526877.6704091146 20 182414.4235645573 30 0.0 11 526695.6134468584 21 182494.4830129586 31 0.0 0 LINE 5 1BA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526952.0471927737 20 182605.1847142627 30 0.0 11 526672.7287760333 21 182168.8544161005 31 0.0 0 LINE 5 1BA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526668.6311203727 20 182445.7554883518 30 0.0 11 526817.1655042102 21 182332.718434346 31 0.0 0 LINE 5 1BA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526702.3646228387 20 182496.1108717801 30 0.0 11 526668.7997668507 21 182444.9247298686 31 0.0 0 LINE 5 1BA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526436.1625892373 20 182628.7330061977 30 0.0 11 526681.7623917887 21 182461.3212290171 31 0.0 0 LINE 5 1BA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526494.6810839999 20 182593.2752383091 30 0.0 11 526437.4933880692 21 182495.666997106 31 0.0 0 LINE 5 1BA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526370.4823750703 20 182541.9954896542 30 0.0 11 527002.2713055748 21 182127.6111901839 31 0.0 0 LINE 5 1BA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526775.7298006102 20 182194.3158260718 30 0.0 11 526521.3716858642 21 181598.3809927647 31 0.0 0 LINE 5 1BA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526836.0034582111 20 182159.7222829365 30 0.0 11 526664.3722807242 21 182250.0121330097 31 0.0 0 LINE 5 1BA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526801.2315852038 20 182095.9781455227 30 0.0 11 526744.5665462982 21 182126.3873393285 31 0.0 0 LINE 5 1BA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526843.6366063836 20 182130.0233978648 30 0.0 11 526785.6439221603 21 182092.9544877161 31 0.0 0 LINE 5 1BAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526797.4505077304 20 182109.6478487839 30 0.0 11 526755.1504495946 21 181975.5881638581 31 0.0 0 LINE 5 1BAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526945.1918044008 20 181964.6228699824 30 0.0 11 526549.4526529084 21 182061.0708778416 31 0.0 0 LINE 5 1BAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526555.6376883897 20 182072.8624990739 30 0.0 11 526485.4886198253 21 181844.5756622381 31 0.0 0 LINE 5 1BAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526423.8412530552 20 182210.4688230445 30 0.0 11 526561.5714073341 21 182055.7520285342 31 0.0 0 LINE 5 1BAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526508.4605552949 20 182231.4821076646 30 0.0 11 526460.1112191387 21 182161.0998552523 31 0.0 0 LINE 5 1BAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526933.2335520479 20 181839.9368571187 30 0.0 11 526846.9187726854 21 181865.856923905 31 0.0 0 LINE 5 1BB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526693.9603897188 20 182208.0710290557 30 0.0 11 526549.4464527412 21 181809.3845001026 31 0.0 0 LINE 5 1BB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526218.2054566471 20 182195.3725932368 30 0.0 11 526197.8063139856 21 182079.7291640766 31 0.0 0 LINE 5 1BB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526266.863495255 20 182156.8057043941 30 0.0 11 526172.0784459183 21 182101.2953873133 31 0.0 0 LINE 5 1BB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526423.3043811421 20 182048.9654146958 30 0.0 11 526247.3674743625 21 182148.2298906876 31 0.0 0 LINE 5 1BB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526472.6395359299 20 182293.7606723235 30 0.0 11 526275.9831066587 21 181913.3195666171 31 0.0 0 LINE 5 1BB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526558.7276475325 20 182257.0804179532 30 0.0 11 526444.3361225294 21 182297.8485983638 31 0.0 0 LINE 5 1BB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526496.8912697186 20 182385.3812040725 30 0.0 11 526582.9000737242 21 182300.5860591656 31 0.0 0 LINE 5 1BB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526580.0376232157 20 182306.6836811287 30 0.0 11 526556.93538664 21 182255.8515302934 31 0.0 0 LINE 5 1BB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526680.130013927 20 182629.5505262505 30 0.0 11 526394.2875132112 21 182144.9768649251 31 0.0 0 LINE 5 1BB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526397.2724318643 20 182132.2442286813 30 0.0 11 526376.4522828047 21 182144.7452672451 31 0.0 0 LINE 5 1BBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526445.3079441631 20 181948.2717192499 30 0.0 11 526401.4980246618 21 181884.4450689966 31 0.0 0 LINE 5 1BBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526459.8464603266 20 181953.7450394038 30 0.0 11 526438.0674320437 21 181943.5068579403 31 0.0 0 LINE 5 1BBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526517.2272030042 20 181925.1807214987 30 0.0 11 526452.0109765648 21 181955.3254752755 31 0.0 0 LINE 5 1BBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526460.556038041 20 182175.639745292 30 0.0 11 526141.0942032139 21 182330.5525736593 31 0.0 0 LINE 5 1BBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526390.1279269266 20 182539.2785743455 30 0.0 11 526213.0589553081 21 182437.9216424716 31 0.0 0 LINE 5 1BBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526206.4714515425 20 182468.3181180565 30 0.0 11 526437.5285498651 21 182212.1074682804 31 0.0 0 LINE 5 1BC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526502.6138736954 20 182322.9307229501 30 0.0 11 526471.8589425878 21 182340.7107100859 31 0.0 0 LINE 5 1BC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526300.8388694875 20 182267.1124492223 30 0.0 11 526247.1416680035 21 182190.7681583202 31 0.0 0 LINE 5 1BC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526263.8362032798 20 182221.700804359 30 0.0 11 526261.488910905 21 182138.3517044211 31 0.0 0 LINE 5 1BC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526276.0924212611 20 182217.0044086828 30 0.0 11 526205.8453173446 21 182178.4104712177 31 0.0 0 LINE 5 1BC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526116.2847454244 20 182250.2635450903 30 0.0 11 526218.2976433162 21 182176.3350173591 31 0.0 0 LINE 5 1BC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526515.0077327294 20 182692.4233179073 30 0.0 11 526333.9111826571 21 182492.7907652685 31 0.0 0 LINE 5 1BC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526659.1125486551 20 182097.1691473261 30 0.0 11 526613.2254508053 21 182107.3908980991 31 0.0 0 LINE 5 1BC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526638.4627386574 20 182166.0032679689 30 0.0 11 526613.7837812198 21 182105.5735839731 31 0.0 0 LINE 5 1BC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526687.6145087632 20 182172.301604437 30 0.0 11 526596.1104513726 21 182222.401010772 31 0.0 0 LINE 5 1BC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526685.5489706326 20 182344.1118664388 30 0.0 11 526513.4594496156 21 182100.0956208746 31 0.0 0 LINE 5 1BCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526537.9497992656 20 182004.6493978354 30 0.0 11 526473.5071644527 21 182028.8715069656 31 0.0 0 LINE 5 1BCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526485.6204083097 20 182058.3200594264 30 0.0 11 526464.3049847683 21 182002.1219751545 31 0.0 0 LINE 5 1BCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526490.0370887901 20 182050.9337685565 30 0.0 11 526423.6255130356 21 182076.9717892756 31 0.0 0 LINE 5 1BCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526426.9093988549 20 182078.7140380091 30 0.0 11 526405.6874321583 21 182026.7407956217 31 0.0 0 LINE 5 1BCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526473.0971879541 20 182004.204523547 30 0.0 11 526400.6358270344 21 182031.68977363 31 0.0 0 LINE 5 1BCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526554.9709952949 20 182553.7399813713 30 0.0 11 526497.225498478 21 182456.9410756913 31 0.0 0 LINE 5 1BD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526826.2221145276 20 181996.2410562537 30 0.0 11 526760.9871109879 21 181739.8075481622 31 0.0 0 LINE 5 1BD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527412.0818102422 20 181564.1583751753 30 0.0 11 525538.5358990799 21 182148.4234918985 31 0.0 0 LINE 5 1BD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526134.7576759403 20 182192.179583049 30 0.0 11 525907.4484610363 21 182192.3395395591 31 0.0 0 LINE 5 1BD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526218.5082342736 20 182359.2115746763 30 0.0 11 526062.7307945771 21 182426.7858813327 31 0.0 0 LINE 5 1BD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526382.9052427298 20 182784.6622153052 30 0.0 11 526060.0427866276 21 182062.4070552026 31 0.0 0 LINE 5 1BD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526104.2898207399 20 182329.1624117874 30 0.0 11 525674.5130014083 21 182419.581730331 31 0.0 0 LINE 5 1BD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526079.7494059731 20 182264.1439907801 30 0.0 11 526141.5177681991 21 182447.9759454006 31 0.0 0 LINE 5 1BD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526011.276471197 20 182288.3070909581 30 0.0 11 526032.2614591864 21 182349.0958726634 31 0.0 0 LINE 5 1BD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526051.6475756412 20 182251.8730553012 30 0.0 11 526005.8060671727 21 182303.2132113621 31 0.0 0 LINE 5 1BD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526024.1684002717 20 182294.2194085108 30 0.0 11 525625.1965641057 21 182352.687961578 31 0.0 0 LINE 5 1BDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525905.1414408565 20 182121.4676071119 30 0.0 11 525936.6700146762 21 182531.2989112529 31 0.0 0 LINE 5 1BDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525949.296971645 20 182527.0731624555 30 0.0 11 525712.7456148091 21 182559.9247571213 31 0.0 0 LINE 5 1BDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526064.1280438116 20 182679.1245538622 30 0.0 11 525933.351531187 21 182518.4871184777 31 0.0 0 LINE 5 1BDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526098.3649140155 20 182598.9383882181 30 0.0 11 526021.1738839632 21 182635.4468069849 31 0.0 0 LINE 5 1BDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525602.5606954889 20 181842.0189004617 30 0.0 11 525715.1538129658 21 182561.8811309198 31 0.0 0 LINE 5 1BDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526104.8310295083 20 182412.0789316116 30 0.0 11 525688.2026632234 21 182491.1740057715 31 0.0 0 LINE 5 1BE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525927.3506884325 20 182904.9491957143 30 0.0 11 525689.0369715465 21 182484.2488916828 31 0.0 0 LINE 5 1BE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526017.9443528103 20 183100.6657351099 30 0.0 11 525790.2114538591 21 182653.6137042441 31 0.0 0 LINE 5 1BE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526016.436623323 20 182879.722423568 30 0.0 11 525899.0200947565 21 182881.4214081781 31 0.0 0 LINE 5 1BE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525986.1216033472 20 182825.5374699364 30 0.0 11 525916.2081338395 21 182910.2588229799 31 0.0 0 LINE 5 1BE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525904.605267724 20 182653.9030739494 30 0.0 11 525974.5468944026 21 182843.4166624298 31 0.0 0 LINE 5 1BE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526121.5860971713 20 182654.811784923 30 0.0 11 525833.5921459401 21 182741.9152869398 31 0.0 0 LINE 5 1BE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526193.3364792057 20 182711.1169602223 30 0.0 11 526128.4794766109 21 182608.447418775 31 0.0 0 LINE 5 1BE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526223.8499447324 20 182571.9991764507 30 0.0 11 526239.204328213 21 182691.798900466 31 0.0 0 LINE 5 1BE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526240.7146177363 20 182685.2343256837 30 0.0 11 526191.167827044 21 182710.97799336 31 0.0 0 LINE 5 1BE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526518.7129862614 20 182492.9366568091 30 0.0 11 526518.7014051999 21 182492.9411862413 31 0.0 0 LINE 5 1BEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526382.4046717591 20 182546.2477693468 30 0.0 11 525994.7616732592 21 182697.8575929502 31 0.0 0 LINE 5 1BEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525982.6678762281 20 182692.8806623247 30 0.0 11 525991.6892370746 21 182715.4277158023 31 0.0 0 LINE 5 1BEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525808.7082592372 20 182616.1255561446 30 0.0 11 525768.4210246726 21 182636.8879236488 31 0.0 0 LINE 5 1BED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525816.4297002768 20 182602.6457551815 30 0.0 11 525802.8498693046 21 182622.5136847008 31 0.0 0 LINE 5 1BEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525797.3801032143 20 182541.4445890212 30 0.0 11 525816.7405599603 21 182610.6329918491 31 0.0 0 LINE 5 1BEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526035.598679878 20 182637.3260432762 30 0.0 11 526147.3595702719 21 182970.3413998211 31 0.0 0 LINE 5 1BF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526227.8513561675 20 182910.9041209083 30 0.0 11 526067.9281441547 21 182665.8736486268 31 0.0 0 LINE 5 1BF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526187.7113128795 20 182619.2916172854 30 0.0 11 526200.3599981748 21 182652.4880702626 31 0.0 0 LINE 5 1BF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526100.4344341845 20 182809.5850182491 30 0.0 11 526016.5049331899 21 182850.4222446896 31 0.0 0 LINE 5 1BF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526049.7037537386 20 182838.873460631 30 0.0 11 525967.0467297591 21 182827.900829733 31 0.0 0 LINE 5 1BF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526047.0216787222 20 182826.0252123005 30 0.0 11 525997.7207043991 21 182889.2198445766 31 0.0 0 LINE 5 1BF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526074.5251576573 20 183037.7226748375 30 0.0 11 525997.6573086355 21 182876.5959025693 31 0.0 0 LINE 5 1BF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525989.7915622426 20 182428.7977942877 30 0.0 11 525992.5659074848 21 182475.7276669322 31 0.0 0 LINE 5 1BF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526054.4524535999 20 182460.1589158632 30 0.0 11 525990.8608686098 21 182474.886711572 31 0.0 0 LINE 5 1BF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526068.5073888174 20 182412.6402422408 30 0.0 11 526103.3756467485 21 182510.9618961269 31 0.0 0 LINE 5 1BF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526237.7902046644 20 182442.0742503921 30 0.0 11 525969.4564207093 21 182573.0540646057 31 0.0 0 LINE 5 1BFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525879.1362642368 20 182533.658277353 30 0.0 11 525892.7731972832 21 182601.1386286375 31 0.0 0 LINE 5 1BFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525923.7764311459 20 182593.8758875 30 0.0 11 525864.898618392 21 182605.9579039674 31 0.0 0 LINE 5 1BFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525917.1888719714 20 182588.3379796451 30 0.0 11 525932.304539506 21 182658.0516261728 31 0.0 0 LINE 5 1BFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525934.5481091393 20 182655.0875526203 30 0.0 11 525879.8559882184 21 182667.7509527922 31 0.0 0 LINE 5 1BFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525868.3564271535 20 182597.610245419 30 0.0 11 525883.9361791152 21 182673.5270362318 31 0.0 0 LINE 5 1BFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525916.8000977243 20 182247.7333508397 30 0.0 11 525653.2457118757 21 182271.245804112 31 0.0 0 LINE 5 1C00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527244.1243499752 20 183861.7178842388 30 0.0 11 526887.8587946553 21 181585.0043007456 31 0.0 0 LINE 5 1C01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527212.5796583467 20 183246.1310702512 30 0.0 11 527133.3962387643 21 182758.0587468642 31 0.0 0 LINE 5 1C02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527346.8091104488 20 183038.3259333679 30 0.0 11 527389.7655543316 21 182873.6116105945 31 0.0 0 LINE 5 1C03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527794.4787894083 20 183132.0576301447 30 0.0 11 527011.5876332116 21 182924.7692635655 31 0.0 0 LINE 5 1C04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527300.0973198231 20 182930.3311150156 30 0.0 11 527320.2151109535 21 182491.6067800618 31 0.0 0 LINE 5 1C05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527231.9783573573 20 182916.5676132878 30 0.0 11 527423.3516630881 21 182947.964682665 31 0.0 0 LINE 5 1C06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527244.8138405172 20 182845.0997983003 30 0.0 11 527308.1863830451 21 182856.0344476155 31 0.0 0 LINE 5 1C07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527215.3473432128 20 182890.805274612 30 0.0 11 527258.6460484188 21 182837.3031470795 31 0.0 0 LINE 5 1C08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527252.7226938883 20 182856.8729615311 30 0.0 11 527246.2602959411 21 182453.6914451339 31 0.0 0 LINE 5 1C09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527066.7092573773 20 182765.9953699274 30 0.0 11 527472.6425793829 21 182732.3823913409 31 0.0 0 LINE 5 1C0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527470.5027378193 20 182745.5246161631 30 0.0 11 527464.8802400704 21 182506.7691780846 31 0.0 0 LINE 5 1C0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527639.0437239939 20 182834.4050793871 30 0.0 11 527459.4638476878 21 182731.1677318473 31 0.0 0 LINE 5 1C0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527565.4080953913 20 182881.0931789668 30 0.0 11 527589.0259726629 21 182799.0351773181 31 0.0 0 LINE 5 1C0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527035.5118023315 20 182581.3668340386 30 0.0 11 527125.5940504404 21 182578.6687654175 31 0.0 0 LINE 5 1C0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526995.0345653063 20 182511.8963263632 30 0.0 11 527467.1984727799 21 182508.8313647648 31 0.0 0 LINE 5 1C0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527382.0213844116 20 182917.5291695387 30 0.0 11 527393.0771309889 21 182493.6034722552 31 0.0 0 LINE 5 1C10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527723.7383600434 20 182594.346349493 30 0.0 11 527386.376364243 21 182495.5407385079 31 0.0 0 LINE 5 1C11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528083.5754440563 20 182732.5093126143 30 0.0 11 527854.3980075514 21 182659.1965084425 31 0.0 0 LINE 5 1C12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527528.3942624024 20 183313.0177615849 30 0.0 11 527646.3761425884 21 182762.9288193099 31 0.0 0 LINE 5 1C13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527639.5188679864 20 182751.7929515791 30 0.0 11 527663.2233537091 21 182757.070444228 31 0.0 0 LINE 5 1C14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527535.7837706053 20 182592.4432598958 30 0.0 11 527553.7426780206 21 182532.6692124688 31 0.0 0 LINE 5 1C15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527523.7213644617 20 182602.2322355196 30 0.0 11 527541.1464808263 21 182585.6336888271 31 0.0 0 LINE 5 1C16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527460.2530903324 20 182593.2741069957 30 0.0 11 527531.6546121294 21 182601.2543987397 31 0.0 0 LINE 5 1C17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527380.0198904067 20 182801.2983929789 30 0.0 11 527426.7849958205 21 182796.4885225456 31 0.0 0 LINE 5 1C18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527421.3726306412 20 182860.0734020617 30 0.0 11 527425.6807543277 21 182794.940939201 31 0.0 0 LINE 5 1C19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527376.733173879 20 182881.5881515784 30 0.0 11 527479.3828969314 21 182900.1886190805 31 0.0 0 LINE 5 1C1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527433.0110471161 20 183043.9329499576 30 0.0 11 527519.127408857 21 182758.0261406934 31 0.0 0 LINE 5 1C1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527465.7176284195 20 182675.2182058559 30 0.0 11 527534.5127772507 21 182677.824208477 31 0.0 0 LINE 5 1C1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527532.3310817872 20 182709.5919298885 30 0.0 11 527534.7860246275 21 182649.5374112223 31 0.0 0 LINE 5 1C1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527525.8057444187 20 182703.9808398422 30 0.0 11 527597.0429492604 21 182707.687126868 31 0.0 0 LINE 5 1C1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527594.4783161435 20 182710.3782221283 30 0.0 11 527598.1802909119 21 182654.3613927147 31 0.0 0 LINE 5 1C1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527527.1031916927 20 182654.2928210643 30 0.0 11 527604.5374235002 21 182657.4594506405 31 0.0 0 LINE 5 1C20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526988.8188472393 20 182388.6928958193 30 0.0 11 527217.0229275381 21 182409.8910709357 31 0.0 0 LINE 5 1C21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527052.3626297287 20 182411.7094164673 30 0.0 11 527135.7854414482 21 182093.7294633607 31 0.0 0 LINE 5 1C22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527227.2159459994 20 182355.1323276016 30 0.0 11 527050.5631702309 21 182294.8526828323 31 0.0 0 LINE 5 1C23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527211.1326827404 20 182413.5698367184 30 0.0 11 527226.7933031375 21 182354.3974981635 31 0.0 0 LINE 5 1C24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527505.6096122967 20 182455.2290636664 30 0.0 11 527219.6793507476 21 182374.0511622241 31 0.0 0 LINE 5 1C25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527437.9658937181 20 182327.9040809348 30 0.0 11 526810.1065464444 21 182158.7874360434 31 0.0 0 LINE 5 1C26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527046.1172069397 20 182150.4489677819 30 0.0 11 527058.2752633564 21 181885.3087652044 31 0.0 0 LINE 5 1C27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526977.9982444741 20 182136.6854660542 30 0.0 11 527169.3715502046 21 182168.0825354316 31 0.0 0 LINE 5 1C28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526990.8337276338 20 182065.2176510666 30 0.0 11 527054.2062701618 21 182076.152300382 31 0.0 0 LINE 5 1C29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526961.3672303293 20 182110.9231273783 30 0.0 11 527004.6659355352 21 182057.4209998459 31 0.0 0 LINE 5 1C2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526998.7425810051 20 182076.9908142976 30 0.0 11 526992.2801830577 21 181673.8092979005 31 0.0 0 LINE 5 1C2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526922.3970494072 20 181977.1444343519 30 0.0 11 527218.6624664996 21 181952.5002441074 31 0.0 0 LINE 5 1C2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527216.5226249359 20 181965.6424689295 30 0.0 11 527210.900127187 21 181726.8870308509 31 0.0 0 LINE 5 1C2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527510.2724370283 20 182121.4202003876 30 0.0 11 527205.4837348044 21 181951.2855846136 31 0.0 0 LINE 5 1C2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527241.1336385168 20 182299.7189575159 30 0.0 11 527335.0458597796 21 182019.1530300846 31 0.0 0 LINE 5 1C2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527128.0412715281 20 182137.647022305 30 0.0 11 527139.0970181055 21 181713.7213250218 31 0.0 0 LINE 5 1C30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527644.5683360037 20 181893.7221573058 30 0.0 11 527280.5326643672 21 181897.9420612434 31 0.0 0 LINE 5 1C31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527274.414149519 20 182533.1356143514 30 0.0 11 527336.2037937141 21 182220.4267102733 31 0.0 0 LINE 5 1C32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527325.0335880328 20 182244.5270912905 30 0.0 11 527691.2728910904 21 182079.0561384222 31 0.0 0 LINE 5 1C33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527598.9071578056 20 182144.6278645905 30 0.0 11 527531.865750263 21 181991.8653653745 31 0.0 0 LINE 5 1C34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527450.9444338949 20 182540.5796976902 30 0.0 11 527511.1304576061 21 182404.0055193513 31 0.0 0 LINE 5 1C35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527126.0397775233 20 182021.4162457452 30 0.0 11 527172.8048829372 21 182016.6063753122 31 0.0 0 LINE 5 1C36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527167.3925177578 20 182080.1912548282 30 0.0 11 527171.7006414443 21 182015.0587919673 31 0.0 0 LINE 5 1C37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527122.7530609956 20 182101.7060043448 30 0.0 11 527225.4027840479 21 182120.3064718471 31 0.0 0 LINE 5 1C38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527179.0309342328 20 182264.0508027241 30 0.0 11 527265.1472959734 21 181978.1439934599 31 0.0 0 LINE 5 1C39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527211.737515536 20 181895.3360586223 30 0.0 11 527280.5326643672 21 181897.9420612434 31 0.0 0 LINE 5 1C3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527369.1858417139 20 182421.6441571977 30 0.0 11 527393.3662381814 21 182311.5538353243 31 0.0 0 LINE 5 1C3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527802.8122269755 20 182483.2968750188 30 0.0 11 527583.6445782589 21 182670.5338326724 31 0.0 0 LINE 5 1C3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527384.3609804307 20 182352.4964698768 30 0.0 11 527384.3733994724 21 182352.4971056026 31 0.0 0 LINE 5 1C3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527689.197375687 20 182379.5744221103 30 0.0 11 527946.2242562205 21 182381.2580377173 31 0.0 0 LINE 5 1C3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527886.3906322288 20 182282.7998223323 30 0.0 11 527887.5998568822 21 182688.0099292871 31 0.0 0 LINE 5 1C3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527814.4709905778 20 182564.0233585824 30 0.0 11 527866.6988063393 21 182374.0463819468 31 0.0 0 LINE 5 1C40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527572.1680598442 20 182088.2086467597 30 0.0 11 527906.2226569025 21 182703.8343193632 31 0.0 0 LINE 5 1C41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527881.2945578066 20 182520.6635047166 30 0.0 11 527993.0588859202 21 182481.5747727534 31 0.0 0 LINE 5 1C42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527605.0161793467 20 183011.740254553 30 0.0 11 527444.9266236437 21 182966.5454992318 31 0.0 0 LINE 5 1C43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527070.7837827931 20 182765.6579821643 30 0.0 11 526900.6797779977 21 182664.0271809811 31 0.0 0 LINE 5 1C44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524802.1481827238 20 181562.0366289828 30 0.0 11 524281.0200600184 21 181032.262673504 31 0.0 0 LINE 5 1C45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524777.053703827 20 181357.5184435995 30 0.0 11 524684.092533473 21 181242.5579481624 31 0.0 0 LINE 5 1C46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524613.2310495336 20 181373.7712167126 30 0.0 11 525043.4239603823 21 181130.0117733084 31 0.0 0 LINE 5 1C47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524696.6030450924 20 181272.7118425649 30 0.0 11 524686.699858292 21 181191.3298719215 31 0.0 0 LINE 5 1C48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524616.9155208406 20 181274.995281273 30 0.0 11 524703.9691052645 21 181263.2011336066 31 0.0 0 LINE 5 1C49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524634.8557972559 20 181281.3092651929 30 0.0 11 524496.5522201735 21 181138.3884012488 31 0.0 0 LINE 5 1C4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524531.9507471499 20 181347.9530573438 30 0.0 11 524792.8333296382 21 181002.4107307421 31 0.0 0 LINE 5 1C4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524531.7445357123 20 181094.7342720634 30 0.0 11 524689.3308695419 21 181194.7661977195 31 0.0 0 LINE 5 1C4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524496.2389124904 20 181143.8562075754 30 0.0 11 524532.5821545919 21 181094.6039037225 31 0.0 0 LINE 5 1C4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524279.4212524852 20 180940.2824972378 30 0.0 11 524521.708080378 21 181112.4540953071 31 0.0 0 LINE 5 1C4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524332.9951300431 20 180982.8443014322 30 0.0 11 524404.6669084259 21 180895.3174055657 31 0.0 0 LINE 5 1C4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524337.9495387016 20 180848.5670295033 30 0.0 11 524993.7823634268 21 181334.4770326099 31 0.0 0 LINE 5 1C50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524804.7283952061 20 181107.8431824673 30 0.0 11 525134.2787297177 21 180817.5324099774 31 0.0 0 LINE 5 1C51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524858.1013985478 20 181152.3510417901 30 0.0 11 524713.8250135487 21 181022.7599817463 31 0.0 0 LINE 5 1C52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524905.8017889537 20 181097.6055309042 30 0.0 11 524857.6059376409 21 181055.0284758354 31 0.0 0 LINE 5 1C53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524888.6026609199 20 181149.1948226532 30 0.0 11 524903.2237374958 21 181081.9380040936 31 0.0 0 LINE 5 1C54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524891.6697933747 20 181098.8072110047 30 0.0 11 525210.1397417366 21 180851.473449173 31 0.0 0 LINE 5 1C55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525078.9775679318 20 181186.9861926767 30 0.0 11 524851.094926959 21 180849.375179546 31 0.0 0 LINE 5 1C56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524842.1852879555 20 180859.2703969775 30 0.0 11 525031.9003218494 21 180714.2049717113 31 0.0 0 LINE 5 1C57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524667.3719613483 20 180783.4673521569 30 0.0 11 524860.2914843905 21 180858.8924111912 31 0.0 0 LINE 5 1C58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524677.0544180947 20 180870.1174212477 30 0.0 11 524726.2643675579 21 180800.3341808871 31 0.0 0 LINE 5 1C59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525423.1171166157 20 181253.2601729294 30 0.0 11 525126.9555856972 21 181071.2670086604 31 0.0 0 LINE 5 1C5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525322.0041594378 20 181083.8277647864 30 0.0 11 525028.8409972251 21 180713.6879130657 31 0.0 0 LINE 5 1C5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524763.431323889 20 181035.9405116734 30 0.0 11 525087.1132389359 21 180761.9601397101 31 0.0 0 LINE 5 1C5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524675.2302947439 20 180519.5676355819 30 0.0 11 525089.7968232458 21 180768.3984353517 31 0.0 0 LINE 5 1C5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524468.5794109521 20 180373.0130680584 30 0.0 11 524918.345269609 21 180670.801917173 31 0.0 0 LINE 5 1C5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524610.1124200717 20 180585.388272364 30 0.0 11 524711.4732601816 21 180526.0965543799 31 0.0 0 LINE 5 1C5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524663.1774156499 20 180617.6235927516 30 0.0 11 524682.3142602708 21 180509.4599109629 31 0.0 0 LINE 5 1C60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524818.6363339504 20 180726.8746960876 30 0.0 11 524664.4485827883 21 180596.3627473906 31 0.0 0 LINE 5 1C61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524606.2118737778 20 180858.155023537 30 0.0 11 524837.1099606695 21 180615.3052638189 31 0.0 0 LINE 5 1C62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524670.5069143573 20 180926.1458448061 30 0.0 11 524592.5487836899 21 180833.0330347883 31 0.0 0 LINE 5 1C63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524528.7166376978 20 180912.716519252 30 0.0 11 524638.1041728994 21 180963.9229456919 31 0.0 0 LINE 5 1C64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524631.3919774674 20 180963.3563338301 30 0.0 11 524671.0368695406 21 180924.0383554253 31 0.0 0 LINE 5 1C65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524363.3830957445 20 181169.3483862856 30 0.0 11 524718.5236090007 21 180733.0081700438 31 0.0 0 LINE 5 1C66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524731.5003627983 20 180731.3853250246 30 0.0 11 524712.5467186364 21 180716.2026393256 31 0.0 0 LINE 5 1C67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524920.7041831621 20 180712.5383351309 30 0.0 11 524945.5466481336 21 180674.6306959616 31 0.0 0 LINE 5 1C68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524920.6206858733 20 180728.0727715202 30 0.0 11 524922.6578734268 21 180704.0936910647 31 0.0 0 LINE 5 1C69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524967.3350531292 20 180771.9616969969 30 0.0 11 524916.4174040469 21 180721.2738741675 31 0.0 0 LINE 5 1C6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524712.7839783264 20 180805.8009324259 30 0.0 11 524393.8048668058 21 180510.9965713254 31 0.0 0 LINE 5 1C6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524399.2505034822 20 180542.2857734541 30 0.0 11 524559.8302091394 21 180420.9248637786 31 0.0 0 LINE 5 1C6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524347.3201296349 20 180866.0461988797 30 0.0 11 524414.8002064813 21 180509.6321081265 31 0.0 0 LINE 5 1C6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524320.3012945151 20 180612.5770980434 30 0.0 11 524670.5888307349 21 180796.8717918515 31 0.0 0 LINE 5 1C6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524589.2673918903 20 180896.3942352395 30 0.0 11 524561.9130884548 21 180873.7284942734 31 0.0 0 LINE 5 1C6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524571.5360312731 20 180687.7931066333 30 0.0 11 524624.479636645 21 180610.9242907791 31 0.0 0 LINE 5 1C70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524601.2702712349 20 180637.3224243558 30 0.0 11 524678.6162067298 21 180606.1745752426 31 0.0 0 LINE 5 1C71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524609.9308592037 20 180647.1847378564 30 0.0 11 524621.7261504309 21 180567.9066278729 31 0.0 0 LINE 5 1C72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524481.7577776428 20 180476.4688388858 30 0.0 11 524627.9970410905 21 180578.8630808189 31 0.0 0 LINE 5 1C73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524142.4573055844 20 180955.8171789115 30 0.0 11 524295.3029998789 21 181044.3303311023 31 0.0 0 LINE 5 1C74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524235.4919657421 20 181022.7282783792 30 0.0 11 524371.3906109211 21 180797.1836498444 31 0.0 0 LINE 5 1C75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524855.327798902 20 180964.7461489882 30 0.0 11 524829.8059644724 21 180925.2651927524 31 0.0 0 LINE 5 1C76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524783.6066146152 20 180969.2873539066 30 0.0 11 524831.7040670197 21 180925.1576278679 31 0.0 0 LINE 5 1C77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524794.7704363647 20 181017.5671077454 30 0.0 11 524716.0105759171 21 180949.1578436337 31 0.0 0 LINE 5 1C78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524632.9369456995 20 181075.2988483744 30 0.0 11 524801.9989999381 21 180829.1753973185 31 0.0 0 LINE 5 1C79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524900.0096459172 20 180818.993452846 30 0.0 11 524854.9146575729 21 180766.9741700884 31 0.0 0 LINE 5 1C7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524831.5059540864 20 180788.5607520285 30 0.0 11 524876.8033334446 21 180749.0548109575 31 0.0 0 LINE 5 1C7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524839.9663818906 20 180790.1373054382 30 0.0 11 524792.4847093471 21 180736.9022916819 31 0.0 0 LINE 5 1C7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524791.9913793488 20 180740.5868489466 30 0.0 11 524833.3593439895 21 180702.6358108023 31 0.0 0 LINE 5 1C7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524877.9038921384 20 180758.0230111801 30 0.0 11 524826.9640158099 21 180699.6173881792 31 0.0 0 LINE 5 1C7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524391.0079010363 20 181025.6511740913 30 0.0 11 524461.7269989744 21 180937.8822745294 31 0.0 0 LINE 5 1C7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525008.009930925 20 181086.4024399666 30 0.0 11 525225.8263071603 21 180936.1700333339 31 0.0 0 LINE 5 1C80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525597.873440998 20 181037.2752526085 30 0.0 11 526110.5041094252 21 180741.7467624144 31 0.0 0 LINE 5 1C81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525570.8176342342 20 181166.5921935663 30 0.0 11 525451.2708726696 21 180952.4554538928 31 0.0 0 LINE 5 1C82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524652.5268457475 20 181472.4103574203 30 0.0 11 525810.6022995788 21 180839.9092790389 31 0.0 0 LINE 5 1C83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525463.7813842892 20 180982.6093482953 30 0.0 11 525453.8781974885 21 180901.2273776519 31 0.0 0 LINE 5 1C84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525384.0938600372 20 180984.8927870034 30 0.0 11 525471.1474444611 21 180973.0986393367 31 0.0 0 LINE 5 1C85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525400.9027190662 20 180989.7782740392 30 0.0 11 525262.5991419836 21 180846.8574100953 31 0.0 0 LINE 5 1C86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525247.8458925852 20 181125.7758109726 30 0.0 11 525560.0116688346 21 180712.3082364724 31 0.0 0 LINE 5 1C87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525298.922874909 20 180804.6317777938 30 0.0 11 525456.5092087385 21 180904.6637034498 31 0.0 0 LINE 5 1C88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525263.4172516872 20 180853.7537133059 30 0.0 11 525299.7604937888 21 180804.5014094529 31 0.0 0 LINE 5 1C89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525046.5995916819 20 180650.180002968 30 0.0 11 525288.8864195746 21 180822.3516010374 31 0.0 0 LINE 5 1C8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525100.1734692398 20 180692.7418071628 30 0.0 11 525171.8452476225 21 180605.214911296 31 0.0 0 LINE 5 1C8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525105.1278778982 20 180558.4645352336 30 0.0 11 525713.1359778347 21 181007.015257858 31 0.0 0 LINE 5 1C8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525571.9067344027 20 180817.7406881978 30 0.0 11 525901.4570689142 21 180527.4299157075 31 0.0 0 LINE 5 1C8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525625.2797377445 20 180862.2485475206 30 0.0 11 525481.0033527453 21 180732.6574874768 31 0.0 0 LINE 5 1C8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525672.9801281504 20 180807.5030366347 30 0.0 11 525624.7842768374 21 180764.9259815658 31 0.0 0 LINE 5 1C8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525655.7810001165 20 180859.0923283836 30 0.0 11 525670.4020766922 21 180791.8355098239 31 0.0 0 LINE 5 1C90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525658.8481325714 20 180808.7047167351 30 0.0 11 525977.3180809332 21 180561.3709549034 31 0.0 0 LINE 5 1C91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525846.1559071286 20 180896.8836984073 30 0.0 11 525618.2732661557 21 180559.2726852762 31 0.0 0 LINE 5 1C92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525609.3636271522 20 180569.167902708 30 0.0 11 525799.0786610461 21 180424.1024774419 31 0.0 0 LINE 5 1C93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525434.5503005449 20 180493.3648578872 30 0.0 11 525627.4698235871 21 180568.7899169216 31 0.0 0 LINE 5 1C94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525444.2327572913 20 180580.0149269779 30 0.0 11 525493.4427067547 21 180510.2316866175 31 0.0 0 LINE 5 1C95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525961.6524090845 20 180835.2787713809 30 0.0 11 525907.3690808953 21 180763.3384399991 31 0.0 0 LINE 5 1C96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526089.1824986345 20 180793.7252705167 30 0.0 11 525796.0193364219 21 180423.5854187961 31 0.0 0 LINE 5 1C97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525530.6096630857 20 180745.8380174036 30 0.0 11 525854.2915781323 21 180471.8576454403 31 0.0 0 LINE 5 1C98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525389.9409016577 20 180200.0512254642 30 0.0 11 525856.9751624424 21 180478.295941082 31 0.0 0 LINE 5 1C99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525377.2907592685 20 180295.2857780945 30 0.0 11 525478.6515993782 21 180235.9940601101 31 0.0 0 LINE 5 1C9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525430.3557548465 20 180327.521098482 30 0.0 11 525449.4925994674 21 180219.3574166934 31 0.0 0 LINE 5 1C9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525585.8146731471 20 180436.772201818 30 0.0 11 525431.626921985 21 180306.260253121 31 0.0 0 LINE 5 1C9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525373.3902129744 20 180568.0525292673 30 0.0 11 525604.2882998661 21 180325.2027695491 31 0.0 0 LINE 5 1C9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525437.6852535538 20 180636.0433505364 30 0.0 11 525359.7271228865 21 180542.9305405187 31 0.0 0 LINE 5 1C9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525295.8949768945 20 180622.6140249824 30 0.0 11 525405.282512096 21 180673.8204514221 31 0.0 0 LINE 5 1C9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525398.5703166641 20 180673.2538395604 30 0.0 11 525438.2152087374 21 180633.9358611555 31 0.0 0 LINE 5 1CA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525130.5614349412 20 180879.2458920159 30 0.0 11 525485.7019481972 21 180442.9056757742 31 0.0 0 LINE 5 1CA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525498.678701995 20 180441.282830755 30 0.0 11 525479.7250578333 21 180426.1001450563 31 0.0 0 LINE 5 1CA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525687.8825223587 20 180422.4358408612 30 0.0 11 525712.7249873302 21 180384.528201692 31 0.0 0 LINE 5 1CA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525687.79902507 20 180437.9702772509 30 0.0 11 525689.8362126233 21 180413.9911967952 31 0.0 0 LINE 5 1CA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525734.5133923259 20 180481.8592027276 30 0.0 11 525683.5957432436 21 180431.1713798979 31 0.0 0 LINE 5 1CA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525479.962317523 20 180515.6984381563 30 0.0 11 525223.7445992931 21 180269.921447433 31 0.0 0 LINE 5 1CA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525114.4984688314 20 180575.9437046102 30 0.0 11 525148.0515304179 21 180374.6954986379 31 0.0 0 LINE 5 1CA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525117.2592444702 20 180379.0745464745 30 0.0 11 525437.7671699316 21 180506.769297582 31 0.0 0 LINE 5 1CA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525356.4457310868 20 180606.2917409695 30 0.0 11 525329.0914276513 21 180583.626000004 31 0.0 0 LINE 5 1CA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525338.7143704697 20 180397.6906123634 30 0.0 11 525391.6579758414 21 180320.8217965096 31 0.0 0 LINE 5 1CAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525368.4486104316 20 180347.2199300862 30 0.0 11 525445.7945459263 21 180316.0720809731 31 0.0 0 LINE 5 1CAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525377.1091984003 20 180357.0822435868 30 0.0 11 525388.9044896276 21 180277.8041336032 31 0.0 0 LINE 5 1CAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525290.4199535019 20 180218.7723081885 30 0.0 11 525395.1753802871 21 180288.7605865493 31 0.0 0 LINE 5 1CAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525014.2560689964 20 180746.2368038634 30 0.0 11 525138.5689501177 21 180507.0811555747 31 0.0 0 LINE 5 1CAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525622.5061380987 20 180674.6436547186 30 0.0 11 525596.9843036692 21 180635.1626984828 31 0.0 0 LINE 5 1CAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525550.7849538118 20 180679.1848596368 30 0.0 11 525598.8824062162 21 180635.0551335983 31 0.0 0 LINE 5 1CB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525561.9487755611 20 180727.4646134757 30 0.0 11 525483.1889151137 21 180659.0553493637 31 0.0 0 LINE 5 1CB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525400.1152848961 20 180785.1963541049 30 0.0 11 525569.1773391347 21 180539.072903049 31 0.0 0 LINE 5 1CB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525667.1879851137 20 180528.8909585764 30 0.0 11 525622.0929967695 21 180476.8716758188 31 0.0 0 LINE 5 1CB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525598.6842932832 20 180498.4582577588 30 0.0 11 525643.9816726412 21 180458.9523166879 31 0.0 0 LINE 5 1CB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525607.1447210872 20 180500.0348111686 30 0.0 11 525559.6630485436 21 180446.7997974125 31 0.0 0 LINE 5 1CB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525559.1697185455 20 180450.484354677 30 0.0 11 525600.537683186 21 180412.5333165327 31 0.0 0 LINE 5 1CB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525645.082231335 20 180467.9205169104 30 0.0 11 525594.1423550066 21 180409.5148939096 31 0.0 0 LINE 5 1CB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525158.1862402328 20 180735.5486798217 30 0.0 11 525228.9053381709 21 180647.7797802598 31 0.0 0 LINE 5 1CB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525775.1882701215 20 180796.2999456968 30 0.0 11 525993.0046463569 21 180646.0675390643 31 0.0 0 LINE 5 1CB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525418.1832166672 20 180231.9287973527 30 0.0 11 525223.1231718565 21 179691.1013030836 31 0.0 0 LINE 5 1CBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525223.754888888 20 180352.4700418386 30 0.0 11 525106.2860575173 21 180229.8569459029 31 0.0 0 LINE 5 1CBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524881.8800376533 20 180654.3909091102 30 0.0 11 525421.6381162864 21 180125.682277721 31 0.0 0 LINE 5 1CBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525212.2662827289 20 180234.9251137939 30 0.0 11 524986.8238694697 21 179857.9887050464 31 0.0 0 LINE 5 1CBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525264.71496686 20 180189.3316651403 30 0.0 11 525113.7772041884 21 180311.099107059 31 0.0 0 LINE 5 1CBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525218.275614624 20 180133.512450071 30 0.0 11 525168.5585218523 21 180174.3028458577 31 0.0 0 LINE 5 1CBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525266.4625094876 20 180158.7173740281 30 0.0 11 525202.3974678277 21 180133.5593542309 31 0.0 0 LINE 5 1CC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525217.2085946082 20 180147.655250444 30 0.0 11 525023.8187307353 21 179793.8227218339 31 0.0 0 LINE 5 1CC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525334.1253874497 20 179976.8038566251 30 0.0 11 524964.4981331313 21 180147.9394376977 31 0.0 0 LINE 5 1CC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524972.8461245731 20 180158.3128669318 30 0.0 11 524859.8864172327 21 179947.8945307285 31 0.0 0 LINE 5 1CC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524870.1391553542 20 180318.8029888629 30 0.0 11 524975.3599812941 21 180140.3780475297 31 0.0 0 LINE 5 1CC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524957.2244979571 20 180323.0606344381 30 0.0 11 524896.180502328 21 180263.353429186 31 0.0 0 LINE 5 1CC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525270.1249543759 20 179800.8353309385 30 0.0 11 525190.4496126549 21 179842.9533902513 31 0.0 0 LINE 5 1CC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525134.6987595177 20 180264.2290642028 30 0.0 11 524915.8342363212 21 179901.0024863818 31 0.0 0 LINE 5 1CC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524610.868708002 20 180268.9667676791 30 0.0 11 524899.8257795197 21 179931.447802198 31 0.0 0 LINE 5 1CC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524458.7969630624 20 180421.892763538 30 0.0 11 524798.9324632437 21 180053.0762331568 31 0.0 0 LINE 5 1CC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524665.464301145 20 180343.7465446084 30 0.0 11 524623.0929854331 21 180234.228512604 31 0.0 0 LINE 5 1CCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524705.7483468587 20 180296.5003246841 30 0.0 11 524602.0198271621 21 180260.3617707335 31 0.0 0 LINE 5 1CCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524838.3894159758 20 180160.4502396316 30 0.0 11 524684.9621933807 21 180291.8554097274 31 0.0 0 LINE 5 1CCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524912.8934556925 20 180364.2409513169 30 0.0 11 524731.1929690219 21 180124.4233765795 31 0.0 0 LINE 5 1CCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524885.0114208989 20 180451.0797803243 30 0.0 11 524958.7659591307 21 180354.6031841114 31 0.0 0 LINE 5 1CCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525026.0671377887 20 180431.3791693508 30 0.0 11 524919.0566906104 21 180487.3835902562 31 0.0 0 LINE 5 1CCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524925.7371762494 20 180486.5200347311 30 0.0 11 524884.3885775652 21 180448.9978508899 31 0.0 0 LINE 5 1CD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525202.6127386466 20 180680.4308629602 30 0.0 11 525202.6044691076 21 180680.4215757932 31 0.0 0 LINE 5 1CD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525105.2808209763 20 180571.121535247 30 0.0 11 524828.4815915741 21 180260.2601199806 31 0.0 0 LINE 5 1CD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524828.9486333343 20 180247.1906273707 30 0.0 11 524810.9380603054 21 180263.4809260549 31 0.0 0 LINE 5 1CD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524840.5110408532 20 180057.4023100257 30 0.0 11 524807.0494777431 21 180026.8333557182 31 0.0 0 LINE 5 1CD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524855.8334198841 20 180059.9616823253 30 0.0 11 524832.4859485963 21 180054.1271286077 31 0.0 0 LINE 5 1CD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524906.6093788347 20 180020.8429926709 30 0.0 11 524848.451298822 21 180063.0271140968 31 0.0 0 LINE 5 1CD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524899.427885137 20 180277.5330191347 30 0.0 11 524625.9545763003 21 180497.9917991143 31 0.0 0 LINE 5 1CD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524709.6465865055 20 180552.8312479539 30 0.0 11 524883.8850270141 21 180317.7645937127 31 0.0 0 LINE 5 1CD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524969.1676192615 20 180413.9143342909 30 0.0 11 524942.4302544877 21 180437.3046539747 31 0.0 0 LINE 5 1CD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524760.4080436268 20 180398.1576980424 30 0.0 11 524692.9644496469 21 180333.6348196841 31 0.0 0 LINE 5 1CDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524715.3241523529 20 180360.7563940109 30 0.0 11 524696.9074980718 21 180279.4335246133 31 0.0 0 LINE 5 1CDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524726.4412079268 20 180353.7791390408 30 0.0 11 524650.0581049922 21 180329.4939747678 31 0.0 0 LINE 5 1CDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524537.4723958892 20 180453.0920036419 30 0.0 11 524661.8742680996 21 180325.0503028359 31 0.0 0 LINE 5 1CDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525079.0679994453 20 180162.1564531274 30 0.0 11 525036.0227337291 21 180181.0565863907 31 0.0 0 LINE 5 1CDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525072.1152669157 20 180233.6841423673 30 0.0 11 525036.2191946904 21 180179.1656166461 31 0.0 0 LINE 5 1CDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525121.5573963299 20 180230.3612842898 30 0.0 11 525041.4651988386 21 180297.2057525356 31 0.0 0 LINE 5 1CE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525152.7464166145 20 180399.3295582072 30 0.0 11 524936.7285080018 21 180193.1864174004 31 0.0 0 LINE 5 1CE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524942.3044836137 20 180094.8061998036 30 0.0 11 524883.7603928235 21 180131.029854864 31 0.0 0 LINE 5 1CE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524901.33831756 20 180157.581022084 30 0.0 11 524869.560407142 21 180106.5640017272 31 0.0 0 LINE 5 1CE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524904.243703815 20 180149.4802140999 30 0.0 11 524844.1188824767 21 180187.8661721603 31 0.0 0 LINE 5 1CE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524847.6776396538 20 180188.9406879022 30 0.0 11 524816.8081996556 21 180142.0507372842 31 0.0 0 LINE 5 1CE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524878.5893528519 20 180106.9074897788 30 0.0 11 524812.8086682417 21 180147.8829620847 31 0.0 0 LINE 5 1CE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525223.5127926947 20 180030.8256179181 30 0.0 11 525109.9329272069 21 179791.8415935258 31 0.0 0 LINE 5 1CE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524672.8650839235 20 181333.8745039805 30 0.0 11 524859.5012256396 21 182053.1810553086 31 0.0 0 LINE 5 1CE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524716.8211785645 20 181530.7940420282 30 0.0 11 525208.540654474 21 181263.8590629573 31 0.0 0 LINE 5 1CE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524835.4109704701 20 181460.5088428871 30 0.0 11 524886.2527054516 21 181599.335399024 31 0.0 0 LINE 5 1CEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524737.2758838151 20 181592.6887182873 30 0.0 11 525600.752012998 21 181111.7085048984 31 0.0 0 LINE 5 1CEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524866.8151658661 20 181573.106554149 30 0.0 11 524931.5378577799 21 181623.4262461793 31 0.0 0 LINE 5 1CEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524823.9027735845 20 181640.2916879391 30 0.0 11 524878.7593920745 21 181571.6755099045 31 0.0 0 LINE 5 1CED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524827.7064194305 20 181621.6569840489 30 0.0 11 524879.2308113621 21 181813.7493832228 31 0.0 0 LINE 5 1CEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524717.6514214086 20 181675.682364936 30 0.0 11 525148.1439612566 21 181629.4720364983 31 0.0 0 LINE 5 1CEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524934.7650866334 20 181805.9952657354 30 0.0 11 524929.9422093081 21 181619.4032546132 31 0.0 0 LINE 5 1CF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524874.3793247449 20 181811.2080950981 30 0.0 11 524935.3073960814 21 181805.343727744 31 0.0 0 LINE 5 1CF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524937.5832628485 20 182101.8236752705 30 0.0 11 524914.4064158528 21 181805.4981787039 31 0.0 0 LINE 5 1CF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524928.6053765027 20 182033.9925239486 30 0.0 11 525040.5229816188 21 182017.4924942015 31 0.0 0 LINE 5 1CF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525046.3391693385 20 182098.7511986293 30 0.0 11 524968.8315460129 21 181292.6000975962 31 0.0 0 LINE 5 1CF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525063.8136333624 20 181565.0834485425 30 0.0 11 525482.2168983525 21 181431.582604177 31 0.0 0 LINE 5 1CF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525053.0631203627 20 181496.4244833779 30 0.0 11 525090.0831673517 21 181686.7900113307 31 0.0 0 LINE 5 1CF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525124.5401973068 20 181483.640678055 30 0.0 11 525136.2950800057 21 181546.8662143109 31 0.0 0 LINE 5 1CF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525071.4460584255 20 181471.8815350281 30 0.0 11 525136.6554013828 21 181493.9041850524 31 0.0 0 LINE 5 1CF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525116.2465394077 20 181495.1460060711 30 0.0 11 525492.088159179 21 181349.0632398076 31 0.0 0 LINE 5 1CF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525136.866173508 20 181289.1494869064 30 0.0 11 525309.3652517367 21 181658.142389622 31 0.0 0 LINE 5 1CFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525296.2978940966 20 181660.6999586831 30 0.0 11 525518.2396293072 21 181572.5090415504 31 0.0 0 LINE 5 1CFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525271.4829984441 20 181849.6179877786 30 0.0 11 525305.9274088119 21 181645.3621078251 31 0.0 0 LINE 5 1CFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525202.1277142461 20 181796.7802266995 30 0.0 11 525287.2804677732 21 181790.4297678073 31 0.0 0 LINE 5 1CFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525371.3681014678 20 181183.7777599395 30 0.0 11 525517.1109097619 21 181575.3991642102 31 0.0 0 LINE 5 1CFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525104.2704918624 20 181637.4622076297 30 0.0 11 525505.6490466426 21 181500.602856059 31 0.0 0 LINE 5 1CFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525501.9037164204 20 181978.5020695708 30 0.0 11 525501.5052255752 21 181494.9919717723 31 0.0 0 LINE 5 1D00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525521.4196865071 20 182231.0925601788 30 0.0 11 525497.1132152171 21 181692.2264156459 31 0.0 0 LINE 5 1D01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525411.9747038597 20 182000.5353745444 30 0.0 11 525514.9292324447 21 181944.0562388116 31 0.0 0 LINE 5 1D02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525411.5936965098 20 181938.4478196756 30 0.0 11 525514.2151067717 21 181977.6198382092 31 0.0 0 LINE 5 1D03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525397.7689600213 20 181748.9427919842 30 0.0 11 525430.4852564121 21 181948.2838948999 31 0.0 0 LINE 5 1D04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525175.9815577455 20 181863.6991593308 30 0.0 11 525502.9710926166 21 181790.4340488745 31 0.0 0 LINE 5 1D05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524784.2330615084 20 181912.0751880627 30 0.0 11 525341.0568122784 21 181831.6707165202 31 0.0 0 LINE 5 1D06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525349.1180495949 20 181821.3728420787 30 0.0 11 525352.4014790639 21 181845.4347136385 31 0.0 0 LINE 5 1D07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525462.5226132335 20 181668.7533819362 30 0.0 11 525507.8082858266 21 181666.9244393336 31 0.0 0 LINE 5 1D08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525449.1537364944 20 181660.8414402994 30 0.0 11 525470.770769125 21 181671.4173720726 31 0.0 0 LINE 5 1D09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525435.5121121047 20 181598.2125653963 30 0.0 11 525452.8258801166 21 181667.9412955474 31 0.0 0 LINE 5 1D0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525275.6629654501 20 181799.1841898901 30 0.0 11 525364.6241005938 21 182224.3232275521 31 0.0 0 LINE 5 1D0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525036.1607473376 20 182081.7297691328 30 0.0 11 525376.5846581334 21 182207.013949368 31 0.0 0 LINE 5 1D0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525239.7094067614 20 182235.172089817 30 0.0 11 525261.6374529488 21 181839.9695430297 31 0.0 0 LINE 5 1D0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525304.3029185713 20 181980.9988828615 30 0.0 11 525397.4527456271 21 181975.0870371206 31 0.0 0 LINE 5 1D0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525362.8796105945 20 181981.4300989267 30 0.0 11 525429.3494648776 21 181931.0878630456 31 0.0 0 LINE 5 1D0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525358.8702955248 20 181968.9322429417 30 0.0 11 525432.939661286 21 181999.5570151602 31 0.0 0 LINE 5 1D10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525447.6529162399 20 182281.8852571326 30 0.0 11 525426.7636260753 21 181988.54681444 31 0.0 0 LINE 5 1D11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524853.8675979557 20 182211.3322892552 30 0.0 11 524856.4895709922 21 182034.7267694308 31 0.0 0 LINE 5 1D12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524844.2820292215 20 182097.1365796394 30 0.0 11 525107.6038457547 21 182096.4716284987 31 0.0 0 LINE 5 1D13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525212.5715177859 20 181595.2190166764 30 0.0 11 525233.3232547421 21 181637.4028447537 31 0.0 0 LINE 5 1D14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525171.8164555471 20 181654.4100271384 30 0.0 11 525234.3910139501 21 181635.8298686707 31 0.0 0 LINE 5 1D15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525136.1378398911 20 181620.021047339 30 0.0 11 525154.3447919175 21 181722.7412981756 31 0.0 0 LINE 5 1D16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525003.4429764331 20 181729.1773837962 30 0.0 11 525301.4615792174 21 181710.639753487 31 0.0 0 LINE 5 1D17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525360.566326539 20 181631.7956822925 30 0.0 11 525382.0146893034 21 181697.2138104154 31 0.0 0 LINE 5 1D18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525351.4666208391 20 181706.2006581319 30 0.0 11 525408.6357065016 21 181687.6462085011 31 0.0 0 LINE 5 1D19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525354.4622434232 20 181698.1327832805 30 0.0 11 525375.7269195981 21 181766.2230870276 31 0.0 0 LINE 5 1D1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525372.3126460178 20 181764.7526882235 30 0.0 11 525426.1284504718 21 181748.7699166965 31 0.0 0 LINE 5 1D1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525401.5080878492 20 181682.0931105359 30 0.0 11 525425.4310228318 21 181755.807294926 31 0.0 0 LINE 5 1D1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525550.4821613834 20 181139.8508269699 30 0.0 11 525791.2774661715 21 181120.4520406538 31 0.0 0 LINE 5 1D1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525580.7167677637 20 181592.8036794261 30 0.0 11 525540.1266019988 21 181073.841759013 31 0.0 0 LINE 5 1D1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525689.4726742537 20 181589.7312027846 30 0.0 11 525617.1625483183 21 180837.6388906033 31 0.0 0 LINE 5 1D1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525706.9471382775 20 181056.0634526979 30 0.0 11 526125.3504032675 21 180922.5626083323 31 0.0 0 LINE 5 1D20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525696.1966252777 20 180987.4044875335 30 0.0 11 525733.2166722667 21 181177.7700154862 31 0.0 0 LINE 5 1D21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525767.673702222 20 180974.6206822104 30 0.0 11 525779.4285849208 21 181037.8462184663 31 0.0 0 LINE 5 1D22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525714.5795633408 20 180962.8615391838 30 0.0 11 525779.7889062979 21 180984.8841892078 31 0.0 0 LINE 5 1D23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525759.3800443228 20 180986.1260102264 30 0.0 11 526135.2216640942 21 180840.0432439632 31 0.0 0 LINE 5 1D24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525826.4972455265 20 180879.8564422131 30 0.0 11 525952.4987566518 21 181149.1223937773 31 0.0 0 LINE 5 1D25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525939.4313990119 20 181151.6799628386 30 0.0 11 526161.3731342222 21 181063.4890457058 31 0.0 0 LINE 5 1D26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525914.6165033592 20 181340.597991934 30 0.0 11 525949.060913727 21 181136.3421119805 31 0.0 0 LINE 5 1D27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525845.2612191611 20 181287.7602308549 30 0.0 11 525930.4139726882 21 181281.4097719626 31 0.0 0 LINE 5 1D28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526039.6595348584 20 180749.1254239648 30 0.0 11 526160.244414677 21 181066.3791683655 31 0.0 0 LINE 5 1D29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525747.4039967776 20 181128.442211785 30 0.0 11 526148.7825515574 21 180991.5828602147 31 0.0 0 LINE 5 1D2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526143.3048822115 20 181529.6072795687 30 0.0 11 526144.6387304903 21 180985.9719759277 31 0.0 0 LINE 5 1D2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526055.1082087747 20 181491.5153786999 30 0.0 11 526158.0627373598 21 181435.0362429673 31 0.0 0 LINE 5 1D2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526054.727201425 20 181429.4278238311 30 0.0 11 526157.3486116869 21 181468.5998423646 31 0.0 0 LINE 5 1D2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526040.9024649364 20 181239.9227961396 30 0.0 11 526073.6187613272 21 181439.2638990554 31 0.0 0 LINE 5 1D2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525819.1150626604 20 181354.6791634863 30 0.0 11 526146.1045975316 21 181281.41405303 31 0.0 0 LINE 5 1D2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525793.8332015857 20 181264.5823737513 30 0.0 11 525833.643721944 21 181379.3106963023 31 0.0 0 LINE 5 1D30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525741.8105573311 20 181279.0130101218 30 0.0 11 525795.9134356442 21 181265.2108562477 31 0.0 0 LINE 5 1D31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525427.3665664235 20 181403.0551922181 30 0.0 11 525984.1903171935 21 181322.6507206756 31 0.0 0 LINE 5 1D32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525992.25155451 20 181312.3528462341 30 0.0 11 525995.5349839787 21 181336.4147177941 31 0.0 0 LINE 5 1D33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526105.6561181488 20 181159.7333860918 30 0.0 11 526150.9417907415 21 181157.904443489 31 0.0 0 LINE 5 1D34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526092.2872414094 20 181151.8214444548 30 0.0 11 526113.90427404 21 181162.397376228 31 0.0 0 LINE 5 1D35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526078.6456170197 20 181089.1925695517 30 0.0 11 526095.9593850317 21 181158.9212997027 31 0.0 0 LINE 5 1D36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525918.7964703651 20 181290.1641940455 30 0.0 11 525997.955051366 21 181636.2678885616 31 0.0 0 LINE 5 1D37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525679.2942522527 20 181572.7097732883 30 0.0 11 525869.1756024465 21 181647.3537361884 31 0.0 0 LINE 5 1D38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525849.5941156315 20 181671.517889556 30 0.0 11 525904.7709578639 21 181330.9495471852 31 0.0 0 LINE 5 1D39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525777.6039437721 20 181349.5625448107 30 0.0 11 525782.9892644946 21 181384.6765313503 31 0.0 0 LINE 5 1D3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525947.4364234862 20 181471.9788870168 30 0.0 11 526040.5862505421 21 181466.0670412759 31 0.0 0 LINE 5 1D3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526006.0131155095 20 181472.4101030822 30 0.0 11 526072.4829697926 21 181422.0678672007 31 0.0 0 LINE 5 1D3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526002.0038004398 20 181459.9122470971 30 0.0 11 526076.073166201 21 181490.5370193159 31 0.0 0 LINE 5 1D3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526076.09878786 20 181605.3584441946 30 0.0 11 526069.8971309905 21 181479.5268185956 31 0.0 0 LINE 5 1D3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525481.6937793638 20 181571.182850897 30 0.0 11 525750.7373506701 21 181587.451632654 31 0.0 0 LINE 5 1D3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525855.7050227011 20 181086.1990208319 30 0.0 11 525876.4567596575 21 181128.3828489091 31 0.0 0 LINE 5 1D40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525814.9499604622 20 181145.390031294 30 0.0 11 525877.5245188651 21 181126.8098728261 31 0.0 0 LINE 5 1D41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525779.2713448061 20 181111.0010514946 30 0.0 11 525797.4782968325 21 181213.721302331 31 0.0 0 LINE 5 1D42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525646.5764813483 20 181220.1573879517 30 0.0 11 525944.5950841326 21 181201.6197576427 31 0.0 0 LINE 5 1D43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526003.6998314539 20 181122.7756864479 30 0.0 11 526025.1481942186 21 181188.1938145709 31 0.0 0 LINE 5 1D44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525994.6001257541 20 181197.1806622872 30 0.0 11 526051.769211417 21 181178.6262126565 31 0.0 0 LINE 5 1D45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525997.5957483383 20 181189.112787436 30 0.0 11 526018.8604245131 21 181257.2030911829 31 0.0 0 LINE 5 1D46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526015.4461509327 20 181255.7326923791 30 0.0 11 526069.261955387 21 181239.7499208522 31 0.0 0 LINE 5 1D47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526044.6415927642 20 181173.0731146914 30 0.0 11 526068.5645277468 21 181246.7872990814 31 0.0 0 LINE 5 1D48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525564.8320348503 20 181453.2075964477 30 0.0 11 525676.4676305909 21 181437.6491804908 31 0.0 0 LINE 5 1D49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526130.473714444 20 181488.9973167478 30 0.0 11 526494.1671899047 21 181934.2723503464 31 0.0 0 LINE 5 1D4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526109.8328697965 20 181554.5942094994 30 0.0 11 526251.9934859582 21 181731.9634965217 31 0.0 0 LINE 5 1D4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525927.1473617616 20 181593.8350989162 30 0.0 11 525971.9586043235 21 181757.6180350803 31 0.0 0 LINE 5 1D4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525492.4506609762 20 181731.9415880005 30 0.0 11 526223.3911410159 21 181540.6365567163 31 0.0 0 LINE 5 1D4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526022.0770722465 20 181664.0999425277 30 0.0 11 526215.550577524 21 182147.2371812123 31 0.0 0 LINE 5 1D4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526088.1434775098 20 181642.5393970146 30 0.0 11 525906.1162328381 21 181709.4393245857 31 0.0 0 LINE 5 1D4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526112.1606457125 20 181711.0636543148 30 0.0 11 526051.6183006626 21 181732.749367538 31 0.0 0 LINE 5 1D50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526115.3035619875 20 181656.7738108306 30 0.0 11 526103.9601991942 21 181724.6603606289 31 0.0 0 LINE 5 1D51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526099.4801024202 20 181704.710611271 30 0.0 11 526304.7553206837 21 181949.7835141037 31 0.0 0 LINE 5 1D52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525857.313670571 20 181761.9825238141 30 0.0 11 526087.2040436257 21 182113.8961217255 31 0.0 0 LINE 5 1D53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525668.4671300806 20 181833.7424880624 30 0.0 11 525789.1324778181 21 181820.0552903225 31 0.0 0 LINE 5 1D54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525757.8593417412 20 181722.8647994392 30 0.0 11 525654.8212814394 21 181785.8797904769 31 0.0 0 LINE 5 1D55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525658.9953514573 20 181780.5928484492 30 0.0 11 525669.9329835094 21 181835.3467441867 31 0.0 0 LINE 5 1D56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525634.9459465169 20 181443.4235846078 30 0.0 11 525634.9496634225 21 181443.4354514254 31 0.0 0 LINE 5 1D57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525678.693672931 20 181583.0952272422 30 0.0 11 525919.2417741847 21 182168.4730579651 31 0.0 0 LINE 5 1D58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525976.3153867182 20 181897.5490736705 30 0.0 11 525495.0880701026 21 182031.8608562202 31 0.0 0 LINE 5 1D59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525491.0565304261 20 181931.8835367471 30 0.0 11 525809.6864879597 21 181871.5776837387 31 0.0 0 LINE 5 1D5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525743.5990615419 20 181780.6507845993 30 0.0 11 525709.7929964333 21 181791.5660808326 31 0.0 0 LINE 5 1D5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526157.4518696392 20 181859.1409376143 30 0.0 11 525977.7109751933 21 181842.9721210265 31 0.0 0 LINE 5 1D5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525951.114209062 20 181784.9639954642 30 0.0 11 525979.4340796496 21 181843.775410835 31 0.0 0 LINE 5 1D5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525850.4565019642 20 181630.6661921994 30 0.0 11 525902.2043944721 21 181859.6510289999 31 0.0 0 LINE 5 1D5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525093.3682658213 20 181879.2959285518 30 0.0 11 525080.1517503274 21 181713.4750750022 31 0.0 0 LINE 5 1D5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525075.2920115007 20 181977.1120209499 30 0.0 11 524897.6469292312 21 181927.1785198064 31 0.0 0 LINE 5 1D60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525559.1342218785 20 181754.3305998252 30 0.0 11 525635.1712887211 21 181559.4054345479 31 0.0 0 LINE 5 1D61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525968.0301132713 20 181790.5144936306 30 0.0 11 525860.2933285217 21 181836.5902880851 31 0.0 0 LINE 5 1D62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525138.5976201284 20 181292.8532256214 30 0.0 11 525174.8263971197 21 181098.0413473536 31 0.0 0 LINE 5 1D63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527943.7217281111 20 183084.8932846896 30 0.0 11 526886.0691300294 21 180903.8038450779 31 0.0 0 LINE 5 1D64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527579.4189956524 20 183075.1156235687 30 0.0 11 527883.4646186981 21 182875.7659136232 31 0.0 0 LINE 5 1D65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527616.3711753756 20 182837.7830018993 30 0.0 11 527887.6384030865 21 182669.8299575536 31 0.0 0 LINE 5 1D66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527511.1304576061 20 182404.0055193513 30 0.0 11 527703.9479938831 21 182285.0018235103 31 0.0 0 LINE 5 1D67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527759.9654076744 20 182990.4690615484 30 0.0 11 527606.7760979401 21 182800.9552573995 31 0.0 0 LINE 5 1D68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527938.6573479137 20 182899.213051281 30 0.0 11 527799.4197403971 21 182644.7157533081 31 0.0 0 LINE 5 1D69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526976.0672279639 20 181073.1283888675 30 0.0 11 525228.9175514841 21 178041.3051799581 31 0.0 0 LINE 5 1D6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526349.4510224499 20 181723.5957364893 30 0.0 11 526137.0436574432 21 181866.8871380226 31 0.0 0 LINE 5 1D6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527011.5634163477 20 181549.3135720685 30 0.0 11 526853.7736129552 21 181139.4524424818 31 0.0 0 LINE 5 1D6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527223.0841845988 20 181435.1536054864 30 0.0 11 526900.2058964616 21 181605.0098790062 31 0.0 0 LINE 5 1D6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527037.0652009413 20 181450.9758915195 30 0.0 11 526980.4001620355 21 181481.3850853253 31 0.0 0 LINE 5 1D6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527181.0254201383 20 181319.6206159791 30 0.0 11 526785.2862686458 21 181416.0686238382 31 0.0 0 LINE 5 1D6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526791.4713041271 20 181427.8602450707 30 0.0 11 526721.3222355628 21 181199.5734082347 31 0.0 0 LINE 5 1D70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526659.6748687927 20 181565.4665690411 30 0.0 11 526797.4050230715 21 181410.7497745311 31 0.0 0 LINE 5 1D71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526744.2941710323 20 181586.4798536614 30 0.0 11 526695.9448348761 21 181516.0976012488 31 0.0 0 LINE 5 1D72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527175.4863038696 20 181208.5202604197 30 0.0 11 527089.1715245067 21 181234.440327206 31 0.0 0 LINE 5 1D73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527168.689694969 20 181055.8945927876 30 0.0 11 526719.774874828 21 181202.2627374366 31 0.0 0 LINE 5 1D74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526929.7940054563 20 181563.0687750525 30 0.0 11 526785.2800684787 21 181164.3822460992 31 0.0 0 LINE 5 1D75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526414.9304229288 20 181466.4465204097 30 0.0 11 526792.2496135724 21 181164.1016811281 31 0.0 0 LINE 5 1D76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526205.7293076139 20 181609.3371162689 30 0.0 11 526641.1837374633 21 181290.9867341505 31 0.0 0 LINE 5 1D77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526454.0390723845 20 181550.3703392336 30 0.0 11 526433.6399297231 21 181434.7269100732 31 0.0 0 LINE 5 1D78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526502.6971109922 20 181511.8034503905 30 0.0 11 526407.9120616558 21 181456.2931333099 31 0.0 0 LINE 5 1D79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526659.1379968794 20 181403.9631606926 30 0.0 11 526483.2010900999 21 181503.2276366846 31 0.0 0 LINE 5 1D7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526792.3949678253 20 181815.5482342014 30 0.0 11 526560.9288521117 21 181347.8919828472 31 0.0 0 LINE 5 1D7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526633.1060476017 20 181487.2419746779 30 0.0 11 526612.2858985422 21 181499.7430132419 31 0.0 0 LINE 5 1D7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526681.1415599006 20 181303.2694652466 30 0.0 11 526654.2210802562 21 181266.8081851133 31 0.0 0 LINE 5 1D7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526695.680076064 20 181308.7427854004 30 0.0 11 526673.901047781 21 181298.5046039371 31 0.0 0 LINE 5 1D7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526753.0608187414 20 181280.1784674954 30 0.0 11 526687.8445923023 21 181310.3232212721 31 0.0 0 LINE 5 1D7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526696.3896537784 20 181530.6374912887 30 0.0 11 526309.1554281505 21 181727.3782837355 31 0.0 0 LINE 5 1D80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526340.3883101176 20 181733.1381633065 30 0.0 11 526282.3497671501 21 181540.4056030153 31 0.0 0 LINE 5 1D81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526378.8858323255 20 181831.5850459025 30 0.0 11 526673.3621656025 21 181567.1052142773 31 0.0 0 LINE 5 1D82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526536.6724852248 20 181622.110195219 30 0.0 11 526482.9752837407 21 181545.7659043168 31 0.0 0 LINE 5 1D83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526499.6698190174 20 181576.6985503557 30 0.0 11 526497.3225266423 21 181493.3494504177 31 0.0 0 LINE 5 1D84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526511.9260369985 20 181572.0021546795 30 0.0 11 526441.678933082 21 181533.4082172145 31 0.0 0 LINE 5 1D85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526307.3223704611 20 181632.9086127737 30 0.0 11 526454.1312590536 21 181531.3327633558 31 0.0 0 LINE 5 1D86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526894.9461643925 20 181452.1668933229 30 0.0 11 526849.0590665425 21 181462.3886440957 31 0.0 0 LINE 5 1D87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526874.2963543948 20 181521.0010139657 30 0.0 11 526849.6173969573 21 181460.5713299699 31 0.0 0 LINE 5 1D88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526923.4481245006 20 181527.2993504338 30 0.0 11 526831.9440671101 21 181577.3987567687 31 0.0 0 LINE 5 1D89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526921.3825863701 20 181699.1096124356 30 0.0 11 526749.2930653531 21 181455.0933668714 31 0.0 0 LINE 5 1D8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526773.7834150032 20 181359.6471438321 30 0.0 11 526709.34078019 21 181383.8692529624 31 0.0 0 LINE 5 1D8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526721.454024047 20 181413.3178054233 30 0.0 11 526700.1386005055 21 181357.1197211509 31 0.0 0 LINE 5 1D8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526725.8707045275 20 181405.9315145532 30 0.0 11 526659.4591287731 21 181431.9695352724 31 0.0 0 LINE 5 1D8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526662.7430145923 20 181433.7117840057 30 0.0 11 526641.5210478957 21 181381.7385416184 31 0.0 0 LINE 5 1D8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526708.9308036916 20 181359.2022695438 30 0.0 11 526636.4694427717 21 181386.6875196267 31 0.0 0 LINE 5 1D8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527324.4023127908 20 181542.1238641195 30 0.0 11 527121.7425878764 21 180197.6711064802 31 0.0 0 LINE 5 1D90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527230.4778736888 20 180841.7992848049 30 0.0 11 527090.3880768281 21 180889.0490839605 31 0.0 0 LINE 5 1D91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527188.824350887 20 181001.0694914723 30 0.0 11 527109.6409313045 21 180512.9971680853 31 0.0 0 LINE 5 1D92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527123.0099071885 20 180887.7895473195 30 0.0 11 527043.2541387421 21 180868.8128338491 31 0.0 0 LINE 5 1D93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527097.4761990254 20 180963.3100436179 30 0.0 11 527116.6493709036 21 180877.5789643039 31 0.0 0 LINE 5 1D94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527182.2719981973 20 181140.0052827173 30 0.0 11 526902.953581457 21 180703.6749845552 31 0.0 0 LINE 5 1D95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526724.9058894234 20 181128.0958067637 30 0.0 11 526667.7181934928 21 181030.4875655608 31 0.0 0 LINE 5 1D96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526600.7071804941 20 181076.8160581087 30 0.0 11 527232.4961109984 21 180662.4317586386 31 0.0 0 LINE 5 1D97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527005.9546060342 20 180729.1363945265 30 0.0 11 526852.309829773 21 180252.8250246601 31 0.0 0 LINE 5 1D98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527066.2282636347 20 180694.542851391 30 0.0 11 526894.597086148 21 180784.8327014642 31 0.0 0 LINE 5 1D99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527031.4563906275 20 180630.7987139774 30 0.0 11 526974.7913517218 21 180661.2079077832 31 0.0 0 LINE 5 1D9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527073.8614118073 20 180664.8439663194 30 0.0 11 527015.8687275841 21 180627.7750561708 31 0.0 0 LINE 5 1D9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527027.6753131541 20 180644.4684172386 30 0.0 11 526985.3752550181 21 180510.4087323127 31 0.0 0 LINE 5 1D9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527175.4166098245 20 180499.4434384371 30 0.0 11 526402.0073828482 21 180690.8630085347 31 0.0 0 LINE 5 1D9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526785.8624938135 20 180607.6830675286 30 0.0 11 526728.7625141292 21 180418.1739236337 31 0.0 0 LINE 5 1D9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527163.4583574716 20 180374.7574255732 30 0.0 11 527077.143578109 21 180400.6774923597 31 0.0 0 LINE 5 1D9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526924.1851951425 20 180742.8915975102 30 0.0 11 526779.21622005 21 180342.9497047469 31 0.0 0 LINE 5 1DA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526702.8643413537 20 180828.581240778 30 0.0 11 526506.2079120824 21 180448.1401350717 31 0.0 0 LINE 5 1DA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526910.3548193506 20 181164.3710947051 30 0.0 11 526624.5123186351 21 180679.7974333797 31 0.0 0 LINE 5 1DA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526690.7808434647 20 180710.4603137467 30 0.0 11 526215.2065931234 21 180941.0748792045 31 0.0 0 LINE 5 1DA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526620.3527323503 20 181074.0991428002 30 0.0 11 526443.2837607318 21 180972.7422109263 31 0.0 0 LINE 5 1DA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526436.6962569662 20 181003.1386865113 30 0.0 11 526667.7533552889 21 180746.9280367352 31 0.0 0 LINE 5 1DA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526531.0636749112 20 180801.933017677 30 0.0 11 526408.4835079856 21 180625.7016248967 31 0.0 0 LINE 5 1DA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526346.5095508479 20 180785.0841135451 30 0.0 11 526459.7865481565 21 180663.571212232 31 0.0 0 LINE 5 1DA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526745.2325381531 20 181227.243886362 30 0.0 11 526564.135988081 21 181027.6113337231 31 0.0 0 LINE 5 1DA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526889.3373540787 20 180631.9897157808 30 0.0 11 526843.4502562289 21 180642.2114665537 31 0.0 0 LINE 5 1DA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526868.6875440812 20 180700.8238364236 30 0.0 11 526844.0085866436 21 180640.3941524279 31 0.0 0 LINE 5 1DAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526917.8393141868 20 180707.1221728916 30 0.0 11 526826.3352567963 21 180757.2215792266 31 0.0 0 LINE 5 1DAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526785.1958007188 20 181088.5605498259 30 0.0 11 526727.4503039016 21 180991.761644146 31 0.0 0 LINE 5 1DAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527056.4469199513 20 180531.0616247083 30 0.0 11 526941.7075286161 21 180189.3892904521 31 0.0 0 LINE 5 1DAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526364.9824813638 20 180727.0001515036 30 0.0 11 526014.8921859642 21 180764.5781846883 31 0.0 0 LINE 5 1DAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526613.1300481536 20 181319.4827837597 30 0.0 11 526290.2675920513 21 180597.2276236572 31 0.0 0 LINE 5 1DAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526294.3528492354 20 181213.945122317 30 0.0 11 526135.5486117216 21 181037.9738909294 31 0.0 0 LINE 5 1DB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526328.5897194393 20 181133.7589566729 30 0.0 11 526251.3986893869 21 181170.2673754394 31 0.0 0 LINE 5 1DB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526246.6614287466 20 181414.5429920229 30 0.0 11 526129.2449001803 21 181416.2419766329 31 0.0 0 LINE 5 1DB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526216.3464087707 20 181360.3580383912 30 0.0 11 526146.4329392632 21 181445.0793914347 31 0.0 0 LINE 5 1DB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526342.9116307196 20 181175.2131736575 30 0.0 11 526123.3088360611 21 181290.8186824505 31 0.0 0 LINE 5 1DB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526423.5612846294 20 181245.937528677 30 0.0 11 526358.7042820345 21 181143.2679872298 31 0.0 0 LINE 5 1DB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526454.0747501559 20 181106.8197449054 30 0.0 11 526469.4291336368 21 181226.6194689207 31 0.0 0 LINE 5 1DB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526470.93942316 20 181220.0548941384 30 0.0 11 526421.3926324677 21 181245.7985618147 31 0.0 0 LINE 5 1DB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526748.9377916851 20 181027.7572252637 30 0.0 11 526748.9262106236 21 181027.7617546961 31 0.0 0 LINE 5 1DB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526612.6294771829 20 181081.0683378015 30 0.0 11 526224.986478683 21 181232.678161405 31 0.0 0 LINE 5 1DB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526265.8234853017 20 181172.1466117311 30 0.0 11 526377.5843756956 21 181505.1619682758 31 0.0 0 LINE 5 1DBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526458.0761615913 20 181445.7246893631 30 0.0 11 526298.1529495785 21 181200.6942170815 31 0.0 0 LINE 5 1DBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526417.9361183032 20 181154.1121857402 30 0.0 11 526430.5848035984 21 181187.3086387173 31 0.0 0 LINE 5 1DBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526330.6592396082 20 181344.4055867037 30 0.0 11 526246.7297386135 21 181385.2428131443 31 0.0 0 LINE 5 1DBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526279.9285591622 20 181373.6940290857 30 0.0 11 526197.2715351827 21 181362.7213981878 31 0.0 0 LINE 5 1DBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526277.2464841459 20 181360.8457807552 30 0.0 11 526227.9455098227 21 181424.0404130312 31 0.0 0 LINE 5 1DBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526304.749963081 20 181572.5432432923 30 0.0 11 526227.8821140592 21 181411.4164710242 31 0.0 0 LINE 5 1DC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526468.0150100879 20 180976.8948188468 30 0.0 11 526199.6812261328 21 181107.8746330602 31 0.0 0 LINE 5 1DC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527177.7303266084 20 181751.4685846251 30 0.0 11 527701.5928006742 21 181808.0544919456 31 0.0 0 LINE 5 1DC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527450.2036285262 20 181826.5587563648 30 0.0 11 527363.6210441879 21 181292.8793153189 31 0.0 0 LINE 5 1DC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527369.3614103036 20 181546.873448078 30 0.0 11 527720.1122960226 21 181749.5979243848 31 0.0 0 LINE 5 1DC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 528024.703594832 20 181666.8781985996 30 0.0 11 527183.1410703766 21 181445.7012363482 31 0.0 0 LINE 5 1DC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527614.5857858546 20 180887.3170383316 30 0.0 11 527614.5982048961 21 180887.3176740574 31 0.0 0 LINE 5 1DC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527301.0085882168 20 181300.4785506191 30 0.0 11 527130.9045834213 21 181198.8477494359 31 0.0 0 LINE 5 1DC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524905.0467234861 20 179966.2211383896 30 0.0 11 524511.244865442 21 179567.0832419587 31 0.0 0 LINE 5 1DC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524886.0389746226 20 179957.9478773517 30 0.0 11 525573.550575652 21 179566.6698251386 31 0.0 0 LINE 5 1DC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525007.2785092507 20 179892.3390120542 30 0.0 11 524914.3173388969 21 179777.3785166172 31 0.0 0 LINE 5 1DCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524926.827850516 20 179807.5324110196 30 0.0 11 524916.9246637157 21 179726.1504403762 31 0.0 0 LINE 5 1DCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524847.1403262642 20 179809.8158497277 30 0.0 11 524934.1939106882 21 179798.0217020612 31 0.0 0 LINE 5 1DCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524865.0806026798 20 179816.1298336475 30 0.0 11 524726.7770255972 21 179673.2089697036 31 0.0 0 LINE 5 1DCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524762.1755525736 20 179882.7736257986 30 0.0 11 525023.0581350619 21 179537.2312991965 31 0.0 0 LINE 5 1DCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524761.9693411359 20 179629.5548405179 30 0.0 11 524919.5556749655 21 179729.5867661742 31 0.0 0 LINE 5 1DCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524726.4637179141 20 179678.6767760302 30 0.0 11 524762.8069600158 21 179629.4244721773 31 0.0 0 LINE 5 1DD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524509.6460579089 20 179475.1030656924 30 0.0 11 524751.9328858016 21 179647.2746637618 31 0.0 0 LINE 5 1DD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524563.219935467 20 179517.664869887 30 0.0 11 524634.8917138494 21 179430.1379740204 31 0.0 0 LINE 5 1DD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524568.1743441253 20 179383.3875979579 30 0.0 11 525137.7149643251 21 179837.1898916572 31 0.0 0 LINE 5 1DD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525034.9532006296 20 179642.663750922 30 0.0 11 525364.5035351414 21 179352.3529784319 31 0.0 0 LINE 5 1DD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525088.3262039714 20 179687.1716102447 30 0.0 11 524944.0498189723 21 179557.5805502009 31 0.0 0 LINE 5 1DD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525136.0265943775 20 179632.4260993589 30 0.0 11 525087.8307430644 21 179589.8490442901 31 0.0 0 LINE 5 1DD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525118.8274663434 20 179684.0153911079 30 0.0 11 525133.4485429193 21 179616.7585725482 31 0.0 0 LINE 5 1DD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525121.8945987984 20 179633.6277794594 30 0.0 11 525440.3645471604 21 179386.2940176274 31 0.0 0 LINE 5 1DD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525309.2023733555 20 179721.8067611314 30 0.0 11 525081.3197323827 21 179384.1957480005 31 0.0 0 LINE 5 1DD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525072.4100933793 20 179394.0909654322 30 0.0 11 525262.1251272731 21 179249.0255401661 31 0.0 0 LINE 5 1DDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524897.5967667719 20 179318.2879206117 30 0.0 11 525090.5162898143 21 179393.7129796461 31 0.0 0 LINE 5 1DDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524907.2792235184 20 179404.9379897022 30 0.0 11 524956.4891729818 21 179335.1547493418 31 0.0 0 LINE 5 1DDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525411.4637193101 20 179678.027908497 30 0.0 11 525357.1803911208 21 179606.0875771149 31 0.0 0 LINE 5 1DDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525552.2289648615 20 179618.6483332411 30 0.0 11 525259.0658026489 21 179248.5084815205 31 0.0 0 LINE 5 1DDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524993.6561293127 20 179570.7610801281 30 0.0 11 525317.3380443595 21 179296.7807081647 31 0.0 0 LINE 5 1DDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524905.4551001676 20 179054.3882040365 30 0.0 11 525320.0216286696 21 179303.2190038064 31 0.0 0 LINE 5 1DE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524698.8042163758 20 178907.8336365132 30 0.0 11 525148.5700750326 21 179205.6224856277 31 0.0 0 LINE 5 1DE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524840.3372254955 20 179120.2088408187 30 0.0 11 524941.6980656054 21 179060.9171228345 31 0.0 0 LINE 5 1DE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524893.4022210735 20 179152.4441612063 30 0.0 11 524912.5390656945 21 179044.2804794176 31 0.0 0 LINE 5 1DE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525048.8611393741 20 179261.6952645422 30 0.0 11 524894.6733882119 21 179131.1833158452 31 0.0 0 LINE 5 1DE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524836.4366792015 20 179392.9755919916 30 0.0 11 525067.3347660931 21 179150.1258322735 31 0.0 0 LINE 5 1DE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524900.7317197808 20 179460.9664132607 30 0.0 11 524822.7735891135 21 179367.8536032429 31 0.0 0 LINE 5 1DE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524758.9414431214 20 179447.5370877066 30 0.0 11 524868.3289783231 21 179498.7435141465 31 0.0 0 LINE 5 1DE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524861.6167828911 20 179498.1769022848 30 0.0 11 524901.2616749643 21 179458.8589238799 31 0.0 0 LINE 5 1DE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524593.6079011682 20 179704.1689547404 30 0.0 11 524948.7484144244 21 179267.8287384986 31 0.0 0 LINE 5 1DE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524961.7251682221 20 179266.2058934793 30 0.0 11 524942.7715240602 21 179251.0232077804 31 0.0 0 LINE 5 1DEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525150.9289885858 20 179247.3589035855 30 0.0 11 525175.7714535572 21 179209.4512644161 31 0.0 0 LINE 5 1DEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525150.8454912971 20 179262.8933399751 30 0.0 11 525152.8826788504 21 179238.9142595195 31 0.0 0 LINE 5 1DEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525197.5598585529 20 179306.7822654515 30 0.0 11 525146.6422094706 21 179256.0944426223 31 0.0 0 LINE 5 1DED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524943.0087837501 20 179340.6215008807 30 0.0 11 524624.0296722295 21 179045.8171397802 31 0.0 0 LINE 5 1DEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524577.5449350585 20 179400.8667673345 30 0.0 11 524645.025011905 21 179044.4526765811 31 0.0 0 LINE 5 1DEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524550.5260999387 20 179147.397666498 30 0.0 11 524900.8136361586 21 179331.692360306 31 0.0 0 LINE 5 1DF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524819.4921973141 20 179431.214803694 30 0.0 11 524792.1378938785 21 179408.5490627281 31 0.0 0 LINE 5 1DF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524801.7608366968 20 179222.613675088 30 0.0 11 524854.7044420686 21 179145.7448592339 31 0.0 0 LINE 5 1DF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524831.4950766586 20 179172.1429928104 30 0.0 11 524908.8410121534 21 179140.9951436974 31 0.0 0 LINE 5 1DF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524840.1556646274 20 179182.0053063112 30 0.0 11 524851.9509558546 21 179102.7271963276 31 0.0 0 LINE 5 1DF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524303.5770037772 20 179361.6882295428 30 0.0 11 524525.5278053027 21 179579.1508995571 31 0.0 0 LINE 5 1DF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524465.7167711658 20 179557.5488468338 30 0.0 11 524601.6154163449 21 179332.0042182991 31 0.0 0 LINE 5 1DF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525085.5526043257 20 179499.5667174429 30 0.0 11 525060.0307698961 21 179460.0857612072 31 0.0 0 LINE 5 1DF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525013.8314200389 20 179504.1079223612 30 0.0 11 525061.9288724432 21 179459.9781963227 31 0.0 0 LINE 5 1DF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525024.9952417884 20 179552.3876762001 30 0.0 11 524946.2353813408 21 179483.9784120883 31 0.0 0 LINE 5 1DF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524863.1617511231 20 179610.1194168292 30 0.0 11 525032.2238053618 21 179363.9959657733 31 0.0 0 LINE 5 1DFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525130.2344513407 20 179353.8140213007 30 0.0 11 525085.1394629966 21 179301.794738543 31 0.0 0 LINE 5 1DFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525061.7307595102 20 179323.3813204832 30 0.0 11 525107.0281388681 21 179283.8753794123 31 0.0 0 LINE 5 1DFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525070.1911873143 20 179324.9578738929 30 0.0 11 525022.7095147707 21 179271.7228601367 31 0.0 0 LINE 5 1DFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525022.2161847724 20 179275.4074174014 30 0.0 11 525063.5841494132 21 179237.4563792571 31 0.0 0 LINE 5 1DFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525108.1286975622 20 179292.8435796346 30 0.0 11 525057.1888212336 21 179234.4379566338 31 0.0 0 LINE 5 1DFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524621.23270646 20 179560.471742546 30 0.0 11 524691.951804398 21 179472.702842984 31 0.0 0 LINE 5 1E00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525238.2347363486 20 179621.2230084213 30 0.0 11 525456.0511125839 21 179470.9906017885 31 0.0 0 LINE 5 1E01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525211.4080794374 20 179919.2887862473 30 0.0 11 526340.7289148488 21 179276.5673308692 31 0.0 0 LINE 5 1E02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525774.4568484473 20 179602.2365177847 30 0.0 11 525681.4956780933 21 179487.2760223476 31 0.0 0 LINE 5 1E03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525610.6341941539 20 179618.4892908976 30 0.0 11 526040.8271050026 21 179374.7298474935 31 0.0 0 LINE 5 1E04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525694.0061897128 20 179517.42991675 30 0.0 11 525684.1030029122 21 179436.0479461065 31 0.0 0 LINE 5 1E05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525614.3186654611 20 179519.713355458 30 0.0 11 525701.3722498848 21 179507.9192077916 31 0.0 0 LINE 5 1E06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525631.1275244898 20 179524.5988424941 30 0.0 11 525492.8239474074 21 179381.67797855 31 0.0 0 LINE 5 1E07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525478.070698009 20 179660.5963794274 30 0.0 11 525790.2364742585 21 179247.1288049273 31 0.0 0 LINE 5 1E08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525529.1476803325 20 179339.4523462485 30 0.0 11 525686.7340141623 21 179439.4842719045 31 0.0 0 LINE 5 1E09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525493.6420571108 20 179388.5742817606 30 0.0 11 525529.9852992123 21 179339.3219779076 31 0.0 0 LINE 5 1E0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525276.8243971054 20 179185.0005714228 30 0.0 11 525519.1112249984 21 179357.172169492 31 0.0 0 LINE 5 1E0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525330.3982746635 20 179227.5623756174 30 0.0 11 525402.0700530462 21 179140.0354797507 31 0.0 0 LINE 5 1E0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525335.3526833219 20 179093.2851036883 30 0.0 11 525943.3607832583 21 179541.8358263128 31 0.0 0 LINE 5 1E0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525802.1315398264 20 179352.5612566525 30 0.0 11 526131.681874338 21 179062.2504841623 31 0.0 0 LINE 5 1E0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525855.5045431681 20 179397.0691159753 30 0.0 11 525711.228158169 21 179267.4780559315 31 0.0 0 LINE 5 1E0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525903.204933574 20 179342.3236050893 30 0.0 11 525855.0090822612 21 179299.7465500204 31 0.0 0 LINE 5 1E10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525886.00580554 20 179393.9128968382 30 0.0 11 525900.626882116 21 179326.6560782785 31 0.0 0 LINE 5 1E11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525889.072937995 20 179343.5252851897 30 0.0 11 526207.5428863568 21 179096.191523358 31 0.0 0 LINE 5 1E12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526267.3138975824 20 179615.3908302213 30 0.0 11 525890.2062519648 21 179035.9957485947 31 0.0 0 LINE 5 1E13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525839.588432576 20 179103.9884711629 30 0.0 11 526029.3034664696 21 178958.9230458965 31 0.0 0 LINE 5 1E14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525664.7751059686 20 179028.1854263421 30 0.0 11 525857.6946290109 21 179103.6104853765 31 0.0 0 LINE 5 1E15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525674.4575627151 20 179114.8354954328 30 0.0 11 525723.6675121784 21 179045.0522550722 31 0.0 0 LINE 5 1E16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526239.8931634749 20 179340.4647148076 30 0.0 11 526185.6098352858 21 179268.5243834258 31 0.0 0 LINE 5 1E17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526319.4073040581 20 179328.5458389713 30 0.0 11 526026.2441418455 21 178958.4059872507 31 0.0 0 LINE 5 1E18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525760.8344685093 20 179280.6585858584 30 0.0 11 526084.5163835561 21 179006.678213895 31 0.0 0 LINE 5 1E19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525782.854755432 20 178831.7969486525 30 0.0 11 526087.1999678662 21 179013.1165095366 31 0.0 0 LINE 5 1E1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525603.615018398 20 179102.8730977221 30 0.0 11 525834.5131052899 21 178860.023338004 31 0.0 0 LINE 5 1E1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525667.9100589774 20 179170.8639189911 30 0.0 11 525589.9519283101 21 179077.7511089732 31 0.0 0 LINE 5 1E1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525526.1197823183 20 179157.4345934369 30 0.0 11 525635.5073175197 21 179208.641019877 31 0.0 0 LINE 5 1E1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525628.7951220878 20 179208.0744080153 30 0.0 11 525668.4400141611 21 179168.7564296102 31 0.0 0 LINE 5 1E1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525360.7862403647 20 179414.0664604705 30 0.0 11 525715.9267536209 21 178977.7262442288 31 0.0 0 LINE 5 1E1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525728.9035074186 20 178976.1033992095 30 0.0 11 525709.949863257 21 178960.9207135108 31 0.0 0 LINE 5 1E20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525918.1073277824 20 178957.2564093159 30 0.0 11 525942.9497927538 21 178919.3487701466 31 0.0 0 LINE 5 1E21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525918.0238304939 20 178972.7908457055 30 0.0 11 525920.0610180469 21 178948.8117652499 31 0.0 0 LINE 5 1E22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525964.7381977496 20 179016.6797711822 30 0.0 11 525913.8205486673 21 178965.9919483526 31 0.0 0 LINE 5 1E23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525710.1871229467 20 179050.5190066111 30 0.0 11 525453.9694047169 21 178804.7420158878 31 0.0 0 LINE 5 1E24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525344.7232742551 20 179110.7642730649 30 0.0 11 525378.2763358416 21 178909.5160670926 31 0.0 0 LINE 5 1E25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525347.4840498939 20 178913.895114929 30 0.0 11 525667.9919753553 21 179041.5898660366 31 0.0 0 LINE 5 1E26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525586.6705365106 20 179141.1123094243 30 0.0 11 525559.3162330751 21 179118.4465684587 31 0.0 0 LINE 5 1E27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525244.4808744201 20 179281.0573723183 30 0.0 11 525368.7937555415 21 179041.9017240295 31 0.0 0 LINE 5 1E28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525852.7309435223 20 179209.4642231735 30 0.0 11 525827.2091090929 21 179169.9832669377 31 0.0 0 LINE 5 1E29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525781.0097592355 20 179214.0054280916 30 0.0 11 525829.1072116399 21 179169.8757020531 31 0.0 0 LINE 5 1E2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525792.1735809848 20 179262.2851819305 30 0.0 11 525713.4137205373 21 179193.8759178186 31 0.0 0 LINE 5 1E2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525630.3400903196 20 179320.0169225595 30 0.0 11 525799.4021445584 21 179073.8934715036 31 0.0 0 LINE 5 1E2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525388.4110456565 20 179270.3692482764 30 0.0 11 525459.1301435945 21 179182.6003487144 31 0.0 0 LINE 5 1E2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526037.8628631727 20 179311.0930584983 30 0.0 11 526223.2294517805 21 179180.8881075191 31 0.0 0 LINE 5 1E2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525453.9796943118 20 178887.2906102932 30 0.0 11 525336.510862941 21 178764.6775143576 31 0.0 0 LINE 5 1E2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525112.104843077 20 179189.2114775647 30 0.0 11 525651.8629217101 21 178660.5028461757 31 0.0 0 LINE 5 1E30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525442.4910881526 20 178769.7456822486 30 0.0 11 525208.4408025759 21 178398.1219055309 31 0.0 0 LINE 5 1E31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525494.9397722838 20 178724.1522335949 30 0.0 11 525344.0020096121 21 178845.9196755137 31 0.0 0 LINE 5 1E32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525448.5004200477 20 178668.3330185256 30 0.0 11 525398.783327276 21 178709.1234143126 31 0.0 0 LINE 5 1E33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525496.6873149113 20 178693.5379424829 30 0.0 11 525432.6222732513 21 178668.3799226858 31 0.0 0 LINE 5 1E34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525447.4334000319 20 178682.4758188987 30 0.0 11 525254.0435361588 21 178328.6432902885 31 0.0 0 LINE 5 1E35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525564.3501928733 20 178511.6244250797 30 0.0 11 525194.722938555 21 178682.7600061523 31 0.0 0 LINE 5 1E36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525203.0709299968 20 178693.1334353863 30 0.0 11 525099.213844755 21 178499.6712213452 31 0.0 0 LINE 5 1E37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525100.363960778 20 178853.6235573177 30 0.0 11 525205.5847867179 21 178675.1986159843 31 0.0 0 LINE 5 1E38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525187.4493033807 20 178857.8812028928 30 0.0 11 525126.4053077517 21 178798.1739976407 31 0.0 0 LINE 5 1E39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525501.2617850861 20 178255.2585961814 30 0.0 11 525127.8717471582 21 178461.7315855154 31 0.0 0 LINE 5 1E3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525364.9235649414 20 178799.0496326572 30 0.0 11 525146.0590417449 21 178435.8230548363 31 0.0 0 LINE 5 1E3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524315.2950718407 20 179499.9302652056 30 0.0 11 525161.4225941317 21 178440.5096480434 31 0.0 0 LINE 5 1E3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525068.6142213994 20 178695.2708080864 30 0.0 11 524915.1869988046 21 178826.6759781821 31 0.0 0 LINE 5 1E3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525143.1182611162 20 178899.0615197718 30 0.0 11 524961.4177744454 21 178659.2439450341 31 0.0 0 LINE 5 1E3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525115.2362263225 20 178985.9003487789 30 0.0 11 525188.9907645544 21 178889.423752566 31 0.0 0 LINE 5 1E3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525256.2919432123 20 178966.1997378055 30 0.0 11 525149.2814960341 21 179022.2041587109 31 0.0 0 LINE 5 1E40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525155.9619816731 20 179021.3406031857 30 0.0 11 525114.613382989 21 178983.8184193446 31 0.0 0 LINE 5 1E41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525432.8375440702 20 179215.2514314149 30 0.0 11 525432.8292745313 21 179215.2421442479 31 0.0 0 LINE 5 1E42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525335.5056263998 20 179105.9421037015 30 0.0 11 525058.7063969978 21 178795.0806884354 31 0.0 0 LINE 5 1E43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525059.173438758 20 178782.0111958253 30 0.0 11 525041.1628657293 21 178798.3014945095 31 0.0 0 LINE 5 1E44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525129.6526905607 20 178812.3535875894 30 0.0 11 524856.1793817239 21 179032.8123675689 31 0.0 0 LINE 5 1E45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524939.8713919292 20 179087.6518164087 30 0.0 11 525114.1098324377 21 178852.5851621675 31 0.0 0 LINE 5 1E46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525199.3924246851 20 178948.7349027456 30 0.0 11 525172.6550599113 21 178972.1252224294 31 0.0 0 LINE 5 1E47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524990.6328490503 20 178932.978266497 30 0.0 11 524923.1892550706 21 178868.4553881387 31 0.0 0 LINE 5 1E48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524945.5489577764 20 178895.5769624656 30 0.0 11 524927.1323034953 21 178814.2540930681 31 0.0 0 LINE 5 1E49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524956.6660133504 20 178888.5997074953 30 0.0 11 524880.2829104158 21 178864.3145432224 31 0.0 0 LINE 5 1E4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524767.6972013128 20 178987.9125720965 30 0.0 11 524892.0990735233 21 178859.8708712906 31 0.0 0 LINE 5 1E4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525309.292804869 20 178696.9770215821 30 0.0 11 525266.2475391527 21 178715.8771548452 31 0.0 0 LINE 5 1E4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525302.3400723392 20 178768.5047108219 30 0.0 11 525266.444000114 21 178713.9861851008 31 0.0 0 LINE 5 1E4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525351.7822017535 20 178765.1818527446 30 0.0 11 525271.6900042621 21 178832.0263209903 31 0.0 0 LINE 5 1E4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525382.9712220381 20 178934.1501266619 30 0.0 11 525166.9533134254 21 178728.0069858551 31 0.0 0 LINE 5 1E4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525172.5292890373 20 178629.6267682583 30 0.0 11 525113.9851982472 21 178665.8504233187 31 0.0 0 LINE 5 1E50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525131.5631229839 20 178692.4015905385 30 0.0 11 525099.7852125658 21 178641.384570182 31 0.0 0 LINE 5 1E51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525134.4685092385 20 178684.3007825545 30 0.0 11 525074.3436879002 21 178722.686740615 31 0.0 0 LINE 5 1E52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525077.9024450775 20 178723.7612563569 30 0.0 11 525047.0330050794 21 178676.8713057391 31 0.0 0 LINE 5 1E53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525108.8141582754 20 178641.7280582332 30 0.0 11 525043.0334736655 21 178682.7035305395 31 0.0 0 LINE 5 1E54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525277.2864968406 20 179951.9759059466 30 0.0 11 525397.6936000875 21 179883.749843338 31 0.0 0 LINE 5 1E55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525294.0384387862 20 180099.9040169973 30 0.0 11 525712.441703776 21 179966.4031726317 31 0.0 0 LINE 5 1E56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525346.4713448314 20 180029.9665745256 30 0.0 11 525722.3129646027 21 179883.8838082623 31 0.0 0 LINE 5 1E57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525367.0909789318 20 179823.9700553612 30 0.0 11 525515.7739640111 21 180142.0179360354 31 0.0 0 LINE 5 1E58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525529.3928401671 20 179730.5940236112 30 0.0 11 525563.208015364 21 179814.1321880935 31 0.0 0 LINE 5 1E59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525580.4817299055 20 179668.5095368278 30 0.0 11 525747.3357151855 21 180110.2197326648 31 0.0 0 LINE 5 1E5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525334.4952972862 20 180172.2827760843 30 0.0 11 525735.8738520661 21 180035.4234245136 31 0.0 0 LINE 5 1E5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525732.0503643001 20 180418.4899406992 30 0.0 11 525731.7300309989 21 180029.8125402269 31 0.0 0 LINE 5 1E5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525442.7963232096 20 180130.0395851312 30 0.0 11 525463.5480601659 21 180172.2234132085 31 0.0 0 LINE 5 1E5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525402.0412609708 20 180189.2305955932 30 0.0 11 525464.6158193738 21 180170.6504371254 31 0.0 0 LINE 5 1E5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525506.3853305195 20 179710.566768304 30 0.0 11 526021.5022715954 21 179655.2726091083 31 0.0 0 LINE 5 1E5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525810.9415731873 20 180127.6242478806 30 0.0 11 525780.88439704 21 179743.3309206274 31 0.0 0 LINE 5 1E60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525919.6974796773 20 180124.5517712393 30 0.0 11 525847.3873537419 21 179372.4594590579 31 0.0 0 LINE 5 1E61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525937.1719437012 20 179590.8840211527 30 0.0 11 526355.5752086912 21 179457.3831767871 31 0.0 0 LINE 5 1E62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525926.4214307014 20 179522.2250559882 30 0.0 11 525963.4414776904 21 179712.5905839408 31 0.0 0 LINE 5 1E63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525997.8985076456 20 179509.4412506651 30 0.0 11 526009.6533903446 21 179572.666786921 31 0.0 0 LINE 5 1E64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525944.8043687644 20 179497.6821076383 30 0.0 11 526010.0137117215 21 179519.7047576626 31 0.0 0 LINE 5 1E65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526143.2653595122 20 179461.2215478405 30 0.0 11 526365.4464695179 21 179374.8638124178 31 0.0 0 LINE 5 1E66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526075.4860245848 20 179822.5807993095 30 0.0 11 526160.6387781117 21 179816.2303404174 31 0.0 0 LINE 5 1E67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526269.8843402822 20 179283.9459924196 30 0.0 11 526324.2307933421 21 179493.875925033 31 0.0 0 LINE 5 1E68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525977.6288022012 20 179663.2627802396 30 0.0 11 526379.0073569811 21 179526.4034286693 31 0.0 0 LINE 5 1E69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526049.3398680841 20 179889.4997319409 30 0.0 11 526376.3294029554 21 179816.2346214849 31 0.0 0 LINE 5 1E6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526024.0580070095 20 179799.402942206 30 0.0 11 526063.8685273676 21 179914.1312647571 31 0.0 0 LINE 5 1E6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525972.0353627549 20 179813.8335785763 30 0.0 11 526026.138241068 21 179800.0314247022 31 0.0 0 LINE 5 1E6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525657.5913718472 20 179937.8757606729 30 0.0 11 526214.4151226173 21 179857.4712891304 31 0.0 0 LINE 5 1E6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526222.4763599335 20 179847.1734146887 30 0.0 11 526225.7597894024 21 179871.2352862486 31 0.0 0 LINE 5 1E6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526149.0212757887 20 179824.9847625001 30 0.0 11 526228.1798567896 21 180171.0884570164 31 0.0 0 LINE 5 1E6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525909.5190576763 20 180107.530341743 30 0.0 11 526099.4004078702 21 180182.1743046431 31 0.0 0 LINE 5 1E70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526079.818921055 20 180206.3384580108 30 0.0 11 526134.9957632876 21 179865.7701156398 31 0.0 0 LINE 5 1E71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525711.9185847874 20 180106.0034193516 30 0.0 11 525980.9621560936 21 180122.2722011088 31 0.0 0 LINE 5 1E72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526085.9298281247 20 179621.0195892866 30 0.0 11 526106.6815650811 21 179663.2034173638 31 0.0 0 LINE 5 1E73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526045.1747658859 20 179680.2105997487 30 0.0 11 526107.7493242888 21 179661.6304412809 31 0.0 0 LINE 5 1E74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526009.4961502297 20 179645.8216199492 30 0.0 11 526027.7031022563 21 179748.5418707858 31 0.0 0 LINE 5 1E75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525795.056840274 20 179988.0281649024 30 0.0 11 525906.6924360145 21 179972.4697489455 31 0.0 0 LINE 5 1E76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526157.3721671854 20 180128.6556673708 30 0.0 11 526202.1834097474 21 180292.4386035349 31 0.0 0 LINE 5 1E77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525722.6754663999 20 180266.7621564555 30 0.0 11 526453.6159464396 21 180075.4571251711 31 0.0 0 LINE 5 1E78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526252.3018776702 20 180198.9205109824 30 0.0 11 526445.7753829477 21 180682.057749667 31 0.0 0 LINE 5 1E79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526318.3682829335 20 180177.3599654693 30 0.0 11 526136.3410382619 21 180244.2598930404 31 0.0 0 LINE 5 1E7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526301.4865506871 20 180101.2214370023 30 0.0 11 526334.1850046179 21 180259.4809290837 31 0.0 0 LINE 5 1E7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526329.704907844 20 180239.5311797255 30 0.0 11 526534.9801261073 21 180484.6040825584 31 0.0 0 LINE 5 1E7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526087.5384759946 20 180296.8030922689 30 0.0 11 526317.4288490493 21 180648.7166901801 31 0.0 0 LINE 5 1E7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525898.6919355042 20 180368.563056517 30 0.0 11 526019.3572832418 21 180354.8758587771 31 0.0 0 LINE 5 1E7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525988.0841471649 20 180257.6853678938 30 0.0 11 525885.0460868631 21 180320.7003589317 31 0.0 0 LINE 5 1E7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525889.220156881 20 180315.4134169037 30 0.0 11 525900.1577889329 21 180370.1673126414 31 0.0 0 LINE 5 1E80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525865.1707519406 20 179978.2441530627 30 0.0 11 525865.1744688462 21 179978.2560198802 31 0.0 0 LINE 5 1E81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525908.9184783546 20 180117.9157956967 30 0.0 11 526306.8625173747 21 181086.3192754854 31 0.0 0 LINE 5 1E82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526206.5401921418 20 180432.3696421253 30 0.0 11 525861.4479683868 21 180549.1055735451 31 0.0 0 LINE 5 1E83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525770.026693169 20 180436.6193017752 30 0.0 11 526039.9112933834 21 180406.3982521934 31 0.0 0 LINE 5 1E84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525973.8238669656 20 180315.4713530542 30 0.0 11 525940.0178018569 21 180326.3866492873 31 0.0 0 LINE 5 1E85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526387.676675063 20 180393.9615060689 30 0.0 11 526207.9357806169 21 180377.7926894812 31 0.0 0 LINE 5 1E86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526181.3390144858 20 180319.7845639188 30 0.0 11 526209.6588850731 21 180378.5959792896 31 0.0 0 LINE 5 1E87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526080.6813073879 20 180165.4867606541 30 0.0 11 526132.4291998959 21 180394.4715974546 31 0.0 0 LINE 5 1E88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525789.3590273023 20 180289.1511682799 30 0.0 11 525865.3960941447 21 180094.2260030026 31 0.0 0 LINE 5 1E89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526198.2549186949 20 180325.3350620853 30 0.0 11 526090.5181339454 21 180371.4108565399 31 0.0 0 LINE 5 1E8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525368.8224255521 20 179827.6737940761 30 0.0 11 525405.0512025434 21 179632.8619158082 31 0.0 0 LINE 5 1E8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526340.1321654935 20 180444.2921744968 30 0.0 11 525959.6088533624 21 180667.0275531655 31 0.0 0 LINE 5 1E8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525943.4109402349 20 180796.5443965836 30 0.0 11 526008.5505737855 21 181146.5684762149 31 0.0 0 LINE 5 1E8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525600.2574380592 20 180032.4074553064 30 0.0 11 525594.054054251 21 180351.3841439652 31 0.0 0 LINE 5 1E8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526288.1311668085 20 179495.7837681826 30 0.0 11 526168.5844052437 21 179281.6470285089 31 0.0 0 LINE 5 1E8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526267.7956939577 20 179469.0424015861 30 0.0 11 526508.5909987458 21 179449.6436152699 31 0.0 0 LINE 5 1E90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526406.7862068278 20 179918.9227774008 30 0.0 11 526334.4760808925 21 179166.8304652195 31 0.0 0 LINE 5 1E91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526424.2606708517 20 179385.2550273141 30 0.0 11 526842.6639358418 21 179251.7541829487 31 0.0 0 LINE 5 1E92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526413.5101578521 20 179316.5960621496 30 0.0 11 526450.530204841 21 179506.9615901023 31 0.0 0 LINE 5 1E93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526484.9872347962 20 179303.8122568266 30 0.0 11 526496.7421174952 21 179367.0377930824 31 0.0 0 LINE 5 1E94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526476.6935768971 20 179315.3175848426 30 0.0 11 526852.5351966685 21 179169.2348185793 31 0.0 0 LINE 5 1E95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526543.8107781008 20 179209.0480168294 30 0.0 11 526669.8122892258 21 179478.3139683937 31 0.0 0 LINE 5 1E96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526656.744931586 20 179480.8715374547 30 0.0 11 526878.6866667965 21 179392.680620322 31 0.0 0 LINE 5 1E97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526631.9300359334 20 179669.7895665503 30 0.0 11 526666.3744463014 21 179465.5336865968 31 0.0 0 LINE 5 1E98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526562.5747517353 20 179616.9518054711 30 0.0 11 526647.7275052624 21 179610.601346579 31 0.0 0 LINE 5 1E99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526756.9730674327 20 179078.316998581 30 0.0 11 526877.5579472513 21 179395.5707429818 31 0.0 0 LINE 5 1E9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526464.7175293518 20 179457.6337864013 30 0.0 11 526866.0960841318 21 179320.7744348308 31 0.0 0 LINE 5 1E9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526860.6184147858 20 179858.7988541849 30 0.0 11 526861.9522630644 21 179315.163550544 31 0.0 0 LINE 5 1E9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526772.4217413488 20 179820.7069533161 30 0.0 11 526875.3762699339 21 179764.2278175836 31 0.0 0 LINE 5 1E9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526772.0407339991 20 179758.6193984473 30 0.0 11 526874.6621442611 21 179797.7914169808 31 0.0 0 LINE 5 1E9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526758.2159975106 20 179569.1143707557 30 0.0 11 526790.9322939016 21 179768.4554736715 31 0.0 0 LINE 5 1E9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526536.4285952347 20 179683.8707381025 30 0.0 11 526963.5064845303 21 179587.5356502704 31 0.0 0 LINE 5 1EA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526511.14673416 20 179593.7739483675 30 0.0 11 526550.9572545182 21 179708.5022709184 31 0.0 0 LINE 5 1EA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526459.1240899054 20 179608.204584738 30 0.0 11 526513.2269682183 21 179594.4024308638 31 0.0 0 LINE 5 1EA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525753.434535395 20 179785.4801100221 30 0.0 11 526701.5038497678 21 179651.842295292 31 0.0 0 LINE 5 1EA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526709.5650870841 20 179641.5444208502 30 0.0 11 526712.8485165531 21 179665.6062924103 31 0.0 0 LINE 5 1EA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526822.969650723 20 179488.9249607078 30 0.0 11 526868.2553233158 21 179487.0960181053 31 0.0 0 LINE 5 1EA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526809.6007739837 20 179481.013019071 30 0.0 11 526831.2178066143 21 179491.5889508443 31 0.0 0 LINE 5 1EA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526795.9591495938 20 179418.3841441678 30 0.0 11 526813.2729176061 21 179488.112874319 31 0.0 0 LINE 5 1EA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526636.1100029395 20 179619.3557686616 30 0.0 11 526715.2685839402 21 179965.4594631777 31 0.0 0 LINE 5 1EA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526396.6077848269 20 179901.9013479045 30 0.0 11 526586.4891350208 21 179976.5453108047 31 0.0 0 LINE 5 1EA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526566.9076482057 20 180000.7094641722 30 0.0 11 526622.0844904381 21 179660.1411218014 31 0.0 0 LINE 5 1EAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526494.9174763462 20 179678.7541194271 30 0.0 11 526500.3027970688 21 179713.8681059663 31 0.0 0 LINE 5 1EAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526664.7499560606 20 179801.1704616331 30 0.0 11 526757.8997831164 21 179795.258615892 31 0.0 0 LINE 5 1EAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526723.3266480838 20 179801.6016776982 30 0.0 11 526789.7965023669 21 179751.2594418172 31 0.0 0 LINE 5 1EAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526719.3173330142 20 179789.1038217133 30 0.0 11 526793.3866987752 21 179819.7285939321 31 0.0 0 LINE 5 1EAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526793.4123204343 20 179934.5500188108 30 0.0 11 526787.2106635646 21 179808.7183932118 31 0.0 0 LINE 5 1EAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526163.6968290265 20 179991.1895204469 30 0.0 11 526468.0508832441 21 179916.6432072703 31 0.0 0 LINE 5 1EB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526573.0185552753 20 179415.3905954482 30 0.0 11 526593.7702922315 21 179457.5744235253 31 0.0 0 LINE 5 1EB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526532.2634930363 20 179474.5816059103 30 0.0 11 526594.8380514394 21 179456.0014474424 31 0.0 0 LINE 5 1EB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526496.5848773803 20 179440.1926261107 30 0.0 11 526514.7918294069 21 179542.9128769474 31 0.0 0 LINE 5 1EB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526363.8900139225 20 179549.3489625679 30 0.0 11 526661.9086167068 21 179530.8113322588 31 0.0 0 LINE 5 1EB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526721.0133640281 20 179451.967261064 30 0.0 11 526742.4617267929 21 179517.3853891871 31 0.0 0 LINE 5 1EB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526711.9136583285 20 179526.3722369036 30 0.0 11 526769.0827439912 21 179507.8177872728 31 0.0 0 LINE 5 1EB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526714.9092809126 20 179518.3043620523 30 0.0 11 526736.1739570874 21 179586.3946657991 31 0.0 0 LINE 5 1EB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526732.759683507 20 179584.9242669951 30 0.0 11 526786.5754879611 21 179568.9414954683 31 0.0 0 LINE 5 1EB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526761.9551253384 20 179502.2646893075 30 0.0 11 526785.878060321 21 179575.9788736977 31 0.0 0 LINE 5 1EB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526282.1455674244 20 179782.3991710638 30 0.0 11 526393.7811631652 21 179766.8407551071 31 0.0 0 LINE 5 1EBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526847.7872470182 20 179818.1888913642 30 0.0 11 527137.9529271293 21 180223.3699557505 31 0.0 0 LINE 5 1EBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526827.1464023706 20 179883.7857841154 30 0.0 11 526969.3070185326 21 180061.1550711378 31 0.0 0 LINE 5 1EBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526644.4608943359 20 179923.0266735323 30 0.0 11 526616.8198055494 21 180035.3862282373 31 0.0 0 LINE 5 1EBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526307.4165122343 20 180027.1168364971 30 0.0 11 527138.5741937184 21 179816.0033204743 31 0.0 0 LINE 5 1EBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526829.4741782867 20 180040.2552289311 30 0.0 11 526768.9318332369 21 180061.9409421541 31 0.0 0 LINE 5 1EBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526832.6170945618 20 179985.9653854469 30 0.0 11 526821.2737317685 21 180053.8519352452 31 0.0 0 LINE 5 1EC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526816.7936349946 20 180033.9021858869 30 0.0 11 526957.2168035019 21 180224.7761332145 31 0.0 0 LINE 5 1EC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526352.2594790912 20 179772.6151592242 30 0.0 11 526352.2631959968 21 179772.6270260417 31 0.0 0 LINE 5 1EC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526314.9106074973 20 180249.9782180647 30 0.0 11 526507.1714302967 21 180187.2289110584 31 0.0 0 LINE 5 1EC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527073.8171808937 20 179977.5827294601 30 0.0 11 526861.4098158871 21 180120.8741309933 31 0.0 0 LINE 5 1EC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527049.1786023032 20 180034.3736699857 30 0.0 11 526985.7328634694 21 179826.2728416301 31 0.0 0 LINE 5 1EC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 527002.591502373 20 179513.810835256 30 0.0 11 526852.862144296 21 179367.1654655456 31 0.0 0 LINE 5 1EC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526660.724472809 20 179125.7359711999 30 0.0 11 526725.8641063598 21 179475.760050831 31 0.0 0 LINE 5 1EC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525746.0995262102 20 182025.6174555021 30 0.0 11 525056.4892183749 21 182481.9606767529 31 0.0 0 LINE 5 1EC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526255.1770219457 20 176496.5269798067 30 0.0 11 526588.3769258359 21 177160.7654823236 31 0.0 0 LINE 5 1EC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526351.7667754745 20 176673.6706001668 30 0.0 11 525577.3034436981 21 176834.8452365946 31 0.0 0 LINE 5 1ECA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526216.2354019187 20 176698.8657335175 30 0.0 11 526269.3892037421 21 176836.823582357 31 0.0 0 LINE 5 1ECB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526377.1301782186 20 176733.7209433581 30 0.0 11 525892.8589853867 21 176833.5508917015 31 0.0 0 LINE 5 1ECC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526266.7460571489 20 176804.2846207156 30 0.0 11 526251.1719546794 21 176884.7740336025 31 0.0 0 LINE 5 1ECD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526343.2823493881 20 176826.5895884126 30 0.0 11 526256.8146720737 21 176811.0728471291 31 0.0 0 LINE 5 1ECE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526328.1489277797 20 176815.0700631957 30 0.0 11 526415.8642461339 21 176993.564532887 31 0.0 0 LINE 5 1ECF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526446.5501364223 20 176783.258144649 30 0.0 11 526092.1384880852 21 177031.9579734428 31 0.0 0 LINE 5 1ED0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526368.9639172092 20 177024.2979221347 30 0.0 11 526249.7236978589 21 176880.6956629269 31 0.0 0 LINE 5 1ED1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526417.8419793417 20 176988.4573184709 30 0.0 11 526368.1267487453 21 177024.1646920515 31 0.0 0 LINE 5 1ED2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526561.6444323391 20 177248.7898130673 30 0.0 11 526383.958226091 21 177010.5177453355 31 0.0 0 LINE 5 1ED3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526523.7346062075 20 177191.8291896897 30 0.0 11 526428.6418707171 21 177253.1086558552 31 0.0 0 LINE 5 1ED4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526477.7731172824 20 177318.0926977102 30 0.0 11 526002.9071639054 21 176654.219553631 31 0.0 0 LINE 5 1ED5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526113.2047176925 20 176927.9689911812 30 0.0 11 525710.4109407036 21 177103.0145304551 31 0.0 0 LINE 5 1ED6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526076.0838334604 20 176869.2181019876 30 0.0 11 526173.577774299 21 177036.861919683 31 0.0 0 LINE 5 1ED7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526013.8731623593 20 176906.6644717475 30 0.0 11 526046.6602886157 21 176961.9876138668 31 0.0 0 LINE 5 1ED8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526046.0877021004 20 176862.852504689 30 0.0 11 526011.5139015976 21 176922.3664345021 31 0.0 0 LINE 5 1ED9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526027.6910453359 20 176909.8618838492 30 0.0 11 525648.6434118033 21 177047.4118357381 31 0.0 0 LINE 5 1EDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525876.5253984999 20 176768.4098338997 30 0.0 11 525989.6849763969 21 177159.6982239322 31 0.0 0 LINE 5 1EDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526001.2034243672 20 177153.0182275587 30 0.0 11 525776.1000689673 21 177232.7944839307 31 0.0 0 LINE 5 1EDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526144.2802689023 20 177278.8546981125 30 0.0 11 525983.856499181 21 177147.8161693907 31 0.0 0 LINE 5 1EDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526161.6826575419 20 177193.4196859003 30 0.0 11 526093.4161965302 21 177244.7130583994 31 0.0 0 LINE 5 1EDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525765.760308933 20 176778.6599923234 30 0.0 11 525795.3209390993 21 176863.7967067469 31 0.0 0 LINE 5 1EDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525613.560714316 20 176791.9291939231 30 0.0 11 525778.8526571896 21 177234.2262921855 31 0.0 0 LINE 5 1EE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526130.4185050208 20 177009.0808133312 30 0.0 11 525738.2257169645 21 177170.3881081017 31 0.0 0 LINE 5 1EE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526055.738486585 20 177527.5817907187 30 0.0 11 525737.6495586863 21 177163.4367544813 31 0.0 0 LINE 5 1EE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526207.3805466062 20 177730.5288642783 30 0.0 11 525870.8327531437 21 177308.9803985171 31 0.0 0 LINE 5 1EE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526137.9265610156 20 177484.9459577887 30 0.0 11 526023.2532773761 21 177510.2355949675 31 0.0 0 LINE 5 1EE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526097.3289771107 20 177437.968880216 30 0.0 11 526045.8921695055 21 177535.0248213197 31 0.0 0 LINE 5 1EE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525982.9452194781 20 177286.2466509642 30 0.0 11 526089.5884684561 21 177457.8113583155 31 0.0 0 LINE 5 1EE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526225.4256337584 20 177226.5647915325 30 0.0 11 525931.0934040827 21 177386.7474088776 31 0.0 0 LINE 5 1EE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526185.12413629 20 177142.1112935483 30 0.0 11 526230.7113104238 21 177254.669167911 31 0.0 0 LINE 5 1EE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526315.9341363822 20 177198.4457698113 30 0.0 11 526227.5644827577 21 177116.1139091223 31 0.0 0 LINE 5 1EE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526233.7781151948 20 177118.7149451577 30 0.0 11 526183.9724349232 21 177143.9541033457 31 0.0 0 LINE 5 1EEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526552.1051833143 20 177005.0075836561 30 0.0 11 526080.1018509581 21 177311.1618302548 31 0.0 0 LINE 5 1EEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526067.253986068 20 177308.720082347 30 0.0 11 526080.6275394143 21 177328.9908160026 31 0.0 0 LINE 5 1EEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525881.4082668052 20 177268.5372091289 30 0.0 11 525846.1225825818 21 177296.9811480634 31 0.0 0 LINE 5 1EED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525886.2595165639 20 177253.7794633145 30 0.0 11 525876.9550485725 21 177275.9734559256 31 0.0 0 LINE 5 1EEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525855.2852228508 20 177197.6629504452 30 0.0 11 525888.1711318466 21 177261.5407976287 31 0.0 0 LINE 5 1EEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526107.9240993181 20 177243.6514450411 30 0.0 11 526320.9250431739 21 177622.1853045925 31 0.0 0 LINE 5 1EF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526325.353944576 20 177590.736076287 30 0.0 11 526135.2587465105 21 177656.903499832 31 0.0 0 LINE 5 1EF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526474.2247281625 20 177298.5801819529 30 0.0 11 526300.5256348284 21 177617.0345583299 31 0.0 0 LINE 5 1EF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526422.077933941 20 177548.0943386304 30 0.0 11 526145.3364330091 21 177265.1101803126 31 0.0 0 LINE 5 1EF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526253.2970288973 20 177195.3792482302 30 0.0 11 526272.3664885074 21 177225.3517262752 31 0.0 0 LINE 5 1EF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526206.0940969802 20 177399.3417821021 30 0.0 11 526132.0979797496 21 177456.2312788077 31 0.0 0 LINE 5 1EF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526162.294088263 20 177438.2387489769 30 0.0 11 526079.1197531001 21 177444.1219634151 31 0.0 0 LINE 5 1EF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526157.0816685246 20 177426.1929326067 30 0.0 11 526121.5043960536 21 177498.0149717119 31 0.0 0 LINE 5 1EF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526226.6183319566 20 177628.0267985385 30 0.0 11 526118.902231297 21 177485.6619692671 31 0.0 0 LINE 5 1EF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526696.7584575979 20 177276.0780754461 30 0.0 11 526578.4914040608 21 177144.8938979601 31 0.0 0 LINE 5 1EF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526628.7751494532 20 177183.8240075886 30 0.0 11 526430.1651325173 21 177356.7195899359 31 0.0 0 LINE 5 1EFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526021.0958195116 20 177048.6048545089 30 0.0 11 526033.2561919037 21 177094.0166952692 31 0.0 0 LINE 5 1EFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526090.744449026 20 177066.3141521915 30 0.0 11 526031.4168155517 21 177093.5360102175 31 0.0 0 LINE 5 1EFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526094.9506934654 20 177016.939330121 30 0.0 11 526148.8891460266 21 177106.2342704555 31 0.0 0 LINE 5 1EFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526266.6937747585 20 177011.7099319813 30 0.0 11 526030.2023995345 21 177194.0024463306 31 0.0 0 LINE 5 1EFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525933.8026293408 20 177173.5857123843 30 0.0 11 525960.7383942654 21 177236.9420721305 31 0.0 0 LINE 5 1EFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525989.6462154662 20 177223.5897018464 30 0.0 11 525934.4035908969 21 177247.2714329343 31 0.0 0 LINE 5 1F00 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525982.0791010418 20 177219.4905386911 30 0.0 11 526010.9127192368 21 177284.7369821109 31 0.0 0 LINE 5 1F01 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526012.5140018397 20 177281.3821004813 30 0.0 11 525961.4884440385 21 177304.7911210896 31 0.0 0 LINE 5 1F02 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525936.1110470527 20 177238.398753624 30 0.0 11 525966.6473939993 21 177309.6280966901 31 0.0 0 LINE 5 1F03 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526481.6757723958 20 177133.2718294049 30 0.0 11 526387.4153207091 21 177195.0742386724 31 0.0 0 LINE 5 1F04 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525913.1651616291 20 176885.9301494603 30 0.0 11 525659.7319104015 21 176961.9915518347 31 0.0 0 LINE 5 1F05 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525397.0355684111 20 176739.2847153854 30 0.0 11 525450.1893702347 21 176877.2425642249 31 0.0 0 LINE 5 1F06 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525557.930344711 20 176774.139925226 30 0.0 11 525073.6591518792 21 176873.9698735696 31 0.0 0 LINE 5 1F07 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525447.5462236413 20 176844.7036025835 30 0.0 11 525431.9721211719 21 176925.1930154706 31 0.0 0 LINE 5 1F08 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525524.0825158807 20 176867.0085702805 30 0.0 11 525437.6148385663 21 176851.4918289969 31 0.0 0 LINE 5 1F09 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525509.5870126812 20 176857.1960215582 30 0.0 11 525597.3023310353 21 177035.6904912493 31 0.0 0 LINE 5 1F0A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525697.0190445365 20 176774.7887669079 30 0.0 11 525272.9386545777 21 177072.376955311 31 0.0 0 LINE 5 1F0B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525549.7640837018 20 177064.7169040027 30 0.0 11 525430.5238643515 21 176921.1146447949 31 0.0 0 LINE 5 1F0C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525598.6421458342 20 177028.8763003388 30 0.0 11 525548.9269152378 21 177064.5836739195 31 0.0 0 LINE 5 1F0D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525742.4445988317 20 177289.2087949354 30 0.0 11 525564.7583925835 21 177050.9367272036 31 0.0 0 LINE 5 1F0E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525704.5347726999 20 177232.2481715577 30 0.0 11 525609.4420372094 21 177293.5276377232 31 0.0 0 LINE 5 1F0F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525658.5732837748 20 177358.5116795782 30 0.0 11 525217.744042467 21 176744.8821656507 31 0.0 0 LINE 5 1F10 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525294.004884185 20 176968.3879730492 30 0.0 11 524709.4042916746 21 177247.8133178601 31 0.0 0 LINE 5 1F11 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525256.8839999527 20 176909.6370838556 30 0.0 11 525354.3779407914 21 177077.280901551 31 0.0 0 LINE 5 1F12 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525194.6733288519 20 176947.0834536155 30 0.0 11 525227.4604551082 21 177002.4065957346 31 0.0 0 LINE 5 1F13 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525226.887868593 20 176903.2714865569 30 0.0 11 525192.3140680902 21 176962.78541637 31 0.0 0 LINE 5 1F14 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525208.4912118285 20 176950.2808657172 30 0.0 11 525076.3479310441 21 176998.2334191865 31 0.0 0 LINE 5 1F15 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525057.3255649925 20 176808.8288157677 30 0.0 11 525170.4851428896 21 177200.1172058003 31 0.0 0 LINE 5 1F16 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525182.0035908596 20 177193.4372094267 30 0.0 11 524956.9002354598 21 177273.2134657988 31 0.0 0 LINE 5 1F17 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525325.0804353948 20 177319.2736799805 30 0.0 11 525164.6566656736 21 177188.2351512587 31 0.0 0 LINE 5 1F18 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525342.4828240345 20 177233.8386677683 30 0.0 11 525274.2163630228 21 177285.1320402674 31 0.0 0 LINE 5 1F19 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524933.259545622 20 176826.0690141637 30 0.0 11 524962.8201757881 21 176911.205728587 31 0.0 0 LINE 5 1F1A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525311.2186715134 20 177049.4997951991 30 0.0 11 524919.025883457 21 177210.8070899695 31 0.0 0 LINE 5 1F1B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525318.7267275081 20 177525.3649396567 30 0.0 11 525204.0534438687 21 177550.6545768355 31 0.0 0 LINE 5 1F1C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525278.1291436034 20 177478.3878620838 30 0.0 11 525226.6923359981 21 177575.4438031876 31 0.0 0 LINE 5 1F1D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525163.7453859706 20 177326.6656328321 30 0.0 11 525270.3886349485 21 177498.2303401834 31 0.0 0 LINE 5 1F1E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525406.2258002512 20 177266.9837734004 30 0.0 11 525034.4753566237 21 177479.6120728989 31 0.0 0 LINE 5 1F1F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525365.9243027826 20 177182.5302754163 30 0.0 11 525411.5114769163 21 177295.0881497791 31 0.0 0 LINE 5 1F20 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525496.7343028748 20 177238.8647516793 30 0.0 11 525408.3646492504 21 177156.5328909903 31 0.0 0 LINE 5 1F21 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525414.5782816872 20 177159.1339270254 30 0.0 11 525364.7726014158 21 177184.3730852137 31 0.0 0 LINE 5 1F22 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525732.9053498066 20 177045.4265655241 30 0.0 11 525260.9020174507 21 177351.580812123 31 0.0 0 LINE 5 1F23 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525248.0541525605 20 177349.139064215 30 0.0 11 525261.427705907 21 177369.4097978704 31 0.0 0 LINE 5 1F24 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525062.2084332978 20 177308.9561909968 30 0.0 11 525000.2989745414 21 177355.4359634337 31 0.0 0 LINE 5 1F25 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525067.0596830563 20 177294.1984451826 30 0.0 11 525057.755215065 21 177316.3924377936 31 0.0 0 LINE 5 1F26 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525036.0853893436 20 177238.0819323134 30 0.0 11 525068.971298339 21 177301.9597794967 31 0.0 0 LINE 5 1F27 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525288.7242658106 20 177284.0704269092 30 0.0 11 525457.0581157747 21 177596.6685127321 31 0.0 0 LINE 5 1F28 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525655.024894655 20 177338.9991638207 30 0.0 11 525561.2756183285 21 177520.2109778318 31 0.0 0 LINE 5 1F29 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525591.9243254799 20 177525.5022615888 30 0.0 11 525326.1365995015 21 177305.5291621807 31 0.0 0 LINE 5 1F2A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525434.0971953899 20 177235.7982300982 30 0.0 11 525453.1666549999 21 177265.7707081433 31 0.0 0 LINE 5 1F2B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525386.8942634725 20 177439.76076397 30 0.0 11 525312.8981462424 21 177496.6502606758 31 0.0 0 LINE 5 1F2C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525343.0942547557 20 177478.6577308449 30 0.0 11 525259.9199195926 21 177484.540945283 31 0.0 0 LINE 5 1F2D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525337.8818350173 20 177466.6119144748 30 0.0 11 525302.304562546 21 177538.43395358 31 0.0 0 LINE 5 1F2E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525377.8945772925 20 177624.8637513252 30 0.0 11 525299.7023977896 21 177526.0809511351 31 0.0 0 LINE 5 1F2F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525802.7306519567 20 177207.7311645296 30 0.0 11 525610.9652990102 21 177397.138571804 31 0.0 0 LINE 5 1F30 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525201.8959860041 20 177089.0238363769 30 0.0 11 525214.0563583964 21 177134.4356771372 31 0.0 0 LINE 5 1F31 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525271.5446155183 20 177106.7331340595 30 0.0 11 525212.2169820442 21 177133.9549920855 31 0.0 0 LINE 5 1F32 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525275.750859958 20 177057.3583119888 30 0.0 11 525329.6893125192 21 177146.6532523234 31 0.0 0 LINE 5 1F33 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525447.4939412511 20 177052.1289138494 30 0.0 11 525211.0025660272 21 177234.4214281987 31 0.0 0 LINE 5 1F34 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525114.6027958332 20 177214.0046942522 30 0.0 11 525141.5385607578 21 177277.3610539983 31 0.0 0 LINE 5 1F35 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525170.4463819585 20 177264.0086837144 30 0.0 11 525115.2037573895 21 177287.6904148024 31 0.0 0 LINE 5 1F36 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525162.8792675344 20 177259.909520559 30 0.0 11 525191.7128857292 21 177325.1559639791 31 0.0 0 LINE 5 1F37 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525193.314168332 20 177321.8010823494 30 0.0 11 525142.2886105311 21 177345.2101029576 31 0.0 0 LINE 5 1F38 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525116.9112135452 20 177278.8177354919 30 0.0 11 525147.4475604918 21 177350.047078558 31 0.0 0 LINE 5 1F39 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525662.4759388884 20 177173.6908112729 30 0.0 11 525568.2154872015 21 177235.4932205403 31 0.0 0 LINE 5 1F3A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525093.9653281217 20 176926.3491313284 30 0.0 11 524840.532076894 21 177002.4105337027 31 0.0 0 LINE 5 1F3B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524637.4032810166 20 176359.3587226847 30 0.0 11 525300.6708435408 21 178206.4147988111 31 0.0 0 LINE 5 1F3C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525319.0788219256 20 177608.8730437454 30 0.0 11 525328.8875517543 21 177835.970585752 31 0.0 0 LINE 5 1F3D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525482.4051818097 20 177518.1077287009 30 0.0 11 525556.5310875172 21 177670.8763371959 31 0.0 0 LINE 5 1F3E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525900.4939529543 20 177335.7991895602 30 0.0 11 525192.5947924674 21 177689.029228539 31 0.0 0 LINE 5 1F3F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525457.2314948729 20 177633.4987321044 30 0.0 11 525565.8126626467 21 178059.0500187968 31 0.0 0 LINE 5 1F40 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525393.3133794839 20 177660.7769569792 30 0.0 11 525574.3576694129 21 177591.260892679 31 0.0 0 LINE 5 1F41 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525420.3612685173 20 177728.1624888528 30 0.0 11 525480.204479206 21 177704.6160276196 31 0.0 0 LINE 5 1F42 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525382.2463826507 20 177689.3743398424 30 0.0 11 525435.4861634504 21 177732.9952208904 31 0.0 0 LINE 5 1F43 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525425.7210150123 20 177715.0312112448 30 0.0 11 525501.0725929005 21 178111.1615401282 31 0.0 0 LINE 5 1F44 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525258.1774284148 20 177841.2839282224 30 0.0 11 525666.3009968047 21 177792.387080208 31 0.0 0 LINE 5 1F45 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525661.543062447 20 177779.9508807949 30 0.0 11 525704.4062784762 21 178014.8945259626 31 0.0 0 LINE 5 1F46 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525808.5830059624 20 177658.7689688832 30 0.0 11 525653.6416162046 21 177796.2464130009 31 0.0 0 LINE 5 1F47 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525727.0158142383 20 177627.9667339593 30 0.0 11 525766.767963913 21 177703.5384638431 31 0.0 0 LINE 5 1F48 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524991.8246753834 20 178155.4541019633 30 0.0 11 525706.2586647039 21 178012.4054534317 31 0.0 0 LINE 5 1F49 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525540.0503052236 20 177629.4383357195 30 0.0 11 525636.7593045289 21 178042.3337169034 31 0.0 0 LINE 5 1F4A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526040.0100858348 20 177785.8371415856 30 0.0 11 525629.8050172541 21 178041.7941207417 31 0.0 0 LINE 5 1F4B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526231.7046598897 20 177687.0172746743 30 0.0 11 525794.7224773271 21 177933.5215620383 31 0.0 0 LINE 5 1F4C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526011.024494235 20 177697.9023401254 30 0.0 11 526017.7060938436 21 177815.1409172062 31 0.0 0 LINE 5 1F4D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525958.1752044581 20 177730.490101728 30 0.0 11 526045.7879111788 21 177796.7442676439 31 0.0 0 LINE 5 1F4E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525790.155749319 20 177819.2185726607 30 0.0 11 525976.5296098422 21 177741.2954344097 31 0.0 0 LINE 5 1F4F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525781.8531474059 20 177602.3947434703 30 0.0 11 525881.1030283052 21 177886.4317078795 31 0.0 0 LINE 5 1F50 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525835.0618820717 20 177528.3189671136 30 0.0 11 525735.2379582577 21 177597.4756714956 31 0.0 0 LINE 5 1F51 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525694.774242326 20 177503.738335011 30 0.0 11 525813.8142166504 21 177483.3124818092 31 0.0 0 LINE 5 1F52 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525807.1914493779 20 177482.082209412 30 0.0 11 525835.0150963279 21 177530.4915635056 31 0.0 0 LINE 5 1F53 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525603.2665140946 20 177212.4971446795 30 0.0 11 525603.2715310418 21 177212.5085230352 31 0.0 0 LINE 5 1F54 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525662.315648034 20 177346.4196263749 30 0.0 11 525830.2436531786 21 177727.2776287684 31 0.0 0 LINE 5 1F55 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525825.7845710629 20 177739.5717880226 30 0.0 11 525847.9283594355 21 177729.6014716514 31 0.0 0 LINE 5 1F56 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525756.4829586113 20 177916.6327413126 30 0.0 11 525778.9367416901 21 177956.0023336231 31 0.0 0 LINE 5 1F57 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525742.68754455 20 177909.4904562009 30 0.0 11 525763.1140086971 21 177922.214684864 31 0.0 0 LINE 5 1F58 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525682.3501668144 20 177931.1207760227 30 0.0 11 525750.6543864948 21 177908.8408311148 31 0.0 0 LINE 5 1F59 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525768.0331965474 20 177689.0468989655 30 0.0 11 526096.0043194264 21 177563.2507667763 31 0.0 0 LINE 5 1F5A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526033.2038644383 20 177485.3545500873 30 0.0 11 525795.1827360411 21 177655.5347737426 31 0.0 0 LINE 5 1F5B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525743.5580844673 20 177537.8369041633 30 0.0 11 525776.1876994059 21 177523.7904825929 31 0.0 0 LINE 5 1F5C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525937.38473207 20 177616.9574620742 30 0.0 11 525981.7478251474 21 177699.0778381885 31 0.0 0 LINE 5 1F5D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525968.8002129287 20 177666.3991687407 30 0.0 11 525961.3461323477 21 177749.4474614664 31 0.0 0 LINE 5 1F5E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525956.0773950968 20 177669.6242141621 30 0.0 11 526021.3078160592 21 177716.1982390985 31 0.0 0 LINE 5 1F5F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526166.4165668602 20 177633.1593019857 30 0.0 11 526008.6979435723 21 177716.7974441392 31 0.0 0 LINE 5 1F60 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525561.6373423731 20 177743.6644239177 30 0.0 11 525608.4071486459 21 177738.9004802636 31 0.0 0 LINE 5 1F61 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525590.2254440928 20 177677.7305839139 30 0.0 11 525607.6393274828 21 177740.6396795464 31 0.0 0 LINE 5 1F62 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525542.1529911521 20 177665.7054096925 30 0.0 11 525638.9059212225 21 177626.6949808709 31 0.0 0 LINE 5 1F63 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525564.3746808246 20 177495.325748098 30 0.0 11 525706.6267833462 21 177757.8577855168 31 0.0 0 LINE 5 1F64 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525671.1004532344 20 177849.7688217813 30 0.0 11 525737.9411154572 21 177833.2797458222 31 0.0 0 LINE 5 1F65 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525729.3688821658 20 177802.6127483302 30 0.0 11 525743.9392788691 21 177860.9246295939 31 0.0 0 LINE 5 1F66 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525724.1155973437 20 177809.4294453208 30 0.0 11 525793.1247719047 21 177791.3681678577 31 0.0 0 LINE 5 1F67 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525790.068134001 20 177789.2524406895 30 0.0 11 525805.0417143705 21 177843.3577240329 31 0.0 0 LINE 5 1F68 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525735.4523658776 20 177857.8242824288 30 0.0 11 525810.6393939268 21 177839.0360251497 31 0.0 0 LINE 5 1F69 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525383.8344721295 20 177824.2759981915 30 0.0 11 525418.5132004842 21 178086.5947652645 31 0.0 0 LINE 5 1F6A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526308.1239966137 20 176753.3706925865 30 0.0 11 526351.46407407 21 176011.5104619067 31 0.0 0 LINE 5 1F6B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526940.0214358629 20 176429.6370203297 30 0.0 11 524680.4828571335 21 176882.2243582025 31 0.0 0 LINE 5 1F6C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526192.3355979434 20 176582.9287149022 30 0.0 11 526186.5959414836 21 176435.1966904509 31 0.0 0 LINE 5 1F6D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526326.328497571 20 176487.2839683498 30 0.0 11 525842.057304739 21 176587.1139166937 31 0.0 0 LINE 5 1F6E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526197.0368922976 20 176466.1281759423 30 0.0 11 526150.9002913538 21 176398.3600985904 31 0.0 0 LINE 5 1F6F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526258.5121904945 20 176415.3728478937 30 0.0 11 526185.2305518461 21 176463.8210668214 31 0.0 0 LINE 5 1F70 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526249.168325507 20 176431.9382364462 30 0.0 11 526259.1409477169 21 176233.3059138232 31 0.0 0 LINE 5 1F71 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526370.497744524 20 176414.3309524263 30 0.0 11 525946.6235430839 21 176326.0706404363 31 0.0 0 LINE 5 1F72 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526203.9097136959 20 176223.6264067887 30 0.0 11 526151.1830329954 21 176402.6787340636 31 0.0 0 LINE 5 1F73 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526262.9772598672 20 176237.2145935001 30 0.0 11 526203.1934871118 21 176224.0798610557 31 0.0 0 LINE 5 1F74 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526292.0988566732 20 175941.234719471 30 0.0 11 526223.1314125833 21 176230.353134325 31 0.0 0 LINE 5 1F75 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526279.8066610718 20 176008.5442244475 30 0.0 11 526168.2315331545 21 175989.8682466451 31 0.0 0 LINE 5 1F76 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526187.6571765576 20 175910.7515640599 30 0.0 11 526013.7881416039 21 176701.736132844 31 0.0 0 LINE 5 1F77 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526007.0981989844 20 176413.2503998727 30 0.0 11 525567.9153355425 21 176411.7738974628 31 0.0 0 LINE 5 1F78 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525996.2386453274 20 176481.8922028909 30 0.0 11 526019.4839204014 21 176289.358633614 31 0.0 0 LINE 5 1F79 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525924.2904011676 20 176472.1019848462 30 0.0 11 525932.5251302081 21 176408.3224039468 31 0.0 0 LINE 5 1F7A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525971.2054875981 20 176499.6017974548 30 0.0 11 525915.9136219851 21 176458.6132000153 31 0.0 0 LINE 5 1F7B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525935.717234424 20 176463.7005078429 30 0.0 11 525533.1734404422 21 176487.2715001471 31 0.0 0 LINE 5 1F7C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525852.8175313351 20 176653.4038932794 30 0.0 11 525802.0036205032 21 176249.2632733093 31 0.0 0 LINE 5 1F7D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525815.2248326041 20 176250.843319441 30 0.0 11 525576.923260623 21 176266.5955410115 31 0.0 0 LINE 5 1F7E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525896.8708853521 20 176078.6814106625 30 0.0 11 525801.3494721967 21 176262.481686859 31 0.0 0 LINE 5 1F7F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525946.6426193002 20 176150.2688323363 30 0.0 11 525863.6560382271 21 176130.1554755012 31 0.0 0 LINE 5 1F80 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525669.6796913576 20 176692.4104188136 30 0.0 11 525663.1602053267 21 176602.5238942365 31 0.0 0 LINE 5 1F81 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525601.9899951039 20 176735.8000854975 30 0.0 11 525578.8851832505 21 176264.1918612483 31 0.0 0 LINE 5 1F82 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525990.8302451481 20 176331.9435991444 30 0.0 11 525566.8173502574 21 176338.8927944822 31 0.0 0 LINE 5 1F83 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525653.4333764499 20 176004.2532276039 30 0.0 11 525569.0373073484 21 176345.5052876603 31 0.0 0 LINE 5 1F84 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525776.1972912831 20 175638.8756795467 30 0.0 11 525712.6787874618 21 175870.9585620065 31 0.0 0 LINE 5 1F85 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526379.7490696148 20 176168.9147862752 30 0.0 11 525825.147800122 21 176074.3896555292 31 0.0 0 LINE 5 1F86 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525814.3130500861 20 176081.7134494056 30 0.0 11 525818.5795679024 21 176057.8063082598 31 0.0 0 LINE 5 1F87 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525659.5103779263 20 176192.1191891137 30 0.0 11 525599.027879986 21 176176.7137827821 31 0.0 0 LINE 5 1F88 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525669.8025604574 20 176203.7551963534 30 0.0 11 525652.4793060129 21 176187.050368067 31 0.0 0 LINE 5 1F89 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525663.5466343454 20 176267.5465223788 30 0.0 11 525668.4888511959 21 176195.8706068711 31 0.0 0 LINE 5 1F8A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526163.1087802012 20 175749.3538325748 30 0.0 11 525979.5087794271 21 175614.8763002626 31 0.0 0 LINE 5 1F8B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526192.1149468061 20 175930.0766157012 30 0.0 11 526158.0071352461 21 175717.5680579371 31 0.0 0 LINE 5 1F8C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526405.4054263194 20 175862.7358636809 30 0.0 11 526348.661430612 21 176029.9976445105 31 0.0 0 LINE 5 1F8D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526379.4495038881 20 175974.3550077079 30 0.0 11 526128.6542323571 21 175894.1019516912 31 0.0 0 LINE 5 1F8E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525874.789192354 20 176338.8771021823 30 0.0 11 525867.9985523191 21 176292.3583194611 31 0.0 0 LINE 5 1F8F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525931.7558665713 20 176295.0667284537 30 0.0 11 525866.4992371829 21 176293.5272581273 31 0.0 0 LINE 5 1F90 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525955.1460984748 20 176338.7526826987 30 0.0 11 525969.3724818535 21 176235.4059215012 31 0.0 0 LINE 5 1F91 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526114.955662 20 176275.6342544645 30 0.0 11 525825.6510484453 21 176201.7318057975 31 0.0 0 LINE 5 1F92 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525745.1849126536 20 176258.6085120067 30 0.0 11 525744.8683208652 21 176189.7647503285 31 0.0 0 LINE 5 1F93 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525776.7000182735 20 176190.5959896947 30 0.0 11 525716.5954207258 21 176190.6924791494 31 0.0 0 LINE 5 1F94 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525771.3709760044 20 176197.3536274314 30 0.0 11 525772.0500154658 21 176126.0233055297 31 0.0 0 LINE 5 1F95 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525774.8475497621 20 176128.4713942915 30 0.0 11 525718.7240675965 21 176127.1505822807 31 0.0 0 LINE 5 1F96 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525721.6726684595 20 176198.1665275917 30 0.0 11 525721.5494828701 21 176120.6676719627 31 0.0 0 LINE 5 1F97 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525479.1614602226 20 176747.2399923062 30 0.0 11 525490.653625448 21 176518.3417724971 31 0.0 0 LINE 5 1F98 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525499.4599018504 20 176682.7764694169 30 0.0 11 525178.2253902241 21 176612.9265973124 31 0.0 0 LINE 5 1F99 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525435.5115608358 20 176510.4823636649 30 0.0 11 525382.7848801356 21 176689.5346909398 31 0.0 0 LINE 5 1F9A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525494.5791070076 20 176524.0705503761 30 0.0 11 525434.795334252 21 176510.9358179317 31 0.0 0 LINE 5 1F9B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525523.7007038133 20 176228.090676347 30 0.0 11 525454.7332597232 21 176517.2090912012 31 0.0 0 LINE 5 1F9C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525399.3618533586 20 176301.078169511 30 0.0 11 525257.049278716 21 176935.550336463 31 0.0 0 LINE 5 1F9D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525238.7000461245 20 176700.1063567486 30 0.0 11 524973.2827348328 21 176699.2140421064 31 0.0 0 LINE 5 1F9E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525227.8404924674 20 176768.7481597669 30 0.0 11 525251.0857675414 21 176576.2145904901 31 0.0 0 LINE 5 1F9F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525155.8922483074 20 176758.9579417224 30 0.0 11 525164.1269773482 21 176695.1783608227 31 0.0 0 LINE 5 1FA0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525202.8073347379 20 176786.4577543309 30 0.0 11 525147.5154691249 21 176745.4691568915 31 0.0 0 LINE 5 1FA1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525167.3190815642 20 176750.5564647189 30 0.0 11 524764.7752875822 21 176774.127457023 31 0.0 0 LINE 5 1FA2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525070.8034445501 20 176831.0715042767 30 0.0 11 525033.6054676431 21 176536.1192301853 31 0.0 0 LINE 5 1FA3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525046.8266797438 20 176537.6992763171 30 0.0 11 524808.5251077629 21 176553.4514978876 31 0.0 0 LINE 5 1FA4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525112.755593354 20 176395.779953145 30 0.0 11 525032.9513193365 21 176549.3376437352 31 0.0 0 LINE 5 1FA5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525379.5573529772 20 176498.9294258487 30 0.0 11 525095.257885367 21 176417.0114323773 31 0.0 0 LINE 5 1FA6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525222.4320922882 20 176618.7995560205 30 0.0 11 524798.4191973975 21 176625.7487513584 31 0.0 0 LINE 5 1FA7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524956.8013278007 20 176113.092283917 30 0.0 11 524976.4701680052 21 176476.6207072047 31 0.0 0 LINE 5 1FA8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525041.1314063764 20 176178.7608441982 30 0.0 11 524925.8054389438 21 176200.8843377061 31 0.0 0 LINE 5 1FA9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525022.4222532825 20 176237.9636923282 30 0.0 11 524936.7949349053 21 176169.1627967839 31 0.0 0 LINE 5 1FAA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525611.3509167548 20 176455.7707431512 30 0.0 11 525296.3009969729 21 176407.3107920077 31 0.0 0 LINE 5 1FAB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525320.8538129465 20 176417.4479063852 30 0.0 11 525139.9857252317 21 176058.562690482 31 0.0 0 LINE 5 1FAC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525209.4191285801 20 176148.0617544851 30 0.0 11 525059.6401223514 21 176221.5272619363 31 0.0 0 LINE 5 1FAD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525081.9842410516 20 176212.0232199121 30 0.0 11 525003.2641276836 21 176239.513690866 31 0.0 0 LINE 5 1FAE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525081.9606900939 20 176225.1484039835 30 0.0 11 525020.8795128013 21 176173.2519937195 31 0.0 0 LINE 5 1FAF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525056.1253922576 20 176063.9739618511 30 0.0 11 525023.3748981102 21 176185.6270081834 31 0.0 0 LINE 5 1FB0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525611.2948584211 20 176279.0835830742 30 0.0 11 525472.2889781802 21 176224.7491658278 31 0.0 0 LINE 5 1FB1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525106.3910394939 20 176625.7330590585 30 0.0 11 525099.6003994591 21 176579.2142763372 31 0.0 0 LINE 5 1FB2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525163.3577137114 20 176581.9226853298 30 0.0 11 525098.1010843228 21 176580.3832150034 31 0.0 0 LINE 5 1FB3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525186.747945615 20 176625.6086395747 30 0.0 11 525200.9743289936 21 176522.2618783774 31 0.0 0 LINE 5 1FB4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525346.55750914 20 176562.4902113408 30 0.0 11 525057.2528955853 21 176488.5877626738 31 0.0 0 LINE 5 1FB5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524976.7867597936 20 176545.4644688829 30 0.0 11 524976.4701680052 21 176476.6207072047 31 0.0 0 LINE 5 1FB6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525124.8475752318 20 176409.0964892458 30 0.0 11 524948.1972678658 21 176477.5484360255 31 0.0 0 LINE 5 1FB7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525495.9370425737 20 176365.8171089485 30 0.0 11 525384.9195298884 21 176346.3316676994 31 0.0 0 LINE 5 1FB8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524968.6361060145 20 176158.0067721589 30 0.0 11 524759.3034177146 21 175622.5419037983 31 0.0 0 LINE 5 1FB9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525008.428749703 20 176101.9216376339 30 0.0 11 524927.6245599849 21 175889.4594346649 31 0.0 0 LINE 5 1FBA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525194.3357915465 20 176120.6943316627 30 0.0 11 525202.001045836 21 175951.0649075782 31 0.0 0 LINE 5 1FBB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525333.8731606127 20 176105.4721252761 30 0.0 11 524371.1220574266 21 176050.7676381506 31 0.0 0 LINE 5 1FBC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525125.5792390395 20 176024.6665509538 30 0.0 11 525057.0097835689 21 175590.8670611235 31 0.0 0 LINE 5 1FBD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525056.084082703 20 176024.8907673184 30 0.0 11 525249.860849121 21 176017.1394507645 31 0.0 0 LINE 5 1FBE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525054.2770043241 20 175952.3019756577 30 0.0 11 525118.5536201788 21 175950.261790285 31 0.0 0 LINE 5 1FBF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525034.6095598894 20 176003.0016468368 30 0.0 11 525066.257551652 21 175941.8815998767 31 0.0 0 LINE 5 1FC0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525064.3929867726 20 175962.2430134911 30 0.0 11 524976.9385344599 21 175568.6076282395 31 0.0 0 LINE 5 1FC1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524863.8983838503 20 175910.6518377226 30 0.0 11 525254.7663220056 21 175796.0483946414 31 0.0 0 LINE 5 1FC2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525255.3145936151 20 175809.3523937935 30 0.0 11 525201.7670636297 21 175576.6112635104 31 0.0 0 LINE 5 1FC3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525438.2922485863 20 175862.5029210243 30 0.0 11 525241.6127186602 21 175797.5102721375 31 0.0 0 LINE 5 1FC4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525375.5567296231 20 175923.0523975084 30 0.0 11 525382.1806715409 21 175837.9204813144 31 0.0 0 LINE 5 1FC5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524742.5622633709 20 175676.171281405 30 0.0 11 525204.4528169983 21 175578.1648225352 31 0.0 0 LINE 5 1FC6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525203.2519185999 20 175995.6424744553 30 0.0 11 525128.7833911182 21 175578.1623374859 31 0.0 0 LINE 5 1FC7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525600.5985110734 20 175654.2686996066 30 0.0 11 525122.6094655095 21 175581.4082453863 31 0.0 0 LINE 5 1FC8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525801.8496525614 20 175652.8800890392 30 0.0 11 525316.9017097373 21 175615.6316209963 31 0.0 0 LINE 5 1FC9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525608.7527508469 20 175746.4977742084 30 0.0 11 525568.5237424624 21 175636.1748182397 31 0.0 0 LINE 5 1FCA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525547.3241824866 20 175737.4677894125 30 0.0 11 525601.5917047545 21 175641.9657637425 31 0.0 0 LINE 5 1FCB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525357.9121957003 20 175722.4219221779 30 0.0 11 525559.9088859833 21 175720.2845228642 31 0.0 0 LINE 5 1FCC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525436.036643558 20 175924.8523466458 30 0.0 11 525414.8631771929 21 175624.7203418022 31 0.0 0 LINE 5 1FCD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525539.1274344841 20 175929.9645081115 30 0.0 11 525735.4989487451 21 176140.9866987503 31 0.0 0 LINE 5 1FCE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525426.207520169 20 176353.5908584147 30 0.0 11 525426.2076281533 21 176353.5784235813 31 0.0 0 LINE 5 1FCF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525440.321241981 20 176047.8798081949 30 0.0 11 525431.0929545699 21 175791.013129566 31 0.0 0 LINE 5 1FD0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525422.1352744367 20 175781.4847649781 30 0.0 11 525446.4168434282 21 175781.8847391607 31 0.0 0 LINE 5 1FD1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525288.4589785783 20 175646.266635299 30 0.0 11 525293.5121681359 21 175601.2266258793 31 0.0 0 LINE 5 1FD2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525278.6129131255 20 175658.2824865316 30 0.0 11 525292.341856174 21 175638.5173010937 31 0.0 0 LINE 5 1FD3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525214.6402196538 20 175662.2780312479 30 0.0 11 525286.1871600408 21 175655.7283982416 31 0.0 0 LINE 5 1FD4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525389.0739232269 20 175850.7302177447 30 0.0 11 525740.0568714903 21 175836.5635545971 31 0.0 0 LINE 5 1FD5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525619.2862598824 20 175914.8895411783 30 0.0 11 525427.2635288181 21 175870.7730233485 31 0.0 0 LINE 5 1FD6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525154.18579619 20 176177.1716581862 30 0.0 11 525755.0764899278 21 175817.2858196714 31 0.0 0 LINE 5 1FD7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525573.128933022 20 175849.9667621131 30 0.0 11 525581.3980240038 21 175756.9965392731 31 0.0 0 LINE 5 1FD8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525582.429850939 20 175792.1315849146 30 0.0 11 525542.7392790357 21 175718.8019132671 31 0.0 0 LINE 5 1FD9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525569.4688321452 20 175794.2011267442 30 0.0 11 525610.9619874878 21 175725.626600297 31 0.0 0 LINE 5 1FDA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525777.0809907501 20 175744.5075799035 30 0.0 11 525599.1431815309 21 175730.0632382783 31 0.0 0 LINE 5 1FDB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525177.9045442866 20 175882.1915599004 30 0.0 11 525222.7454192442 21 175868.0704455326 31 0.0 0 LINE 5 1FDC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525230.2376718728 20 175931.443915932 30 0.0 11 525221.352372083 21 175866.7766978408 31 0.0 0 LINE 5 1FDD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525278.6324720035 20 176109.2014176325 30 0.0 11 525305.4602313113 21 175811.8144598258 31 0.0 0 LINE 5 1FDE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525236.4809838362 20 175741.4466963524 30 0.0 11 525401.5150701644 21 175717.8045106914 31 0.0 0 LINE 5 1FDF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524982.7168481601 20 175878.4700206413 30 0.0 11 524910.8256864786 21 175623.8224001321 31 0.0 0 LINE 5 1FE0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526075.4906367242 20 176105.1506865437 30 0.0 11 526037.1321662943 21 176267.0143930995 31 0.0 0 LINE 5 1FE1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526122.7396103357 20 176017.616273911 30 0.0 11 526276.4577789378 21 176119.7037581224 31 0.0 0 LINE 5 1FE2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525215.8445735419 20 175920.96562573 30 0.0 11 525332.5259441775 21 175910.2114930633 31 0.0 0 LINE 5 1FE3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525852.3074904985 20 176649.3473619765 30 0.0 11 525757.9889398609 21 176823.6121122912 31 0.0 0 LINE 5 1FE4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524542.8023875946 20 179000.7833106453 30 0.0 11 524431.8915657004 21 179098.5405829653 31 0.0 0 LINE 5 1FE5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524565.994524599 20 179163.7684003769 30 0.0 11 524304.1937811976 21 178744.3104435472 31 0.0 0 LINE 5 1FE6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524461.4872296996 20 179084.7613623397 30 0.0 11 524380.5989865734 21 179098.1101592356 31 0.0 0 LINE 5 1FE7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524467.151219915 20 179164.2801326305 30 0.0 11 524451.672415497 21 179077.8056560839 31 0.0 0 LINE 5 1FE8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524472.6979763602 20 179146.0880078581 30 0.0 11 524335.776701389 21 179290.3336914834 31 0.0 0 LINE 5 1FE9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524543.6498567635 20 179246.07138166 30 0.0 11 524187.3449274755 21 179000.0916697241 31 0.0 0 LINE 5 1FEA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524290.6680611737 20 179257.0261451039 30 0.0 11 524383.920532796 21 179095.3356528147 31 0.0 0 LINE 5 1FEB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524341.2528787772 20 179290.414617019 30 0.0 11 524290.5022547393 21 179256.1948151342 31 0.0 0 LINE 5 1FEC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524147.066225208 20 179515.6782332696 30 0.0 11 524308.7979445157 21 179266.3013756385 31 0.0 0 LINE 5 1FED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524187.3155401592 20 179460.3459625875 30 0.0 11 524096.8251819277 21 179392.4541634975 31 0.0 0 LINE 5 1FEE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524052.9489909405 20 179461.095877851 30 0.0 11 524510.5819551447 21 178785.2280688973 31 0.0 0 LINE 5 1FEF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524292.1774219008 20 178983.7318844501 30 0.0 11 523988.1394265688 21 178666.8018211947 31 0.0 0 LINE 5 1FF0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524334.3795647158 20 178928.5176999585 30 0.0 11 524211.0296152242 21 179078.1649788252 31 0.0 0 LINE 5 1FF1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524277.6585918697 20 178883.1841643977 30 0.0 11 524237.1657510626 21 178933.1439036428 31 0.0 0 LINE 5 1FF2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524329.9314599481 20 178898.1779061311 30 0.0 11 524262.1146210516 21 178886.4249539442 31 0.0 0 LINE 5 1FF3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524279.4590697602 20 178897.252412813 30 0.0 11 524018.8296930751 21 178589.5684422194 31 0.0 0 LINE 5 1FF4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524359.6076526764 20 178706.370407703 30 0.0 11 524031.9742005421 21 178948.3787036076 31 0.0 0 LINE 5 1FF5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524042.2386991308 20 178956.8602756267 30 0.0 11 523889.2509233729 21 178773.4740379708 31 0.0 0 LINE 5 1FF6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523973.9245285336 20 179134.7337555477 30 0.0 11 524041.0924745702 21 178938.7864439398 31 0.0 0 LINE 5 1FF7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524060.085491399 20 179121.3818672867 30 0.0 11 523988.2762647926 21 179075.1784611826 31 0.0 0 LINE 5 1FF8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524411.2137166957 20 178359.7278200375 30 0.0 11 524241.9561798962 21 178663.3477312312 31 0.0 0 LINE 5 1FF9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524246.2261103226 20 178467.9417783873 30 0.0 11 523888.8641942761 21 178776.5525534257 31 0.0 0 LINE 5 1FFA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524222.0925554075 20 179028.0438879628 30 0.0 11 523934.6193464978 21 178716.2837549942 31 0.0 0 LINE 5 1FFB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523709.9291016019 20 179138.0846317387 30 0.0 11 523940.9379251233 21 178713.3292940167 31 0.0 0 LINE 5 1FFC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523572.2786335773 20 179350.7702628629 30 0.0 11 523850.7072225497 21 178888.7691296246 31 0.0 0 LINE 5 1FFD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523778.4545626078 20 179200.3498308638 30 0.0 11 523714.913678927 21 179101.5971912518 31 0.0 0 LINE 5 1FFE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523808.4083026672 20 179145.9643264288 30 0.0 11 523699.5297843255 21 179131.4361082373 31 0.0 0 LINE 5 1FFF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523910.9619477837 20 178986.0079925976 30 0.0 11 523787.1126615274 21 179145.596794382 31 0.0 0 LINE 5 2000 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524051.1410301031 20 179192.6683432578 30 0.0 11 523798.708901256 21 178972.2869632569 31 0.0 0 LINE 5 2001 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524116.3413454738 20 179125.5451513231 30 0.0 11 524026.6216614344 21 179207.3855070313 31 0.0 0 LINE 5 2002 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524108.9428978228 20 179267.7776803463 30 0.0 11 524155.4598415749 21 179156.3151085556 31 0.0 0 LINE 5 2003 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524155.178662528 20 179163.0453057934 30 0.0 11 524114.213259897 21 179125.1051334082 31 0.0 0 LINE 5 2004 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524372.3616001382 20 179422.0685826785 30 0.0 11 523921.3395205944 21 179085.7701256054 31 0.0 0 LINE 5 2005 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523919.1672955888 20 179072.8739554913 30 0.0 11 523904.8028469463 21 179092.4549970173 31 0.0 0 LINE 5 2006 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523892.3058896266 20 178884.6406971708 30 0.0 11 523853.3778947085 21 178861.4297431853 31 0.0 0 LINE 5 2007 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523907.8298685278 20 178884.0647068877 30 0.0 11 523883.7859259912 21 178883.0472296616 31 0.0 0 LINE 5 2008 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523949.6962839617 20 178835.529429549 30 0.0 11 523901.2155219774 21 178888.5528025903 31 0.0 0 LINE 5 2009 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523994.310310179 20 179088.4146450171 30 0.0 11 523713.3118281377 21 179419.6202277009 31 0.0 0 LINE 5 200A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523744.3416693581 20 179412.851322139 30 0.0 11 523616.2737920614 21 179257.5679325866 31 0.0 0 LINE 5 200B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524070.0146388352 20 179450.9917698515 30 0.0 11 523711.0573757446 21 179398.7017312847 31 0.0 0 LINE 5 200C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523817.9209068757 20 179488.7456151748 30 0.0 11 523987.1803352345 21 179130.9507883419 31 0.0 0 LINE 5 200D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524090.0650417751 20 179207.9743582003 30 0.0 11 524068.5808773766 21 179236.2661310338 31 0.0 0 LINE 5 200E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523882.4046020887 20 179234.5445255751 30 0.0 11 523803.3576987031 21 179184.9116003569 31 0.0 0 LINE 5 200F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523830.7172395122 20 179206.9794871106 30 0.0 11 523796.3142523012 21 179131.0254436837 31 0.0 0 LINE 5 2010 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523840.2030354173 20 179197.9080656343 30 0.0 11 523760.4956905026 21 179189.4886366538 31 0.0 0 LINE 5 2011 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523675.0817546599 20 179333.2122401419 30 0.0 11 523771.1760785405 21 179182.7583140627 31 0.0 0 LINE 5 2012 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524168.4008082703 20 179651.8593062971 30 0.0 11 524250.3461214321 21 179495.3941343705 31 0.0 0 LINE 5 2013 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524231.3024235346 20 179556.068231453 30 0.0 11 524000.1924044534 21 179429.8660908105 31 0.0 0 LINE 5 2014 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524147.0615027255 20 178939.2523313183 30 0.0 11 524108.6994938733 21 178966.4270661795 31 0.0 0 LINE 5 2015 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524154.6430655738 20 179010.7161034157 30 0.0 11 524108.5114544834 21 178964.5352404283 31 0.0 0 LINE 5 2016 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524202.4054162988 20 178997.5129447023 30 0.0 11 524137.4010440239 21 179079.1056810162 31 0.0 0 LINE 5 2017 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524266.9546972896 20 179156.7499469993 30 0.0 11 524013.8766698282 21 178998.287827364 31 0.0 0 LINE 5 2018 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523999.5435054869 20 178900.7977298236 30 0.0 11 523949.4853209126 21 178948.0602086997 31 0.0 0 LINE 5 2019 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523972.0461085181 20 178970.5314966329 30 0.0 11 523930.6529734734 21 178926.9519104971 31 0.0 0 LINE 5 201A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523973.2621091063 20 178962.0117723504 30 0.0 11 523922.0906002993 21 179011.7103900734 31 0.0 0 LINE 5 201B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523925.7927776032 20 179012.0468717714 30 0.0 11 523886.1199414426 21 178972.3271554368 31 0.0 0 LINE 5 201C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523939.5663733144 20 178925.4716578331 30 0.0 11 523883.3757110357 21 178978.8448465255 31 0.0 0 LINE 5 201D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524227.6212786628 20 179400.568396655 30 0.0 11 524136.9295746451 21 179333.6386919953 31 0.0 0 LINE 5 201E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524262.1270243825 20 178781.5437002942 30 0.0 11 524102.784066827 21 178570.3007793799 31 0.0 0 LINE 5 201F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524188.0053421091 20 178194.2972296616 30 0.0 11 523870.9828607271 21 177694.6733340894 31 0.0 0 LINE 5 2020 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524318.3542007789 20 178215.8393498417 30 0.0 11 524109.4850426079 21 178344.368125777 31 0.0 0 LINE 5 2021 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524662.8767133136 20 179120.3209471774 30 0.0 11 523981.7872581052 21 177990.1379863591 31 0.0 0 LINE 5 2022 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524139.0807066072 20 178330.5889051513 30 0.0 11 524058.192463481 21 178343.9377020474 31 0.0 0 LINE 5 2023 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524144.7446968224 20 178410.1076754422 30 0.0 11 524129.2658924044 21 178323.6331988957 31 0.0 0 LINE 5 2024 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524148.9122708286 20 178393.1065857026 30 0.0 11 524011.9909958576 21 178537.3522693281 31 0.0 0 LINE 5 2025 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524291.2842484481 20 178540.2525750229 30 0.0 11 523864.9384043831 21 178245.9192125361 31 0.0 0 LINE 5 2026 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523968.2615380813 20 178502.8536879156 30 0.0 11 524061.5140097036 21 178341.1631956266 31 0.0 0 LINE 5 2027 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524018.8463556848 20 178536.2421598306 30 0.0 11 523968.095731647 21 178502.0223579458 31 0.0 0 LINE 5 2028 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523824.6597021152 20 178761.5057760814 30 0.0 11 523986.3914214229 21 178512.1289184503 31 0.0 0 LINE 5 2029 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523864.9090170671 20 178706.1735053991 30 0.0 11 523774.4186588351 21 178638.2817063094 31 0.0 0 LINE 5 202A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523730.542467848 20 178706.9234206626 30 0.0 11 524152.8799091047 21 178080.4230726436 31 0.0 0 LINE 5 202B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523969.7708988082 20 178229.5594272618 30 0.0 11 523665.732903476 21 177912.6293640066 31 0.0 0 LINE 5 202C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524011.9730416233 20 178174.3452427703 30 0.0 11 523888.6230921318 21 178323.992521637 31 0.0 0 LINE 5 202D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523955.2520687775 20 178129.0117072094 30 0.0 11 523914.75922797 21 178178.9714464547 31 0.0 0 LINE 5 202E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524007.5249368556 20 178144.0054489427 30 0.0 11 523939.7080979591 21 178132.2524967561 31 0.0 0 LINE 5 202F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523957.052546668 20 178143.0799556247 30 0.0 11 523696.423169983 21 177835.3959850311 31 0.0 0 LINE 5 2030 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524037.201129584 20 177952.1979505146 30 0.0 11 523709.5676774497 21 178194.2062464195 31 0.0 0 LINE 5 2031 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523719.8321760384 20 178202.6878184385 30 0.0 11 523566.8444002805 21 178019.3015807826 31 0.0 0 LINE 5 2032 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523651.518005441 20 178380.5612983597 30 0.0 11 523718.6859514777 21 178184.6139867516 31 0.0 0 LINE 5 2033 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523737.6789683065 20 178367.2094100985 30 0.0 11 523665.8697417005 21 178321.0060039942 31 0.0 0 LINE 5 2034 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523970.7490853096 20 177839.4205821743 30 0.0 11 523901.1778382863 21 177896.7087361529 31 0.0 0 LINE 5 2035 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523923.8195872301 20 177713.769321199 30 0.0 11 523566.4576711837 21 178022.3800962373 31 0.0 0 LINE 5 2036 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523899.6860323151 20 178273.8714307745 30 0.0 11 523612.212823405 21 177962.111297806 31 0.0 0 LINE 5 2037 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523360.362347059 20 178437.5811898571 30 0.0 11 523618.5314020309 21 177959.1568368285 31 0.0 0 LINE 5 2038 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523456.0480395155 20 178446.1773736755 30 0.0 11 523392.5071558344 21 178347.4247340636 31 0.0 0 LINE 5 2039 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523486.0017795747 20 178391.7918692405 30 0.0 11 523377.123261233 21 178377.263651049 31 0.0 0 LINE 5 203A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523588.5554246914 20 178231.8355354097 30 0.0 11 523464.706138435 21 178391.4243371938 31 0.0 0 LINE 5 203B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523728.7345070106 20 178438.4958860697 30 0.0 11 523476.3023781635 21 178218.1145060688 31 0.0 0 LINE 5 203C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523793.9348223813 20 178371.3726941348 30 0.0 11 523704.215138342 21 178453.213049843 31 0.0 0 LINE 5 203D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523786.5363747306 20 178513.6052231579 30 0.0 11 523833.0533184824 21 178402.1426513674 31 0.0 0 LINE 5 203E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523832.7721394355 20 178408.8728486055 30 0.0 11 523791.8067368046 21 178370.93267622 31 0.0 0 LINE 5 203F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524049.9550770458 20 178667.8961254901 30 0.0 11 523598.932997502 21 178331.5976684171 31 0.0 0 LINE 5 2040 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523596.7607724965 20 178318.7014983031 30 0.0 11 523582.396323854 21 178338.2825398289 31 0.0 0 LINE 5 2041 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523569.8993665342 20 178130.4682399823 30 0.0 11 523530.971371616 21 178107.2572859973 31 0.0 0 LINE 5 2042 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523585.4233454357 20 178129.8922496992 30 0.0 11 523561.3794028986 21 178128.8747724734 31 0.0 0 LINE 5 2043 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523627.2897608695 20 178081.3569723606 30 0.0 11 523578.8089988852 21 178134.3803454021 31 0.0 0 LINE 5 2044 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523671.9037870865 20 178334.242187829 30 0.0 11 523437.2243629574 21 178600.6618120954 31 0.0 0 LINE 5 2045 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523747.6081157428 20 178696.8193126631 30 0.0 11 523545.1170284044 21 178671.8391625966 31 0.0 0 LINE 5 2046 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523550.7992131782 20 178702.4178105399 30 0.0 11 523664.7738121421 21 178376.7783311538 31 0.0 0 LINE 5 2047 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523767.6585186823 20 178453.801901012 30 0.0 11 523746.1743542842 21 178482.0936738456 31 0.0 0 LINE 5 2048 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523559.9980789962 20 178480.3720683869 30 0.0 11 523480.9511756107 21 178430.7391431687 31 0.0 0 LINE 5 2049 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523508.3107164198 20 178452.8070299222 30 0.0 11 523473.9077292088 21 178376.8529864954 31 0.0 0 LINE 5 204A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523517.7965123248 20 178443.7356084459 30 0.0 11 523438.0891674102 21 178435.3161794655 31 0.0 0 LINE 5 204B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523383.2910629254 20 178536.217755333 30 0.0 11 523448.7695554481 21 178428.5858568744 31 0.0 0 LINE 5 204C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523922.0028546302 20 178789.7426866138 30 0.0 11 523677.7858813611 21 178675.6936336222 31 0.0 0 LINE 5 204D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523824.6549796329 20 178185.0798741302 30 0.0 11 523786.2929707809 21 178212.2546089911 31 0.0 0 LINE 5 204E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523832.2365424811 20 178256.5436462275 30 0.0 11 523786.1049313909 21 178210.3627832404 31 0.0 0 LINE 5 204F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523879.9988932064 20 178243.3404875143 30 0.0 11 523814.9945209313 21 178324.933223828 31 0.0 0 LINE 5 2050 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523944.5481741972 20 178402.577489811 30 0.0 11 523691.4701467358 21 178244.1153701758 31 0.0 0 LINE 5 2051 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523677.1369823944 20 178146.6252726353 30 0.0 11 523627.0787978201 21 178193.8877515116 31 0.0 0 LINE 5 2052 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523649.6395854257 20 178216.3590394448 30 0.0 11 523608.246450381 21 178172.779453309 31 0.0 0 LINE 5 2053 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523650.8555860139 20 178207.8393151623 30 0.0 11 523599.6840772069 21 178257.5379328851 31 0.0 0 LINE 5 2054 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523603.3862545109 20 178257.8744145832 30 0.0 11 523563.7134183502 21 178218.1546982485 31 0.0 0 LINE 5 2055 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523617.1598502217 20 178171.2992006449 30 0.0 11 523560.9691879433 21 178224.6723893374 31 0.0 0 LINE 5 2056 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523905.2147555707 20 178646.3959394668 30 0.0 11 523814.5230515527 21 178579.466234807 31 0.0 0 LINE 5 2057 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523939.7205012899 20 178027.3712431062 30 0.0 11 523780.3775437346 21 177816.1283221916 31 0.0 0 LINE 5 2058 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523391.0123446939 20 178408.0111781633 30 0.0 11 522858.9523112461 21 178625.8526812025 31 0.0 0 LINE 5 2059 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523519.6981161965 20 178597.1474741987 30 0.0 11 523402.1819029408 21 178719.7151586041 31 0.0 0 LINE 5 205A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523835.8588979495 20 178925.8981153875 30 0.0 11 523284.7149343134 21 178409.0693896933 31 0.0 0 LINE 5 205B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523402.7468093565 20 178613.6153219293 30 0.0 11 523035.7198233606 21 178854.8548905876 31 0.0 0 LINE 5 205C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523354.9680920425 20 178563.1492818721 30 0.0 11 523483.0328498929 21 178708.7821624604 31 0.0 0 LINE 5 205D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523301.1704663153 20 178611.9162140408 30 0.0 11 523344.0345082054 21 178659.857006848 31 0.0 0 LINE 5 205E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523324.3072144031 20 178562.7028427259 30 0.0 11 523301.8913304754 21 178627.7780582134 31 0.0 0 LINE 5 205F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523315.3458125261 20 178612.3819327488 30 0.0 11 522970.0413020606 21 178820.6171190256 31 0.0 0 LINE 5 2060 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523139.6854806142 20 178502.8228938208 30 0.0 11 523326.3569039595 21 178864.852552758 31 0.0 0 LINE 5 2061 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523336.366624138 20 178856.0717499962 30 0.0 11 523130.9329078317 21 178977.8615685262 31 0.0 0 LINE 5 2062 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523501.0718386049 20 178951.8735928333 30 0.0 11 523318.3412608636 21 178854.3214638997 31 0.0 0 LINE 5 2063 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523501.6290112135 20 178864.6860134383 30 0.0 11 523444.5668437729 21 178928.2094642923 31 0.0 0 LINE 5 2064 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522966.5922798777 20 178574.2352269626 30 0.0 11 523012.0544690127 21 178652.050908915 31 0.0 0 LINE 5 2065 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523435.3169658926 20 178689.8690239371 30 0.0 11 523081.708232544 21 178923.9546707615 31 0.0 0 LINE 5 2066 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523462.2861582033 20 179213.0258181883 30 0.0 11 523112.8056404958 21 178938.6563428773 31 0.0 0 LINE 5 2067 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523621.5295212859 20 179358.469027492 30 0.0 11 523238.6072048998 21 179034.295784951 31 0.0 0 LINE 5 2068 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523534.681036312 20 179155.3051507301 30 0.0 11 523427.0603128358 21 179202.2871431067 31 0.0 0 LINE 5 2069 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523485.7674071429 20 179117.0629421416 30 0.0 11 523454.0645383182 21 179222.2319917162 31 0.0 0 LINE 5 206A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523344.2095454536 20 178990.3165392215 30 0.0 11 523482.0090182521 21 179138.0275295288 31 0.0 0 LINE 5 206B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523544.6539933986 20 178907.2290588684 30 0.0 11 523312.7654748956 21 179098.9456491675 31 0.0 0 LINE 5 206C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523632.5980994354 20 178931.3997911901 30 0.0 11 523533.0776977153 21 178861.8070101844 31 0.0 0 LINE 5 206D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523606.9276528144 20 178791.3074733768 30 0.0 11 523667.4240192958 21 178895.8441684115 31 0.0 0 LINE 5 206E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523666.2776660543 20 178889.2063607339 30 0.0 11 523630.544485245 21 178932.1104477491 31 0.0 0 LINE 5 206F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523848.2607838725 20 178604.3491488078 30 0.0 11 523848.2518561053 21 178604.3578051187 31 0.0 0 LINE 5 2070 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523743.1815674026 20 178706.2333457597 30 0.0 11 523444.3500346296 21 178995.9786613726 31 0.0 0 LINE 5 2071 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523431.2724968967 20 178996.0668199145 30 0.0 11 523448.3126328807 21 179013.3696618109 31 0.0 0 LINE 5 2072 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523241.1644374892 20 178992.5710486596 30 0.0 11 523212.0434267714 21 179027.3000553831 31 0.0 0 LINE 5 2073 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523243.0710921107 20 178977.1538389934 30 0.0 11 523238.2328606282 21 179000.7279338593 31 0.0 0 LINE 5 2074 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523201.8323023783 20 178928.0841731191 30 0.0 11 523246.4471202749 21 178984.3991835094 31 0.0 0 LINE 5 2075 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523458.5958068072 20 178924.3631072621 30 0.0 11 523690.464388803 21 179188.2317961954 31 0.0 0 LINE 5 2076 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523741.7018148549 20 179102.2873729164 30 0.0 11 523499.4508888406 21 178938.1841891197 31 0.0 0 LINE 5 2077 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523591.893854295 20 178848.8970607549 30 0.0 11 523616.3980502818 21 178874.6174438973 31 0.0 0 LINE 5 2078 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523585.0129347177 20 179058.1373172804 30 0.0 11 523523.4110875841 21 179128.2590159926 31 0.0 0 LINE 5 2079 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523549.5590820407 20 179104.7681989575 30 0.0 11 523469.0912701507 21 179126.6202810466 31 0.0 0 LINE 5 207A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523542.1162144856 20 179093.9573370996 30 0.0 11 523521.0952816062 21 179171.3024597549 31 0.0 0 LINE 5 207B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523649.360992273 20 179278.540149505 30 0.0 11 523516.1540374569 21 179159.6855738952 31 0.0 0 LINE 5 207C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523335.6977949764 20 178749.7824630303 30 0.0 11 523356.4080963917 21 178791.9866494723 31 0.0 0 LINE 5 207D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523407.4561459401 20 178753.6926912383 30 0.0 11 523354.5104915972 21 178791.870634271 31 0.0 0 LINE 5 207E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523402.0375425117 20 178704.4361760988 30 0.0 11 523472.2215485359 21 178781.6187410497 31 0.0 0 LINE 5 207F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523569.5295937877 20 178666.1028311331 30 0.0 11 523372.7418774964 21 178890.6764851088 31 0.0 0 LINE 5 2080 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523274.2136426055 20 178889.281620349 30 0.0 11 523312.8897520948 21 178946.2353059817 31 0.0 0 LINE 5 2081 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523338.6708325046 20 178927.5461697877 30 0.0 11 523289.0487180073 21 178961.4610295014 31 0.0 0 LINE 5 2082 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523330.453997045 20 178924.9872687913 30 0.0 11 523371.3575600804 21 178983.4284738455 31 0.0 0 LINE 5 2083 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523372.2800436911 20 178979.8273128224 30 0.0 11 523326.7427159016 21 179012.6593333595 31 0.0 0 LINE 5 2084 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523289.0086319607 20 178952.42564142 30 0.0 11 523332.7394576793 21 179016.4076910938 31 0.0 0 LINE 5 2085 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523198.3538800154 20 178611.042650443 30 0.0 11 522964.4065476657 21 178734.6646365355 31 0.0 0 LINE 5 2086 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524738.0077992766 20 178705.4710425049 30 0.0 11 524586.8667262392 21 178293.1118015007 31 0.0 0 LINE 5 2087 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524758.5993848548 20 178957.9025597381 30 0.0 11 524445.747518893 21 178322.7063720054 31 0.0 0 LINE 5 2088 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524459.2215830315 20 178644.1973088366 30 0.0 11 525002.3886547115 21 178361.5835693572 31 0.0 0 LINE 5 2089 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524823.6695363629 20 178469.1375592657 30 0.0 11 524726.1370328227 21 178251.1394343973 31 0.0 0 LINE 5 208A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524864.5810622931 20 178645.0206934348 30 0.0 11 525061.4539381199 21 178431.2255060558 31 0.0 0 LINE 5 208B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524343.9905950533 20 178414.3796104963 30 0.0 11 524729.0724628618 21 178252.1444554355 31 0.0 0 LINE 5 208C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524808.6039906535 20 178661.9782852946 30 0.0 11 524654.8301096539 21 178266.7709727712 31 0.0 0 LINE 5 208D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525390.9100109588 20 178239.0326645809 30 0.0 11 524649.4001813499 21 178271.1492320292 31 0.0 0 LINE 5 208E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525116.8958157751 20 178519.6602617097 30 0.0 11 524857.3147946125 21 178236.5020363899 31 0.0 0 LINE 5 208F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524824.6597237038 20 178302.720810087 30 0.0 11 524820.9101242572 21 178257.5535910312 31 0.0 0 LINE 5 2090 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524817.3224011424 20 178316.4134863543 30 0.0 11 524826.9711914755 21 178294.3670064145 31 0.0 0 LINE 5 2091 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524755.3290416091 20 178332.7013119114 30 0.0 11 524824.2599803013 21 178312.4432749316 31 0.0 0 LINE 5 2092 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524761.8016675394 20 178555.5680322682 30 0.0 11 524803.0665951361 21 178533.0443627539 31 0.0 0 LINE 5 2093 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524822.6693148313 20 178593.7737953252 30 0.0 11 524801.4497121466 21 178532.0443363133 31 0.0 0 LINE 5 2094 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524441.6662571833 20 178845.7581638587 30 0.0 11 524891.6806406799 21 178608.329156404 31 0.0 0 LINE 5 2095 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524904.5164691505 20 178758.8217562954 30 0.0 11 524867.3512457227 21 178404.7561514077 31 0.0 0 LINE 5 2096 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524292.5001459931 20 178237.2916223235 30 0.0 11 524262.8974638588 21 177997.536803959 31 0.0 0 LINE 5 2097 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524743.7613223771 20 178187.8571337603 30 0.0 11 524226.9901518362 21 178250.4398286003 31 0.0 0 LINE 5 2098 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524736.0750984626 20 178079.329675156 30 0.0 11 523987.7301282686 21 178183.4997569488 31 0.0 0 LINE 5 2099 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524202.146601295 20 178084.5243154731 30 0.0 11 524051.0055282573 21 177672.1650744688 31 0.0 0 LINE 5 209A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524134.0058635479 20 178098.1796033321 30 0.0 11 524322.6283647658 21 178053.1122077325 31 0.0 0 LINE 5 209B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524118.1994916559 20 178027.3096039344 30 0.0 11 524180.8690639548 21 178012.8814921389 31 0.0 0 LINE 5 209C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524108.7047100372 20 178080.8550439858 30 0.0 11 524127.939476443 21 178014.7696501053 31 0.0 0 LINE 5 209D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524130.046502145 20 178035.1074034045 30 0.0 11 523968.1415224852 21 177665.8055278164 31 0.0 0 LINE 5 209E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524021.02369991 20 177972.5616731266 30 0.0 11 524284.6983858481 21 177835.2438175031 31 0.0 0 LINE 5 209F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524287.8083383811 20 177848.1908322338 30 0.0 11 524190.2758348411 21 177630.1927073653 31 0.0 0 LINE 5 20A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524477.6094411748 20 177864.9640889815 30 0.0 11 524272.075554444 21 177839.2210645568 31 0.0 0 LINE 5 20A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524427.7633272846 20 177936.4997400382 30 0.0 11 524417.803992296 21 177851.6933050936 31 0.0 0 LINE 5 20A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523881.3621119936 20 177765.1408410339 30 0.0 11 524193.21126488 21 177631.1977284036 31 0.0 0 LINE 5 20A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524272.7427926718 20 178041.0315582626 30 0.0 11 524118.9689116724 21 177645.8242457393 31 0.0 0 LINE 5 20A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524656.740906261 20 177628.458690205 30 0.0 11 524113.5389833685 21 177650.2025049972 31 0.0 0 LINE 5 20A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524622.4271487831 20 177718.1928094959 30 0.0 11 524561.6286626985 21 177617.7285281862 31 0.0 0 LINE 5 20A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524560.4117291013 20 177721.2089921625 30 0.0 11 524595.1923233731 21 177617.0172883553 31 0.0 0 LINE 5 20A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524371.664348211 20 177743.0654572557 30 0.0 11 524569.4370217646 21 177701.916934115 31 0.0 0 LINE 5 20A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524495.7318062599 20 177959.7817268529 30 0.0 11 524408.6525428254 21 177636.196909216 31 0.0 0 LINE 5 20A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524406.7893995179 20 177988.8652669207 30 0.0 11 524519.7244190173 21 177944.220593137 31 0.0 0 LINE 5 20AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524423.4153081321 20 178040.2284633169 30 0.0 11 524407.3290128842 21 177986.760229771 31 0.0 0 LINE 5 20AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524560.6933372315 20 178349.1236382285 30 0.0 11 524456.725047904 21 177796.2148181869 31 0.0 0 LINE 5 20AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524446.0942685496 20 177788.5979753106 30 0.0 11 524469.9950757708 21 177784.2961168499 31 0.0 0 LINE 5 20AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524288.7985257223 20 177681.7740830548 30 0.0 11 524285.0489262757 21 177636.6068639992 31 0.0 0 LINE 5 20AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524281.4612031608 20 177695.4667593225 30 0.0 11 524291.1099934939 21 177673.4202793828 31 0.0 0 LINE 5 20AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524219.4678436274 20 177711.7545848795 30 0.0 11 524288.3987823195 21 177691.4965478998 31 0.0 0 LINE 5 20B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524427.0436683059 20 177862.9287246882 30 0.0 11 524769.475248697 21 177769.1499368164 31 0.0 0 LINE 5 20B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524719.5010690223 20 178090.2214557565 30 0.0 11 524786.0175886017 21 177897.3427348676 31 0.0 0 LINE 5 20B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524810.9911650572 20 177915.8808419147 30 0.0 11 524468.3876208303 21 177875.2103215432 31 0.0 0 LINE 5 20B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524492.3818808952 20 178001.4726224788 30 0.0 11 524527.2356194102 21 177994.6016224428 31 0.0 0 LINE 5 20B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524607.4787635174 20 177826.5968390907 30 0.0 11 524597.618183188 21 177733.7819202675 31 0.0 0 LINE 5 20B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524605.4231027638 20 177768.0546401694 30 0.0 11 524552.304701948 21 177703.7816463328 31 0.0 0 LINE 5 20B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524593.1067007006 20 177772.5908557468 30 0.0 11 524620.5597418726 21 177697.2882784462 31 0.0 0 LINE 5 20B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524735.2765859546 20 177692.3886915756 30 0.0 11 524609.8216280412 21 177703.9261125934 31 0.0 0 LINE 5 20B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524726.363351182 20 178287.7086387874 30 0.0 11 524731.1969941583 21 178018.2169832271 31 0.0 0 LINE 5 20B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524225.9404695578 20 177934.6213052363 30 0.0 11 524267.2053971543 21 177912.0976357217 31 0.0 0 LINE 5 20BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524286.8081168498 20 177972.8270682933 30 0.0 11 524265.5885141649 21 177911.0976092813 31 0.0 0 LINE 5 20BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524253.9646341658 20 178009.9332832979 30 0.0 11 524355.8194426984 21 177987.3824293719 31 0.0 0 LINE 5 20BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524368.6552711687 20 178137.8750292635 30 0.0 11 524337.4839301416 21 177840.9119358636 31 0.0 0 LINE 5 20BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524256.2020210389 20 177785.207268455 30 0.0 11 524320.6507359999 21 177761.0013416544 31 0.0 0 LINE 5 20BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524330.9262008103 20 177791.1403984032 30 0.0 11 524309.9617375784 21 177734.8104486604 31 0.0 0 LINE 5 20BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524322.7384384093 20 177788.4899444518 30 0.0 11 524389.8647176601 21 177764.3541090383 31 0.0 0 LINE 5 20C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524388.540574712 20 177767.8277213047 30 0.0 11 524370.2878131228 21 177714.7388666447 31 0.0 0 LINE 5 20C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524304.7162010103 20 177742.1673631482 30 0.0 11 524377.3484529812 21 177715.1369400639 31 0.0 0 LINE 5 20C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524604.9653448457 20 178209.65318257 30 0.0 11 524584.6821974333 21 178098.7786387176 31 0.0 0 LINE 5 20C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524616.7122096681 20 177643.0021215638 30 0.0 11 525046.1476847069 21 177260.7352351909 31 0.0 0 LINE 5 20C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524683.1261485707 20 177660.8398771929 30 0.0 11 524854.3010716392 21 177511.278349791 31 0.0 0 LINE 5 20C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524730.0863801362 20 177841.6950095487 30 0.0 11 524891.8195255732 21 177789.9718299717 31 0.0 0 LINE 5 20C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524886.5205772781 20 178270.1374980642 30 0.0 11 524664.3607069593 21 177547.9764409759 31 0.0 0 LINE 5 20C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524796.2582747829 20 177743.868231316 30 0.0 11 525270.7473973083 21 177530.0606981159 31 0.0 0 LINE 5 20C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524771.912748007 20 177678.7765855139 30 0.0 11 524846.4791452751 21 177857.7999653004 31 0.0 0 LINE 5 20C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524839.355750728 20 177651.8723183613 30 0.0 11 524863.5918447558 21 177711.4395698372 31 0.0 0 LINE 5 20CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524784.9814290404 20 177651.036753114 30 0.0 11 524853.2882977952 21 177659.4882147568 31 0.0 0 LINE 5 20CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524833.5467029925 20 177664.8111088192 30 0.0 11 525069.6851025939 21 177449.3179554017 31 0.0 0 LINE 5 20CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524901.0465769525 20 177904.3281639453 30 0.0 11 525242.8844973097 21 177659.7068234534 31 0.0 0 LINE 5 20CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524980.7580986971 20 178089.9583921551 30 0.0 11 524961.961184173 21 177969.9828049263 31 0.0 0 LINE 5 20CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524866.1857902924 20 178005.3533362377 30 0.0 11 524933.5177864408 21 178105.6236372292 31 0.0 0 LINE 5 20CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524928.058427062 20 178101.6777518159 30 0.0 11 524982.2986856754 21 178088.4257618186 31 0.0 0 LINE 5 20D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524592.2139268167 20 178140.017783274 30 0.0 11 524592.2256251614 21 178140.013565991 31 0.0 0 LINE 5 20D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524729.9026557909 20 178090.3806476191 30 0.0 11 525304.5419744521 21 177825.2009968782 31 0.0 0 LINE 5 20D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525031.4395001166 20 177779.6791227352 30 0.0 11 525186.0575622661 21 178254.7713664581 31 0.0 0 LINE 5 20D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525159.7267250844 20 178479.6984389388 30 0.0 11 525012.5646530729 21 177947.2602766442 31 0.0 0 LINE 5 20D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524924.525016998 20 178017.1478391817 30 0.0 11 524936.8654889531 21 178050.4600964139 31 0.0 0 LINE 5 20D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524985.3770249892 20 177600.3362702277 30 0.0 11 524976.8524993605 21 177780.6014976812 31 0.0 0 LINE 5 20D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524920.025649624 20 177809.6366444678 30 0.0 11 524977.5819220661 21 177778.845847944 31 0.0 0 LINE 5 20D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524770.1396820498 20 177916.7533229772 30 0.0 11 524996.7215091665 21 177855.3320279399 31 0.0 0 LINE 5 20D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524906.0587970422 20 178202.5636635308 30 0.0 11 524708.0816721999 21 178134.8693976615 31 0.0 0 LINE 5 20D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524924.8530914603 20 177792.5003773588 30 0.0 11 524975.4606124475 21 177898.1842098137 31 0.0 0 LINE 5 20DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524462.8484862399 20 178642.3102049752 30 0.0 11 524266.6743453862 21 178614.3835392793 31 0.0 0 LINE 5 20DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526557.2525553547 20 175535.8312332927 30 0.0 11 523999.9723634475 21 176912.9282941857 31 0.0 0 LINE 5 20DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525747.934562985 20 175742.1415793237 30 0.0 11 526031.2914894814 21 175652.8044649422 31 0.0 0 LINE 5 20DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526139.8954430117 20 176128.0346140474 30 0.0 11 525830.2490952948 21 175696.8619054419 31 0.0 0 LINE 5 20DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526215.600250218 20 175902.2688151789 30 0.0 11 525996.0746696981 21 175977.801639612 31 0.0 0 LINE 5 20DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525901.2081771194 20 176101.1901361145 30 0.0 11 525721.8916498757 21 175837.2967542493 31 0.0 0 LINE 5 20E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525472.2889781802 20 176224.7491658278 30 0.0 11 525345.2077450251 21 176037.1569429094 31 0.0 0 LINE 5 20E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526047.6612660637 20 175951.2440488057 30 0.0 11 525864.820922853 21 176112.3398447609 31 0.0 0 LINE 5 20E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525948.9023176328 20 175776.5868444847 30 0.0 11 525700.5448251069 21 175926.5019602293 31 0.0 0 LINE 5 20E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524165.3240109262 20 176815.8237554785 30 0.0 11 521210.3972538704 21 178690.0947664428 31 0.0 0 LINE 5 20E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524841.8039351653 20 177414.2638539312 30 0.0 11 524993.9825398388 21 177620.3972736916 31 0.0 0 LINE 5 20E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524639.5732319613 20 176760.1462516073 30 0.0 11 524236.7794549726 21 176935.191790881 31 0.0 0 LINE 5 20E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524516.5374395311 20 176553.6620460306 30 0.0 11 524699.9462885679 21 176869.0391801092 31 0.0 0 LINE 5 20E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524540.2416766282 20 176738.8417321735 30 0.0 11 524573.0288028847 21 176794.1648742926 31 0.0 0 LINE 5 20E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524402.8939127689 20 176600.5870943258 30 0.0 11 524516.0534906659 21 176991.8754843581 31 0.0 0 LINE 5 20E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524527.5719386363 20 176985.1954879848 30 0.0 11 524302.4685832363 21 177064.9717443567 31 0.0 0 LINE 5 20EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524670.6487831715 20 177111.0319585387 30 0.0 11 524510.2250134501 21 176979.9934298166 31 0.0 0 LINE 5 20EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524688.051171811 20 177025.5969463264 30 0.0 11 524619.7847107993 21 177076.8903188255 31 0.0 0 LINE 5 20EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524292.1288232022 20 176610.8372527493 30 0.0 11 524321.6894533681 21 176695.9739671731 31 0.0 0 LINE 5 20ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524139.9292285851 20 176624.1064543491 30 0.0 11 524305.2211714586 21 177066.4035526116 31 0.0 0 LINE 5 20EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524656.7870192897 20 176841.2580737571 30 0.0 11 524264.5942312336 21 177002.5653685276 31 0.0 0 LINE 5 20EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524582.1070008542 20 177359.7590511446 30 0.0 11 524264.0180729551 21 176995.6140149074 31 0.0 0 LINE 5 20F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524733.7490608754 20 177562.7061247043 30 0.0 11 524397.2012674127 21 177141.1576589432 31 0.0 0 LINE 5 20F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524664.2950752848 20 177317.1232182147 30 0.0 11 524549.6217916453 21 177342.4128553935 31 0.0 0 LINE 5 20F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524623.6974913797 20 177270.1461406419 30 0.0 11 524572.2606837746 21 177367.2020817456 31 0.0 0 LINE 5 20F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524509.3137337471 20 177118.4239113903 30 0.0 11 524615.9569827252 21 177289.9886187415 31 0.0 0 LINE 5 20F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524914.8712808239 20 176967.8159134291 30 0.0 11 524457.4619183516 21 177218.9246693036 31 0.0 0 LINE 5 20F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524593.6225003369 20 177140.8973427732 30 0.0 11 524606.9960536835 21 177161.1680764284 31 0.0 0 LINE 5 20F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524407.7767810743 20 177100.7144695549 30 0.0 11 524372.4910968508 21 177129.1584084896 31 0.0 0 LINE 5 20F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524412.6280308329 20 177085.9567237407 30 0.0 11 524403.3235628415 21 177108.1507163518 31 0.0 0 LINE 5 20F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524381.65373712 20 177029.8402108713 30 0.0 11 524414.5396461155 21 177093.7180580547 31 0.0 0 LINE 5 20F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524634.2926135871 20 177075.8287054672 30 0.0 11 524847.2935574429 21 177454.3625650186 31 0.0 0 LINE 5 20FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524851.722458845 20 177422.913336713 30 0.0 11 524661.6272607795 21 177489.0807602579 31 0.0 0 LINE 5 20FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524948.4464482099 20 177380.2715990563 30 0.0 11 524671.7049472782 21 177097.2874407387 31 0.0 0 LINE 5 20FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524732.4626112492 20 177231.5190425282 30 0.0 11 524658.4664940188 21 177288.4085392337 31 0.0 0 LINE 5 20FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524688.6626025321 20 177270.4160094029 30 0.0 11 524605.488267369 21 177276.2992238412 31 0.0 0 LINE 5 20FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524683.4501827937 20 177258.3701930328 30 0.0 11 524647.8729103227 21 177330.192232138 31 0.0 0 LINE 5 20FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524752.9868462255 20 177460.2040589644 30 0.0 11 524645.2707455659 21 177317.8392296933 31 0.0 0 LINE 5 2100 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524547.4643337807 20 176880.782114935 30 0.0 11 524559.6247061727 21 176926.1939556954 31 0.0 0 LINE 5 2101 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524617.112963295 20 176898.4914126176 30 0.0 11 524557.7853298208 21 176925.7132706436 31 0.0 0 LINE 5 2102 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524621.3192077346 20 176849.1165905469 30 0.0 11 524675.2576602958 21 176938.4115308814 31 0.0 0 LINE 5 2103 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524793.0622890275 20 176843.8871924073 30 0.0 11 524556.5709138037 21 177026.1797067567 31 0.0 0 LINE 5 2104 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524460.1711436096 20 177005.7629728102 30 0.0 11 524487.1069085343 21 177069.1193325565 31 0.0 0 LINE 5 2105 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524516.0147297351 20 177055.7669622723 30 0.0 11 524460.7721051657 21 177079.4486933603 31 0.0 0 LINE 5 2106 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524508.447615311 20 177051.6677991172 30 0.0 11 524537.2812335059 21 177116.9142425369 31 0.0 0 LINE 5 2107 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524538.8825161087 20 177113.5593609073 30 0.0 11 524487.8569583077 21 177136.9683815156 31 0.0 0 LINE 5 2108 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524462.4795613218 20 177070.5760140498 30 0.0 11 524493.0159082682 21 177141.8053571161 31 0.0 0 LINE 5 2109 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524058.9354562361 20 176546.2668424607 30 0.0 11 523284.4721244596 21 176707.4414788887 31 0.0 0 LINE 5 210A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523923.4040826801 20 176571.4619758116 30 0.0 11 523976.5578845037 21 176709.4198246509 31 0.0 0 LINE 5 210B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524084.29885898 20 176606.317185652 30 0.0 11 523600.0276661482 21 176706.1471339956 31 0.0 0 LINE 5 210C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523973.9147379101 20 176676.8808630096 30 0.0 11 523958.3406354409 21 176757.3702758966 31 0.0 0 LINE 5 210D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524050.4510301497 20 176699.1858307063 30 0.0 11 523963.9833528352 21 176683.6690894231 31 0.0 0 LINE 5 210E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524223.3875588055 20 176606.9660273341 30 0.0 11 523799.3071688467 21 176904.554215737 31 0.0 0 LINE 5 210F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524230.9032869689 20 177064.4254319837 30 0.0 11 524135.8105514784 21 177125.7048981491 31 0.0 0 LINE 5 2110 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524184.9417980438 20 177190.6889400043 30 0.0 11 523744.1125567359 21 176577.0594260767 31 0.0 0 LINE 5 2111 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523820.3733984538 20 176800.5652334753 30 0.0 11 523351.0133256151 21 176974.2901895443 31 0.0 0 LINE 5 2112 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523783.2525142218 20 176741.8143442817 30 0.0 11 523880.7464550603 21 176909.458161977 31 0.0 0 LINE 5 2113 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523721.0418431207 20 176779.2607140414 30 0.0 11 523753.8289693772 21 176834.5838561607 31 0.0 0 LINE 5 2114 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523753.256382862 20 176735.448746983 30 0.0 11 523718.6825823592 21 176794.9626767961 31 0.0 0 LINE 5 2115 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523734.8597260975 20 176782.4581261431 30 0.0 11 523602.716445313 21 176830.4106796125 31 0.0 0 LINE 5 2116 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523583.6940792614 20 176641.0060761937 30 0.0 11 523807.7711164501 21 177405.5927394266 31 0.0 0 LINE 5 2117 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523708.3721051288 20 177025.6144698526 30 0.0 11 523414.0942205851 21 177128.0965747663 31 0.0 0 LINE 5 2118 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523459.628059891 20 176658.2462745898 30 0.0 11 523489.188690057 21 176743.3829890131 31 0.0 0 LINE 5 2119 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523837.5871857822 20 176881.6770556252 30 0.0 11 523401.4561761059 21 177061.0559618133 31 0.0 0 LINE 5 211A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523932.59431452 20 177099.1610338265 30 0.0 11 523560.8438708927 21 177311.7893333251 31 0.0 0 LINE 5 211B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524259.2738640755 20 176877.6038259502 30 0.0 11 523787.2705317197 21 177183.7580725489 31 0.0 0 LINE 5 211C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523815.0927800796 20 177116.2476873352 30 0.0 11 524065.686859798 21 177581.6040589463 31 0.0 0 LINE 5 211D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524181.393408924 20 177171.1764242468 30 0.0 11 524087.6441325976 21 177352.3882382578 31 0.0 0 LINE 5 211E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524118.2928397489 20 177357.6795220147 30 0.0 11 523852.5051137707 21 177137.7064226066 31 0.0 0 LINE 5 211F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523913.2627777417 20 177271.938024396 30 0.0 11 523742.3935641112 21 177401.888449398 31 0.0 0 LINE 5 2120 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523904.2630915616 20 177457.0410117514 30 0.0 11 523778.0512849523 21 177349.0241465069 31 0.0 0 LINE 5 2121 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524329.0991662258 20 177039.9084249556 30 0.0 11 524137.3338132791 21 177229.3158322298 31 0.0 0 LINE 5 2122 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523728.264500273 20 176921.2010968029 30 0.0 11 523740.4248726654 21 176966.6129375633 31 0.0 0 LINE 5 2123 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523797.9131297873 20 176938.9103944856 30 0.0 11 523738.5854963134 21 176966.1322525115 31 0.0 0 LINE 5 2124 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523802.119374227 20 176889.5355724147 30 0.0 11 523856.0578267882 21 176978.8305127494 31 0.0 0 LINE 5 2125 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524188.8444531574 20 177005.8680716988 30 0.0 11 524094.5840014705 21 177067.6704809664 31 0.0 0 LINE 5 2126 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523620.3338423907 20 176758.5263917544 30 0.0 11 523286.1844197433 21 176841.7763756921 31 0.0 0 LINE 5 2127 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523845.4473361947 20 177441.0503041714 30 0.0 11 523897.8522793977 21 177789.229920805 31 0.0 0 LINE 5 2128 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524426.8624672233 20 177167.9764499862 30 0.0 11 523718.9633067363 21 177521.2064889649 31 0.0 0 LINE 5 2129 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524334.9515202315 20 177490.9462293093 30 0.0 11 524165.8798881372 21 177657.0770312377 31 0.0 0 LINE 5 212A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524253.3843285075 20 177460.1439943853 30 0.0 11 524293.136478182 21 177535.7157242692 31 0.0 0 LINE 5 212B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524537.393008504 20 177530.0796005514 30 0.0 11 524544.0746081126 21 177647.3181776323 31 0.0 0 LINE 5 212C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524484.5437187272 20 177562.6673621539 30 0.0 11 524572.1564254478 21 177628.9215280699 31 0.0 0 LINE 5 212D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524294.1932385935 20 177444.0753259245 30 0.0 11 524419.0163395771 21 177658.572912265 31 0.0 0 LINE 5 212E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524361.4303963406 20 177360.4962275396 30 0.0 11 524261.6064725267 21 177429.6529319217 31 0.0 0 LINE 5 212F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524221.1427565949 20 177335.9155954373 30 0.0 11 524340.1827309195 21 177315.4897422352 31 0.0 0 LINE 5 2130 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524333.559963647 20 177314.2594698381 30 0.0 11 524361.383610597 21 177362.6688239315 31 0.0 0 LINE 5 2131 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524129.6350283636 20 177044.6744051055 30 0.0 11 524129.6400453109 21 177044.6857834614 31 0.0 0 LINE 5 2132 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524188.6841623029 20 177178.5968868009 30 0.0 11 524356.6121674477 21 177559.4548891945 31 0.0 0 LINE 5 2133 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524294.4017108166 20 177521.2241593916 30 0.0 11 524622.3728336955 21 177395.4280272024 31 0.0 0 LINE 5 2134 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524559.5723787072 20 177317.5318105132 30 0.0 11 524321.55125031 21 177487.7120341687 31 0.0 0 LINE 5 2135 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524269.9265987363 20 177370.0141645893 30 0.0 11 524302.556213675 21 177355.9677430189 31 0.0 0 LINE 5 2136 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524463.7532463389 20 177449.1347225002 30 0.0 11 524508.1163394164 21 177531.2550986146 31 0.0 0 LINE 5 2137 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524495.1687271976 20 177498.5764291668 30 0.0 11 524487.7146466169 21 177581.6247218925 31 0.0 0 LINE 5 2138 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524482.4459093658 20 177501.8014745882 30 0.0 11 524547.6763303283 21 177548.3754995245 31 0.0 0 LINE 5 2139 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524692.7850811292 20 177465.3365624116 30 0.0 11 524535.0664578412 21 177548.9747045653 31 0.0 0 LINE 5 213A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524090.7431950936 20 177327.5030085241 30 0.0 11 524232.9952976152 21 177590.0350459429 31 0.0 0 LINE 5 213B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524834.4925108826 20 176585.5479530126 30 0.0 11 524868.7902796302 21 176059.7556749212 31 0.0 0 LINE 5 213C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524853.1503024604 20 176384.6466599991 30 0.0 11 524078.0846057808 21 176542.899247733 31 0.0 0 LINE 5 213D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524718.7041122123 20 176415.1059753282 30 0.0 11 524712.9644557525 21 176267.373950877 31 0.0 0 LINE 5 213E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524852.6970118399 20 176319.461228776 30 0.0 11 524368.4258190082 21 176419.2911771196 31 0.0 0 LINE 5 213F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524723.4054065664 20 176298.3054363685 30 0.0 11 524677.2688056228 21 176230.5373590165 31 0.0 0 LINE 5 2140 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524784.8807047635 20 176247.5501083199 30 0.0 11 524711.5990661153 21 176295.9983272473 31 0.0 0 LINE 5 2141 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524775.536839776 20 176264.1154968722 30 0.0 11 524785.5094619859 21 176065.4831742494 31 0.0 0 LINE 5 2142 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524896.866258793 20 176246.5082128524 30 0.0 11 524472.992057353 21 176158.2479008623 31 0.0 0 LINE 5 2143 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524730.2782279649 20 176055.8036672147 30 0.0 11 524677.5515472646 21 176234.8559944898 31 0.0 0 LINE 5 2144 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524789.3457741364 20 176069.3918539262 30 0.0 11 524729.562001381 21 176056.2571214818 31 0.0 0 LINE 5 2145 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524818.4673709424 20 175773.411979897 30 0.0 11 524749.4999268523 21 176062.5303947511 31 0.0 0 LINE 5 2146 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524806.1751753408 20 175840.7214848734 30 0.0 11 524694.6000474236 21 175822.0455070709 31 0.0 0 LINE 5 2147 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524714.0256908267 20 175742.9288244858 30 0.0 11 524528.7710855574 21 176593.1214276208 31 0.0 0 LINE 5 2148 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524533.4667132535 20 176245.4276602987 30 0.0 11 524094.2838498115 21 176243.951157889 31 0.0 0 LINE 5 2149 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524522.6071595965 20 176314.069463317 30 0.0 11 524545.8524346704 21 176121.53589404 31 0.0 0 LINE 5 214A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524450.6589154366 20 176304.2792452722 30 0.0 11 524458.8936444774 21 176240.4996643729 31 0.0 0 LINE 5 214B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524497.5740018673 20 176331.7790578808 30 0.0 11 524442.2821362541 21 176290.7904604414 31 0.0 0 LINE 5 214C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524462.085748693 20 176295.877768269 30 0.0 11 524059.5419547112 21 176319.4487605732 31 0.0 0 LINE 5 214D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524379.1860456042 20 176485.5811537055 30 0.0 11 524328.3721347721 21 176081.4405337352 31 0.0 0 LINE 5 214E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524341.5933468728 20 176083.0205798669 30 0.0 11 524103.2917748921 21 176098.7728014375 31 0.0 0 LINE 5 214F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524423.2393996213 20 175910.8586710884 30 0.0 11 524327.7179864655 21 176094.6589472851 31 0.0 0 LINE 5 2150 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524473.0111335692 20 175982.4460927623 30 0.0 11 524390.0245524959 21 175962.3327359273 31 0.0 0 LINE 5 2151 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524196.0482056268 20 176524.5876792396 30 0.0 11 524189.5287195957 21 176434.7011546625 31 0.0 0 LINE 5 2152 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524128.358509373 20 176567.9773459235 30 0.0 11 524105.2536975196 21 176096.3691216743 31 0.0 0 LINE 5 2153 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524517.1987594172 20 176164.1208595706 30 0.0 11 524093.1858645262 21 176171.0700549083 31 0.0 0 LINE 5 2154 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524179.8018907191 20 175836.4304880299 30 0.0 11 524110.3161840115 21 176113.4995720353 31 0.0 0 LINE 5 2155 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524401.0527004668 20 175571.5431528407 30 0.0 11 524337.5341966459 21 175803.6260353005 31 0.0 0 LINE 5 2156 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524906.1175838838 20 176001.0920467013 30 0.0 11 524351.516314391 21 175906.5669159554 31 0.0 0 LINE 5 2157 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524185.8788921953 20 176024.2964495397 30 0.0 11 524125.3963942551 21 176008.8910432083 31 0.0 0 LINE 5 2158 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524196.1710747265 20 176035.9324567793 30 0.0 11 524178.8478202819 21 176019.2276284931 31 0.0 0 LINE 5 2159 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524189.9151486143 20 176099.7237828048 30 0.0 11 524194.857365465 21 176028.0478672973 31 0.0 0 LINE 5 215A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524689.4772944703 20 175581.5310930009 30 0.0 11 524505.877293696 21 175447.0535606886 31 0.0 0 LINE 5 215B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524718.4834610751 20 175762.2538761273 30 0.0 11 524684.3756495151 21 175549.7453183631 31 0.0 0 LINE 5 215C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524401.1577066231 20 176171.0543626083 30 0.0 11 524394.3670665881 21 176124.5355798873 31 0.0 0 LINE 5 215D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524458.1243808401 20 176127.2439888799 30 0.0 11 524392.8677514518 21 176125.7045185535 31 0.0 0 LINE 5 215E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524481.5146127438 20 176170.9299431248 30 0.0 11 524495.7409961227 21 176067.5831819273 31 0.0 0 LINE 5 215F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524641.3241762692 20 176107.8115148906 30 0.0 11 524352.0195627142 21 176033.9090662238 31 0.0 0 LINE 5 2160 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524271.5534269223 20 176090.7857724328 30 0.0 11 524271.2368351342 21 176021.9420107544 31 0.0 0 LINE 5 2161 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524303.0685325427 20 176022.7732501209 30 0.0 11 524242.9639349946 21 176022.8697395756 31 0.0 0 LINE 5 2162 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524297.7394902733 20 176029.5308878573 30 0.0 11 524298.4185297348 21 175958.2005659559 31 0.0 0 LINE 5 2163 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524301.2160640311 20 175960.6486547176 30 0.0 11 524245.0925818655 21 175959.3278427067 31 0.0 0 LINE 5 2164 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524248.0411827285 20 176030.3437880178 30 0.0 11 524247.917997139 21 175952.8449323889 31 0.0 0 LINE 5 2165 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523955.0072537066 20 176585.1613932447 30 0.0 11 523908.8706527628 21 176517.3933158926 31 0.0 0 LINE 5 2166 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524016.4825519034 20 176534.4060651959 30 0.0 11 523943.2009132551 21 176582.8542841236 31 0.0 0 LINE 5 2167 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524007.0495175071 20 176549.1513555462 30 0.0 11 524017.0221397171 21 176350.5190329231 31 0.0 0 LINE 5 2168 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524211.791502212 20 176550.7140082577 30 0.0 11 523704.593904493 21 176445.1038577385 31 0.0 0 LINE 5 2169 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523961.8800751049 20 176342.6596240908 30 0.0 11 523909.1533944044 21 176521.7119513658 31 0.0 0 LINE 5 216A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524020.9476212765 20 176356.2478108022 30 0.0 11 523961.163848521 21 176343.1130783577 31 0.0 0 LINE 5 216B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524050.0692180822 20 176060.2679367731 30 0.0 11 523981.1017739921 21 176349.3863516272 31 0.0 0 LINE 5 216C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523925.7303676276 20 176133.255429937 30 0.0 11 523783.4177929851 21 176767.7275968893 31 0.0 0 LINE 5 216D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523765.0685603935 20 176532.2836171748 30 0.0 11 523499.6512491019 21 176531.3913025323 31 0.0 0 LINE 5 216E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523754.2090067364 20 176600.925420193 30 0.0 11 523777.4542818105 21 176408.3918509162 31 0.0 0 LINE 5 216F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523682.2607625766 20 176591.1352021484 30 0.0 11 523690.4954916173 21 176527.3556212487 31 0.0 0 LINE 5 2170 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523729.1758490071 20 176618.635014757 30 0.0 11 523673.883983394 21 176577.6464173176 31 0.0 0 LINE 5 2171 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523693.6875958331 20 176582.7337251451 30 0.0 11 523291.1438018511 21 176606.3047174492 31 0.0 0 LINE 5 2172 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523597.1719588192 20 176663.2487647028 30 0.0 11 523559.9739819122 21 176368.2964906114 31 0.0 0 LINE 5 2173 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523573.1951940131 20 176369.8765367431 30 0.0 11 523334.893622032 21 176385.6287583135 31 0.0 0 LINE 5 2174 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523654.8412467612 20 176197.7146279646 30 0.0 11 523559.3198336054 21 176381.5149041611 31 0.0 0 LINE 5 2175 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523905.9258672462 20 176331.1066862747 30 0.0 11 523621.6263996359 21 176249.1886928035 31 0.0 0 LINE 5 2176 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523748.8006065571 20 176450.9768164465 30 0.0 11 523287.6327858075 21 176455.5451722603 31 0.0 0 LINE 5 2177 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523581.6567369846 20 176045.7597572108 30 0.0 11 523601.3255771891 21 176409.2881804986 31 0.0 0 LINE 5 2178 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523665.9868155602 20 176111.4283174921 30 0.0 11 523550.6608481276 21 176133.5518110002 31 0.0 0 LINE 5 2179 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523647.2776624665 20 176170.6311656222 30 0.0 11 523561.6503440895 21 176101.8302700779 31 0.0 0 LINE 5 217A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524137.7194310238 20 176287.9480035772 30 0.0 11 523822.669511242 21 176239.4880524337 31 0.0 0 LINE 5 217B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523912.551407782 20 176284.3224058519 30 0.0 11 523764.8411344153 21 175991.2301637763 31 0.0 0 LINE 5 217C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523834.274537764 20 176080.7292277792 30 0.0 11 523684.4955315352 21 176154.1947352304 31 0.0 0 LINE 5 217D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523706.8396502355 20 176144.6906932061 30 0.0 11 523628.1195368675 21 176172.1811641599 31 0.0 0 LINE 5 217E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523706.8160992776 20 176157.8158772775 30 0.0 11 523645.7349219852 21 176105.9194670136 31 0.0 0 LINE 5 217F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523680.9808014415 20 175996.6414351451 30 0.0 11 523648.2303072941 21 176118.2944814773 31 0.0 0 LINE 5 2180 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524137.66337269 20 176111.2608435002 30 0.0 11 523998.6574924492 21 176056.9264262539 31 0.0 0 LINE 5 2181 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523632.759553763 20 176457.9103194846 30 0.0 11 523625.9689137283 21 176411.3915367633 31 0.0 0 LINE 5 2182 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523689.7262279803 20 176414.0999457557 30 0.0 11 523624.4695985917 21 176412.5604754293 31 0.0 0 LINE 5 2183 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523713.1164598839 20 176457.7859000009 30 0.0 11 523727.3428432626 21 176354.4391388034 31 0.0 0 LINE 5 2184 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523872.9260234091 20 176394.6674717667 30 0.0 11 523583.6214098542 21 176320.7650230998 31 0.0 0 LINE 5 2185 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523503.1552740625 20 176377.641729309 30 0.0 11 523502.8386822742 21 176308.7979676306 31 0.0 0 LINE 5 2186 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523534.6703796825 20 176309.629206997 30 0.0 11 523474.5657821348 21 176309.7256964516 31 0.0 0 LINE 5 2187 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524022.3055568426 20 176197.9943693747 30 0.0 11 523911.2880441574 21 176178.5089281253 31 0.0 0 LINE 5 2188 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523593.4915151983 20 176090.6742454528 30 0.0 11 523384.1588268988 21 175555.2093770923 31 0.0 0 LINE 5 2189 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523633.2841588868 20 176034.5891109277 30 0.0 11 523552.479969169 21 175822.1269079588 31 0.0 0 LINE 5 218A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523819.1912007304 20 176053.3618049566 30 0.0 11 523826.85645502 21 175883.7323808723 31 0.0 0 LINE 5 218B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523958.7285697965 20 176038.1395985702 30 0.0 11 522674.7588793094 21 175965.1831478631 31 0.0 0 LINE 5 218C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523750.4346482233 20 175957.3340242478 30 0.0 11 523681.8651927528 21 175523.5345344176 31 0.0 0 LINE 5 218D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523680.9394918868 20 175957.5582406125 30 0.0 11 523874.7162583049 21 175949.8069240586 31 0.0 0 LINE 5 218E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523679.132413508 20 175884.9694489518 30 0.0 11 523743.4090293628 21 175882.9292635791 31 0.0 0 LINE 5 218F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523659.4649690731 20 175935.669120131 30 0.0 11 523691.1129608358 21 175874.5490731707 31 0.0 0 LINE 5 2190 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523689.2483959566 20 175894.910486785 30 0.0 11 523601.7939436437 21 175501.2751015337 31 0.0 0 LINE 5 2191 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523488.7537930343 20 175843.3193110165 30 0.0 11 523879.6217311897 21 175728.7158679355 31 0.0 0 LINE 5 2192 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523880.170002799 20 175742.0198670875 30 0.0 11 523826.6224728135 21 175509.2787368043 31 0.0 0 LINE 5 2193 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524063.14765777 20 175795.1703943184 30 0.0 11 523866.4681278443 21 175730.1777454313 31 0.0 0 LINE 5 2194 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524000.4121388068 20 175855.7198708024 30 0.0 11 524007.0360807248 21 175770.5879546085 31 0.0 0 LINE 5 2195 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523421.0452457656 20 175668.7440261316 30 0.0 11 523508.7422612466 21 175647.9756734188 31 0.0 0 LINE 5 2196 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523367.4176725549 20 175608.8387546992 30 0.0 11 523829.3082261822 21 175510.8322958291 31 0.0 0 LINE 5 2197 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523828.1073277839 20 175928.3099477495 30 0.0 11 523753.6388003021 21 175510.8298107797 31 0.0 0 LINE 5 2198 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524225.4539202574 20 175586.9361729005 30 0.0 11 523747.4648746935 21 175514.0757186803 31 0.0 0 LINE 5 2199 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524426.7050617454 20 175585.5475623332 30 0.0 11 523941.7571189213 21 175548.2990942904 31 0.0 0 LINE 5 219A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524233.6081600306 20 175679.1652475025 30 0.0 11 524193.379151646 21 175568.8422915338 31 0.0 0 LINE 5 219B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524172.1795916705 20 175670.1352627065 30 0.0 11 524226.4471139384 21 175574.6332370366 31 0.0 0 LINE 5 219C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523982.767604884 20 175655.0893954719 30 0.0 11 524184.7642951671 21 175652.9519961581 31 0.0 0 LINE 5 219D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524060.8920527418 20 175857.5198199396 30 0.0 11 524039.718586377 21 175557.3878150962 31 0.0 0 LINE 5 219E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524163.9828436678 20 175862.6319814055 30 0.0 11 524262.2482765593 21 175978.5874908516 31 0.0 0 LINE 5 219F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523952.5760344381 20 176185.7681188406 30 0.0 11 523952.5761424223 21 176185.7556840073 31 0.0 0 LINE 5 21A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524065.176651165 20 175980.5472814888 30 0.0 11 524055.9483637536 21 175723.6806028601 31 0.0 0 LINE 5 21A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524046.9906836203 20 175714.1522382722 30 0.0 11 524071.272252612 21 175714.5522124547 31 0.0 0 LINE 5 21A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523913.3143877621 20 175578.9341085931 30 0.0 11 523918.3675773197 21 175533.8940991734 31 0.0 0 LINE 5 21A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523903.4683223095 20 175590.9499598256 30 0.0 11 523917.1972653579 21 175571.1847743874 31 0.0 0 LINE 5 21A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523839.4956288376 20 175594.9455045419 30 0.0 11 523911.0425692246 21 175588.3958715355 31 0.0 0 LINE 5 21A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524013.929332411 20 175783.3976910387 30 0.0 11 524364.9122806743 21 175769.2310278912 31 0.0 0 LINE 5 21A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524244.1416690661 20 175847.5570144723 30 0.0 11 524052.1189380022 21 175803.4404966425 31 0.0 0 LINE 5 21A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523779.0412053739 20 176109.8391314804 30 0.0 11 524379.9318991116 21 175749.9532929654 31 0.0 0 LINE 5 21A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524197.9843422059 20 175782.6342354071 30 0.0 11 524206.2534331876 21 175689.6640125672 31 0.0 0 LINE 5 21A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524207.2852601229 20 175724.7990582087 30 0.0 11 524167.5946882196 21 175651.4693865612 31 0.0 0 LINE 5 21AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524194.3242413292 20 175726.8686000381 30 0.0 11 524235.8173966716 21 175658.294073591 31 0.0 0 LINE 5 21AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524401.936399934 20 175677.1750531974 30 0.0 11 524223.9985907147 21 175662.7307115722 31 0.0 0 LINE 5 21AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523802.7599534706 20 175814.8590331944 30 0.0 11 523847.6008284282 21 175800.7379188267 31 0.0 0 LINE 5 21AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523855.0930810568 20 175864.1113892261 30 0.0 11 523846.207781267 21 175799.4441711348 31 0.0 0 LINE 5 21AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523903.4878811873 20 176041.8688909265 30 0.0 11 523930.3156404951 21 175744.4819331198 31 0.0 0 LINE 5 21AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523861.3363930202 20 175674.1141696465 30 0.0 11 524026.3704793484 21 175650.4719839854 31 0.0 0 LINE 5 21B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523607.5722573438 20 175811.1374939353 30 0.0 11 523535.6810956624 21 175556.489873426 31 0.0 0 LINE 5 21B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524601.8591509933 20 175937.3279469695 30 0.0 11 524563.5006805631 21 176099.1916535255 31 0.0 0 LINE 5 21B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524649.1081246048 20 175849.7935343369 30 0.0 11 524802.8262932069 21 175951.8810185483 31 0.0 0 LINE 5 21B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523840.6999827257 20 175853.6330990243 30 0.0 11 523957.3813533612 21 175842.8789663575 31 0.0 0 LINE 5 21B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524378.6760047676 20 176481.5246224025 30 0.0 11 524284.3574541301 21 176655.7893727172 31 0.0 0 LINE 5 21B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523147.326013239 20 178931.9640315077 30 0.0 11 522765.2641434303 21 179342.3537138884 31 0.0 0 LINE 5 21B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523139.8670581723 20 178951.3058347943 30 0.0 11 522719.7578980884 21 178281.0230517039 31 0.0 0 LINE 5 21B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523069.1709018637 20 178832.9605710714 30 0.0 11 522958.2600799692 21 178930.7178433913 31 0.0 0 LINE 5 21B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522987.8557439687 20 178916.9386227657 30 0.0 11 522906.9675008426 21 178930.2874196615 31 0.0 0 LINE 5 21B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522993.5197341839 20 178996.4573930566 30 0.0 11 522978.0409297662 21 178909.9829165099 31 0.0 0 LINE 5 21BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522999.0664906292 20 178978.2652682841 30 0.0 11 522862.1452156581 21 179122.5109519096 31 0.0 0 LINE 5 21BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523070.0183710327 20 179078.2486420859 30 0.0 11 522713.7134417443 21 178832.2689301503 31 0.0 0 LINE 5 21BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522817.0365754428 20 179089.20340553 30 0.0 11 522910.289047065 21 178927.5129132409 31 0.0 0 LINE 5 21BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522867.6213930463 20 179122.5918774449 30 0.0 11 522816.8707690084 21 179088.3720755601 31 0.0 0 LINE 5 21BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522673.4347394771 20 179347.8554936956 30 0.0 11 522835.1664587846 21 179098.4786360647 31 0.0 0 LINE 5 21BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522713.6840544283 20 179292.5232230136 30 0.0 11 522623.1936961966 21 179224.6314239237 31 0.0 0 LINE 5 21C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522579.3175052096 20 179293.273138277 30 0.0 11 523008.5346679032 21 178704.9826767926 31 0.0 0 LINE 5 21C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522818.5459361698 20 178815.9091448761 30 0.0 11 522514.5079408377 21 178498.9790816208 31 0.0 0 LINE 5 21C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522860.7480789847 20 178760.6949603847 30 0.0 11 522737.3981294931 21 178910.3422392513 31 0.0 0 LINE 5 21C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522804.027106139 20 178715.3614248236 30 0.0 11 522763.5342653316 21 178765.321164069 31 0.0 0 LINE 5 21C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522856.299974217 20 178730.3551665571 30 0.0 11 522788.4831353206 21 178718.6022143702 31 0.0 0 LINE 5 21C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522805.8275840294 20 178729.429673239 30 0.0 11 522545.1982073443 21 178421.7457026453 31 0.0 0 LINE 5 21C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522885.9761669452 20 178538.5476681291 30 0.0 11 522558.3427148113 21 178780.5559640336 31 0.0 0 LINE 5 21C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522568.6072133998 20 178789.0375360528 30 0.0 11 522415.6194376418 21 178605.6512983969 31 0.0 0 LINE 5 21C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522500.2930428026 20 178966.9110159738 30 0.0 11 522567.4609888394 21 178770.9637043657 31 0.0 0 LINE 5 21C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522586.4540056679 20 178953.5591277127 30 0.0 11 522514.6447790618 21 178907.3557216087 31 0.0 0 LINE 5 21CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522837.8959411886 20 178438.2368376785 30 0.0 11 522768.3246941651 21 178495.5249916571 31 0.0 0 LINE 5 21CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522772.5946245916 20 178300.1190388134 30 0.0 11 522415.2327085451 21 178608.7298138516 31 0.0 0 LINE 5 21CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522748.4610696767 20 178860.2211483888 30 0.0 11 522460.9878607667 21 178548.4610154204 31 0.0 0 LINE 5 21CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522236.2976158708 20 178970.2618921646 30 0.0 11 522467.3064393924 21 178545.5065544425 31 0.0 0 LINE 5 21CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522098.6471478465 20 179182.9475232887 30 0.0 11 522377.0757368185 21 178720.9463900508 31 0.0 0 LINE 5 21CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522304.8230768771 20 179032.5270912898 30 0.0 11 522241.2821931961 21 178933.7744516778 31 0.0 0 LINE 5 21D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522334.7768169362 20 178978.1415868549 30 0.0 11 522225.8982985945 21 178963.6133686634 31 0.0 0 LINE 5 21D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522437.3304620526 20 178818.1852530238 30 0.0 11 522313.4811757963 21 178977.7740548083 31 0.0 0 LINE 5 21D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522577.5095443722 20 179024.845603684 30 0.0 11 522325.0774155249 21 178804.4642236829 31 0.0 0 LINE 5 21D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522642.7098597427 20 178957.7224117491 30 0.0 11 522552.9901757035 21 179039.5627674574 31 0.0 0 LINE 5 21D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522635.311412092 20 179099.9549407722 30 0.0 11 522681.828355844 21 178988.4923689815 31 0.0 0 LINE 5 21D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522681.547176797 20 178995.2225662195 30 0.0 11 522640.581774166 21 178957.2823938343 31 0.0 0 LINE 5 21D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522898.7301144073 20 179254.2458431046 30 0.0 11 522447.7080348636 21 178917.9473860314 31 0.0 0 LINE 5 21D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522445.5358098579 20 178905.0512159173 30 0.0 11 522431.1713612153 21 178924.6322574431 31 0.0 0 LINE 5 21D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522418.6744038956 20 178716.8179575967 30 0.0 11 522379.7464089774 21 178693.6070036115 31 0.0 0 LINE 5 21D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522434.198382797 20 178716.2419673135 30 0.0 11 522410.1544402602 21 178715.2244900878 31 0.0 0 LINE 5 21DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522476.0647982307 20 178667.7066899749 30 0.0 11 522427.5840362466 21 178720.7300630164 31 0.0 0 LINE 5 21DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522520.6788244482 20 178920.5919054432 30 0.0 11 522239.6803424068 21 179251.7974881269 31 0.0 0 LINE 5 21DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522270.7101836271 20 179245.0285825652 30 0.0 11 522142.6423063304 21 179089.7451930127 31 0.0 0 LINE 5 21DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522596.3831531044 20 179283.1690302777 30 0.0 11 522237.4258900137 21 179230.8789917106 31 0.0 0 LINE 5 21DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522344.2894211447 20 179320.9228756008 30 0.0 11 522513.5488495037 21 178963.1280487681 31 0.0 0 LINE 5 21DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522616.433556044 20 179040.1516186263 30 0.0 11 522594.9493916457 21 179068.44339146 31 0.0 0 LINE 5 21E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522408.7731163578 20 179066.7217860012 30 0.0 11 522329.726212972 21 179017.088860783 31 0.0 0 LINE 5 21E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522357.0857537812 20 179039.1567475365 30 0.0 11 522322.6827665701 21 178963.2027041097 31 0.0 0 LINE 5 21E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522366.5715496863 20 179030.0853260603 30 0.0 11 522286.8642047714 21 179021.6658970797 31 0.0 0 LINE 5 21E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522201.450268929 20 179165.3895005678 30 0.0 11 522297.5445928094 21 179014.9355744889 31 0.0 0 LINE 5 21E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522694.7693225394 20 179484.036566723 30 0.0 11 522776.714635701 21 179327.5713947966 31 0.0 0 LINE 5 21E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522757.6709378034 20 179388.2454918792 30 0.0 11 522526.5609187225 21 179262.0433512364 31 0.0 0 LINE 5 21E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522673.4300169945 20 178771.4295917444 30 0.0 11 522635.0680081422 21 178798.6043266053 31 0.0 0 LINE 5 21E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522681.0115798427 20 178842.8933638417 30 0.0 11 522634.8799687523 21 178796.7125008545 31 0.0 0 LINE 5 21E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522728.7739305676 20 178829.6902051285 30 0.0 11 522663.7695582929 21 178911.2829414423 31 0.0 0 LINE 5 21E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522793.3232115586 20 178988.9272074254 30 0.0 11 522540.2451840974 21 178830.46508779 31 0.0 0 LINE 5 21EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522525.9120197558 20 178732.9749902497 30 0.0 11 522475.8538351816 21 178780.2374691257 31 0.0 0 LINE 5 21EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522498.4146227873 20 178802.708757059 30 0.0 11 522457.0214877424 21 178759.1291709232 31 0.0 0 LINE 5 21EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522499.6306233752 20 178794.1890327764 30 0.0 11 522448.4591145681 21 178843.8876504995 31 0.0 0 LINE 5 21ED 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522452.1612918723 20 178844.2241321974 30 0.0 11 522412.4884557117 21 178804.5044158627 31 0.0 0 LINE 5 21EE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522465.9348875831 20 178757.6489182592 30 0.0 11 522409.7442253048 21 178811.0221069516 31 0.0 0 LINE 5 21EF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522753.9897929319 20 179232.745657081 30 0.0 11 522663.2980889141 21 179165.8159524214 31 0.0 0 LINE 5 21F0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522788.4955386514 20 178613.7209607204 30 0.0 11 522629.152581096 21 178402.478039806 31 0.0 0 LINE 5 21F1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523087.4314069828 20 178627.8710157389 30 0.0 11 522397.3513749961 21 177526.8505945155 31 0.0 0 LINE 5 21F2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522746.7643787713 20 178078.788113883 30 0.0 11 522635.8535568769 21 178176.5453862029 31 0.0 0 LINE 5 21F3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522769.9565157756 20 178241.7732036145 30 0.0 11 522508.1557723742 21 177822.3152467851 31 0.0 0 LINE 5 21F4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522665.4492208762 20 178162.7661655775 30 0.0 11 522584.5609777499 21 178176.1149624734 31 0.0 0 LINE 5 21F5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522671.1132110915 20 178242.2849358682 30 0.0 11 522655.6344066736 21 178155.8104593216 31 0.0 0 LINE 5 21F6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522675.2807850979 20 178225.2838461286 30 0.0 11 522538.3595101266 21 178369.5295297541 31 0.0 0 LINE 5 21F7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522817.6527627173 20 178372.429835449 30 0.0 11 522391.3069186522 21 178078.096472962 31 0.0 0 LINE 5 21F8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522494.6300523502 20 178335.0309483416 30 0.0 11 522587.8825239725 21 178173.3404560525 31 0.0 0 LINE 5 21F9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522545.2148699541 20 178368.4194202566 30 0.0 11 522494.4642459159 21 178334.199618372 31 0.0 0 LINE 5 21FA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522351.0282163845 20 178593.6830365074 30 0.0 11 522512.7599356921 21 178344.3061788763 31 0.0 0 LINE 5 21FB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522391.2775313359 20 178538.3507658254 30 0.0 11 522300.7871731041 21 178470.4589667354 31 0.0 0 LINE 5 21FC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522256.9109821169 20 178539.1006810888 30 0.0 11 522679.2484233736 21 177912.6003330697 31 0.0 0 LINE 5 21FD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522496.1394130775 20 178061.7366876876 30 0.0 11 522192.1014177453 21 177744.8066244325 31 0.0 0 LINE 5 21FE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522538.3415558925 20 178006.5225031963 30 0.0 11 522414.991606401 21 178156.1697820629 31 0.0 0 LINE 5 21FF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522481.6205830464 20 177961.1889676354 30 0.0 11 522441.1277422392 21 178011.1487068806 31 0.0 0 LINE 5 2200 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522533.8934511245 20 177976.1827093689 30 0.0 11 522466.0766122282 21 177964.429757182 31 0.0 0 LINE 5 2201 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522483.4210609369 20 177975.2572160508 30 0.0 11 522222.7916842517 21 177667.5732454571 31 0.0 0 LINE 5 2202 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522738.9858306533 20 177585.8169169486 30 0.0 11 522176.1206057709 21 177987.17906715 31 0.0 0 LINE 5 2203 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522246.2006903077 20 178034.8650788645 30 0.0 11 522093.2129145495 21 177851.4788412087 31 0.0 0 LINE 5 2204 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522177.8865197101 20 178212.7385587857 30 0.0 11 522245.0544657469 21 178016.7912471776 31 0.0 0 LINE 5 2205 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522264.0474825756 20 178199.3866705242 30 0.0 11 522192.2382559694 21 178153.1832644204 31 0.0 0 LINE 5 2206 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522465.4714841699 20 177624.8831154229 30 0.0 11 522395.9002371468 21 177682.1712694014 31 0.0 0 LINE 5 2207 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522450.1881014992 20 177545.9465816251 30 0.0 11 522092.8261854525 21 177854.5573566635 31 0.0 0 LINE 5 2208 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522426.0545465842 20 178106.0486912007 30 0.0 11 522138.5813376741 21 177794.2885582321 31 0.0 0 LINE 5 2209 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521976.6627601065 20 178103.1017202797 30 0.0 11 522144.8999162999 21 177791.3340972542 31 0.0 0 LINE 5 220A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522255.1030212797 20 178270.6731464957 30 0.0 11 522002.6708924326 21 178050.2917664946 31 0.0 0 LINE 5 220B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522320.3033366504 20 178203.5499545608 30 0.0 11 522230.5836526111 21 178285.390310269 31 0.0 0 LINE 5 220C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522312.9048889996 20 178345.782483584 30 0.0 11 522359.4218327516 21 178234.3199117933 31 0.0 0 LINE 5 220D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522359.1406537046 20 178241.0501090313 30 0.0 11 522318.1752510736 21 178203.1099366461 31 0.0 0 LINE 5 220E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522576.3235913146 20 178500.0733859163 30 0.0 11 522125.301511771 21 178163.7749288433 31 0.0 0 LINE 5 220F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522123.1292867654 20 178150.8787587293 30 0.0 11 522108.7648381229 21 178170.4598002547 31 0.0 0 LINE 5 2210 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522096.2678808032 20 177962.6455004086 30 0.0 11 522057.339885885 21 177939.4345464232 31 0.0 0 LINE 5 2211 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522111.7918597045 20 177962.0695101251 30 0.0 11 522087.7479171678 21 177961.0520328995 31 0.0 0 LINE 5 2212 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522153.6582751383 20 177913.5342327866 30 0.0 11 522105.1775131542 21 177966.5576058281 31 0.0 0 LINE 5 2213 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522198.2723013558 20 178166.4194482549 30 0.0 11 521963.5928772264 21 178432.8390725215 31 0.0 0 LINE 5 2214 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522273.9766300119 20 178528.9965730892 30 0.0 11 522071.4855426733 21 178504.0164230226 31 0.0 0 LINE 5 2215 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522077.167727447 20 178534.5950709659 30 0.0 11 522191.142326411 21 178208.9555915796 31 0.0 0 LINE 5 2216 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522294.0270329515 20 178285.979161438 30 0.0 11 522272.5428685532 21 178314.2709342715 31 0.0 0 LINE 5 2217 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522448.3713688994 20 178621.9199470397 30 0.0 11 522204.1543956301 21 178507.8708940481 31 0.0 0 LINE 5 2218 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522351.0234939022 20 178017.2571345561 30 0.0 11 522312.66148505 21 178044.4318694172 31 0.0 0 LINE 5 2219 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522358.6050567503 20 178088.7209066533 30 0.0 11 522312.47344566 21 178042.5400436663 31 0.0 0 LINE 5 221A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522406.3674074755 20 178075.5177479402 30 0.0 11 522341.3630352003 21 178157.1104842541 31 0.0 0 LINE 5 221B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522470.9166884662 20 178234.7547502371 30 0.0 11 522217.8386610046 21 178076.2926306018 31 0.0 0 LINE 5 221C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522431.5832698395 20 178478.573199893 30 0.0 11 522340.8915658216 21 178411.6434952332 31 0.0 0 LINE 5 221D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522444.7021691809 20 177827.9780981021 30 0.0 11 522306.7460580036 21 177648.3055826175 31 0.0 0 LINE 5 221E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522046.0666304656 20 178429.3247346246 30 0.0 11 521928.5504172098 21 178551.8924190301 31 0.0 0 LINE 5 221F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522362.2274122185 20 178758.0753758135 30 0.0 11 521811.0834485826 21 178241.2466501194 31 0.0 0 LINE 5 2220 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521929.1153236254 20 178445.7925823553 30 0.0 11 521567.7615717663 21 178695.4067518605 31 0.0 0 LINE 5 2221 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521881.3366063116 20 178395.3265422981 30 0.0 11 522009.4013641621 21 178540.9594228863 31 0.0 0 LINE 5 2222 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521827.5389805842 20 178444.093474467 30 0.0 11 521870.4030224746 21 178492.034267274 31 0.0 0 LINE 5 2223 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521850.6757286721 20 178394.8801031518 30 0.0 11 521828.2598447447 21 178459.9553186394 31 0.0 0 LINE 5 2224 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521841.714326795 20 178444.559193175 30 0.0 11 521496.4098163296 21 178652.7943794518 31 0.0 0 LINE 5 2225 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521666.0539948833 20 178335.0001542468 30 0.0 11 521852.7254182287 21 178697.029813184 31 0.0 0 LINE 5 2226 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521862.7351384069 20 178688.2490104224 30 0.0 11 521657.3014221008 21 178810.0388289521 31 0.0 0 LINE 5 2227 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522027.4403528741 20 178784.0508532594 30 0.0 11 521844.7097751325 21 178686.4987243258 31 0.0 0 LINE 5 2228 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522027.9975254821 20 178696.8632738643 30 0.0 11 521970.9353580419 21 178760.3867247183 31 0.0 0 LINE 5 2229 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521412.5972422444 20 178408.9140228072 30 0.0 11 521660.2788883792 21 178810.9114751353 31 0.0 0 LINE 5 222A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521961.6854801614 20 178522.0462843632 30 0.0 11 521608.076746813 21 178756.1319311876 31 0.0 0 LINE 5 222B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521988.6546724721 20 179045.2030786144 30 0.0 11 521606.1675726558 21 178749.4231064354 31 0.0 0 LINE 5 222C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522147.8980355549 20 179190.6462879181 30 0.0 11 521764.9757191689 21 178866.4730453769 31 0.0 0 LINE 5 222D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522061.0495505812 20 178987.4824111563 30 0.0 11 521953.4288271045 21 179034.4644035328 31 0.0 0 LINE 5 222E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522012.1359214122 20 178949.2402025678 30 0.0 11 521980.4330525875 21 179054.4092521422 31 0.0 0 LINE 5 222F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521870.5780597225 20 178822.4937996476 30 0.0 11 522008.3775325211 21 178970.2047899548 31 0.0 0 LINE 5 2230 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522071.0225076675 20 178739.4063192945 30 0.0 11 521839.1339891647 21 178931.1229095936 31 0.0 0 LINE 5 2231 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522158.9666137042 20 178763.5770516162 30 0.0 11 522059.4462119843 21 178693.9842706105 31 0.0 0 LINE 5 2232 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522133.2961670834 20 178623.4847338028 30 0.0 11 522193.7925335648 21 178728.0214288374 31 0.0 0 LINE 5 2233 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522192.6461803232 20 178721.3836211599 30 0.0 11 522156.9129995139 21 178764.2877081752 31 0.0 0 LINE 5 2234 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522374.6292981416 20 178436.5264092339 30 0.0 11 522374.6203703744 21 178436.5350655447 31 0.0 0 LINE 5 2235 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522269.5500816715 20 178538.4106061858 30 0.0 11 521970.7185488986 21 178828.1559217988 31 0.0 0 LINE 5 2236 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521957.6410111656 20 178828.2440803406 30 0.0 11 521974.6811471498 21 178845.5469222367 31 0.0 0 LINE 5 2237 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521767.5329517585 20 178824.7483090856 30 0.0 11 521738.4119410404 21 178859.4773158093 31 0.0 0 LINE 5 2238 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521769.4396063798 20 178809.3310994195 30 0.0 11 521764.6013748971 21 178832.9051942855 31 0.0 0 LINE 5 2239 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521728.2008166475 20 178760.2614335449 30 0.0 11 521772.8156345441 21 178816.5764439355 31 0.0 0 LINE 5 223A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521984.9643210763 20 178756.5403676881 30 0.0 11 522216.8329030719 21 179020.4090566216 31 0.0 0 LINE 5 223B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522268.0703291239 20 178934.4646333423 30 0.0 11 522025.8194031096 21 178770.3614495457 31 0.0 0 LINE 5 223C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522118.262368564 20 178681.074321181 30 0.0 11 522142.766564551 21 178706.7947043234 31 0.0 0 LINE 5 223D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522111.3814489866 20 178890.3145777064 30 0.0 11 522049.7796018531 21 178960.4362764188 31 0.0 0 LINE 5 223E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522075.9275963096 20 178936.9454593836 30 0.0 11 521995.4597844196 21 178958.7975414727 31 0.0 0 LINE 5 223F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522068.4847287545 20 178926.1345975258 30 0.0 11 522047.4637958751 21 179003.4797201811 31 0.0 0 LINE 5 2240 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522175.729506542 20 179110.717409931 30 0.0 11 522042.522551726 21 178991.8628343214 31 0.0 0 LINE 5 2241 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521862.0663092455 20 178581.9597234564 30 0.0 11 521882.7766106609 21 178624.1639098984 31 0.0 0 LINE 5 2242 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521933.824660209 20 178585.8699516644 30 0.0 11 521880.879005866 21 178624.0478946972 31 0.0 0 LINE 5 2243 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521928.4060567806 20 178536.6134365247 30 0.0 11 521998.5900628049 21 178613.7960014759 31 0.0 0 LINE 5 2244 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522095.8981080569 20 178498.2800915594 30 0.0 11 521899.1103917653 21 178722.8537455348 31 0.0 0 LINE 5 2245 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521800.5821568744 20 178721.4588807749 30 0.0 11 521839.2582663639 21 178778.4125664076 31 0.0 0 LINE 5 2246 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521865.0393467737 20 178759.7234302135 30 0.0 11 521815.4172322763 21 178793.6382899275 31 0.0 0 LINE 5 2247 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521856.8225113138 20 178757.1645292175 30 0.0 11 521897.7260743494 21 178815.6057342713 31 0.0 0 LINE 5 2248 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521898.6485579601 20 178812.0045732485 30 0.0 11 521853.1112301707 21 178844.8365937855 31 0.0 0 LINE 5 2249 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521815.3771462296 20 178784.6029018461 30 0.0 11 521859.1079719484 21 178848.5849515198 31 0.0 0 LINE 5 224A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 521724.7223942844 20 178443.219910869 30 0.0 11 521490.7750619347 21 178566.8418969614 31 0.0 0 LINE 5 224B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523117.2926295911 20 178560.6644605667 30 0.0 11 523044.0169703556 21 178443.2619738169 31 0.0 0 LINE 5 224C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523264.3763135458 20 178537.648302931 30 0.0 11 523113.2352405079 21 178125.2890619266 31 0.0 0 LINE 5 224D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523192.2762143955 20 178488.2313908624 30 0.0 11 523030.3712347359 21 178118.9295152746 31 0.0 0 LINE 5 224E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522985.5900973007 20 178476.3745692628 30 0.0 11 523297.0399504419 21 178314.3249674994 31 0.0 0 LINE 5 224F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522885.4087712395 20 178318.1826624708 30 0.0 11 522967.4362385638 21 178280.8519029954 31 0.0 0 LINE 5 2250 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522821.2116009624 20 178269.7752097155 30 0.0 11 523255.4409771307 21 178084.3217158616 31 0.0 0 LINE 5 2251 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523334.9725049224 20 178494.1555457205 30 0.0 11 523181.1986239229 21 178098.9482331972 31 0.0 0 LINE 5 2252 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523564.082167775 20 178086.5077055402 30 0.0 11 523175.7686956189 21 178103.3264924552 31 0.0 0 LINE 5 2253 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523288.1701818084 20 178387.7452926942 30 0.0 11 523329.4351094049 21 178365.2216231799 31 0.0 0 LINE 5 2254 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523349.0378291003 20 178425.9510557512 30 0.0 11 523327.8182264157 21 178364.2215967394 31 0.0 0 LINE 5 2255 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522866.3761997883 20 178342.019559905 30 0.0 11 522789.2659781276 21 177829.7140643849 31 0.0 0 LINE 5 2256 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523270.1298366463 20 178020.0343941863 30 0.0 11 522887.4587682224 21 178066.3771239369 31 0.0 0 LINE 5 2257 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523262.4436127314 20 177911.5069355821 30 0.0 11 522514.0986425375 21 178015.677017375 31 0.0 0 LINE 5 2258 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522728.5151155639 20 177916.7015758992 30 0.0 11 522577.3740425265 21 177504.3423348947 31 0.0 0 LINE 5 2259 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522660.374377817 20 177930.3568637583 30 0.0 11 522848.9968790347 21 177885.2894681586 31 0.0 0 LINE 5 225A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522644.5680059249 20 177859.4868643608 30 0.0 11 522707.2375782236 21 177845.0587525647 31 0.0 0 LINE 5 225B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522635.0732243063 20 177913.0323044117 30 0.0 11 522654.3079907121 21 177846.9469105315 31 0.0 0 LINE 5 225C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522590.2211719876 20 177716.2978878188 30 0.0 11 522494.5100367545 21 177497.9827882424 31 0.0 0 LINE 5 225D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522954.1318415535 20 177768.6770004641 30 0.0 11 522944.1725065651 21 177683.8705655197 31 0.0 0 LINE 5 225E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522407.7306262626 20 177597.3181014599 30 0.0 11 522615.1644193533 21 177534.1094386737 31 0.0 0 LINE 5 225F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522799.1113069407 20 177873.2088186888 30 0.0 11 522645.3374259413 21 177478.0015061654 31 0.0 0 LINE 5 2260 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523022.100320529 20 177791.958987279 30 0.0 11 522935.0210570945 21 177468.3741696419 31 0.0 0 LINE 5 2261 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522933.1579137868 20 177821.0425273467 30 0.0 11 523046.0929332863 21 177776.3978535631 31 0.0 0 LINE 5 2262 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522949.7838224009 20 177872.405723743 30 0.0 11 522933.6975271531 21 177818.9374901971 31 0.0 0 LINE 5 2263 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523087.0618515006 20 178181.3008986546 30 0.0 11 522983.093562173 21 177628.3920786128 31 0.0 0 LINE 5 2264 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522972.4627828186 20 177620.7752357368 30 0.0 11 522996.3635900396 21 177616.473377276 31 0.0 0 LINE 5 2265 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522953.4121825747 20 177695.1059851142 30 0.0 11 523295.8437629662 21 177601.3271972424 31 0.0 0 LINE 5 2266 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523245.8695832916 20 177922.3987161826 30 0.0 11 523312.3861028709 21 177729.5199952934 31 0.0 0 LINE 5 2267 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523337.3596793261 20 177748.0581023406 30 0.0 11 522994.7561350993 21 177707.3875819691 31 0.0 0 LINE 5 2268 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523252.7318654509 20 178119.8858992136 30 0.0 11 523257.5655084273 21 177850.3942436533 31 0.0 0 LINE 5 2269 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522752.3089838269 20 177766.7985656624 30 0.0 11 522793.5739114233 21 177744.2748961479 31 0.0 0 LINE 5 226A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522813.1766311186 20 177805.0043287195 30 0.0 11 522791.957028434 21 177743.2748697074 31 0.0 0 LINE 5 226B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522780.3331484347 20 177842.1105437243 30 0.0 11 522882.1879569673 21 177819.5596897982 31 0.0 0 LINE 5 226C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523131.3338591148 20 178041.830442996 30 0.0 11 523111.0507117023 21 177930.9558991438 31 0.0 0 LINE 5 226D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523256.4548944052 20 177673.8722699746 30 0.0 11 523418.1880398422 21 177622.1490903978 31 0.0 0 LINE 5 226E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523412.8890915473 20 178102.3147584902 30 0.0 11 523190.7292212283 21 177380.1537014019 31 0.0 0 LINE 5 226F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523322.6267890519 20 177576.0454917421 30 0.0 11 523797.1159115772 21 177362.2379585418 31 0.0 0 LINE 5 2270 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523298.2812622759 20 177510.9538459399 30 0.0 11 523372.8476595442 21 177689.9772257265 31 0.0 0 LINE 5 2271 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523222.927963442 20 177531.0523223896 30 0.0 11 523379.6568120642 21 177491.6654751828 31 0.0 0 LINE 5 2272 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523359.9152172615 20 177496.9883692452 30 0.0 11 523596.0536168629 21 177281.4952158278 31 0.0 0 LINE 5 2273 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523427.4150912213 20 177736.5054243714 30 0.0 11 523769.2530115786 21 177491.8840838794 31 0.0 0 LINE 5 2274 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523507.126612966 20 177922.1356525813 30 0.0 11 523488.329698442 21 177802.1600653523 31 0.0 0 LINE 5 2275 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523392.5543045613 20 177837.5305966636 30 0.0 11 523459.8863007098 21 177937.800897655 31 0.0 0 LINE 5 2276 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523454.426941331 20 177933.855012242 30 0.0 11 523508.6671999444 21 177920.6030222447 31 0.0 0 LINE 5 2277 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523118.5824410856 20 177972.1950437001 30 0.0 11 523118.5941394303 21 177972.1908264169 31 0.0 0 LINE 5 2278 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523256.2711700598 20 177922.5579080452 30 0.0 11 524206.9096920682 21 177483.8653524531 31 0.0 0 LINE 5 2279 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523557.8080143858 20 177611.8563831612 30 0.0 11 523689.0873473517 21 177951.6823052399 31 0.0 0 LINE 5 227A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523580.5831528878 20 178047.796043503 30 0.0 11 523538.933167342 21 177779.4375370703 31 0.0 0 LINE 5 227B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523450.8935312671 20 177849.3250996077 30 0.0 11 523463.2340032221 21 177882.6373568399 31 0.0 0 LINE 5 227C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523511.7455392582 20 177432.5135306539 30 0.0 11 523503.2210136295 21 177612.7787581072 31 0.0 0 LINE 5 227D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523446.394163893 20 177641.8139048939 30 0.0 11 523503.9504363352 21 177611.02310837 31 0.0 0 LINE 5 227E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523296.5081963189 20 177748.9305834032 30 0.0 11 523523.0900234353 21 177687.5092883659 31 0.0 0 LINE 5 227F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523432.4273113113 20 178034.7409239569 30 0.0 11 523234.4501864689 21 177967.0466580876 31 0.0 0 LINE 5 2280 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523451.2216057295 20 177624.6776377849 30 0.0 11 523501.8291267167 21 177730.3614702396 31 0.0 0 LINE 5 2281 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522989.217000509 20 178474.4874654012 30 0.0 11 522793.0428596554 21 178446.5607997053 31 0.0 0 LINE 5 2282 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524372.789972169 20 175674.8090526176 30 0.0 11 524656.1468986651 21 175585.4719382363 31 0.0 0 LINE 5 2283 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524609.9276783371 20 175845.1157330388 30 0.0 11 524455.1045044787 21 175629.5293787359 31 0.0 0 LINE 5 2284 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524837.1252858419 20 175691.9315692493 30 0.0 11 524522.4431839671 21 175809.978900038 31 0.0 0 LINE 5 2285 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524477.787930299 20 175895.319111842 30 0.0 11 524346.7470590595 21 175769.9642275434 31 0.0 0 LINE 5 2286 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524062.1636056715 20 176105.7794112304 30 0.0 11 523970.0631542091 21 175969.8244162033 31 0.0 0 LINE 5 2287 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524574.029780333 20 175783.4213092316 30 0.0 11 524391.1894371221 21 175944.5171051869 31 0.0 0 LINE 5 2288 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524475.2708319019 20 175608.7641049108 30 0.0 11 524226.9133393759 21 175758.6792206554 31 0.0 0 LINE 5 2289 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523564.0490320267 20 177477.8787289761 30 0.0 11 523802.7362644429 21 177848.6042946811 31 0.0 0 LINE 5 228A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523932.823944941 20 177859.2898223397 30 0.0 11 524279.7674590437 21 177779.3509319115 31 0.0 0 LINE 5 228B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523183.9420759116 20 178234.5704337749 30 0.0 11 523502.8945818244 21 178227.2281691125 31 0.0 0 LINE 5 228C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 525106.4182794202 20 176431.403902401 30 0.0 11 525008.4747173305 21 176216.1914333139 31 0.0 0 LINE 5 228D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523366.006484977 20 176426.2010255347 30 0.0 11 523009.6530059661 21 176602.0695102401 31 0.0 0 LINE 5 228E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522712.3374426255 20 175087.5753245441 30 0.0 11 523600.7708103929 21 177556.09968367 31 0.0 0 LINE 5 228F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522618.6029150704 20 177570.0955422215 30 0.0 11 522409.733756899 21 177698.6243181571 31 0.0 0 LINE 5 2290 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522592.7488602845 20 177591.5478147034 30 0.0 11 522563.14617815 21 177351.7929963389 31 0.0 0 LINE 5 2291 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523036.3238127537 20 177433.5858675359 30 0.0 11 522287.97884256 21 177537.755949329 31 0.0 0 LINE 5 2292 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522502.3953155862 20 177438.780507853 30 0.0 11 522351.2542425488 21 177026.4212668487 31 0.0 0 LINE 5 2293 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522434.2545778394 20 177452.4357957124 30 0.0 11 522622.8770790572 21 177407.3684001126 31 0.0 0 LINE 5 2294 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522418.4482059472 20 177381.5657963146 30 0.0 11 522481.1177782461 21 177367.1376845188 31 0.0 0 LINE 5 2295 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522430.2952164364 20 177389.3635957844 30 0.0 11 522268.3902367768 21 177020.0617201964 31 0.0 0 LINE 5 2296 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522321.2724142016 20 177326.8178655068 30 0.0 11 522584.9471001396 21 177189.5000098832 31 0.0 0 LINE 5 2297 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522588.0570526725 20 177202.4470246138 30 0.0 11 522490.5245491324 21 176984.4488997454 31 0.0 0 LINE 5 2298 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522777.8581554662 20 177219.2202813615 30 0.0 11 522572.3242687356 21 177193.4772569366 31 0.0 0 LINE 5 2299 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522728.0120415759 20 177290.7559324181 30 0.0 11 522718.0527065875 21 177205.9494974737 31 0.0 0 LINE 5 229A 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522181.6108262849 20 177119.3970334139 30 0.0 11 522493.4599791716 21 176985.4539207836 31 0.0 0 LINE 5 229B 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522572.9915069632 20 177395.2877506425 30 0.0 11 522419.2176259636 21 177000.0804381194 31 0.0 0 LINE 5 229C 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522956.9896205523 20 176982.7148825853 30 0.0 11 522413.7876976597 21 177004.4586973774 31 0.0 0 LINE 5 229D 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522922.6758630746 20 177072.4490018759 30 0.0 11 522861.8773769898 21 176971.984720566 31 0.0 0 LINE 5 229E 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522860.6604433927 20 177075.4651845424 30 0.0 11 522895.4410376646 21 176971.2734807353 31 0.0 0 LINE 5 229F 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522671.9130625024 20 177097.3216496357 30 0.0 11 522869.6857360561 21 177056.1731264949 31 0.0 0 LINE 5 22A0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522795.9805205514 20 177314.0379192328 30 0.0 11 522708.9012571168 21 176990.453101596 31 0.0 0 LINE 5 22A1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522707.0381138093 20 177343.1214593006 30 0.0 11 522819.9731333086 21 177298.4767855171 31 0.0 0 LINE 5 22A2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522723.6640224234 20 177394.484655697 30 0.0 11 522707.5777271754 21 177341.016422151 31 0.0 0 LINE 5 22A3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522930.7351701595 20 178092.0130773293 30 0.0 11 522756.9737621957 21 177150.4710105668 31 0.0 0 LINE 5 22A4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522746.3429828408 20 177142.8541676907 30 0.0 11 522770.2437900621 21 177138.5523092299 31 0.0 0 LINE 5 22A5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522589.0472400136 20 177036.0302754347 30 0.0 11 522585.2976405672 21 176990.8630563793 31 0.0 0 LINE 5 22A6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522581.7099174523 20 177049.7229517024 30 0.0 11 522591.3587077851 21 177027.6764717624 31 0.0 0 LINE 5 22A7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522519.7165579189 20 177066.0107772594 30 0.0 11 522588.647496611 21 177045.7527402797 31 0.0 0 LINE 5 22A8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522727.2923825973 20 177217.1849170681 30 0.0 11 523069.7239629884 21 177123.4061291966 31 0.0 0 LINE 5 22A9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523019.7497833138 20 177444.4776481365 30 0.0 11 523086.2663028933 21 177251.5989272474 31 0.0 0 LINE 5 22AA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523111.2398793484 20 177270.1370342946 30 0.0 11 522768.6363351217 21 177229.466513923 31 0.0 0 LINE 5 22AB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522792.6305951866 20 177355.728814859 30 0.0 11 522827.4843337016 21 177348.8578148228 31 0.0 0 LINE 5 22AC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522907.727477809 20 177180.8530314709 30 0.0 11 522897.8668974793 21 177088.0381126475 31 0.0 0 LINE 5 22AD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522905.6718170554 20 177122.3108325493 30 0.0 11 522852.5534162397 21 177058.0378387128 31 0.0 0 LINE 5 22AE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522893.3554149922 20 177126.8470481271 30 0.0 11 522920.808456164 21 177051.5444708262 31 0.0 0 LINE 5 22AF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523035.5253002461 20 177046.6448839554 30 0.0 11 522910.0703423325 21 177058.1823049736 31 0.0 0 LINE 5 22B0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523118.8441793682 20 177673.3885298317 30 0.0 11 523031.4457084499 21 177372.4731756072 31 0.0 0 LINE 5 22B1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522526.1891838492 20 177288.8774976165 30 0.0 11 522567.4541114458 21 177266.3538281018 31 0.0 0 LINE 5 22B2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522587.0568311411 20 177327.0832606734 30 0.0 11 522565.8372284563 21 177265.3538016613 31 0.0 0 LINE 5 22B3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522554.2133484569 20 177364.1894756781 30 0.0 11 522656.0681569896 21 177341.6386217522 31 0.0 0 LINE 5 22B4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522668.9039854603 20 177492.1312216434 30 0.0 11 522637.7326444329 21 177195.1681282435 31 0.0 0 LINE 5 22B5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522556.4507353304 20 177139.4634608348 30 0.0 11 522620.8994502913 21 177115.2575340343 31 0.0 0 LINE 5 22B6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522631.1749151017 20 177145.3965907832 30 0.0 11 522610.21045187 21 177089.0666410405 31 0.0 0 LINE 5 22B7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522622.9871527007 20 177142.7461368318 30 0.0 11 522690.1134319515 21 177118.6103014182 31 0.0 0 LINE 5 22B8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522688.7892890037 20 177122.0839136846 30 0.0 11 522670.5365274142 21 177068.9950590248 31 0.0 0 LINE 5 22B9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522604.9649153015 20 177096.4235555283 30 0.0 11 522677.5971672725 21 177069.393132444 31 0.0 0 LINE 5 22BA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522905.2140591371 20 177563.9093749503 30 0.0 11 522884.9309117248 21 177453.0348310975 31 0.0 0 LINE 5 22BB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522916.9609239598 20 176997.2583139437 30 0.0 11 523309.4597069945 21 176690.1548750701 31 0.0 0 LINE 5 22BC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522983.3748628622 20 177015.0960695728 30 0.0 11 523154.5497859308 21 176865.5345421712 31 0.0 0 LINE 5 22BD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523030.3350944276 20 177195.9512019287 30 0.0 11 523192.0682398648 21 177144.2280223518 31 0.0 0 LINE 5 22BE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523149.8577154443 20 177504.407561558 30 0.0 11 522964.6094212506 21 176902.2326333558 31 0.0 0 LINE 5 22BF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523072.1614622984 20 177033.0327778939 30 0.0 11 523146.7278595665 21 177212.0561576804 31 0.0 0 LINE 5 22C0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523139.6044650193 20 177006.1285107414 30 0.0 11 523163.8405590469 21 177065.6957622174 31 0.0 0 LINE 5 22C1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523085.2301433318 20 177005.292945494 30 0.0 11 523153.5370120867 21 177013.7444071367 31 0.0 0 LINE 5 22C2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523133.7954172838 20 177019.0673011991 30 0.0 11 523369.9338168852 21 176803.5741477818 31 0.0 0 LINE 5 22C3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523201.2952912438 20 177258.5843563253 30 0.0 11 523469.6868838103 21 177102.9976669321 31 0.0 0 LINE 5 22C4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522892.4626411082 20 177494.273975654 30 0.0 11 522892.4743394529 21 177494.2697583709 31 0.0 0 LINE 5 22C5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523370.9808339675 20 177511.3258745974 30 0.0 11 523229.2729998291 21 177132.4780320576 31 0.0 0 LINE 5 22C6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523285.6257392806 20 176954.5924626077 30 0.0 11 523277.1012136519 21 177134.8576900612 31 0.0 0 LINE 5 22C7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523220.2743639153 20 177163.8928368478 30 0.0 11 523277.8306363575 21 177133.1020403241 31 0.0 0 LINE 5 22C8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523070.3883963411 20 177271.0095153573 30 0.0 11 523296.9702234576 21 177209.5882203198 31 0.0 0 LINE 5 22C9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523142.0526494567 20 176768.5200463112 30 0.0 11 523294.2312541298 21 176974.6534660719 31 0.0 0 LINE 5 22CA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522970.8974974627 20 176465.2881509185 30 0.0 11 522810.4737277414 21 176334.2496221969 31 0.0 0 LINE 5 22CB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522882.3557151454 20 176714.0152435247 30 0.0 11 522564.2667872466 21 176349.8702072874 31 0.0 0 LINE 5 22CC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523033.9977751668 20 176916.9623170844 30 0.0 11 522697.4499817042 21 176495.4138513231 31 0.0 0 LINE 5 22CD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522964.5437895761 20 176671.3794105949 30 0.0 11 522849.8705059365 21 176696.6690477735 31 0.0 0 LINE 5 22CE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522923.946205671 20 176624.402333022 30 0.0 11 522872.5093980661 21 176721.4582741256 31 0.0 0 LINE 5 22CF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522809.5624480385 20 176472.6801037702 30 0.0 11 522916.2056970165 21 176644.2448111216 31 0.0 0 LINE 5 22D0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523215.1199951155 20 176322.0721058092 30 0.0 11 522757.7106326434 21 176573.1808616837 31 0.0 0 LINE 5 22D1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522893.8712146281 20 176495.1535351531 30 0.0 11 522907.2447679747 21 176515.4242688083 31 0.0 0 LINE 5 22D2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522934.5413278785 20 176430.0848978472 30 0.0 11 523147.5422717344 21 176808.6187573986 31 0.0 0 LINE 5 22D3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523151.9711731364 20 176777.1695290931 30 0.0 11 522961.8759750708 21 176843.336952638 31 0.0 0 LINE 5 22D4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523258.3890803028 20 176748.837564359 30 0.0 11 522971.9536615696 21 176451.5436331187 31 0.0 0 LINE 5 22D5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523032.7113255405 20 176585.7752349081 30 0.0 11 522958.7152083104 21 176642.6647316137 31 0.0 0 LINE 5 22D6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522988.9113168237 20 176624.6722017828 30 0.0 11 522905.7369816604 21 176630.5554162212 31 0.0 0 LINE 5 22D7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522983.6988970849 20 176612.6263854128 30 0.0 11 522948.121624614 21 176684.4484245179 31 0.0 0 LINE 5 22D8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 523053.235560517 20 176814.4602513443 30 0.0 11 522945.5194598575 21 176672.0954220733 31 0.0 0 LINE 5 22D9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522635.2002345229 20 176845.2024216892 30 0.0 11 522466.1286024288 21 177011.3332236175 31 0.0 0 LINE 5 22DA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522553.6330427988 20 176814.4001867653 30 0.0 11 522593.3851924734 21 176889.9719166494 31 0.0 0 LINE 5 22DB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522837.6417227955 20 176884.3357929314 30 0.0 11 522844.323322404 21 177001.5743700122 31 0.0 0 LINE 5 22DC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522784.7924330184 20 176916.9235545342 30 0.0 11 522872.4051397392 21 176983.1777204499 31 0.0 0 LINE 5 22DD 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522594.441952885 20 176798.3315183045 30 0.0 11 522719.2650538682 21 177012.829104645 31 0.0 0 LINE 5 22DE 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522661.679110632 20 176714.7524199197 30 0.0 11 522561.8551868182 21 176783.9091243017 31 0.0 0 LINE 5 22DF 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522521.3914708863 20 176690.1717878172 30 0.0 11 522640.4314452108 21 176669.7459346153 31 0.0 0 LINE 5 22E0 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522633.8086779382 20 176668.5156622181 30 0.0 11 522661.6323248885 21 176716.9250163114 31 0.0 0 LINE 5 22E1 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522488.9328765944 20 176532.853079181 30 0.0 11 522656.8608817391 21 176913.7110815744 31 0.0 0 LINE 5 22E2 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522594.650425108 20 176875.4803517717 30 0.0 11 522922.6215479869 21 176749.6842195823 31 0.0 0 LINE 5 22E3 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522859.8210929988 20 176671.7880028932 30 0.0 11 522621.7999646015 21 176841.9682265487 31 0.0 0 LINE 5 22E4 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522570.1753130277 20 176724.2703569694 30 0.0 11 522602.804927966 21 176710.223935399 31 0.0 0 LINE 5 22E5 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522764.0019606305 20 176803.3909148802 30 0.0 11 522808.3650537079 21 176885.5112909946 31 0.0 0 LINE 5 22E6 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522795.4174414889 20 176852.8326215467 30 0.0 11 522787.9633609084 21 176935.8809142724 31 0.0 0 LINE 5 22E7 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522782.6946236574 20 176856.0576669683 30 0.0 11 522847.9250446198 21 176902.6316919044 31 0.0 0 LINE 5 22E8 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522993.0337954206 20 176819.5927547916 30 0.0 11 522835.3151721327 21 176903.2308969453 31 0.0 0 LINE 5 22E9 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522390.9919093851 20 176681.7592009042 30 0.0 11 522533.2440119064 21 176944.2912383229 31 0.0 0 LINE 5 22EA 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 522233.0726592325 20 177213.5460147199 30 0.0 11 522580.016173335 21 177133.6071242916 31 0.0 0 LINE 5 22EB 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 524709.0037862509 20 178824.6619104634 30 0.0 11 524537.941867023 21 178950.6289273412 31 0.0 0 LINE 5 22EC 330 6F 100 AcDbEntity 8 0 100 AcDbLine 10 526843.0193992567 20 179583.5671331468 30 0.0 11 527269.5564950807 21 179979.6252205521 31 0.0 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 281 1 3 ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 B4 3 ACAD_COLOR 350 62 3 ACAD_DETAILVIEWSTYLE 350 69 3 ACAD_GROUP 350 D 3 ACAD_LAYOUT 350 61 3 ACAD_MATERIAL 350 10 3 ACAD_MLEADERSTYLE 350 65 3 ACAD_MLINESTYLE 350 5E 3 ACAD_PLOTSETTINGS 350 60 3 ACAD_PLOTSTYLENAME 350 E 3 ACAD_SCALELIST 350 42 3 ACAD_SECTIONVIEWSTYLE 350 67 3 ACAD_TABLESTYLE 350 63 3 ACAD_VISUALSTYLE 350 29 3 ACDB_RECOMPOSE_DATA 350 22F5 3 AcDbVariableDictionary 350 34B 0 DICTIONARY 5 345 330 2 100 AcDbDictionary 280 1 281 1 3 ACAD_LAYERSTATES 360 346 0 DICTIONARY 5 340 330 54 100 AcDbDictionary 280 1 281 1 3 ADSK_XREC_LAYER_RECONCILED 360 341 0 DICTIONARY 5 135 330 6F 100 AcDbDictionary 280 1 281 1 3 ACAD_SORTENTS 360 136 0 XRECORD 5 B4 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 300 ACDMAC 300 2018 300 ACDMAC_F_S 0 DICTIONARY 5 62 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 69 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Imperial24 350 6A 0 DICTIONARY 5 D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 61 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Layout1 350 6E 3 Model 350 72 0 DICTIONARY 5 10 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 ByBlock 350 19 3 ByLayer 350 11 3 Global 350 21 0 DICTIONARY 5 65 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 66 0 DICTIONARY 5 5E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 5F 0 DICTIONARY 5 60 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 ACDBDICTIONARYWDFLT 5 E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Normal 350 F 100 AcDbDictionaryWithDefault 340 F 0 DICTIONARY 5 42 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 A0 350 43 3 A1 350 44 3 A2 350 45 3 A3 350 46 3 A4 350 47 3 A5 350 48 3 A6 350 49 3 A7 350 4A 3 A8 350 4B 3 A9 350 4C 3 B0 350 4D 3 B1 350 4E 3 B2 350 4F 3 B3 350 50 3 B4 350 51 3 B5 350 52 3 B6 350 53 0 DICTIONARY 5 67 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Imperial24 350 68 0 DICTIONARY 5 63 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 64 0 DICTIONARY 5 29 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 2dWireframe 350 2F 3 Basic 350 2E 3 Brighten 350 35 3 ColorChange 350 39 3 Conceptual 350 32 3 Dim 350 34 3 EdgeColorOff 350 41 3 Facepattern 350 38 3 Flat 350 2A 3 FlatWithEdges 350 2B 3 Gouraud 350 2C 3 GouraudWithEdges 350 2D 3 Hidden 350 31 3 JitterOff 350 3F 3 Linepattern 350 37 3 OverhangOff 350 40 3 Realistic 350 33 3 Shaded 350 3E 3 Shaded with edges 350 3D 3 Shades of Gray 350 3A 3 Sketchy 350 3B 3 Thicken 350 36 3 Wireframe 350 30 3 X-Ray 350 3C 0 XRECORD 5 22F5 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 90 1 330 64 0 DICTIONARY 5 34B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 CANNOSCALE 350 351 3 CMLEADERSTYLE 350 34D 3 CTABLESTYLE 350 34C 3 CVIEWDETAILSTYLE 350 34E 3 CVIEWSECTIONSTYLE 350 34F 3 LAYEREVAL 350 353 3 LAYERNOTIFY 350 354 3 LIGHTINGUNITS 350 352 3 MSLTSCALE 350 350 0 DICTIONARY 5 346 102 {ACAD_REACTORS 330 345 102 } 330 345 100 AcDbDictionary 281 1 0 XRECORD 5 341 102 {ACAD_REACTORS 330 340 102 } 330 340 100 AcDbXrecord 280 1 290 1 0 SORTENTSTABLE 5 136 102 {ACAD_REACTORS 330 135 102 } 330 135 100 AcDbSortentsTable 330 6F 331 324 5 1BF 331 320 5 321 331 31C 5 31D 331 147 5 147 331 BD 5 BD 331 318 5 319 331 143 5 143 331 B9 5 B9 331 17C 5 17C 331 13F 5 13F 331 AD 5 AD 331 A9 5 A9 331 13B 5 13B 331 1B6 5 1B6 331 1F7 5 1F8 331 1F3 5 1F4 331 1B2 5 1B2 331 237 5 238 331 233 5 234 331 2AE 5 2AF 331 22F 5 230 331 26C 5 26D 331 268 5 269 331 2AA 5 2AB 331 22B 5 22C 331 2E7 5 2E8 331 2A6 5 2A7 331 2A2 5 2A3 331 2E3 5 2E4 331 310 5 311 331 EE 5 EE 331 12F 5 130 331 A5 5 A5 331 EA 5 EA 331 308 5 309 331 170 5 170 331 12B 5 12C 331 A1 5 A1 331 E6 5 E6 331 E2 5 E2 331 16C 5 16C 331 127 5 128 331 9D 5 9D 331 168 5 168 331 99 5 99 331 1AE 5 1AE 331 1EF 5 1F0 331 123 5 124 331 1EB 5 1EC 331 1A6 5 1A6 331 1E7 5 1E8 331 1A2 5 1A2 331 227 5 228 331 264 5 265 331 223 5 224 331 260 5 261 331 21F 5 220 331 2DF 5 2E0 331 25C 5 25D 331 258 5 259 331 29A 5 29B 331 21B 5 21C 331 2DB 5 2DC 331 2D7 5 2D8 331 296 5 297 331 292 5 293 331 2D3 5 2D4 331 74 5 74 331 134 5 11B 331 130 5 131 331 DE 5 DE 331 DA 5 DA 331 2F8 5 2F9 331 11F 5 120 331 160 5 160 331 11B 5 11C 331 91 5 91 331 D6 5 D6 331 D2 5 D2 331 15C 5 15C 331 117 5 117 331 8D 5 8D 331 89 5 89 331 19E 5 19E 331 113 5 113 331 1D7 5 1DC 331 1D3 5 1D4 331 217 5 218 331 254 5 255 331 213 5 214 331 250 5 251 331 28E 5 28F 331 20F 5 210 331 2CF 5 2D0 331 24C 5 24D 331 248 5 249 331 28A 5 28B 331 20B 5 20C 331 2CB 5 2CC 331 2C7 5 2C8 331 286 5 287 331 282 5 283 331 F0 5 F0 331 2F4 5 2F5 331 2F0 5 2F1 331 2EC 5 2ED 331 85 5 85 331 CA 5 CA 331 2E8 5 2E9 331 10F 5 10F 331 150 5 150 331 10B 5 10B 331 81 5 81 331 C6 5 C6 331 C2 5 C2 331 14C 5 14C 331 107 5 107 331 7D 5 7D 331 148 5 148 331 1CF 5 1D0 331 18E 5 18E 331 79 5 79 331 1CB 5 1CC 331 186 5 186 331 1C7 5 1C8 331 182 5 182 331 1C3 5 1C4 331 244 5 245 331 207 5 208 331 203 5 204 331 240 5 241 331 27E 5 27F 331 1FF 5 200 331 23C 5 23D 331 27A 5 27B 331 1FB 5 1FC 331 2BB 5 2BC 331 238 5 239 331 2B7 5 2B8 331 276 5 277 331 2B3 5 2B4 331 272 5 273 331 BE 5 BE 331 31D 5 31E 331 319 5 31A 331 144 5 144 331 BA 5 BA 331 FF 5 FF 331 140 5 140 331 AE 5 AE 331 FB 5 FB 331 13C 5 13C 331 17D 5 17D 331 AA 5 AA 331 179 5 179 331 1BF 5 1C0 331 138 5 138 331 1BB 5 1BB 331 1B7 5 1B7 331 1F4 5 1F5 331 1F0 5 1F1 331 1B3 5 1B3 331 234 5 235 331 230 5 231 331 22C 5 22D 331 2AF 5 2B0 331 26D 5 26E 331 269 5 26A 331 2AB 5 2AC 331 228 5 229 331 2E4 5 2E5 331 2A7 5 2A8 331 2A3 5 2A4 331 2E0 5 2E1 331 311 5 312 331 A6 5 A6 331 EF 5 EF 331 A2 5 A2 331 12C 5 12D 331 EB 5 EB 331 309 5 30A 331 9E 5 9E 331 171 5 171 331 E7 5 E7 331 E3 5 E3 331 124 5 125 331 16D 5 16D 331 9A 5 9A 331 169 5 169 331 1AF 5 1AF 331 1EC 5 1ED 331 1AB 5 1AB 331 1E8 5 1E9 331 1A7 5 1A7 331 1E4 5 1E5 331 1E0 5 1E1 331 1A3 5 1A3 331 224 5 225 331 265 5 266 331 220 5 221 331 261 5 262 331 21C 5 21D 331 29F 5 2A0 331 2DC 5 2DD 331 25D 5 25E 331 218 5 219 331 29B 5 29C 331 2D8 5 2D9 331 2D4 5 2D5 331 297 5 298 331 293 5 294 331 2D0 5 2D1 331 75 5 75 331 131 5 132 331 DF 5 DF 331 92 5 92 331 11C 5 11D 331 DB 5 DB 331 2F9 5 2FA 331 8E 5 8E 331 118 5 118 331 D7 5 D7 331 D3 5 D3 331 114 5 114 331 15D 5 15D 331 8A 5 8A 331 159 5 159 331 19F 5 19F 331 1DC 5 1DD 331 110 5 110 331 1D4 5 1D6 331 1D0 5 1D1 331 214 5 215 331 255 5 256 331 210 5 211 331 251 5 252 331 20C 5 20D 331 28F 5 290 331 2CC 5 2CD 331 24D 5 24E 331 249 5 24A 331 208 5 209 331 28B 5 28C 331 2C8 5 2C9 331 287 5 288 331 283 5 284 331 F1 5 F1 331 2F5 5 2F6 331 2F1 5 2F2 331 86 5 86 331 2ED 5 2EE 331 82 5 82 331 CB 5 CB 331 2E9 5 2EA 331 10C 5 10C 331 7E 5 7E 331 108 5 108 331 151 5 151 331 C7 5 C7 331 C3 5 C3 331 104 5 104 331 14D 5 14D 331 7A 5 7A 331 1CC 5 1CD 331 149 5 149 331 18B 5 18B 331 1C8 5 1C9 331 187 5 187 331 1C0 5 1C1 331 183 5 183 331 204 5 205 331 245 5 246 331 200 5 201 331 241 5 242 331 1FC 5 1FD 331 27F 5 280 331 2BC 5 2BD 331 23D 5 23E 331 239 5 23A 331 1F8 5 1F9 331 27B 5 27C 331 2B8 5 2B9 331 2B4 5 2B5 331 277 5 278 331 273 5 274 331 2B0 5 2B1 331 322 5 323 331 31E 5 31F 331 BF 5 BF 331 BB 5 BB 331 141 5 141 331 AF 5 AF 331 AB 5 AB 331 13D 5 13D 331 17A 5 17A 331 1BC 5 1BC 331 139 5 139 331 1B8 5 1B8 331 1F5 5 1F6 331 1B4 5 1B4 331 1F1 5 1F2 331 1B0 5 1B0 331 235 5 236 331 231 5 232 331 26E 5 26F 331 26A 5 26B 331 2AC 5 2AD 331 22D 5 22E 331 2A8 5 2A9 331 229 5 22A 331 2A4 5 2A5 331 2E5 5 2E6 331 2A0 5 2A1 331 2E1 5 2E2 331 312 5 313 331 A7 5 A7 331 EC 5 EC 331 30A 5 30B 331 12D 5 12E 331 A3 5 A3 331 E8 5 E8 331 E4 5 E4 331 16E 5 16E 331 129 5 12A 331 9F 5 9F 331 E0 5 E0 331 16A 5 16A 331 125 5 126 331 9B 5 9B 331 1ED 5 1EE 331 1E9 5 1EA 331 1A4 5 1A4 331 1E5 5 1E6 331 1E1 5 1E2 331 1A0 5 1A0 331 225 5 226 331 262 5 263 331 221 5 222 331 25E 5 25F 331 29C 5 29D 331 21D 5 21E 331 2DD 5 2DE 331 25A 5 25B 331 2D9 5 2DA 331 298 5 299 331 219 5 21A 331 2D5 5 2D6 331 294 5 295 331 290 5 291 331 76 5 76 331 2D1 5 2D2 331 97 5 97 331 DC 5 DC 331 11D 5 11E 331 93 5 93 331 D8 5 D8 331 15E 5 15E 331 119 5 119 331 8F 5 8F 331 D4 5 D4 331 D0 5 D0 331 15A 5 15A 331 115 5 115 331 8B 5 8B 331 1DD 5 1DE 331 111 5 111 331 194 5 194 331 1D1 5 1D2 331 256 5 257 331 215 5 216 331 252 5 253 331 211 5 212 331 24E 5 24F 331 28C 5 28D 331 20D 5 20E 331 2CD 5 2CE 331 24A 5 24B 331 288 5 289 331 209 5 20A 331 2C9 5 2CA 331 2C5 5 2C6 331 284 5 285 331 280 5 281 331 2F6 5 2F7 331 2F2 5 2F3 331 2EE 5 2EF 331 87 5 87 331 2EA 5 2EB 331 10D 5 10D 331 83 5 83 331 C8 5 C8 331 14E 5 14E 331 109 5 109 331 7F 5 7F 331 C4 5 C4 331 C0 5 C0 331 14A 5 14A 331 105 5 105 331 7B 5 7B 331 18C 5 18C 331 1CD 5 1CE 331 188 5 188 331 1C9 5 1CA 331 184 5 184 331 1C1 5 1C2 331 180 5 180 331 246 5 247 331 205 5 206 331 242 5 243 331 201 5 202 331 23E 5 23F 331 27C 5 27D 331 1FD 5 1FE 331 2BD 5 2BE 331 23A 5 23B 331 278 5 279 331 1F9 5 1FA 331 2B9 5 2BA 331 2B5 5 2B6 331 274 5 275 331 270 5 271 331 2B1 5 2B2 331 323 5 324 331 31F 5 320 331 146 5 146 331 BC 5 BC 331 142 5 142 331 B8 5 B8 331 17F 5 17F 331 AC 5 AC 331 A8 5 A8 331 F9 5 F9 331 17B 5 17B 331 13A 5 13A 331 1BD 5 1BD 331 1B9 5 1B9 331 1F6 5 1F7 331 1F2 5 1F3 331 1B5 5 1B5 331 1B1 5 1B1 331 236 5 237 331 232 5 233 331 22E 5 22F 331 26F 5 270 331 26B 5 26C 331 22A 5 22B 331 2E6 5 2E7 331 2A9 5 2AA 331 2A5 5 2A6 331 2E2 5 2E3 331 2A1 5 2A2 331 317 5 318 331 A4 5 A4 331 ED 5 ED 331 30B 5 30C 331 12E 5 12F 331 A0 5 A0 331 12A 5 12B 331 E9 5 E9 331 126 5 127 331 16F 5 16F 331 9C 5 9C 331 98 5 98 331 E1 5 E1 331 122 5 123 331 1EE 5 1EF 331 16B 5 16B 331 1AD 5 1AD 331 1EA 5 1EB 331 1E6 5 1E7 331 1E2 5 1E3 331 1A5 5 1A5 331 1A1 5 1A1 331 226 5 227 331 267 5 268 331 222 5 223 331 263 5 264 331 21E 5 21F 331 2DE 5 2DF 331 25F 5 260 331 25B 5 25C 331 21A 5 21B 331 29D 5 29E 331 2DA 5 2DB 331 2D6 5 2D7 331 299 5 29A 331 295 5 296 331 2D2 5 2D3 331 291 5 292 331 77 5 77 331 73 5 73 331 137 5 137 331 133 5 134 331 307 5 308 331 94 5 94 331 2FB 5 2FC 331 167 5 167 331 11E 5 11F 331 90 5 90 331 11A 5 11A 331 D9 5 D9 331 D5 5 D5 331 116 5 116 331 8C 5 8C 331 D1 5 D1 331 112 5 112 331 1DE 5 1DF 331 15B 5 15B 331 88 5 88 331 19D 5 19D 331 199 5 199 331 1D6 5 1D7 331 1D2 5 1D3 331 257 5 258 331 216 5 217 331 212 5 213 331 253 5 254 331 20E 5 20F 331 2CE 5 2CF 331 24F 5 250 331 20A 5 20B 331 28D 5 28E 331 2CA 5 2CB 331 24B 5 24C 331 2C6 5 2C7 331 289 5 28A 331 2C2 5 2C3 331 285 5 286 331 281 5 282 331 B7 5 B7 331 2F7 5 2F8 331 2F3 5 2F4 331 2EF 5 2F0 331 84 5 84 331 CD 5 CD 331 2EB 5 2EC 331 80 5 80 331 10A 5 10A 331 C9 5 C9 331 7C 5 7C 331 106 5 106 331 14F 5 14F 331 C5 5 C5 331 C1 5 C1 331 1CE 5 1CF 331 14B 5 14B 331 78 5 78 331 18D 5 18D 331 1CA 5 1CB 331 1C6 5 1C7 331 185 5 185 331 1C2 5 1C3 331 181 5 181 331 247 5 248 331 206 5 207 331 202 5 203 331 243 5 244 331 1FE 5 1FF 331 2BE 5 2BF 331 23F 5 240 331 1FA 5 1FB 331 27D 5 27E 331 2BA 5 2BB 331 23B 5 23C 331 279 5 27A 331 2B6 5 2B7 331 2B2 5 2B3 331 275 5 276 331 271 5 272 0 ACDBDETAILVIEWSTYLE 5 6A 102 {ACAD_REACTORS 330 69 102 } 330 69 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 300 Imperial24 90 0 100 AcDbDetailViewStyle 70 0 71 0 90 3 71 1 340 55 62 256 40 0.24 340 0 62 256 40 0.24 300 40 0.36 280 3 71 2 340 5C 90 25 62 256 71 3 340 55 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewDetailId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 340 5C 90 25 62 256 340 5C 90 25 62 256 280 0 0 LAYOUT 5 6E 102 {ACAD_REACTORS 330 61 102 } 330 61 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout1 70 1 71 1 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 1.000000000000000E+20 24 1.000000000000000E+20 34 1.000000000000000E+20 15 -1.000000000000000E+20 25 -1.000000000000000E+20 35 -1.000000000000000E+20 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 6B 0 LAYOUT 5 72 102 {ACAD_REACTORS 330 61 102 } 330 61 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 1712 72 0 73 0 74 0 7 75 0 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Model 70 1 71 0 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 6F 331 B3 0 MATERIAL 5 19 102 {ACAD_XDICTIONARY 360 1A 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 ByBlock 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 11 102 {ACAD_XDICTIONARY 360 12 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 ByLayer 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 21 102 {ACAD_XDICTIONARY 360 22 102 } 102 {ACAD_REACTORS 330 10 102 } 330 10 100 AcDbMaterial 1 Global 72 0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0208333333333333 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 0.0208333333333333 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0208333333333333 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0208333333333333 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0208333333333333 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 0.0208333333333333 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MLEADERSTYLE 5 66 102 {ACAD_REACTORS 330 65 102 } 330 65 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 5A 92 -2 290 1 42 0.09 291 1 43 0.36 3 Standard 44 0.18 300 342 55 174 1 178 6 175 1 176 0 93 -1056964608 45 0.18 292 0 297 0 46 0.18 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 0 143 0.125 271 0 272 9 273 9 298 0 0 MLINESTYLE 5 5F 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 AcDbMlineStyle 2 STANDARD 70 0 3 62 256 51 90.0 52 90.0 71 2 49 0.5 62 256 6 BYLAYER 49 -0.5 62 256 6 BYLAYER 0 ACDBPLACEHOLDER 5 F 102 {ACAD_REACTORS 330 E 102 } 330 E 0 SCALE 5 43 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1:1 140 1.0 141 1.0 290 1 0 SCALE 5 44 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/128" = 1'-0" 140 0.0078125 141 12.0 290 0 0 SCALE 5 45 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/64" = 1'-0" 140 0.015625 141 12.0 290 0 0 SCALE 5 46 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/32" = 1'-0" 140 0.03125 141 12.0 290 0 0 SCALE 5 47 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/16" = 1'-0" 140 0.0625 141 12.0 290 0 0 SCALE 5 48 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/32" = 1'-0" 140 0.09375 141 12.0 290 0 0 SCALE 5 49 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/8" = 1'-0" 140 0.125 141 12.0 290 0 0 SCALE 5 4A 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/16" = 1'-0" 140 0.1875 141 12.0 290 0 0 SCALE 5 4B 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/4" = 1'-0" 140 0.25 141 12.0 290 0 0 SCALE 5 4C 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/8" = 1'-0" 140 0.375 141 12.0 290 0 0 SCALE 5 4D 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1/2" = 1'-0" 140 0.5 141 12.0 290 0 0 SCALE 5 4E 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3/4" = 1'-0" 140 0.75 141 12.0 290 0 0 SCALE 5 4F 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1" = 1'-0" 140 1.0 141 12.0 290 0 0 SCALE 5 50 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1-1/2" = 1'-0" 140 1.5 141 12.0 290 0 0 SCALE 5 51 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 3" = 1'-0" 140 3.0 141 12.0 290 0 0 SCALE 5 52 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 6" = 1'-0" 140 6.0 141 12.0 290 0 0 SCALE 5 53 102 {ACAD_REACTORS 330 42 102 } 330 42 100 AcDbScale 70 0 300 1'-0" = 1'-0" 140 12.0 141 12.0 290 0 0 ACDBSECTIONVIEWSTYLE 5 68 102 {ACAD_REACTORS 330 67 102 } 330 67 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 300 Imperial24 90 0 100 AcDbSectionViewStyle 70 0 71 0 90 78 71 1 340 55 62 256 40 0.24 340 0 340 0 62 256 40 0.24 300 I, O, Q, S, X, Z 40 0.48 90 3 40 0.18 90 1 71 2 340 5C 90 25 62 256 340 5C 90 50 62 256 40 0.24 40 0.0 40 0.24 71 3 340 55 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewSectionStartId>%-%<\AcVar ViewSectionEndId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 62 256 62 257 300 ANSI31 40 1.0 90 0 290 0 290 0 90 6 40 0.0 40 1.570796326794896 40 0.2617993877991494 40 1.308996938995747 40 -0.2617993877991494 40 1.832595714594045 0 TABLESTYLE 5 64 102 {ACAD_XDICTIONARY 360 656 102 } 102 {ACAD_REACTORS 330 63 102 } 330 63 100 AcDbTableStyle 280 0 3 Standard 70 0 71 0 40 0.06 41 0.06 280 0 281 0 7 Standard 140 0.18 170 2 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.25 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.18 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 0 VISUALSTYLE 5 2F 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 2dWireframe 70 4 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2E 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Basic 70 7 177 3 291 1 70 58 90 1 176 1 90 0 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 35 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Brighten 70 12 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 39 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 ColorChange 70 16 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 8 420 8421504 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 8 420 8421504 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 32 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Conceptual 70 9 177 3 291 0 70 58 90 3 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 179.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 34 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Dim 70 11 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 -50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 41 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 EdgeColorOff 70 22 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 8 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 38 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Facepattern 70 15 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2A 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Flat 70 0 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2B 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 FlatWithEdges 70 1 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2C 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Gouraud 70 2 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 2D 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 GouraudWithEdges 70 3 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 31 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Hidden 70 6 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 40.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3F 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 JitterOff 70 20 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 10 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 37 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Linepattern 70 14 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 7 176 1 90 7 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 40 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 OverhangOff 70 21 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 9 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 0 VISUALSTYLE 5 33 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Realistic 70 8 177 3 291 0 70 58 90 2 176 1 90 3 176 1 90 0 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3E 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shaded 70 27 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 8 420 7895160 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3D 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shaded with edges 70 26 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3A 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Shades of Gray 70 23 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3B 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Sketchy 70 24 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 11 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 6 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 36 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Thicken 70 13 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 12 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 30 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 Wireframe 70 5 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 3C 102 {ACAD_REACTORS 330 29 102 } 330 29 100 AcDbVisualStyle 2 X-Ray 70 25 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 1 176 1 40 0.5 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 DICTIONARYVAR 5 351 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 1:1 0 DICTIONARYVAR 5 34D 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 34C 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 34E 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 34F 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 353 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 1 0 DICTIONARYVAR 5 354 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 15 0 DICTIONARYVAR 5 352 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 0 0 DICTIONARYVAR 5 350 102 {ACAD_REACTORS 330 34B 102 } 330 34B 100 DictionaryVariables 280 0 1 0 0 DICTIONARY 5 1A 330 19 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 1C 3 DIFFUSETILE 360 1B 3 OPACITYTILE 360 1F 3 REFLECTIONTILE 360 1E 3 REFRACTIONTILE 360 20 3 SPECULARTILE 360 1D 0 DICTIONARY 5 12 330 11 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 14 3 DIFFUSETILE 360 13 3 OPACITYTILE 360 17 3 REFLECTIONTILE 360 16 3 REFRACTIONTILE 360 18 3 SPECULARTILE 360 15 0 DICTIONARY 5 22 330 21 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 24 3 DIFFUSETILE 360 23 3 OPACITYTILE 360 27 3 REFLECTIONTILE 360 26 3 REFRACTIONTILE 360 28 3 SPECULARTILE 360 25 0 DICTIONARY 5 656 330 64 100 AcDbDictionary 280 1 281 1 3 ACAD_ROUNDTRIP_2008_TABLESTYLE_CELLSTYLEMAP 360 22F4 0 XRECORD 5 1C 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1B 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1F 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1E 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 20 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1D 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 14 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 13 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 17 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 16 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 18 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 15 102 {ACAD_REACTORS 330 12 102 } 330 12 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 24 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 23 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 27 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 26 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 28 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 25 102 {ACAD_REACTORS 330 22 102 } 330 22 100 AcDbXrecord 280 1 270 1 271 1 0 CELLSTYLEMAP 5 22F4 102 {ACAD_REACTORS 330 656 102 } 330 656 100 AcDbCellStyleMap 90 3 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 32768 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 55 144 0.25 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 1 91 1 300 _TITLE 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 55 144 0.18 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 2 91 1 300 _HEADER 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 2 62 0 340 55 144 0.18 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 3 91 2 300 _DATA 309 CELLSTYLE_END 0 ENDSEC 0 SECTION 2 ACDSDATA 70 2 71 8 0 ACDSSCHEMA 90 0 1 AcDb_Thumbnail_Schema 2 AcDbDs::ID 280 10 91 8 2 Thumbnail_Data 280 15 91 0 101 ACDSRECORD 95 0 90 1 2 AcDbDs::TreatedAsObjectData 280 1 291 1 101 ACDSRECORD 95 0 90 2 2 AcDbDs::Legacy 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 3 2 AcDs:Indexable 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 4 2 AcDbDs::HandleAttribute 280 7 282 1 0 ACDSSCHEMA 90 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 ACDSSCHEMA 90 2 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 ACDSSCHEMA 90 3 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 ACDSSCHEMA 90 4 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 72 2 Thumbnail_Data 280 15 94 3606 310 89504E470D0A1A0A0000000D4948445200000100000000A90803000000F3C813C600000300504C5445212830FFFFFF2128300000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF0000000000000000000000000000000000000000000000000000000000002E4550F1000003144944415478DAED9DDB6EC3300C43F5FFFFCBF7614B93D66D7C4D065424893DACC3024CC7B22EB6E34558966559D67708B65FDB7E0380BAFDD204200D008724231F5EA539EE4A0036 310 13B17D4912D8BCFE0F82A6FD7BC67F9AAC1803509B00323E109F63AF63FEAFE58503C4014327FDC9A680A8CF7D4900A11902C45DA066BA0C0140DC07CE47FEF8640FD0280251F7037BC013953000665F68A7C1C782C9A34150F400D0AF91B62A61899CD02A032418605EC40042CFFE689741E709821E40B429B04F817A85CC 310 0FE0BDF81B03002E0003D9E1CD702E00134B65D8FBC9DCED70D9158F1608C7C32459011B838922797F2A755844F91DA63BE5EC8901AD38DEAD8F8220356204408C14C9E9E7C0589744571EE2C6463171F4BFA9514E39FCE8DA1FB4001E6DDFF944285AC36E00CC48E0E52CC8C9822FD694AF053886570DC0D99A37AE9A9F87 310 40E7AF6F053E8E7AA8BD0DBA60762E02BD1677C9FCC803606D60795CE0BFCCCFE2020B937AF291ACF35FC2FFD732DB8CF97816D949FC3F2ECEF8F267DF7C9404CBB5CDDC637A11E0AD98867004CC1A04075D9CE3E8C0BD1E9FD205E2BA8F67B63FAE8D6F6E00E55ED68A79BDADF3CC8B21CFA3A08860063057C47C567A4D8E 310 A91743FA00EA9BE704FE5F037014F7A74783722F060E0378FDC402E09637E5E91C801FC0CD356CAAB3B3FD22E8E2026B86E15706B0E7B1DBABF87C9B01F73732548BE1173C4C9B40EEA530FE7B73E6B6799901C00006167FB5C7DFEF45DA030C801940D8050658A8CC017502513B03457957CAD9B887C28BE16B89401700E7 310 85F233AFBCF000C0E0D0735EA0788CE440D02304F0F95EEFCC01788578C77D8DF2B88F73029899E27C0030653F21806A713B7A02263F80E606608C00E08E810200A2F9D65B281098ACF308DB40AC2250E97D2BBF4F746BEE6CBFB3B7C1122E10151F287A683A00D1BBE882FA7EC09133A1F417242A1C01586B89150884B8FD 310 277130F895FCDDBEFF0E030AFF4F765B0509D9F1DF93BB3080D636908E030494E74015807A080899FFA1595C98C7DCFBD401284BDD7E03B02CCBB22CCBB22CCBB22CCBB22CCBB22CCBB22CCBB2AC2FD60F04D22D723269A5C90000000049454E44AE426082DFDB9A0DF2F568874EB03CCE032F0404EEDD83125D01A852492D 310 EF63CC4740DF35A17DBC700F61A0F28C06645295189A5037B9FB4F0984DCB20E8EFE5B8E6BB40F2D529EDF4877AAB92D00D2E147BBBBE44E15B4C4C1C89F00654D681F5E7D23FBE53FE1CF8E12A039551715EE53A778806CFF4EFB94036216C23BE03961BFE6776060A98AE6389976F2E93AF0ECADBF99D03E860CB423AE59 310 9CD6D48DDD5980A7A8106D81A21E1EFCEA47B48FE23B2AC42EEA0668996D800756368ECA19D5A42591C3D964049ABE9B06EFCE62DD5E3EA7310A10A2E10BA3F35009ADF3090E10675F13325CD1D9E73F55C5558850EE95A3D14284898A8DF6E82F8EAE84B45F71F0CF334D894AC922FF81EB8124C11A93F120AEDE191EA089 310 13F7BB41984BD006740F50444113D6421D11F51F0AEC405F8EF3800C546E13F88654510008B9B27AEC0E5110F2A380BCAB100A81238B78F4AFEF5B931A8E91DF51020081CE050611E03CA11389C5146FA56175A911F414BF7705E26FA2EF9A08B6931FEE9EAE08A9D843E4C81990686201D3DE0B15D9B0085BED23BBA0F26A 310 043805986F737AF77D870012F0291E22EA696B3A70A7786487B502AD139110B706B4AF6008AD7740CD509440A9A019823F089C79BB157E81EAB8FD23E9D86938004A329C45E3D00A96CBC09A52260BC24E427A99E824E2910668999D20A7835FAE8AF44E824A08A9FA90442265BC5056845AB71D94C171AD50B017EE1168E0 310 90FF58F56380320B656EC65914DC419F372530775815E4618711DCF7AF11F445F2B38A6532549213A8AC3CBE9277710B39E14E00ED8846B8A0DA7422B7880218D8A9FA5E0DDF0493211614CB48E60082003A7016D95D0D3AA7860238F759DFAAE15BEFC8B0E215EE88B48EC27B8516E2B3034280F8B314128F6747EBE9F6D5 310 F0ADE225D217C88B438BAA2E9E22C9769C053CD99722B17BA062A7E0DC61658F4CEC03F87761CA4806BB3615FEF19A4AA7EA0BDBB7E41CCC664B9C5FA8E1A3ED909AA984BA93D07A33F1818488B3F55EC11837D0045073357CC570915D6CEA4891F4CA61D1D11BBB1CB78E0C84A87CCB8FC67E8A718EC00E77D5F0AEAB055D 310 A2E050C46A802D918E2745C07023CB95E7AE4C5354C3430BE089DE815F844E20EED1358CE2E1F83123FA80C880C44F9CE8463C21209CBFC79542CD986D2E206097E344DD7C6439EC099BC894C8FA89B478BAB247EEBDD84603C02812A090D219AA89361393D32F3302FB276AF81EDB3CAE5A928751440EF60CFDD450BE5BA8 310 4E4C203090E0CD70ED2115989E7509B9DF47CC2CDA9CA40C495D405292A99B54277A29064536534C5125E75621ADB53B70A67C6E3800077C2C034EAF8232FD830A8202A89470A21AF52DAFB689B99FA48FB1C8D3AAF40AD6BC122B6A9DEC8ECCA2DD3397E62B84D9670928A34AA93851474A03FEFD420D3FA7BEC97E26F718 310 22A3B36E8072FC0F92A8F8D1BCA70D070292C7D16AD451A5404BED7F550D3F3F2906FA152D0F465FAA3EECBB34A1BE890729439C729E26C42027CC97B2F776A14A8C3E29F1390EBF886A7182F9E2F015E4F4C416831D3AE9F00392953B63FEA44AD904026891F42F4E0CC5CCD9BCBB0E51D239812FE8BA06E8A53C9CDA078C 310 96841ABE280D7628BA89A75C28A2130A604D1A63F93381D10D00A30BF82349DC16DD425E18D85FFAC909B324D25E472062BEE6C8D1B256A310C890A954A12E0C40A0F7BDE68A3A77FB0DE49023C0217E5012AB5D0D4F42201E9EF420CBD92429F431272E35051CB8DD89FA2388601AD7F37D506C22E292028D9322E00E3E5A 310 5358122C6AED68237D77224B50607E434114E16EE799CE935C80905C6A9BD42B810A892CC4D0D5F875A06A21C4FEEE929E668050252803C477CC6FC5E86C8F6DC8217BA7AD7F1004C8D21AB09F7DF10EF38B71A3E87571417E3600A0F33DC047E4F8469604C01339CC107CBC1E33D11E63DA96D2C07FBFBA845D2168F0915F 310 777947892805E8738813CEF03223933DB687A4C5A442F1B6000EBB1044013C03E4BA9801F27D1455F87A390DD4FE13BCAC01569CF45045C577A5D77438F518C783C93E95A274A83E0112F3507307B9D4FC78F062D6F5785914FD820D7C021129529E2D354C5EDEB99607B497C27CB681D46ED33D16F8D47D76E45A2160E201 310 C6EAF9CC200D10121A1A804F08B559B46B3DC59FF296E87330E5132C09852431171D89C5BBECAB3900B27B8AC4BD36267096F0A14702C602CA108F9580FEBF34E828B9F80E6A84B8D0C756BCB335354010AF357D8AF20A06988A3551C8CCB0644B1C7DF07EC68EE8626FEAA953251487A97A4F3F796CD6C135C57C503C9671 310 DDE7B4829BDD1D5F8A2701E403103153E5D335B841573540E9275A657F56D00B65764DDE4E4A670D44FFFEBDD8A7D5F28925E5749CFBC7E9DCF7C1D44A80E4B17D3EA50A16FE091FB880FDF0F1B5AAD600544D3E8FE4EE06C81931A2E83E0E10BCCBFDFDBFAA7FDC9A889EA1F46DEF6C3DE10ECCC61DB726A9BD3618EFF2D5 310 E3AE00E66B85F767DB8353F51C03B48A08A2378C57DEED51E9BF2A131C2C76DD77710AF24EEFAAFFAD01381E335308B89CFC710600D1998C5F3CA2F09C8F1E532F8A82EEEEA0D3931CA07FBCD4D70D8E1E5300ED18E0874F3E3DC8049AB486BFD265DE32067CF8A7AE7FFC87CEAFB5D65A6BADB5D65A6BADB5D65A6BADB5D6 310 5A6BADB5D65A6BADB5D65A6BADB5D65A6BADB5D65A6BADB5D65A07AEFF00554FE27454DCB1F00000000049454E44AE426082 0 ENDSEC 0 EOF ================================================ FILE: testdata/barnsbury_segment_lines.mid ================================================ 0,2.0012004,0,3,66.173325,365,4156801.8,88.617859,6618.5718,178,357.53516,22549.607,12216.636 1,1.7398858,0,4,82.40506,983,9028389,89.036148,6680.416,178,355.85547,22340.854,12216.636 2,2.0232198,0,4,243.39876,1211,9372838,87.789162,6583.7954,178,360.91016,22668.717,12216.636 3,1.2413905,0,3,138.96246,487,4206866.5,84.789192,6377.4712,178,373.67969,23402.096,12216.636 4,1.9381289,1,3,130.18936,330,4186343.2,89.3825,6714.5283,178,354.47656,22227.355,12216.636 5,2.1624684,1,4,162.06264,692,5878021,90.132393,6768.0562,178,351.52734,22051.561,12216.636 6,1.7826266,1,4,184.86253,1342,11232938,93.362,7145.4531,178,339.36719,20886.877,12216.636 7,2.0335331,1,4,186.81696,1021,8303167,94.585724,7241.9897,178,334.97656,20608.453,12216.636 8,2.0149293,1,3,70.41478,795,5818716.5,94.632072,7246.8599,178,334.8125,20594.604,12216.636 9,4,2,5,64.546532,308,1653464.4,67.747787,4992.2837,178,467.67578,29895.375,12216.636 10,2.6528366,2,5,53.262371,385,1758330.9,66.705902,4920.8042,178,474.98047,30329.635,12216.636 11,3.3471634,2,4,10.496307,238,1142586.6,66.317581,4891.7046,178,477.76172,30510.059,12216.636 12,4,3,5,136.73875,450,4882207.5,80.08831,6026.8027,178,395.61328,24763.744,12216.636 13,4,3,6,144.35603,309,4674048.5,80.518425,6047.978,178,393.5,24677.041,12216.636 14,4,3,5,208.19673,618,6827499,82.457573,6239.9404,178,384.24609,23917.889,12216.636 15,3.6441982,4,4,8.9747467,0,86300.844,54.864071,3917.8215,178,577.5,38094.18,12216.636 16,0.91864121,4,3,62.642906,408,1356859.4,61.200176,4461.4165,178,517.71094,33452.648,12216.636 17,1.5875411,5,3,68.832535,189,772664.94,57.446114,4183.127,178,551.54297,35678.145,12216.636 18,3.0086384,5,4,5.5661507,55,472367.16,57.439606,4182.6602,178,551.60547,35682.125,12216.636 19,2.5961795,6,4,31.722631,347,1240084.2,67.549751,4859.6494,178,469.04688,30711.309,12216.636 20,2.8942552,6,4,153.36557,17,792264.5,64.708687,4663.2021,178,489.64062,32005.088,12216.636 21,4,7,5,78.798721,521,3768654.8,94.541626,6940.915,178,335.13281,21502.381,12216.636 22,4,7,6,92.622635,1212,6392349,94.387596,6921.416,178,335.67969,21562.957,12216.636 23,4,7,6,72.328705,2026,9513038,94.350273,6925.3647,178,335.8125,21550.662,12216.636 24,3.0542002,7,5,78.076729,2484,10539197,94.411774,6929.8618,178,335.59375,21536.678,12216.636 25,1.086924,7,4,38.178894,2364,9562418,94.596756,6949.0996,178,334.9375,21477.057,12216.636 26,3.8588758,7,4,19.806421,183,1061214.2,70.44252,5291.4692,178,449.78516,28205.059,12216.636 27,2.9553642,8,4,152.64659,251,1603799.8,67.250679,4869.6396,178,471.13281,30648.303,12216.636 28,2.5628395,8,4,30.569248,568,1731472.4,65.794159,4767.6074,178,481.5625,31304.215,12216.636 29,1.9056505,9,3,36.273235,29,378006.91,60.132584,4206.0908,178,526.90234,35483.352,12216.636 30,1.9439689,9,3,20.292385,218,1091423.4,60.404408,4222.1895,178,524.53125,35348.059,12216.636 31,2.9565058,10,4,63.638454,179,1265680.5,76.827156,5356.625,178,412.40625,27861.982,12216.636 32,2.0050292,10,4,72.13398,318,1992266.2,76.798058,5353.8901,178,412.5625,27876.215,12216.636 33,3.038465,10,5,69.456345,451,2690610.5,76.773346,5351.5645,178,412.69531,27888.332,12216.636 34,4,10,5,85.215919,289,1667870.4,75.121597,5252.0879,178,421.76953,28416.547,12216.636 35,4,11,4,107.46763,2,838417.31,63.447308,4644.291,178,499.375,32135.412,12216.636 36,3.2855186,12,4,11.691815,194,1175906.4,91.489624,6918.437,178,346.3125,21572.242,12216.636 37,1.7466468,12,4,67.515892,1345,8545044,93.415764,7065.1655,178,339.17188,21124.232,12216.636 38,1.9949708,12,4,71.218079,1564,10169552,93.450203,7068.7441,178,339.04688,21113.537,12216.636 39,2.9728639,12,5,69.910538,1838,11861826,93.480362,7072.0098,178,338.9375,21103.789,12216.636 40,3.021472,12,5,149.26498,2287,15157395,92.603081,7028.9722,178,342.14844,21233.004,12216.636 41,2.9785283,12,5,84.025612,2172,14630360,92.644333,7033.8105,178,341.99609,21218.398,12216.636 42,4,12,6,193.21144,1244,11365588,92.635872,7033.4829,178,342.02734,21219.387,12216.636 43,4,12,5,69.391472,768,7140941.5,93.896996,7157.6016,178,337.43359,20851.426,12216.636 44,1.8460462,13,3,72.605972,316,1933160.2,78.073212,5514.459,178,405.82422,27064.521,12216.636 45,3.079603,13,5,109.37788,478,2846059,77.863358,5500.2261,178,406.91797,27134.557,12216.636 46,4,13,5,236.42712,473,4039082.2,78.030403,5565.8442,178,406.04688,26814.656,12216.636 47,2.9256492,14,3,73.804344,175,1367621.2,65.590919,4713.0044,178,483.05469,31666.893,12216.636 48,3.118978,15,4,1.1576769,21,52568.5,54.646725,3815.7188,178,579.79688,39113.523,12216.636 49,2.881022,15,4,51.738968,143,588109.5,57.167553,4008.4851,178,554.23047,37232.57,12216.636 50,0.67563176,16,2,57.332561,0,576803.94,65.119614,4571.0322,178,486.55078,32650.436,12216.636 51,3.3243682,16,4,1.773312,279,1124254.5,64.529015,4523.1011,178,491.00391,32996.434,12216.636 52,3.5566537,17,4,1.5755012,185,842638.75,76.248665,5384.1821,178,415.53516,27719.381,12216.636 53,2.4433463,17,5,94.138809,909,2878055.8,76.660873,5397.0391,178,413.30078,27653.35,12216.636 54,4,17,5,240.50478,375,3247603.5,76.669571,5422.1479,178,413.25391,27525.291,12216.636 55,2.9502037,18,4,63.214619,480,4244460.5,103.37621,7594.2671,178,306.49219,19652.482,12216.636 56,2.043396,18,4,55.795689,1247,10353393,102.60077,7508.9897,178,308.80859,19875.67,12216.636 57,3.0064003,18,5,61.844196,1345,9701150,102.59558,7507.5396,178,308.82422,19879.51,12216.636 58,4,18,6,57.726696,1684,8941627,102.73723,7506.4736,178,308.39844,19882.332,12216.636 59,4,18,6,78.380333,1829,7873546.5,102.76196,7497.6934,178,308.32422,19905.615,12216.636 60,2.3847485,18,5,76.566856,2421,9062067,103.37885,7527.7261,178,306.48438,19826.199,12216.636 61,3.6152513,18,4,7.2528086,254,949294.31,80.944298,6096.1309,178,391.42969,24482.119,12216.636 62,3.0376058,19,4,4.8203835,969,3415459,88.060799,6053.9453,178,359.79688,24652.717,12216.636 63,2.0014875,19,4,57.263824,1257,4270006.5,88.909271,6120.3413,178,356.36328,24385.273,12216.636 64,2.0467546,19,4,81.338486,1219,4250588,89.006836,6125.0562,178,355.97266,24366.502,12216.636 65,2.9141521,19,5,69.343399,1026,3768641.5,89.135948,6129.8477,178,355.45703,24347.457,12216.636 66,2.9891434,19,4,15.855036,146,408590.09,92.881973,6344.1655,178,341.12109,23524.953,12216.636 67,4,20,5,0.50094116,218,1162905.5,95.223106,6722.3511,178,332.73438,22201.488,12216.636 68,3.7623262,20,5,31.326914,1285,4497112,96.855942,6966.7446,178,327.125,21422.658,12216.636 69,1.3914185,20,4,20.039038,3505,11620107,109.44092,7678.6113,178,289.50781,19436.613,12216.636 70,1.9921591,20,4,80.945,3493,11790712,109.55621,7688.1909,178,289.20312,19412.395,12216.636 71,1.5069535,20,4,54.103935,3332,11531442,110.02882,7732.5884,178,287.96094,19300.938,12216.636 72,3.3471429,20,4,8.468255,2263,8132306,104.11933,7376.3535,178,304.30469,20233.059,12216.636 73,2,21,2,79.482445,0,724714.19,68.040466,4773.4067,178,465.66406,31266.18,12216.636 74,2,22,2,84.41777,0,884771.5,61.031174,4482.9517,178,519.14453,33291.949,12216.636 75,2.0549963,23,3,141.50713,807,5807270,108.51846,7723.2334,178,291.96875,19324.314,12216.636 76,2.0359912,23,4,75.595688,1018,8256845,108.48653,7714.8027,178,292.05469,19345.434,12216.636 77,2.0393751,23,4,72.215797,1600,11373205,108.45172,7712.0181,178,292.14844,19352.418,12216.636 78,2.9666958,23,5,73.287651,2234,14429388,108.67695,7731.8662,178,291.54297,19302.74,12216.636 79,4,23,6,30.462101,3298,17047350,109.00117,7758.3276,178,290.67578,19236.904,12216.636 80,2.9891434,23,4,41.801193,7,305486.44,81.780823,6039.9316,178,387.42578,24709.916,12216.636 81,3.0975204,24,4,19.99411,1982,8221255.5,94.571388,6882.4766,178,335.02734,21684.955,12216.636 82,1.8206327,24,4,81.959412,2197,8739249,94.774712,6903.2329,178,334.30859,21619.754,12216.636 83,3.081847,24,5,61.298454,2277,8390308,94.681778,6897.7725,178,334.63672,21636.869,12216.636 84,4,24,6,230.26486,1424,6303539,94.330521,6897.4736,178,335.88281,21637.807,12216.636 85,3.2086754,24,4,11.345068,44,144973.97,94.284462,6899.8101,178,336.04688,21630.479,12216.636 86,4,25,5,21.704504,197,477300.16,96.725426,6661.9341,178,327.56641,22402.832,12216.636 87,4,25,6,156.13542,1787,5874959,98.494301,6724.2876,178,321.68359,22195.096,12216.636 88,3.1397986,25,5,4.3709054,2150,9321218,104.76485,7310.2856,178,302.42969,20415.92,12216.636 89,1.8853738,25,4,123.53465,3623,16552666,109.2331,7622.9595,178,290.05859,19578.512,12216.636 90,2.9748278,25,5,88.042221,3490,16621146,109.28609,7624.9824,178,289.91797,19573.316,12216.636 91,4,25,6,44.959156,3443,16985778,113.6598,7907.6191,178,278.76172,18873.721,12216.636 92,3.2086754,25,4,32.158134,68,200538.19,101.16245,6671.1152,178,313.19922,22372,12216.636 93,1.5234891,26,3,156.51314,880,4697371,104.36852,7220.9028,178,303.57812,20668.635,12216.636 94,2.5515666,26,4,28.49353,680,4084668.8,101.46744,7087.5713,178,312.25781,21057.453,12216.636 95,2.7092693,26,5,152.589,817,4337584,103.78361,7169.0215,178,305.28906,20818.209,12216.636 96,4,26,5,4.3323708,614,2229197,76.315384,5204.4497,178,415.17188,28676.652,12216.636 97,3.2741685,27,4,5.734199,492,997931.38,80.218208,5351.3374,178,394.97266,27889.516,12216.636 98,2.7258315,27,5,58.77298,1042,3266476.5,81.474419,5444.9028,178,388.88281,27410.258,12216.636 99,4,27,6,26.602385,1344,4041288.8,82.973801,5525.2549,178,381.85547,27011.643,12216.636 100,4,27,5,7.6956849,33,207832.08,82.114479,5449.6763,178,385.85156,27386.25,12216.636 101,3.3356996,28,4,14.008615,194,486196.19,70.869667,4749.543,178,447.07422,31423.277,12216.636 102,2.6643004,28,5,51.947716,511,1172606.5,75.637886,5014.8662,178,418.89062,29760.754,12216.636 103,3.2326641,28,5,24.983932,284,761697.12,76.392288,5051.4565,178,414.75391,29545.182,12216.636 104,2.7673359,28,4,8.5771065,207,681293.75,82.713196,5482.2207,178,383.05859,27223.676,12216.636 105,4,29,5,55.623226,382,1242717.2,74.394005,4952.0566,178,425.89453,30138.227,12216.636 106,2.6909027,29,5,122.1385,689,2199216.8,73.854805,4909.8218,178,429.00391,30397.479,12216.636 107,3.3090973,29,4,13.437029,331,745346.69,72.762947,4875.8032,178,435.44141,30609.561,12216.636 108,2.9276934,30,4,81.830719,222,678286.44,89.582893,5963.4609,178,353.68359,25026.775,12216.636 109,2.7533221,30,5,11.665026,481,3171357.2,90.295944,6051.2231,178,350.89062,24663.807,12216.636 110,3.2466779,30,5,6.1998625,338,2045784.5,86.868698,5836.5537,178,364.73438,25570.945,12216.636 111,4,30,6,5.4097123,2668,11407769,105.92642,7445.8682,178,299.11328,20044.162,12216.636 112,3.0539846,30,5,67.115707,2883,12051203,105.87665,7443.2124,178,299.25391,20051.316,12216.636 113,2.9460154,30,5,59.932568,2769,11646952,105.91536,7444.0581,178,299.14453,20049.037,12216.636 114,3.1116269,30,5,95.806824,2047,9289722,105.9901,7445.4268,178,298.93359,20045.352,12216.636 115,2.8883731,30,4,0.19636907,1405,6988613.5,107.35222,7529.5103,178,295.14062,19821.502,12216.636 116,2.9463861,31,4,85.111755,76,584308.75,69.896194,4771.4482,178,453.30078,31279.014,12216.636 117,2.9276934,31,4,7.8116097,118,404667.56,71.989281,4957.4209,178,440.12109,30105.613,12216.636 118,2.7760887,32,3,80.504349,40,465632.84,67.132118,4718.7378,178,471.96484,31628.416,12216.636 119,1.7224751,33,2,51.585476,7,210206.28,53.71521,3717.9077,178,589.85156,40142.523,12216.636 120,4,34,5,100.73653,1167,7415106.5,108.31992,7600.376,178,292.50391,19636.688,12216.636 121,4,34,6,104.9296,1762,9997418,108.30835,7603.0674,178,292.53516,19629.736,12216.636 122,2.8438091,34,5,68.548241,2983,14175580,108.05441,7573.5566,178,293.22266,19706.225,12216.636 123,2.1506054,34,4,42.451733,3055,14141106,107.82458,7557.7256,178,293.84766,19747.502,12216.636 124,3.0055857,34,5,44.519382,3227,14320575,107.82172,7557.6279,178,293.85547,19747.756,12216.636 125,3.1265831,34,5,83.344948,3250,14420084,107.70002,7561.4126,178,294.1875,19737.873,12216.636 126,2.8734171,34,5,11.506542,3430,13727606,107.9753,7599.6616,178,293.4375,19638.531,12216.636 127,4,34,6,6.0284462,2657,10569333,105.04842,7428.769,178,301.61328,20090.301,12216.636 128,4,34,5,5.419879,326,1180875.9,86.131653,6176.9673,178,367.85547,24161.727,12216.636 129,2,35,2,20.824474,0,212491.75,66.399551,4603.9497,178,477.17188,32416.992,12216.636 130,2.315361,36,3,36.565041,182,517014.62,69.343452,4775.4722,178,456.91406,31252.656,12216.636 131,0.87075675,37,2,15.346227,109,383297.66,64.659164,4430.2266,178,490.01562,33688.164,12216.636 132,2.5553956,38,3,58.902714,107,482010.88,60.524754,4128.2837,178,523.48828,36152.117,12216.636 133,4,39,5,29.471209,2132,7106502.5,102.01877,7046.436,178,310.57031,21180.381,12216.636 134,3.0400231,39,5,0.41702437,1868,6555843,102.04957,7047.5352,178,310.47656,21177.078,12216.636 135,1.8690072,39,4,143.56969,2082,7028887,103.00992,7118.877,178,307.58203,20964.852,12216.636 136,3.0909696,39,5,220.49948,633,2843580.8,102.03416,7091.9126,178,310.52344,21044.562,12216.636 137,3.3558173,39,4,4.6648011,60,48442.176,102.77367,7156.9517,178,308.28906,20853.32,12216.636 138,4,40,5,5.8880019,1198,6602856.5,92.347939,6651.4351,178,343.09375,22438.195,12216.636 139,2.8008873,40,5,86.80928,1314,6988477.5,90.596497,6541.2188,178,349.72656,22816.268,12216.636 140,1.9834378,40,3,83.826813,874,4874680,89.554214,6493.5498,178,353.79688,22983.762,12216.636 141,3.7738943,41,4,33.475399,963,7042259,84.994438,6210.7104,178,372.77734,24030.455,12216.636 142,1.4153167,41,4,178.53447,1362,8652835,90.345222,6721.4429,178,350.69922,22204.488,12216.636 143,1.2796584,41,4,116.47486,1233,6833815.5,91.196457,6782.4829,178,347.42578,22004.656,12216.636 144,2.8869476,41,3,6.8355722,0,32039.699,81.984169,6130.0171,178,386.46484,24346.783,12216.636 145,3.9999998,42,5,314.13025,147,2550125.8,75.341393,5244.0146,178,420.53906,28460.293,12216.636 146,4,42,5,1.4020742,28,787264.31,73.82859,5159.4937,178,429.15625,28926.521,12216.636 147,2,43,2,32.635479,0,340282.88,67.405479,4677.939,178,470.05078,31904.262,12216.636 148,2.372308,44,4,55.385048,1325,2879153,77.915718,5145.1392,178,406.64453,29007.223,12216.636 149,3.6276922,44,4,8.0672827,538,1295412.9,74.798775,5021.2231,178,423.58984,29723.076,12216.636 150,2.6622484,45,4,4.1139636,523,1247895.5,72.8479,4776.5571,178,434.93359,31245.559,12216.636 151,1.9825487,45,4,56.198662,461,1198154.6,72.054512,4745.6021,178,439.72266,31449.371,12216.636 152,3.3552032,45,4,13.687597,169,627264.94,69.173141,4584.3516,178,458.03906,32555.576,12216.636 153,3.7100596,46,4,5.1633153,55,157636.45,69.908241,4694.3491,178,453.22266,31792.736,12216.636 154,0.85895824,46,4,48.794411,682,1540374.1,74.486237,4990.52,178,425.36719,29905.941,12216.636 155,3.4309821,46,4,5.8241816,177,671997.44,69.014816,4629.6465,178,459.08984,32237.061,12216.636 156,2.7051506,47,4,166.88625,383,2285897.5,70.657295,4891.9014,178,448.41797,30508.834,12216.636 157,3.2948494,47,4,4.9959264,274,1980018.8,69.792152,4865.7471,178,453.97656,30672.824,12216.636 158,0.98894149,48,2,114.23679,0,1195344.4,80.295242,6018.9507,178,394.59375,24796.049,12216.636 159,1.182127,48,3,55.910877,274,2741649,80.140541,6005.0312,178,395.35547,24853.525,12216.636 160,3.0480838,49,4,81.635147,126,1503485.5,81.069695,6023.3394,178,390.82422,24777.984,12216.636 161,2.0113289,49,4,108.93696,334,2477706.5,81.778351,6069.8652,178,387.4375,24588.059,12216.636 162,2.940587,49,4,30.296598,330,1952532.9,82.620514,6154.3496,178,383.48828,24250.523,12216.636 163,3.1072955,50,3,40.717644,287,1715661.2,62.152149,4446.2324,178,509.78125,33566.891,12216.636 164,1.1072954,51,1,63.598595,0,651424.19,44.939854,3176.8967,178,705.03125,46978.613,12216.636 165,3.0436037,52,4,4.4063578,96,605797.19,66.459404,4746.5186,178,476.74219,31443.299,12216.636 166,2.9563963,52,4,90.654068,109,1062591.8,67.1894,4814.7637,178,471.5625,30997.617,12216.636 167,3.0721309,53,4,143.34143,93,2134044,75.842278,5481.8882,178,417.76172,27225.328,12216.636 168,2.9278691,53,4,141.29507,294,2936599.2,76.411003,5523.6138,178,414.65234,27019.666,12216.636 169,4,54,4,64.827652,299,1046788.9,60.478722,4116.709,178,523.88672,36253.766,12216.636 170,1.9948233,55,3,26.562881,53,334537.75,46.611523,3140.5879,178,679.74609,47521.742,12216.636 171,1.9981046,55,3,23.211634,55,313906.69,46.611523,3140.5879,178,679.74609,47521.742,12216.636 172,1.9839985,56,2,62.202236,0,264440.84,42.862148,2839.1758,178,739.20703,52566.734,12216.636 173,2.0713086,57,3,25.08102,68,396381.09,52.447456,3490.3325,178,604.10938,42759.883,12216.636 174,1.9357636,57,3,25.400402,91,432314.75,55.001724,3657.7,178,576.05469,40803.289,12216.636 175,2.0160015,58,2,63.467106,26,283843.69,43.754169,2897.7686,178,724.13672,51503.84,12216.636 176,4,59,4,106.14331,8,866621.44,63.394745,4639.7456,178,499.78906,32166.893,12216.636 177,4,60,4,245.73332,0,2100469,73.744011,5285.8833,178,429.64844,28234.865,12216.636 ================================================ FILE: testdata/barnsbury_segment_lines.mif ================================================ Version 300 Charset "WindowsLatin1" Delimiter "," Index 1 CoordSys NonEarth Units "m" Bounds (530635.696268, 183499.852969) (531446.820644, 184583.962646) Columns 13 Depthmap_Ref Integer Angular_Connectivity Float Axial_Line_Ref Float Connectivity Float Segment_Length Float T1024_Choice Float T1024_Choice_Segment_Length_Wgt_ Float T1024_Integration Float T1024_Integration_Segment_Length_Wgt_ Float T1024_Node_Count Float T1024_Total_Depth Float T1024_Total_Depth_Segment_Length_Wgt_ Float T1024_Total_Segment_Length Float Data LINE 530661.6919780188 184270.5626832811 530670.3012171048 184204.951785912 PEN (1,2,0) LINE 530670.3012171048 184204.951785912 530681.0222267658 184123.2471128816 PEN (1,2,0) LINE 530681.0222267658 184123.2471128816 530712.6887355548 183881.9170676302 PEN (1,2,0) LINE 530712.6887355548 183881.9170676302 530730.7679409641 183744.1356819843 PEN (1,2,0) LINE 530661.6919780187 184270.562683281 530782.0935715765 184320.087685171 PEN (1,2,0) LINE 530782.0935715765 184320.087685171 530931.9721717195 184381.7375166726 PEN (1,2,0) LINE 530931.9721717195 184381.7375166726 531102.9365496121 184452.0605986855 PEN (1,2,0) LINE 531102.9365496121 184452.0605986855 531275.7084119404 184523.1271564901 PEN (1,2,0) LINE 531275.7084119404 184523.1271564901 531340.8293390643 184549.9134634117 PEN (1,2,0) LINE 530782.0935715765 184320.087685171 530796.6615005322 184257.2066049815 PEN (1,2,0) LINE 530796.6615005322 184257.2066049815 530808.6826332469 184205.3185286112 PEN (1,2,0) LINE 530808.6826332469 184205.3185286112 530811.0516134852 184195.09305066 PEN (1,2,0) LINE 530670.3012171047 184204.9517859119 530796.6615005322 184257.2066049815 PEN (1,2,0) LINE 530796.6615005322 184257.2066049815 530930.0609102942 184312.3723725155 PEN (1,2,0) LINE 530930.0609102942 184312.3723725155 531122.4555083865 184391.9349110013 PEN (1,2,0) LINE 530804.6982026402 184201.4318404568 530811.0516134852 184195.0930506599 PEN (1,2,0) LINE 530811.0516134852 184195.0930506599 530855.3978358759 184150.8488818384 PEN (1,2,0) LINE 530755.4256480751 184153.3679956899 530804.6982026402 184201.4318404567 PEN (1,2,0) LINE 530804.6982026402 184201.4318404567 530808.6826332469 184205.3185286112 PEN (1,2,0) LINE 530755.4256480752 184153.36799569 530759.8102694125 184121.9498409454 PEN (1,2,0) LINE 530759.8102694125 184121.9498409454 530781.0080675455 183970.0562905679 PEN (1,2,0) LINE 530681.0222267658 184123.2471128815 530759.8102694125 184121.9498409453 PEN (1,2,0) LINE 530759.8102694125 184121.9498409453 530852.4203537111 184120.4249843892 PEN (1,2,0) LINE 530852.4203537111 184120.4249843892 530924.739253607 184119.2342290901 PEN (1,2,0) LINE 530924.739253607 184119.2342290901 531002.80539858 184117.9488434448 PEN (1,2,0) LINE 531002.80539858 184117.9488434448 531040.9791199062 184117.3203001314 PEN (1,2,0) LINE 531040.9791199062 184117.3203001314 531060.7828570851 184116.994224859 PEN (1,2,0) LINE 530837.552389062 183968.5041980529 530852.4203537111 184120.4249843893 PEN (1,2,0) LINE 530852.4203537111 184120.4249843893 530855.3978358759 184150.8488818385 PEN (1,2,0) LINE 530781.0080675455 183970.0562905679 530817.2676436539 183969.0609966963 PEN (1,2,0) LINE 530817.2676436539 183969.0609966963 530837.5523890621 183968.5041980528 PEN (1,2,0) LINE 530804.1027903862 183678.9148130685 530806.9873013139 183742.4878602049 PEN (1,2,0) LINE 530806.9873013139 183742.4878602049 530810.2568850133 183814.5477011403 PEN (1,2,0) LINE 530810.2568850133 183814.5477011403 530813.4051007051 183883.9326574047 PEN (1,2,0) LINE 530813.4051007051 183883.9326574047 530817.2676436539 183969.0609966964 PEN (1,2,0) LINE 530806.9873013139 183742.4878602049 530914.4265599075 183744.9570759712 PEN (1,2,0) LINE 530912.2449280558 183665.7794156555 530912.5669577819 183677.46679556 PEN (1,2,0) LINE 530912.5669577819 183677.46679556 530914.4265599076 183744.9570759712 PEN (1,2,0) LINE 530914.4265599076 183744.9570759712 530916.3881318528 183816.1481328081 PEN (1,2,0) LINE 530916.3881318528 183816.1481328081 530918.3136899534 183886.0321442102 PEN (1,2,0) LINE 530918.3136899534 183886.0321442102 530922.4249214346 184035.2404945642 PEN (1,2,0) LINE 530922.4249214346 184035.2404945642 530924.739253607 184119.2342290901 PEN (1,2,0) LINE 530924.739253607 184119.2342290901 530930.0609102943 184312.3723725156 PEN (1,2,0) LINE 530930.0609102943 184312.3723725156 530931.9721717195 184381.7375166726 PEN (1,2,0) LINE 530997.7409700139 184191.5792263541 531069.1018140045 184204.9679402672 PEN (1,2,0) LINE 531069.1018140045 184204.9679402672 531176.6039484286 184225.1374792238 PEN (1,2,0) LINE 531176.6039484286 184225.1374792238 531408.9765464333 184268.7352011949 PEN (1,2,0) LINE 530997.7409700138 184191.5792263541 531002.8053985799 184117.9488434448 PEN (1,2,0) LINE 531065.9075465151 184257.7680519287 531065.9774551002 184256.612487747 PEN (1,2,0) LINE 531065.9774551002 184256.612487747 531069.1018140046 184204.9679402672 PEN (1,2,0) LINE 531014.260003 184282.658893 531065.9075465151 184257.7680519287 PEN (1,2,0) LINE 531065.9075465151 184257.7680519287 531067.5050192737 184256.9981713527 PEN (1,2,0) LINE 531065.9774551002 184256.612487747 531067.5050192737 184256.9981713527 PEN (1,2,0) LINE 531067.5050192737 184256.9981713527 531158.7795115133 184280.0434063022 PEN (1,2,0) LINE 531158.7795115133 184280.0434063022 531391.9665625809 184338.919114588 PEN (1,2,0) LINE 531102.9365496121 184452.0605986855 531122.4555083866 184391.9349110013 PEN (1,2,0) LINE 531122.4555083866 184391.9349110013 531139.6837024501 184338.8656347355 PEN (1,2,0) LINE 531139.6837024501 184338.8656347355 531158.7795115134 184280.0434063022 PEN (1,2,0) LINE 531158.7795115134 184280.0434063022 531176.6039484288 184225.1374792239 PEN (1,2,0) LINE 531176.6039484288 184225.1374792239 531200.8056679327 184150.5871384435 PEN (1,2,0) LINE 531200.8056679327 184150.5871384435 531224.4474343648 184077.7616623912 PEN (1,2,0) LINE 531224.4474343648 184077.7616623912 531226.6869048447 184070.8632563747 PEN (1,2,0) LINE 531222.0221921728 184069.6481218071 531226.6869048446 184070.8632563747 PEN (1,2,0) LINE 531226.6869048446 184070.8632563747 531282.1014374334 184085.2984678934 PEN (1,2,0) LINE 531282.1014374334 184085.2984678934 531360.8131579099 184105.8024815699 PEN (1,2,0) LINE 531360.8131579099 184105.8024815699 531427.9171605199 184123.2827421834 PEN (1,2,0) LINE 531427.9171605199 184123.2827421834 531443.2601697572 184127.2795201643 PEN (1,2,0) LINE 531168.4909565911 183890.5617386632 531168.6344222261 183891.0416966056 PEN (1,2,0) LINE 531168.6344222261 183891.0416966056 531177.6062062277 183921.056403528 PEN (1,2,0) LINE 531177.6062062277 183921.056403528 531183.345230286 183940.256054913 PEN (1,2,0) LINE 531183.345230286 183940.256054913 531206.5272470647 184017.8104676549 PEN (1,2,0) LINE 531206.5272470647 184017.8104676549 531222.0221921728 184069.6481218071 PEN (1,2,0) LINE 531222.0221921728 184069.6481218071 531224.4474343648 184077.7616623912 PEN (1,2,0) LINE 531103.958023 183944.145791 531183.3452302859 183940.256054913 PEN (1,2,0) LINE 531275.7084119404 184523.1271564901 531297.5108320001 184441.573404 PEN (1,2,0) LINE 531340.8293390643 184549.9134634118 531374.1604658248 184412.3878235204 PEN (1,2,0) LINE 531374.1604658248 184412.3878235204 531391.9665625809 184338.9191145881 PEN (1,2,0) LINE 531391.9665625809 184338.9191145881 531408.9765464333 184268.7352011949 PEN (1,2,0) LINE 531408.9765464333 184268.7352011949 531426.238998241 184197.5095943315 PEN (1,2,0) LINE 531426.238998241 184197.5095943315 531433.4141573964 184167.9045839381 PEN (1,2,0) LINE 531433.4141573964 184167.9045839381 531443.2601697572 184127.2795201643 PEN (1,2,0) LINE 531040.9791199062 184117.3203001315 531060.55370366 184121.3946202041 PEN (1,2,0) LINE 531060.55370366 184121.3946202041 531140.7934071338 184138.0959834922 PEN (1,2,0) LINE 531140.7934071338 184138.0959834922 531200.8056679327 184150.5871384435 PEN (1,2,0) LINE 531200.8056679327 184150.5871384435 531426.238998241 184197.5095943315 PEN (1,2,0) LINE 531426.238998241 184197.5095943315 531437.3460188021 184199.8214471601 PEN (1,2,0) LINE 531379.770131822 183732.4495029183 531382.4238646072 183753.9911641308 PEN (1,2,0) LINE 531382.4238646072 183753.9911641308 531401.5139900263 183908.9551516768 PEN (1,2,0) LINE 531401.5139900263 183908.9551516768 531402.0484051576 183913.2932635508 PEN (1,2,0) LINE 531402.0484051576 183913.2932635508 531417.1525502533 184035.9010778593 PEN (1,2,0) LINE 531417.1525502533 184035.9010778593 531427.9171605199 184123.2827421833 PEN (1,2,0) LINE 531427.9171605199 184123.2827421833 531433.4141573964 184167.9045839381 PEN (1,2,0) LINE 531433.4141573964 184167.9045839381 531437.346018802 184199.8214471601 PEN (1,2,0) LINE 531375.1001237407 183572.3943911834 531387.3458877866 183728.4277266877 PEN (1,2,0) LINE 531387.3458877866 183728.4277266877 531389.5752537736 183756.833909406 PEN (1,2,0) LINE 531389.5752537736 183756.833909406 531401.5139900263 183908.9551516768 PEN (1,2,0) LINE 531401.5139900263 183908.9551516768 531401.8529595991 183913.2742413547 PEN (1,2,0) LINE 531297.7582437188 183720.3357738068 531303.0868777729 183722.4539565722 PEN (1,2,0) LINE 531303.0868777729 183722.4539565722 531357.7029968201 183744.1643838416 PEN (1,2,0) LINE 531357.7029968201 183744.1643838416 531382.4238646072 183753.9911641308 PEN (1,2,0) LINE 531382.4238646072 183753.9911641308 531389.5752537737 183756.8339094061 PEN (1,2,0) LINE 531299.4468674023 183775.0910818076 531311.8200189774 183768.5224902194 PEN (1,2,0) LINE 531311.8200189774 183768.5224902194 531357.7029968201 183744.1643838416 PEN (1,2,0) LINE 531357.7029968201 183744.1643838416 531379.7701318221 183732.4495029183 PEN (1,2,0) LINE 531379.7701318221 183732.4495029183 531387.3458877866 183728.4277266877 PEN (1,2,0) LINE 531304.3126897123 183959.5738054356 531306.4967095837 183903.9934713184 PEN (1,2,0) LINE 531306.4967095837 183903.9934713184 531311.2924203729 183781.9491568425 PEN (1,2,0) LINE 531311.2924203729 183781.9491568425 531311.8200189773 183768.5224902195 PEN (1,2,0) LINE 531075.4349141666 183881.5048417101 531156.8807901648 183889.4317520639 PEN (1,2,0) LINE 531156.8807901648 183889.4317520639 531168.4909565911 183890.5617386632 PEN (1,2,0) LINE 531168.4909565911 183890.5617386632 531174.6616614035 183891.1623169401 PEN (1,2,0) LINE 531174.6616614035 183891.1623169401 531180.0459325081 183891.6863537172 PEN (1,2,0) LINE 531180.0459325081 183891.6863537172 531246.8460016274 183898.1878266653 PEN (1,2,0) LINE 531246.8460016274 183898.1878266653 531306.4967095837 183903.9934713184 PEN (1,2,0) LINE 531306.4967095837 183903.9934713184 531401.8529595992 183913.2742413547 PEN (1,2,0) LINE 531401.8529595992 183913.2742413547 531402.0484051576 183913.2932635508 PEN (1,2,0) LINE 531056.0095225013 183972.3751082587 531073.8019170946 183889.1438577853 PEN (1,2,0) LINE 531073.8019170946 183889.1438577853 531075.4349141666 183881.5048417101 PEN (1,2,0) LINE 530986.8482115235 183887.4036937163 531004.8354864263 183965.872851334 PEN (1,2,0) LINE 531004.8354864263 183965.872851334 531056.0095225013 183972.3751082587 PEN (1,2,0) LINE 530712.6887355547 183881.9170676303 530813.4051007051 183883.9326574047 PEN (1,2,0) LINE 530813.4051007051 183883.9326574047 530918.3136899534 183886.0321442102 PEN (1,2,0) LINE 530918.3136899534 183886.0321442102 530986.8482115236 183887.4036937163 PEN (1,2,0) LINE 530986.8482115236 183887.4036937163 531029.2914457454 183888.2530904232 PEN (1,2,0) LINE 531029.2914457454 183888.2530904232 531073.8019170945 183889.1438577853 PEN (1,2,0) LINE 531073.8019170945 183889.1438577853 531157.1301833935 183890.8114676243 PEN (1,2,0) LINE 531157.1301833935 183890.8114676243 531168.6344222261 183891.0416966057 PEN (1,2,0) LINE 531168.6344222261 183891.0416966057 531174.6616614035 183891.1623169401 PEN (1,2,0) LINE 531174.6616614035 183891.1623169401 531180.0804551976 183891.2707607402 PEN (1,2,0) LINE 531246.8460016274 183898.1878266653 531247.100529 183877.364907 PEN (1,2,0) LINE 531380.713483092 184038.9336762212 531417.1525502533 184035.9010778593 PEN (1,2,0) LINE 531367.8635018886 184047.3232328322 531380.713483092 184038.9336762213 PEN (1,2,0) LINE 531360.8131579099 184105.8024815699 531367.8635018887 184047.323232832 PEN (1,2,0) LINE 531177.6062062277 183921.056403528 531180.0459325082 183891.6863537173 PEN (1,2,0) LINE 531180.0459325082 183891.6863537173 531180.0804551976 183891.2707607402 PEN (1,2,0) LINE 531180.0804551976 183891.2707607402 531191.9656390148 183748.1938739985 PEN (1,2,0) LINE 531191.9656390148 183748.1938739985 531210.2193315655 183528.4512480644 PEN (1,2,0) LINE 531210.2193315655 183528.4512480644 531210.6054995636 183523.8024588018 PEN (1,2,0) LINE 531204.5299233167 183526.934937537 531210.2193315655 183528.4512480644 PEN (1,2,0) LINE 531210.2193315655 183528.4512480644 531294.1006655393 183550.8068506498 PEN (1,2,0) LINE 531294.1006655393 183550.8068506498 531375.1001237407 183572.3943911835 PEN (1,2,0) LINE 530912.5669577818 183677.4667955601 530942.3204781786 183662.1263132498 PEN (1,2,0) LINE 530942.3204781786 183662.1263132498 531101.0050300843 183580.3108665743 PEN (1,2,0) LINE 531101.0050300843 183580.3108665743 531204.5299233167 183526.9349375371 PEN (1,2,0) LINE 531204.5299233167 183526.9349375371 531210.6054995636 183523.8024588018 PEN (1,2,0) LINE 531101.0050300843 183580.3108665743 531156.8807901648 183889.4317520638 PEN (1,2,0) LINE 531156.8807901648 183889.4317520638 531157.1301833934 183890.8114676243 PEN (1,2,0) LINE 531029.2914457454 183888.2530904232 531030.230687 183855.631128 PEN (1,2,0) LINE 531191.9656390148 183748.1938739985 531247.2509705561 183744.8718613147 PEN (1,2,0) LINE 531247.2509705561 183744.8718613147 531255.3037282097 183744.3879831807 PEN (1,2,0) LINE 531247.2509705561 183744.8718613147 531250.8112866409 183746.9331340065 PEN (1,2,0) LINE 531250.8112866409 183746.9331340065 531299.4468674023 183775.0910818077 PEN (1,2,0) LINE 531299.4468674023 183775.0910818077 531311.2924203731 183781.9491568425 PEN (1,2,0) LINE 531250.8112866409 183746.9331340066 531255.3037282097 183744.3879831806 PEN (1,2,0) LINE 531255.3037282097 183744.3879831806 531297.7582437188 183720.3357738067 PEN (1,2,0) LINE 531297.7582437188 183720.3357738067 531302.8256845656 183717.4648625085 PEN (1,2,0) LINE 531294.1006655394 183550.8068506498 531302.8256845657 183717.4648625084 PEN (1,2,0) LINE 531302.8256845657 183717.4648625084 531303.0868777729 183722.4539565722 PEN (1,2,0) LINE 530707.321114 183575.611283 530723.063264805 183688.7582135932 PEN (1,2,0) LINE 530723.063264805 183688.7582135932 530730.7679409641 183744.1356819843 PEN (1,2,0) LINE 530723.0632648049 183688.7582135932 530804.1027903862 183678.9148130685 PEN (1,2,0) LINE 530804.1027903862 183678.9148130685 530912.2449280557 183665.7794156555 PEN (1,2,0) LINE 530912.2449280557 183665.7794156555 530942.3204781786 183662.1263132498 PEN (1,2,0) LINE 531140.7934071338 184138.0959834922 531154.1331188128 184099.6254937419 PEN (1,2,0) LINE 531091.400795 184089.16428 531154.1331188127 184099.6254937418 PEN (1,2,0) LINE 531060.55370366 184121.3946202041 531060.7828570851 184116.994224859 PEN (1,2,0) LINE 531060.7828570851 184116.994224859 531065.4973380617 184026.4628259328 PEN (1,2,0) LINE 530922.4249214346 184035.2404945642 531065.4973380617 184026.4628259328 PEN (1,2,0) LINE 531065.4973380617 184026.4628259328 531206.5272470647 184017.8104676549 PEN (1,2,0) LINE 531282.1014374334 184085.2984678934 531294.5626424844 184021.6797343292 PEN (1,2,0) LINE 531268.4799450308 184016.6518545878 531294.5626424844 184021.6797343292 PEN (1,2,0) LINE 531294.5626424844 184021.6797343292 531317.3546726417 184026.0732824619 PEN (1,2,0) LINE 531268.4799450306 184016.6518545878 531279.5735313552 183955.446866539 PEN (1,2,0) LINE 531279.5735313554 183955.446866539 531304.3126897124 183959.5738054357 PEN (1,2,0) LINE 531304.3126897124 183959.5738054357 531329.3668766369 183963.7532967931 PEN (1,2,0) LINE 531317.3546726417 184026.0732824619 531329.3668766369 183963.7532967931 PEN (1,2,0) LINE 530810.2568850133 183814.5477011403 530916.3881318528 183816.148132808 PEN (1,2,0) LINE 531139.68370245 184338.8656347354 531374.1604658248 184412.3878235204 PEN (1,2,0) ================================================ FILE: testdata/barnsbury_segment_pline.mid ================================================ 0,2.0012004,0,3,66.173325,365,4156801.8,88.617859,6618.5718,178,357.53516,22549.607,12216.636 1,1.7398858,0,4,82.40506,983,9028389,89.036148,6680.416,178,355.85547,22340.854,12216.636 2,2.0232198,0,4,243.39876,1211,9372838,87.789162,6583.7954,178,360.91016,22668.717,12216.636 3,1.2413905,0,3,138.96246,487,4206866.5,84.789192,6377.4712,178,373.67969,23402.096,12216.636 4,1.9381289,1,3,130.18936,330,4186343.2,89.3825,6714.5283,178,354.47656,22227.355,12216.636 5,2.1624684,1,4,162.06264,692,5878021,90.132393,6768.0562,178,351.52734,22051.561,12216.636 6,1.7826266,1,4,184.86253,1342,11232938,93.362,7145.4531,178,339.36719,20886.877,12216.636 7,2.0335331,1,4,186.81696,1021,8303167,94.585724,7241.9897,178,334.97656,20608.453,12216.636 9,4,2,5,64.546532,308,1653464.4,67.747787,4992.2837,178,467.67578,29895.375,12216.636 10,2.6528366,2,5,53.262371,385,1758330.9,66.705902,4920.8042,178,474.98047,30329.635,12216.636 11,3.3471634,2,4,10.496307,238,1142586.6,66.317581,4891.7046,178,477.76172,30510.059,12216.636 12,4,3,5,136.73875,450,4882207.5,80.08831,6026.8027,178,395.61328,24763.744,12216.636 13,4,3,6,144.35603,309,4674048.5,80.518425,6047.978,178,393.5,24677.041,12216.636 14,4,3,5,208.19673,618,6827499,82.457573,6239.9404,178,384.24609,23917.889,12216.636 15,3.6441982,4,4,8.9747467,0,86300.844,54.864071,3917.8215,178,577.5,38094.18,12216.636 16,0.91864121,4,3,62.642906,408,1356859.4,61.200176,4461.4165,178,517.71094,33452.648,12216.636 17,1.5875411,5,3,68.832535,189,772664.94,57.446114,4183.127,178,551.54297,35678.145,12216.636 18,3.0086384,5,4,5.5661507,55,472367.16,57.439606,4182.6602,178,551.60547,35682.125,12216.636 19,2.5961795,6,4,31.722631,347,1240084.2,67.549751,4859.6494,178,469.04688,30711.309,12216.636 20,2.8942552,6,4,153.36557,17,792264.5,64.708687,4663.2021,178,489.64062,32005.088,12216.636 21,4,7,5,78.798721,521,3768654.8,94.541626,6940.915,178,335.13281,21502.381,12216.636 22,4,7,6,92.622635,1212,6392349,94.387596,6921.416,178,335.67969,21562.957,12216.636 23,4,7,6,72.328705,2026,9513038,94.350273,6925.3647,178,335.8125,21550.662,12216.636 24,3.0542002,7,5,78.076729,2484,10539197,94.411774,6929.8618,178,335.59375,21536.678,12216.636 25,1.086924,7,4,38.178894,2364,9562418,94.596756,6949.0996,178,334.9375,21477.057,12216.636 26,3.8588758,7,4,19.806421,183,1061214.2,70.44252,5291.4692,178,449.78516,28205.059,12216.636 27,2.9553642,8,4,152.64659,251,1603799.8,67.250679,4869.6396,178,471.13281,30648.303,12216.636 28,2.5628395,8,4,30.569248,568,1731472.4,65.794159,4767.6074,178,481.5625,31304.215,12216.636 29,1.9056505,9,3,36.273235,29,378006.91,60.132584,4206.0908,178,526.90234,35483.352,12216.636 30,1.9439689,9,3,20.292385,218,1091423.4,60.404408,4222.1895,178,524.53125,35348.059,12216.636 31,2.9565058,10,4,63.638454,179,1265680.5,76.827156,5356.625,178,412.40625,27861.982,12216.636 32,2.0050292,10,4,72.13398,318,1992266.2,76.798058,5353.8901,178,412.5625,27876.215,12216.636 33,3.038465,10,5,69.456345,451,2690610.5,76.773346,5351.5645,178,412.69531,27888.332,12216.636 34,4,10,5,85.215919,289,1667870.4,75.121597,5252.0879,178,421.76953,28416.547,12216.636 35,4,11,4,107.46763,2,838417.31,63.447308,4644.291,178,499.375,32135.412,12216.636 36,3.2855186,12,4,11.691815,194,1175906.4,91.489624,6918.437,178,346.3125,21572.242,12216.636 37,1.7466468,12,4,67.515892,1345,8545044,93.415764,7065.1655,178,339.17188,21124.232,12216.636 38,1.9949708,12,4,71.218079,1564,10169552,93.450203,7068.7441,178,339.04688,21113.537,12216.636 39,2.9728639,12,5,69.910538,1838,11861826,93.480362,7072.0098,178,338.9375,21103.789,12216.636 40,3.021472,12,5,149.26498,2287,15157395,92.603081,7028.9722,178,342.14844,21233.004,12216.636 41,2.9785283,12,5,84.025612,2172,14630360,92.644333,7033.8105,178,341.99609,21218.398,12216.636 42,4,12,6,193.21144,1244,11365588,92.635872,7033.4829,178,342.02734,21219.387,12216.636 43,4,12,5,69.391472,768,7140941.5,93.896996,7157.6016,178,337.43359,20851.426,12216.636 44,1.8460462,13,3,72.605972,316,1933160.2,78.073212,5514.459,178,405.82422,27064.521,12216.636 45,3.079603,13,5,109.37788,478,2846059,77.863358,5500.2261,178,406.91797,27134.557,12216.636 46,4,13,5,236.42712,473,4039082.2,78.030403,5565.8442,178,406.04688,26814.656,12216.636 47,2.9256492,14,3,73.804344,175,1367621.2,65.590919,4713.0044,178,483.05469,31666.893,12216.636 48,3.118978,15,4,1.1576769,21,52568.5,54.646725,3815.7188,178,579.79688,39113.523,12216.636 49,2.881022,15,4,51.738968,143,588109.5,57.167553,4008.4851,178,554.23047,37232.57,12216.636 50,0.67563176,16,2,57.332561,0,576803.94,65.119614,4571.0322,178,486.55078,32650.436,12216.636 51,3.3243682,16,4,1.773312,279,1124254.5,64.529015,4523.1011,178,491.00391,32996.434,12216.636 52,3.5566537,17,4,1.5755012,185,842638.75,76.248665,5384.1821,178,415.53516,27719.381,12216.636 53,2.4433463,17,5,94.138809,909,2878055.8,76.660873,5397.0391,178,413.30078,27653.35,12216.636 54,4,17,5,240.50478,375,3247603.5,76.669571,5422.1479,178,413.25391,27525.291,12216.636 55,2.9502037,18,4,63.214619,480,4244460.5,103.37621,7594.2671,178,306.49219,19652.482,12216.636 56,2.043396,18,4,55.795689,1247,10353393,102.60077,7508.9897,178,308.80859,19875.67,12216.636 57,3.0064003,18,5,61.844196,1345,9701150,102.59558,7507.5396,178,308.82422,19879.51,12216.636 58,4,18,6,57.726696,1684,8941627,102.73723,7506.4736,178,308.39844,19882.332,12216.636 59,4,18,6,78.380333,1829,7873546.5,102.76196,7497.6934,178,308.32422,19905.615,12216.636 60,2.3847485,18,5,76.566856,2421,9062067,103.37885,7527.7261,178,306.48438,19826.199,12216.636 61,3.6152513,18,4,7.2528086,254,949294.31,80.944298,6096.1309,178,391.42969,24482.119,12216.636 62,3.0376058,19,4,4.8203835,969,3415459,88.060799,6053.9453,178,359.79688,24652.717,12216.636 63,2.0014875,19,4,57.263824,1257,4270006.5,88.909271,6120.3413,178,356.36328,24385.273,12216.636 64,2.0467546,19,4,81.338486,1219,4250588,89.006836,6125.0562,178,355.97266,24366.502,12216.636 65,2.9141521,19,5,69.343399,1026,3768641.5,89.135948,6129.8477,178,355.45703,24347.457,12216.636 66,2.9891434,19,4,15.855036,146,408590.09,92.881973,6344.1655,178,341.12109,23524.953,12216.636 67,4,20,5,0.50094116,218,1162905.5,95.223106,6722.3511,178,332.73438,22201.488,12216.636 68,3.7623262,20,5,31.326914,1285,4497112,96.855942,6966.7446,178,327.125,21422.658,12216.636 69,1.3914185,20,4,20.039038,3505,11620107,109.44092,7678.6113,178,289.50781,19436.613,12216.636 70,1.9921591,20,4,80.945,3493,11790712,109.55621,7688.1909,178,289.20312,19412.395,12216.636 71,1.5069535,20,4,54.103935,3332,11531442,110.02882,7732.5884,178,287.96094,19300.938,12216.636 72,3.3471429,20,4,8.468255,2263,8132306,104.11933,7376.3535,178,304.30469,20233.059,12216.636 73,2,21,2,79.482445,0,724714.19,68.040466,4773.4067,178,465.66406,31266.18,12216.636 74,2,22,2,84.41777,0,884771.5,61.031174,4482.9517,178,519.14453,33291.949,12216.636 75,2.0549963,23,3,141.50713,807,5807270,108.51846,7723.2334,178,291.96875,19324.314,12216.636 76,2.0359912,23,4,75.595688,1018,8256845,108.48653,7714.8027,178,292.05469,19345.434,12216.636 77,2.0393751,23,4,72.215797,1600,11373205,108.45172,7712.0181,178,292.14844,19352.418,12216.636 78,2.9666958,23,5,73.287651,2234,14429388,108.67695,7731.8662,178,291.54297,19302.74,12216.636 79,4,23,6,30.462101,3298,17047350,109.00117,7758.3276,178,290.67578,19236.904,12216.636 80,2.9891434,23,4,41.801193,7,305486.44,81.780823,6039.9316,178,387.42578,24709.916,12216.636 81,3.0975204,24,4,19.99411,1982,8221255.5,94.571388,6882.4766,178,335.02734,21684.955,12216.636 82,1.8206327,24,4,81.959412,2197,8739249,94.774712,6903.2329,178,334.30859,21619.754,12216.636 83,3.081847,24,5,61.298454,2277,8390308,94.681778,6897.7725,178,334.63672,21636.869,12216.636 84,4,24,6,230.26486,1424,6303539,94.330521,6897.4736,178,335.88281,21637.807,12216.636 85,3.2086754,24,4,11.345068,44,144973.97,94.284462,6899.8101,178,336.04688,21630.479,12216.636 86,4,25,5,21.704504,197,477300.16,96.725426,6661.9341,178,327.56641,22402.832,12216.636 87,4,25,6,156.13542,1787,5874959,98.494301,6724.2876,178,321.68359,22195.096,12216.636 88,3.1397986,25,5,4.3709054,2150,9321218,104.76485,7310.2856,178,302.42969,20415.92,12216.636 89,1.8853738,25,4,123.53465,3623,16552666,109.2331,7622.9595,178,290.05859,19578.512,12216.636 90,2.9748278,25,5,88.042221,3490,16621146,109.28609,7624.9824,178,289.91797,19573.316,12216.636 91,4,25,6,44.959156,3443,16985778,113.6598,7907.6191,178,278.76172,18873.721,12216.636 92,3.2086754,25,4,32.158134,68,200538.19,101.16245,6671.1152,178,313.19922,22372,12216.636 93,1.5234891,26,3,156.51314,880,4697371,104.36852,7220.9028,178,303.57812,20668.635,12216.636 94,2.5515666,26,4,28.49353,680,4084668.8,101.46744,7087.5713,178,312.25781,21057.453,12216.636 95,2.7092693,26,5,152.589,817,4337584,103.78361,7169.0215,178,305.28906,20818.209,12216.636 96,4,26,5,4.3323708,614,2229197,76.315384,5204.4497,178,415.17188,28676.652,12216.636 97,3.2741685,27,4,5.734199,492,997931.38,80.218208,5351.3374,178,394.97266,27889.516,12216.636 98,2.7258315,27,5,58.77298,1042,3266476.5,81.474419,5444.9028,178,388.88281,27410.258,12216.636 99,4,27,6,26.602385,1344,4041288.8,82.973801,5525.2549,178,381.85547,27011.643,12216.636 100,4,27,5,7.6956849,33,207832.08,82.114479,5449.6763,178,385.85156,27386.25,12216.636 101,3.3356996,28,4,14.008615,194,486196.19,70.869667,4749.543,178,447.07422,31423.277,12216.636 102,2.6643004,28,5,51.947716,511,1172606.5,75.637886,5014.8662,178,418.89062,29760.754,12216.636 103,3.2326641,28,5,24.983932,284,761697.12,76.392288,5051.4565,178,414.75391,29545.182,12216.636 104,2.7673359,28,4,8.5771065,207,681293.75,82.713196,5482.2207,178,383.05859,27223.676,12216.636 105,4,29,5,55.623226,382,1242717.2,74.394005,4952.0566,178,425.89453,30138.227,12216.636 106,2.6909027,29,5,122.1385,689,2199216.8,73.854805,4909.8218,178,429.00391,30397.479,12216.636 107,3.3090973,29,4,13.437029,331,745346.69,72.762947,4875.8032,178,435.44141,30609.561,12216.636 108,2.9276934,30,4,81.830719,222,678286.44,89.582893,5963.4609,178,353.68359,25026.775,12216.636 109,2.7533221,30,5,11.665026,481,3171357.2,90.295944,6051.2231,178,350.89062,24663.807,12216.636 110,3.2466779,30,5,6.1998625,338,2045784.5,86.868698,5836.5537,178,364.73438,25570.945,12216.636 111,4,30,6,5.4097123,2668,11407769,105.92642,7445.8682,178,299.11328,20044.162,12216.636 112,3.0539846,30,5,67.115707,2883,12051203,105.87665,7443.2124,178,299.25391,20051.316,12216.636 113,2.9460154,30,5,59.932568,2769,11646952,105.91536,7444.0581,178,299.14453,20049.037,12216.636 114,3.1116269,30,5,95.806824,2047,9289722,105.9901,7445.4268,178,298.93359,20045.352,12216.636 115,2.8883731,30,4,0.19636907,1405,6988613.5,107.35222,7529.5103,178,295.14062,19821.502,12216.636 116,2.9463861,31,4,85.111755,76,584308.75,69.896194,4771.4482,178,453.30078,31279.014,12216.636 117,2.9276934,31,4,7.8116097,118,404667.56,71.989281,4957.4209,178,440.12109,30105.613,12216.636 118,2.7760887,32,3,80.504349,40,465632.84,67.132118,4718.7378,178,471.96484,31628.416,12216.636 119,1.7224751,33,2,51.585476,7,210206.28,53.71521,3717.9077,178,589.85156,40142.523,12216.636 120,4,34,5,100.73653,1167,7415106.5,108.31992,7600.376,178,292.50391,19636.688,12216.636 121,4,34,6,104.9296,1762,9997418,108.30835,7603.0674,178,292.53516,19629.736,12216.636 122,2.8438091,34,5,68.548241,2983,14175580,108.05441,7573.5566,178,293.22266,19706.225,12216.636 123,2.1506054,34,4,42.451733,3055,14141106,107.82458,7557.7256,178,293.84766,19747.502,12216.636 124,3.0055857,34,5,44.519382,3227,14320575,107.82172,7557.6279,178,293.85547,19747.756,12216.636 125,3.1265831,34,5,83.344948,3250,14420084,107.70002,7561.4126,178,294.1875,19737.873,12216.636 126,2.8734171,34,5,11.506542,3430,13727606,107.9753,7599.6616,178,293.4375,19638.531,12216.636 127,4,34,6,6.0284462,2657,10569333,105.04842,7428.769,178,301.61328,20090.301,12216.636 128,4,34,5,5.419879,326,1180875.9,86.131653,6176.9673,178,367.85547,24161.727,12216.636 129,2,35,2,20.824474,0,212491.75,66.399551,4603.9497,178,477.17188,32416.992,12216.636 130,2.315361,36,3,36.565041,182,517014.62,69.343452,4775.4722,178,456.91406,31252.656,12216.636 131,0.87075675,37,2,15.346227,109,383297.66,64.659164,4430.2266,178,490.01562,33688.164,12216.636 132,2.5553956,38,3,58.902714,107,482010.88,60.524754,4128.2837,178,523.48828,36152.117,12216.636 133,4,39,5,29.471209,2132,7106502.5,102.01877,7046.436,178,310.57031,21180.381,12216.636 134,3.0400231,39,5,0.41702437,1868,6555843,102.04957,7047.5352,178,310.47656,21177.078,12216.636 135,1.8690072,39,4,143.56969,2082,7028887,103.00992,7118.877,178,307.58203,20964.852,12216.636 136,3.0909696,39,5,220.49948,633,2843580.8,102.03416,7091.9126,178,310.52344,21044.562,12216.636 137,3.3558173,39,4,4.6648011,60,48442.176,102.77367,7156.9517,178,308.28906,20853.32,12216.636 138,4,40,5,5.8880019,1198,6602856.5,92.347939,6651.4351,178,343.09375,22438.195,12216.636 139,2.8008873,40,5,86.80928,1314,6988477.5,90.596497,6541.2188,178,349.72656,22816.268,12216.636 140,1.9834378,40,3,83.826813,874,4874680,89.554214,6493.5498,178,353.79688,22983.762,12216.636 141,3.7738943,41,4,33.475399,963,7042259,84.994438,6210.7104,178,372.77734,24030.455,12216.636 142,1.4153167,41,4,178.53447,1362,8652835,90.345222,6721.4429,178,350.69922,22204.488,12216.636 143,1.2796584,41,4,116.47486,1233,6833815.5,91.196457,6782.4829,178,347.42578,22004.656,12216.636 144,2.8869476,41,3,6.8355722,0,32039.699,81.984169,6130.0171,178,386.46484,24346.783,12216.636 145,3.9999998,42,5,314.13025,147,2550125.8,75.341393,5244.0146,178,420.53906,28460.293,12216.636 146,4,42,5,1.4020742,28,787264.31,73.82859,5159.4937,178,429.15625,28926.521,12216.636 147,2,43,2,32.635479,0,340282.88,67.405479,4677.939,178,470.05078,31904.262,12216.636 148,2.372308,44,4,55.385048,1325,2879153,77.915718,5145.1392,178,406.64453,29007.223,12216.636 149,3.6276922,44,4,8.0672827,538,1295412.9,74.798775,5021.2231,178,423.58984,29723.076,12216.636 150,2.6622484,45,4,4.1139636,523,1247895.5,72.8479,4776.5571,178,434.93359,31245.559,12216.636 151,1.9825487,45,4,56.198662,461,1198154.6,72.054512,4745.6021,178,439.72266,31449.371,12216.636 152,3.3552032,45,4,13.687597,169,627264.94,69.173141,4584.3516,178,458.03906,32555.576,12216.636 153,3.7100596,46,4,5.1633153,55,157636.45,69.908241,4694.3491,178,453.22266,31792.736,12216.636 154,0.85895824,46,4,48.794411,682,1540374.1,74.486237,4990.52,178,425.36719,29905.941,12216.636 155,3.4309821,46,4,5.8241816,177,671997.44,69.014816,4629.6465,178,459.08984,32237.061,12216.636 156,2.7051506,47,4,166.88625,383,2285897.5,70.657295,4891.9014,178,448.41797,30508.834,12216.636 157,3.2948494,47,4,4.9959264,274,1980018.8,69.792152,4865.7471,178,453.97656,30672.824,12216.636 158,0.98894149,48,2,114.23679,0,1195344.4,80.295242,6018.9507,178,394.59375,24796.049,12216.636 159,1.182127,48,3,55.910877,274,2741649,80.140541,6005.0312,178,395.35547,24853.525,12216.636 160,3.0480838,49,4,81.635147,126,1503485.5,81.069695,6023.3394,178,390.82422,24777.984,12216.636 161,2.0113289,49,4,108.93696,334,2477706.5,81.778351,6069.8652,178,387.4375,24588.059,12216.636 162,2.940587,49,4,30.296598,330,1952532.9,82.620514,6154.3496,178,383.48828,24250.523,12216.636 163,3.1072955,50,3,40.717644,287,1715661.2,62.152149,4446.2324,178,509.78125,33566.891,12216.636 164,1.1072954,51,1,63.598595,0,651424.19,44.939854,3176.8967,178,705.03125,46978.613,12216.636 165,3.0436037,52,4,4.4063578,96,605797.19,66.459404,4746.5186,178,476.74219,31443.299,12216.636 166,2.9563963,52,4,90.654068,109,1062591.8,67.1894,4814.7637,178,471.5625,30997.617,12216.636 167,3.0721309,53,4,143.34143,93,2134044,75.842278,5481.8882,178,417.76172,27225.328,12216.636 168,2.9278691,53,4,141.29507,294,2936599.2,76.411003,5523.6138,178,414.65234,27019.666,12216.636 169,4,54,4,64.827652,299,1046788.9,60.478722,4116.709,178,523.88672,36253.766,12216.636 170,1.9948233,55,3,26.562881,53,334537.75,46.611523,3140.5879,178,679.74609,47521.742,12216.636 171,1.9981046,55,3,23.211634,55,313906.69,46.611523,3140.5879,178,679.74609,47521.742,12216.636 172,1.9839985,56,2,62.202236,0,264440.84,42.862148,2839.1758,178,739.20703,52566.734,12216.636 173,2.0713086,57,3,25.08102,68,396381.09,52.447456,3490.3325,178,604.10938,42759.883,12216.636 174,1.9357636,57,3,25.400402,91,432314.75,55.001724,3657.7,178,576.05469,40803.289,12216.636 175,2.0160015,58,2,63.467106,26,283843.69,43.754169,2897.7686,178,724.13672,51503.84,12216.636 176,4,59,4,106.14331,8,866621.44,63.394745,4639.7456,178,499.78906,32166.893,12216.636 177,4,60,4,245.73332,0,2100469,73.744011,5285.8833,178,429.64844,28234.865,12216.636 ================================================ FILE: testdata/barnsbury_segment_pline.mif ================================================ Version 300 Charset "WindowsLatin1" Delimiter "," Index 1 CoordSys NonEarth Units "m" Bounds (530635.696268, 183499.852969) (531446.820644, 184583.962646) Columns 13 Depthmap_Ref Integer Angular_Connectivity Float Axial_Line_Ref Float Connectivity Float Segment_Length Float T1024_Choice Float T1024_Choice_Segment_Length_Wgt_ Float T1024_Integration Float T1024_Integration_Segment_Length_Wgt_ Float T1024_Node_Count Float T1024_Total_Depth Float T1024_Total_Depth_Segment_Length_Wgt_ Float T1024_Total_Segment_Length Float Data LINE 530661.6919780188 184270.5626832811 530670.3012171048 184204.951785912 PEN (1,2,0) LINE 530670.3012171048 184204.951785912 530681.0222267658 184123.2471128816 PEN (1,2,0) LINE 530681.0222267658 184123.2471128816 530712.6887355548 183881.9170676302 PEN (1,2,0) LINE 530712.6887355548 183881.9170676302 530730.7679409641 183744.1356819843 PEN (1,2,0) LINE 530661.6919780187 184270.562683281 530782.0935715765 184320.087685171 PEN (1,2,0) LINE 530782.0935715765 184320.087685171 530931.9721717195 184381.7375166726 PEN (1,2,0) LINE 530931.9721717195 184381.7375166726 531102.9365496121 184452.0605986855 PEN (1,2,0) LINE 531102.9365496121 184452.0605986855 531275.7084119404 184523.1271564901 PEN (1,2,0) LINE 530782.0935715765 184320.087685171 530796.6615005322 184257.2066049815 PEN (1,2,0) LINE 530796.6615005322 184257.2066049815 530808.6826332469 184205.3185286112 PEN (1,2,0) LINE 530808.6826332469 184205.3185286112 530811.0516134852 184195.09305066 PEN (1,2,0) LINE 530670.3012171047 184204.9517859119 530796.6615005322 184257.2066049815 PEN (1,2,0) LINE 530796.6615005322 184257.2066049815 530930.0609102942 184312.3723725155 PEN (1,2,0) LINE 530930.0609102942 184312.3723725155 531122.4555083865 184391.9349110013 PEN (1,2,0) LINE 530804.6982026402 184201.4318404568 530811.0516134852 184195.0930506599 PEN (1,2,0) LINE 530811.0516134852 184195.0930506599 530855.3978358759 184150.8488818384 PEN (1,2,0) LINE 530755.4256480751 184153.3679956899 530804.6982026402 184201.4318404567 PEN (1,2,0) LINE 530804.6982026402 184201.4318404567 530808.6826332469 184205.3185286112 PEN (1,2,0) LINE 530755.4256480752 184153.36799569 530759.8102694125 184121.9498409454 PEN (1,2,0) LINE 530759.8102694125 184121.9498409454 530781.0080675455 183970.0562905679 PEN (1,2,0) LINE 530681.0222267658 184123.2471128815 530759.8102694125 184121.9498409453 PEN (1,2,0) LINE 530759.8102694125 184121.9498409453 530852.4203537111 184120.4249843892 PEN (1,2,0) LINE 530852.4203537111 184120.4249843892 530924.739253607 184119.2342290901 PEN (1,2,0) LINE 530924.739253607 184119.2342290901 531002.80539858 184117.9488434448 PEN (1,2,0) LINE 531002.80539858 184117.9488434448 531040.9791199062 184117.3203001314 PEN (1,2,0) LINE 531040.9791199062 184117.3203001314 531060.7828570851 184116.994224859 PEN (1,2,0) LINE 530837.552389062 183968.5041980529 530852.4203537111 184120.4249843893 PEN (1,2,0) LINE 530852.4203537111 184120.4249843893 530855.3978358759 184150.8488818385 PEN (1,2,0) LINE 530781.0080675455 183970.0562905679 530817.2676436539 183969.0609966963 PEN (1,2,0) LINE 530817.2676436539 183969.0609966963 530837.5523890621 183968.5041980528 PEN (1,2,0) LINE 530804.1027903862 183678.9148130685 530806.9873013139 183742.4878602049 PEN (1,2,0) LINE 530806.9873013139 183742.4878602049 530810.2568850133 183814.5477011403 PEN (1,2,0) LINE 530810.2568850133 183814.5477011403 530813.4051007051 183883.9326574047 PEN (1,2,0) LINE 530813.4051007051 183883.9326574047 530817.2676436539 183969.0609966964 PEN (1,2,0) LINE 530806.9873013139 183742.4878602049 530914.4265599075 183744.9570759712 PEN (1,2,0) LINE 530912.2449280558 183665.7794156555 530912.5669577819 183677.46679556 PEN (1,2,0) LINE 530912.5669577819 183677.46679556 530914.4265599076 183744.9570759712 PEN (1,2,0) LINE 530914.4265599076 183744.9570759712 530916.3881318528 183816.1481328081 PEN (1,2,0) LINE 530916.3881318528 183816.1481328081 530918.3136899534 183886.0321442102 PEN (1,2,0) LINE 530918.3136899534 183886.0321442102 530922.4249214346 184035.2404945642 PEN (1,2,0) LINE 530922.4249214346 184035.2404945642 530924.739253607 184119.2342290901 PEN (1,2,0) LINE 530924.739253607 184119.2342290901 530930.0609102943 184312.3723725156 PEN (1,2,0) LINE 530930.0609102943 184312.3723725156 530931.9721717195 184381.7375166726 PEN (1,2,0) LINE 530997.7409700139 184191.5792263541 531069.1018140045 184204.9679402672 PEN (1,2,0) LINE 531069.1018140045 184204.9679402672 531176.6039484286 184225.1374792238 PEN (1,2,0) LINE 531176.6039484286 184225.1374792238 531408.9765464333 184268.7352011949 PEN (1,2,0) LINE 530997.7409700138 184191.5792263541 531002.8053985799 184117.9488434448 PEN (1,2,0) LINE 531065.9075465151 184257.7680519287 531065.9774551002 184256.612487747 PEN (1,2,0) LINE 531065.9774551002 184256.612487747 531069.1018140046 184204.9679402672 PEN (1,2,0) LINE 531014.260003 184282.658893 531065.9075465151 184257.7680519287 PEN (1,2,0) LINE 531065.9075465151 184257.7680519287 531067.5050192737 184256.9981713527 PEN (1,2,0) LINE 531065.9774551002 184256.612487747 531067.5050192737 184256.9981713527 PEN (1,2,0) LINE 531067.5050192737 184256.9981713527 531158.7795115133 184280.0434063022 PEN (1,2,0) LINE 531158.7795115133 184280.0434063022 531391.9665625809 184338.919114588 PEN (1,2,0) LINE 531102.9365496121 184452.0605986855 531122.4555083866 184391.9349110013 PEN (1,2,0) LINE 531122.4555083866 184391.9349110013 531139.6837024501 184338.8656347355 PEN (1,2,0) LINE 531139.6837024501 184338.8656347355 531158.7795115134 184280.0434063022 PEN (1,2,0) LINE 531158.7795115134 184280.0434063022 531176.6039484288 184225.1374792239 PEN (1,2,0) LINE 531176.6039484288 184225.1374792239 531200.8056679327 184150.5871384435 PEN (1,2,0) LINE 531200.8056679327 184150.5871384435 531224.4474343648 184077.7616623912 PEN (1,2,0) LINE 531224.4474343648 184077.7616623912 531226.6869048447 184070.8632563747 PEN (1,2,0) LINE 531222.0221921728 184069.6481218071 531226.6869048446 184070.8632563747 PEN (1,2,0) LINE 531226.6869048446 184070.8632563747 531282.1014374334 184085.2984678934 PEN (1,2,0) LINE 531282.1014374334 184085.2984678934 531360.8131579099 184105.8024815699 PEN (1,2,0) LINE 531360.8131579099 184105.8024815699 531427.9171605199 184123.2827421834 PEN (1,2,0) LINE 531427.9171605199 184123.2827421834 531443.2601697572 184127.2795201643 PEN (1,2,0) LINE 531168.4909565911 183890.5617386632 531168.6344222261 183891.0416966056 PEN (1,2,0) LINE 531168.6344222261 183891.0416966056 531177.6062062277 183921.056403528 PEN (1,2,0) LINE 531177.6062062277 183921.056403528 531183.345230286 183940.256054913 PEN (1,2,0) LINE 531183.345230286 183940.256054913 531206.5272470647 184017.8104676549 PEN (1,2,0) LINE 531206.5272470647 184017.8104676549 531222.0221921728 184069.6481218071 PEN (1,2,0) LINE 531222.0221921728 184069.6481218071 531224.4474343648 184077.7616623912 PEN (1,2,0) LINE 531103.958023 183944.145791 531183.3452302859 183940.256054913 PEN (1,2,0) PLINE 3 531297.5108320001 184441.573404 531275.7084119404 184523.1271564901 531340.8293390643 184549.9134634117 PEN (1,2,0) LINE 531340.8293390643 184549.9134634118 531374.1604658248 184412.3878235204 PEN (1,2,0) LINE 531374.1604658248 184412.3878235204 531391.9665625809 184338.9191145881 PEN (1,2,0) LINE 531391.9665625809 184338.9191145881 531408.9765464333 184268.7352011949 PEN (1,2,0) LINE 531408.9765464333 184268.7352011949 531426.238998241 184197.5095943315 PEN (1,2,0) LINE 531426.238998241 184197.5095943315 531433.4141573964 184167.9045839381 PEN (1,2,0) LINE 531433.4141573964 184167.9045839381 531443.2601697572 184127.2795201643 PEN (1,2,0) LINE 531040.9791199062 184117.3203001315 531060.55370366 184121.3946202041 PEN (1,2,0) LINE 531060.55370366 184121.3946202041 531140.7934071338 184138.0959834922 PEN (1,2,0) LINE 531140.7934071338 184138.0959834922 531200.8056679327 184150.5871384435 PEN (1,2,0) LINE 531200.8056679327 184150.5871384435 531426.238998241 184197.5095943315 PEN (1,2,0) LINE 531426.238998241 184197.5095943315 531437.3460188021 184199.8214471601 PEN (1,2,0) LINE 531379.770131822 183732.4495029183 531382.4238646072 183753.9911641308 PEN (1,2,0) LINE 531382.4238646072 183753.9911641308 531401.5139900263 183908.9551516768 PEN (1,2,0) LINE 531401.5139900263 183908.9551516768 531402.0484051576 183913.2932635508 PEN (1,2,0) LINE 531402.0484051576 183913.2932635508 531417.1525502533 184035.9010778593 PEN (1,2,0) LINE 531417.1525502533 184035.9010778593 531427.9171605199 184123.2827421833 PEN (1,2,0) LINE 531427.9171605199 184123.2827421833 531433.4141573964 184167.9045839381 PEN (1,2,0) LINE 531433.4141573964 184167.9045839381 531437.346018802 184199.8214471601 PEN (1,2,0) LINE 531375.1001237407 183572.3943911834 531387.3458877866 183728.4277266877 PEN (1,2,0) LINE 531387.3458877866 183728.4277266877 531389.5752537736 183756.833909406 PEN (1,2,0) LINE 531389.5752537736 183756.833909406 531401.5139900263 183908.9551516768 PEN (1,2,0) LINE 531401.5139900263 183908.9551516768 531401.8529595991 183913.2742413547 PEN (1,2,0) LINE 531297.7582437188 183720.3357738068 531303.0868777729 183722.4539565722 PEN (1,2,0) LINE 531303.0868777729 183722.4539565722 531357.7029968201 183744.1643838416 PEN (1,2,0) LINE 531357.7029968201 183744.1643838416 531382.4238646072 183753.9911641308 PEN (1,2,0) LINE 531382.4238646072 183753.9911641308 531389.5752537737 183756.8339094061 PEN (1,2,0) LINE 531299.4468674023 183775.0910818076 531311.8200189774 183768.5224902194 PEN (1,2,0) LINE 531311.8200189774 183768.5224902194 531357.7029968201 183744.1643838416 PEN (1,2,0) LINE 531357.7029968201 183744.1643838416 531379.7701318221 183732.4495029183 PEN (1,2,0) LINE 531379.7701318221 183732.4495029183 531387.3458877866 183728.4277266877 PEN (1,2,0) LINE 531304.3126897123 183959.5738054356 531306.4967095837 183903.9934713184 PEN (1,2,0) LINE 531306.4967095837 183903.9934713184 531311.2924203729 183781.9491568425 PEN (1,2,0) LINE 531311.2924203729 183781.9491568425 531311.8200189773 183768.5224902195 PEN (1,2,0) LINE 531075.4349141666 183881.5048417101 531156.8807901648 183889.4317520639 PEN (1,2,0) LINE 531156.8807901648 183889.4317520639 531168.4909565911 183890.5617386632 PEN (1,2,0) LINE 531168.4909565911 183890.5617386632 531174.6616614035 183891.1623169401 PEN (1,2,0) LINE 531174.6616614035 183891.1623169401 531180.0459325081 183891.6863537172 PEN (1,2,0) LINE 531180.0459325081 183891.6863537172 531246.8460016274 183898.1878266653 PEN (1,2,0) LINE 531246.8460016274 183898.1878266653 531306.4967095837 183903.9934713184 PEN (1,2,0) LINE 531306.4967095837 183903.9934713184 531401.8529595992 183913.2742413547 PEN (1,2,0) LINE 531401.8529595992 183913.2742413547 531402.0484051576 183913.2932635508 PEN (1,2,0) LINE 531056.0095225013 183972.3751082587 531073.8019170946 183889.1438577853 PEN (1,2,0) LINE 531073.8019170946 183889.1438577853 531075.4349141666 183881.5048417101 PEN (1,2,0) LINE 530986.8482115235 183887.4036937163 531004.8354864263 183965.872851334 PEN (1,2,0) LINE 531004.8354864263 183965.872851334 531056.0095225013 183972.3751082587 PEN (1,2,0) LINE 530712.6887355547 183881.9170676303 530813.4051007051 183883.9326574047 PEN (1,2,0) LINE 530813.4051007051 183883.9326574047 530918.3136899534 183886.0321442102 PEN (1,2,0) LINE 530918.3136899534 183886.0321442102 530986.8482115236 183887.4036937163 PEN (1,2,0) LINE 530986.8482115236 183887.4036937163 531029.2914457454 183888.2530904232 PEN (1,2,0) LINE 531029.2914457454 183888.2530904232 531073.8019170945 183889.1438577853 PEN (1,2,0) LINE 531073.8019170945 183889.1438577853 531157.1301833935 183890.8114676243 PEN (1,2,0) LINE 531157.1301833935 183890.8114676243 531168.6344222261 183891.0416966057 PEN (1,2,0) LINE 531168.6344222261 183891.0416966057 531174.6616614035 183891.1623169401 PEN (1,2,0) LINE 531174.6616614035 183891.1623169401 531180.0804551976 183891.2707607402 PEN (1,2,0) LINE 531246.8460016274 183898.1878266653 531247.100529 183877.364907 PEN (1,2,0) LINE 531380.713483092 184038.9336762212 531417.1525502533 184035.9010778593 PEN (1,2,0) LINE 531367.8635018886 184047.3232328322 531380.713483092 184038.9336762213 PEN (1,2,0) LINE 531360.8131579099 184105.8024815699 531367.8635018887 184047.323232832 PEN (1,2,0) LINE 531177.6062062277 183921.056403528 531180.0459325082 183891.6863537173 PEN (1,2,0) LINE 531180.0459325082 183891.6863537173 531180.0804551976 183891.2707607402 PEN (1,2,0) LINE 531180.0804551976 183891.2707607402 531191.9656390148 183748.1938739985 PEN (1,2,0) LINE 531191.9656390148 183748.1938739985 531210.2193315655 183528.4512480644 PEN (1,2,0) LINE 531210.2193315655 183528.4512480644 531210.6054995636 183523.8024588018 PEN (1,2,0) LINE 531204.5299233167 183526.934937537 531210.2193315655 183528.4512480644 PEN (1,2,0) LINE 531210.2193315655 183528.4512480644 531294.1006655393 183550.8068506498 PEN (1,2,0) LINE 531294.1006655393 183550.8068506498 531375.1001237407 183572.3943911835 PEN (1,2,0) LINE 530912.5669577818 183677.4667955601 530942.3204781786 183662.1263132498 PEN (1,2,0) LINE 530942.3204781786 183662.1263132498 531101.0050300843 183580.3108665743 PEN (1,2,0) LINE 531101.0050300843 183580.3108665743 531204.5299233167 183526.9349375371 PEN (1,2,0) LINE 531204.5299233167 183526.9349375371 531210.6054995636 183523.8024588018 PEN (1,2,0) LINE 531101.0050300843 183580.3108665743 531156.8807901648 183889.4317520638 PEN (1,2,0) LINE 531156.8807901648 183889.4317520638 531157.1301833934 183890.8114676243 PEN (1,2,0) LINE 531029.2914457454 183888.2530904232 531030.230687 183855.631128 PEN (1,2,0) LINE 531191.9656390148 183748.1938739985 531247.2509705561 183744.8718613147 PEN (1,2,0) LINE 531247.2509705561 183744.8718613147 531255.3037282097 183744.3879831807 PEN (1,2,0) LINE 531247.2509705561 183744.8718613147 531250.8112866409 183746.9331340065 PEN (1,2,0) LINE 531250.8112866409 183746.9331340065 531299.4468674023 183775.0910818077 PEN (1,2,0) LINE 531299.4468674023 183775.0910818077 531311.2924203731 183781.9491568425 PEN (1,2,0) LINE 531250.8112866409 183746.9331340066 531255.3037282097 183744.3879831806 PEN (1,2,0) LINE 531255.3037282097 183744.3879831806 531297.7582437188 183720.3357738067 PEN (1,2,0) LINE 531297.7582437188 183720.3357738067 531302.8256845656 183717.4648625085 PEN (1,2,0) LINE 531294.1006655394 183550.8068506498 531302.8256845657 183717.4648625084 PEN (1,2,0) LINE 531302.8256845657 183717.4648625084 531303.0868777729 183722.4539565722 PEN (1,2,0) LINE 530707.321114 183575.611283 530723.063264805 183688.7582135932 PEN (1,2,0) LINE 530723.063264805 183688.7582135932 530730.7679409641 183744.1356819843 PEN (1,2,0) LINE 530723.0632648049 183688.7582135932 530804.1027903862 183678.9148130685 PEN (1,2,0) LINE 530804.1027903862 183678.9148130685 530912.2449280557 183665.7794156555 PEN (1,2,0) LINE 530912.2449280557 183665.7794156555 530942.3204781786 183662.1263132498 PEN (1,2,0) LINE 531140.7934071338 184138.0959834922 531154.1331188128 184099.6254937419 PEN (1,2,0) LINE 531091.400795 184089.16428 531154.1331188127 184099.6254937418 PEN (1,2,0) LINE 531060.55370366 184121.3946202041 531060.7828570851 184116.994224859 PEN (1,2,0) LINE 531060.7828570851 184116.994224859 531065.4973380617 184026.4628259328 PEN (1,2,0) LINE 530922.4249214346 184035.2404945642 531065.4973380617 184026.4628259328 PEN (1,2,0) LINE 531065.4973380617 184026.4628259328 531206.5272470647 184017.8104676549 PEN (1,2,0) LINE 531282.1014374334 184085.2984678934 531294.5626424844 184021.6797343292 PEN (1,2,0) LINE 531268.4799450308 184016.6518545878 531294.5626424844 184021.6797343292 PEN (1,2,0) LINE 531294.5626424844 184021.6797343292 531317.3546726417 184026.0732824619 PEN (1,2,0) LINE 531268.4799450306 184016.6518545878 531279.5735313552 183955.446866539 PEN (1,2,0) LINE 531279.5735313554 183955.446866539 531304.3126897124 183959.5738054357 PEN (1,2,0) LINE 531304.3126897124 183959.5738054357 531329.3668766369 183963.7532967931 PEN (1,2,0) LINE 531317.3546726417 184026.0732824619 531329.3668766369 183963.7532967931 PEN (1,2,0) LINE 530810.2568850133 183814.5477011403 530916.3881318528 183816.148132808 PEN (1,2,0) LINE 531139.68370245 184338.8656347354 531374.1604658248 184412.3878235204 PEN (1,2,0) ================================================ FILE: testdata/gallery.dxf ================================================ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1027 9 $ACADMAINTVER 70 125 9 $DWGCODEPAGE 3 ANSI_1252 9 $LASTSAVEDBY 1 petros 9 $REQUIREDVERSIONS 160 0 9 $INSBASE 10 0.0 20 0.0 30 0.0 9 $EXTMIN 10 0.6503430354694331 20 4.789033837593649 30 -0.0015258207003583 9 $EXTMAX 10 5.202540408442473 20 7.78257348780491 30 0.0000000349246037 9 $LIMMIN 10 -12.695893 20 -8.793292999999998 9 $LIMMAX 10 17.347693 20 21.250293 9 $ORTHOMODE 70 0 9 $REGENMODE 70 1 9 $FILLMODE 70 1 9 $QTEXTMODE 70 0 9 $MIRRTEXT 70 1 9 $LTSCALE 40 1.0 9 $ATTMODE 70 1 9 $TEXTSIZE 40 0.2 9 $TRACEWID 40 0.05 9 $TEXTSTYLE 7 Standard 9 $CLAYER 8 0 9 $CELTYPE 6 ByLayer 9 $CECOLOR 62 7 9 $CELTSCALE 40 1.0 9 $DISPSILH 70 0 9 $DIMSCALE 40 1.0 9 $DIMASZ 40 0.25 9 $DIMEXO 40 0.125 9 $DIMDLI 40 0.0 9 $DIMRND 40 0.0 9 $DIMDLE 40 0.0 9 $DIMEXE 40 0.125 9 $DIMTP 40 0.0 9 $DIMTM 40 0.0 9 $DIMTXT 40 0.25 9 $DIMCEN 40 0.0 9 $DIMTSZ 40 0.0 9 $DIMTOL 70 0 9 $DIMLIM 70 0 9 $DIMTIH 70 0 9 $DIMTOH 70 0 9 $DIMSE1 70 0 9 $DIMSE2 70 0 9 $DIMTAD 70 1 9 $DIMZIN 70 2 9 $DIMBLK 1 TerminatorOpen 9 $DIMASO 70 1 9 $DIMSHO 70 1 9 $DIMPOST 1 9 $DIMAPOST 1 9 $DIMALT 70 0 9 $DIMALTD 70 4 9 $DIMALTF 40 1.0 9 $DIMLFAC 40 1.0 9 $DIMTOFL 70 0 9 $DIMTVP 40 0.125 9 $DIMTIX 70 0 9 $DIMSOXD 70 0 9 $DIMSAH 70 0 9 $DIMBLK1 1 9 $DIMBLK2 1 9 $DIMSTYLE 2 Standard 9 $DIMCLRD 70 0 9 $DIMCLRE 70 0 9 $DIMCLRT 70 0 9 $DIMTFAC 40 1.0 9 $DIMGAP 40 0.125 9 $DIMJUST 70 0 9 $DIMSD1 70 0 9 $DIMSD2 70 0 9 $DIMTOLJ 70 1 9 $DIMTZIN 70 2 9 $DIMALTZ 70 12 9 $DIMALTTZ 70 12 9 $DIMUPT 70 0 9 $DIMDEC 70 4 9 $DIMTDEC 70 4 9 $DIMALTU 70 2 9 $DIMALTTD 70 4 9 $DIMTXSTY 7 Standard 9 $DIMAUNIT 70 0 9 $DIMADEC 70 4 9 $DIMALTRND 40 0.0 9 $DIMAZIN 70 3 9 $DIMDSEP 70 0 9 $DIMATFIT 70 3 9 $DIMFRAC 70 0 9 $DIMLDRBLK 1 9 $DIMLUNIT 70 2 9 $DIMLWD 70 -2 9 $DIMLWE 70 -2 9 $DIMTMOVE 70 0 9 $DIMFXL 40 1.0 9 $DIMFXLON 70 0 9 $DIMJOGANG 40 0.7853981633974483 9 $DIMTFILL 70 0 9 $DIMTFILLCLR 70 0 9 $DIMARCSYM 70 0 9 $DIMLTYPE 6 9 $DIMLTEX1 6 9 $DIMLTEX2 6 9 $DIMTXTDIRECTION 70 0 9 $LUNITS 70 2 9 $LUPREC 70 4 9 $SKETCHINC 40 0.1 9 $FILLETRAD 40 0.5 9 $AUNITS 70 0 9 $AUPREC 70 4 9 $MENU 1 . 9 $ELEVATION 40 0.0 9 $PELEVATION 40 0.0 9 $THICKNESS 40 0.0 9 $LIMCHECK 70 0 9 $CHAMFERA 40 0.5 9 $CHAMFERB 40 0.5 9 $CHAMFERC 40 1.0 9 $CHAMFERD 40 0.0 9 $SKPOLY 70 0 9 $TDCREATE 40 2458060.813564815 9 $TDUCREATE 40 2458060.730231482 9 $TDUPDATE 40 2459045.696041667 9 $TDUUPDATE 40 2459045.571041666 9 $TDINDWG 40 0.0057293403 9 $TDUSRTIMER 40 0.0057291667 9 $USRTIMER 70 1 9 $ANGBASE 50 0.0 9 $ANGDIR 70 0 9 $PDMODE 70 0 9 $PDSIZE 40 0.0 9 $PLINEWID 40 0.0 9 $SPLFRAME 70 0 9 $SPLINETYPE 70 6 9 $SPLINESEGS 70 8 9 $HANDSEED 5 615 9 $SURFTAB1 70 6 9 $SURFTAB2 70 6 9 $SURFTYPE 70 6 9 $SURFU 70 6 9 $SURFV 70 6 9 $UCSBASE 2 9 $UCSNAME 2 9 $UCSORG 10 0.0 20 0.0 30 0.0 9 $UCSXDIR 10 1.0 20 0.0 30 0.0 9 $UCSYDIR 10 0.0 20 1.0 30 0.0 9 $UCSORTHOREF 2 9 $UCSORTHOVIEW 70 0 9 $UCSORGTOP 10 0.0 20 0.0 30 0.0 9 $UCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $UCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $UCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $UCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $UCSORGBACK 10 0.0 20 0.0 30 0.0 9 $PUCSBASE 2 9 $PUCSNAME 2 9 $PUCSORG 10 0.0 20 0.0 30 0.0 9 $PUCSXDIR 10 1.0 20 0.0 30 0.0 9 $PUCSYDIR 10 0.0 20 1.0 30 0.0 9 $PUCSORTHOREF 2 9 $PUCSORTHOVIEW 70 0 9 $PUCSORGTOP 10 0.0 20 0.0 30 0.0 9 $PUCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $PUCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $PUCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $PUCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $PUCSORGBACK 10 0.0 20 0.0 30 0.0 9 $USERI1 70 0 9 $USERI2 70 0 9 $USERI3 70 0 9 $USERI4 70 0 9 $USERI5 70 0 9 $USERR1 40 0.0 9 $USERR2 40 0.0 9 $USERR3 40 0.0 9 $USERR4 40 0.0 9 $USERR5 40 0.0 9 $WORLDVIEW 70 1 9 $SHADEDGE 70 3 9 $SHADEDIF 70 70 9 $TILEMODE 70 1 9 $MAXACTVP 70 64 9 $PINSBASE 10 0.0 20 0.0 30 0.0 9 $PLIMCHECK 70 0 9 $PEXTMIN 10 1.000000000000000E+20 20 1.000000000000000E+20 30 1.000000000000000E+20 9 $PEXTMAX 10 -1.000000000000000E+20 20 -1.000000000000000E+20 30 -1.000000000000000E+20 9 $PLIMMIN 10 -0.1666668268639272 20 -0.1666666766789955 9 $PLIMMAX 10 11.52777724378691 20 8.097222545954187 9 $UNITMODE 70 0 9 $VISRETAIN 70 1 9 $PLINEGEN 70 0 9 $PSLTSCALE 70 1 9 $TREEDEPTH 70 3020 9 $CMLSTYLE 2 STANDARD 9 $CMLJUST 70 0 9 $CMLSCALE 40 1.0 9 $PROXYGRAPHICS 70 1 9 $MEASUREMENT 70 0 9 $CELWEIGHT 370 -3 9 $ENDCAPS 280 0 9 $JOINSTYLE 280 0 9 $LWDISPLAY 290 1 9 $INSUNITS 70 6 9 $HYPERLINKBASE 1 9 $STYLESHEET 1 9 $XEDIT 290 1 9 $CEPSNTYPE 380 0 9 $PSTYLEMODE 290 1 9 $FINGERPRINTGUID 2 {FDEAD576-A652-11D2-9A35-0060089B3A3F} 9 $VERSIONGUID 2 {428ACE74-CD25-2547-919F-2857E59BC59A} 9 $EXTNAMES 290 1 9 $PSVPSCALE 40 0.0 9 $OLESTARTUP 290 0 9 $SORTENTS 280 127 9 $INDEXCTL 280 0 9 $HIDETEXT 280 0 9 $XCLIPFRAME 280 2 9 $HALOGAP 280 0 9 $OBSCOLOR 70 257 9 $OBSLTYPE 280 0 9 $INTERSECTIONDISPLAY 280 0 9 $INTERSECTIONCOLOR 70 257 9 $DIMASSOC 280 1 9 $PROJECTNAME 1 9 $CAMERADISPLAY 290 0 9 $LENSLENGTH 40 50.0 9 $CAMERAHEIGHT 40 0.0 9 $STEPSPERSEC 40 2.0 9 $STEPSIZE 40 6.0 9 $3DDWFPREC 40 2.0 9 $PSOLWIDTH 40 0.25 9 $PSOLHEIGHT 40 4.0 9 $LOFTANG1 40 1.570796326794896 9 $LOFTANG2 40 1.570796326794896 9 $LOFTMAG1 40 0.0 9 $LOFTMAG2 40 0.0 9 $LOFTPARAM 70 7 9 $LOFTNORMALS 280 1 9 $LATITUDE 40 37.795 9 $LONGITUDE 40 -122.394 9 $NORTHDIRECTION 40 0.0 9 $TIMEZONE 70 -8000 9 $LIGHTGLYPHDISPLAY 280 1 9 $TILEMODELIGHTSYNCH 280 1 9 $CMATERIAL 347 56D 9 $SOLIDHIST 280 0 9 $SHOWHIST 280 1 9 $DWFFRAME 280 2 9 $DGNFRAME 280 0 9 $REALWORLDSCALE 290 1 9 $INTERFERECOLOR 62 1 9 $INTERFEREOBJVS 345 58F 9 $INTERFEREVPVS 346 58C 9 $CSHADOW 280 0 9 $SHADOWPLANELOCATION 40 0.0 0 ENDSEC 0 SECTION 2 CLASSES 0 CLASS 1 ACDBDICTIONARYWDFLT 2 AcDbDictionaryWithDefault 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 IMAGE 2 AcDbRasterImage 3 ISM 90 2175 91 0 280 0 281 1 0 CLASS 1 DICTIONARYVAR 2 AcDbDictionaryVar 3 ObjectDBX Classes 90 0 91 9 280 0 281 0 0 CLASS 1 RASTERVARIABLES 2 AcDbRasterVariables 3 ISM 90 0 91 0 280 0 281 0 0 CLASS 1 IMAGEDEF 2 AcDbRasterImageDef 3 ISM 90 0 91 0 280 0 281 0 0 CLASS 1 IMAGEDEF_REACTOR 2 AcDbRasterImageDefReactor 3 ISM 90 1 91 0 280 0 281 0 0 CLASS 1 IDBUFFER 2 AcDbIdBuffer 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 SPATIAL_FILTER 2 AcDbSpatialFilter 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 SORTENTSTABLE 2 AcDbSortentsTable 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 LAYER_INDEX 2 AcDbLayerIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 SPATIAL_INDEX 2 AcDbSpatialIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 OBJECT_PTR 2 CAseDLPNTableRecord 3 "ASE-LPNTableRecord" 90 1 91 0 280 0 281 0 0 CLASS 1 PLOTSETTINGS 2 AcDbPlotSettings 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 WIPEOUT 2 AcDbWipeout 3 WipeOut|Product Desc: Object Enabler for WipeOut entity | Company: Autodesk, Inc. | WEB Address: www.autodesk.com 90 2175 91 0 280 0 281 1 0 CLASS 1 WIPEOUTVARIABLES 2 AcDbWipeoutVariables 3 "WipeOut|Product Desc: WipeOut Dbx Application|Company: Autodesk, Inc.|WEB Address: www.autodesk.com" 90 0 91 0 280 0 281 0 0 CLASS 1 RTEXT 2 RText 3 RText|AutoCAD Express Tool|expresstools@autodesk.com 90 3071 91 0 280 0 281 1 0 CLASS 1 ARCALIGNEDTEXT 2 AcDbArcAlignedText 3 ATEXT|AutoCAD Express Tool|expresstools@autodesk.com 90 0 91 0 280 0 281 1 0 CLASS 1 MATERIAL 2 AcDbMaterial 3 ObjectDBX Classes 90 1153 91 3 280 0 281 0 0 CLASS 1 VISUALSTYLE 2 AcDbVisualStyle 3 ObjectDBX Classes 90 4095 91 24 280 0 281 0 0 CLASS 1 TABLESTYLE 2 AcDbTableStyle 3 ObjectDBX Classes 90 4095 91 1 280 0 281 0 0 CLASS 1 SCALE 2 AcDbScale 3 ObjectDBX Classes 90 1153 91 17 280 0 281 0 0 CLASS 1 MLEADERSTYLE 2 AcDbMLeaderStyle 3 ACDB_MLEADERSTYLE_CLASS 90 4095 91 1 280 0 281 0 0 CLASS 1 ACDBSECTIONVIEWSTYLE 2 AcDbSectionViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 ACDBDETAILVIEWSTYLE 2 AcDbDetailViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 CELLSTYLEMAP 2 AcDbCellStyleMap 3 ObjectDBX Classes 90 1152 91 3 280 0 281 0 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 520 330 0 100 AcDbSymbolTable 70 1 1001 ACAD 1000 DbSaveVer 1071 70 0 VPORT 5 4B 330 520 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *ACTIVE 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 2.926441721955953 22 6.285803662699279 13 0.0 23 0.0 14 0.1 24 0.1 15 0.1 25 0.1 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 3.124113918573451 41 1.463288521199586 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 100 73 1 74 2 75 0 76 1 77 0 78 1 281 0 65 1 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 348 58B 60 3 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 1001 ACAD_NAV_VCDISPLAY 1070 3 0 ENDTAB 0 TABLE 2 LTYPE 5 51D 330 0 100 AcDbSymbolTable 70 1 0 LTYPE 5 52C 330 51D 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByBlock 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 52D 330 51D 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByLayer 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 52E 330 51D 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 Continuous 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 51A 102 {ACAD_XDICTIONARY 360 5C3 102 } 330 0 100 AcDbSymbolTable 70 2 0 LAYER 5 6 102 {ACAD_XDICTIONARY 360 5D5 102 } 330 51A 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 62 2 6 Continuous 370 0 390 527 347 57D 348 0 0 LAYER 5 293 102 {ACAD_XDICTIONARY 360 5D7 102 } 330 51A 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 Image 70 0 62 7 6 Continuous 370 0 390 527 347 57D 348 0 0 ENDTAB 0 TABLE 2 STYLE 5 51B 330 0 100 AcDbSymbolTable 70 1 0 STYLE 5 529 330 51B 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Standard 70 0 40 0.0 41 1.0 50 0.0 71 0 42 0.2 3 txt 4 0 ENDTAB 0 TABLE 2 VIEW 5 51E 330 0 100 AcDbSymbolTable 70 2 0 ENDTAB 0 TABLE 2 UCS 5 51F 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 521 330 0 100 AcDbSymbolTable 70 3 0 APPID 5 52A 330 521 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 APPID 5 5CA 330 521 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_NAV_VCDISPLAY 70 0 0 APPID 5 5D0 330 521 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_PSEXT 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 522 330 0 100 AcDbSymbolTable 70 1 100 AcDbDimStyleTable 71 0 0 DIMSTYLE 105 2 330 522 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Standard 70 0 41 0.25 42 0.125 43 0.0 44 0.125 73 0 74 0 77 1 78 2 79 3 140 0.25 141 0.0 143 1.0 145 0.125 147 0.125 171 4 179 4 274 4 278 0 284 2 285 12 286 12 340 529 342 562 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 519 330 0 100 AcDbSymbolTable 70 2 0 BLOCK_RECORD 5 518 330 519 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *MODEL_SPACE 340 4A 70 0 280 1 281 0 0 BLOCK_RECORD 5 5BC 330 519 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space 340 5BD 70 0 280 1 281 0 0 BLOCK_RECORD 5 562 330 519 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 TerminatorOpen 340 0 70 0 280 1 281 0 0 BLOCK_RECORD 5 568 330 519 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *PAPER_SPACE1 340 569 70 0 280 1 281 0 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 538 330 518 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *MODEL_SPACE 70 0 10 0.0 20 0.0 30 0.0 3 *MODEL_SPACE 1 0 ENDBLK 5 539 330 518 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 5BE 330 5BC 100 AcDbEntity 67 1 8 0 62 7 370 -3 100 AcDbBlockBegin 2 *Paper_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space 1 0 ENDBLK 5 5BF 330 5BC 100 AcDbEntity 67 1 8 0 62 7 370 -3 100 AcDbBlockEnd 0 BLOCK 5 563 330 562 100 AcDbEntity 8 0 6 Continuous 62 0 370 -2 100 AcDbBlockBegin 2 TerminatorOpen 70 0 10 0.0 20 0.0 30 0.0 3 TerminatorOpen 1 0 LINE 5 564 330 562 100 AcDbEntity 8 0 6 Continuous 62 0 370 -2 100 AcDbLine 10 0.0 20 0.0 30 0.0 11 -1.0 21 0.0 31 0.0 0 LINE 5 565 330 562 100 AcDbEntity 8 0 6 Continuous 62 0 370 -2 100 AcDbLine 10 0.0 20 0.0 30 0.0 11 -1.0 21 0.25 31 0.0 0 LINE 5 566 330 562 100 AcDbEntity 8 0 6 Continuous 62 0 370 -2 100 AcDbLine 10 0.0 20 0.0 30 0.0 11 -1.0 21 -0.25 31 0.0 0 ENDBLK 5 567 330 562 100 AcDbEntity 8 0 6 Continuous 62 0 370 -2 100 AcDbBlockEnd 0 BLOCK 5 534 330 568 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *PAPER_SPACE1 70 0 10 0.0 20 0.0 30 0.0 3 *PAPER_SPACE1 1 0 ENDBLK 5 535 330 568 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LINE 5 250 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.8973459999999999 20 5.496596 30 0.0 11 0.8973459999999999 21 5.096047 31 0.0 0 LINE 5 259 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.393770999999999 20 5.096047 30 0.0 11 1.393770999999999 21 4.919208999999998 31 0.0 0 LINE 5 25A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.393770999999999 20 4.919208999999998 30 0.0 11 1.568479 21 4.919208999999998 31 0.0 0 LINE 5 25C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.568479 20 5.264362999999998 30 0.0 11 1.472603 21 5.264362999999998 31 0.0 0 LINE 5 260 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.472603 20 5.102437999999998 30 0.0 11 1.527998 21 5.102437999999998 31 0.0 0 LINE 5 261 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.527998 20 5.102437999999998 30 0.0 11 1.527998 21 5.079002 31 0.0 0 LINE 5 262 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.527998 20 5.079002 30 0.0 11 1.453427 21 5.079002 31 0.0 0 LINE 5 251 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.8973459999999999 20 5.096047 30 0.0 11 1.393770999999999 21 5.096047 31 0.0 0 LINE 5 263 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.472603 20 5.235732999999998 30 0.0 11 1.453427 21 5.235732999999998 31 0.0 0 LINE 5 264 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.472603 20 5.177674999999998 30 0.0 11 1.453427 21 5.177674999999998 31 0.0 0 LINE 5 252 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.453427 20 5.079002 30 0.0 11 1.453427 21 5.177674999999998 31 0.0 0 LINE 5 265 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.453427 20 5.235732999999998 30 0.0 11 1.453427 21 5.496596 31 0.0 0 LINE 5 25D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.472603 20 5.264362999999998 30 0.0 11 1.472603 21 5.235732999999998 31 0.0 0 LWPOLYLINE 5 26B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 1 43 0.0 10 2.210849 20 4.973271999999998 10 2.210849 20 4.973271999999998 10 2.210849 20 4.973271999999998 10 2.210849 20 4.973271999999998 0 LINE 5 266 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.472603 20 5.177674999999998 30 0.0 11 1.472603 21 5.102437999999998 31 0.0 0 LINE 5 25B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.568479 20 4.919208999999998 30 0.0 11 1.568479 21 5.177674999999998 31 0.0 0 LINE 5 26F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.568479 20 5.235732999999998 30 0.0 11 1.568479 21 5.264362999999998 31 0.0 0 LINE 5 270 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.587118 20 5.235732999999998 30 0.0 11 1.587903 21 5.235732999999998 31 0.0 0 LINE 5 26C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.568479 20 5.235732999999998 30 0.0 11 1.587654 21 5.235732999999998 31 0.0 0 LINE 5 26D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.568479 20 5.177674999999998 30 0.0 11 1.587654 21 5.177674999999998 31 0.0 0 LINE 5 26E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.914697999999999 20 5.235732999999998 30 0.0 11 1.947722 21 5.235732999999998 31 0.0 0 LINE 5 272 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.914697999999999 20 5.177674999999998 30 0.0 11 1.947722 21 5.177674999999998 31 0.0 0 LWPOLYLINE 5 275 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.210849 20 5.177674999999998 10 2.210849 20 4.973271999999998 10 1.947722 20 4.973271999999998 10 1.947722 20 5.177674999999998 0 LWPOLYLINE 5 271 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 1.587654 20 5.235732999999998 10 1.587654 20 5.44413 10 1.914697999999999 20 5.44413 10 1.914697999999999 20 5.235732999999998 0 LWPOLYLINE 5 277 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 1.914697999999999 20 5.177674999999998 10 1.914697999999999 20 4.973271999999998 10 1.587654 20 4.973271999999998 10 1.587654 20 5.177674999999998 0 LINE 5 274 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.210849 20 5.177674999999998 30 0.0 11 2.248133999999998 21 5.177674999999998 31 0.0 0 LINE 5 273 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.210849 20 5.235732999999998 30 0.0 11 2.248133999999998 21 5.235732999999998 31 0.0 0 LINE 5 282 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.581479 20 5.133570999999998 30 0.0 11 2.581479 21 4.909673999999998 31 0.0 0 LINE 5 2AA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.613071999999998 20 5.092559999999998 30 0.0 11 4.613071999999998 21 5.116278 31 0.0 0 LINE 5 2B4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.180502999999998 20 7.035305999999998 30 0.0 11 2.180502999999998 21 7.259110999999998 31 0.0 0 LINE 5 2BA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.178199 20 7.01353 30 0.0 11 2.178199 21 6.869946 31 0.0 0 LINE 5 2EF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.907386999999998 20 5.133570999999998 30 0.0 11 2.907386999999998 21 4.909673999999998 31 0.0 0 LINE 5 2F0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.195667999999998 20 5.133570999999998 30 0.0 11 3.195667999999998 21 4.909673999999998 31 0.0 0 LINE 5 2F8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.313600999999998 20 6.49248 30 0.0 11 2.313600999999998 21 6.147992999999998 31 0.0 0 LINE 5 2F9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.313600999999998 20 6.49248 30 0.0 11 2.636331 21 6.49248 31 0.0 0 LINE 5 2FA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.636331 20 6.49248 30 0.0 11 2.636331 21 6.438087 31 0.0 0 LINE 5 2FF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.434088999999998 20 6.465205999999998 30 0.0 11 3.434088999999998 21 6.336554 31 0.0 0 LINE 5 30A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.954269 20 6.683991999999999 30 0.0 11 0.954269 21 6.663596 31 0.0 0 LINE 5 30B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.003459 20 6.683991999999999 30 0.0 11 1.003459 21 6.663596 31 0.0 0 LINE 5 30E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.350190999999999 20 6.564016 30 0.0 11 1.432172 21 6.645997999999998 31 0.0 0 LINE 5 313 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.335906999999999 20 6.803855 30 0.0 11 1.42334 21 6.716422 31 0.0 0 LINE 5 315 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.106638999999999 20 6.733183 30 0.0 11 1.159428 21 6.733183 31 0.0 0 LINE 5 316 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.106638999999999 20 6.821964999999998 30 0.0 11 1.229014999999998 21 6.821964999999998 31 0.0 0 LINE 5 318 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.229014999999998 20 6.821964999999998 30 0.0 11 1.229014999999998 21 6.802769 31 0.0 0 LINE 5 319 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.071845999999998 20 6.761977 30 0.0 11 1.106638999999999 21 6.761977 31 0.0 0 LINE 5 31A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.106638999999999 20 6.807567999999997 30 0.0 11 1.071845999999998 21 6.807567999999997 31 0.0 0 LINE 5 31D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.071845999999998 20 6.529222999999999 30 0.0 11 1.146230999999998 21 6.529222999999999 31 0.0 0 LINE 5 31F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.113837 20 6.615605999999998 30 0.0 11 1.159428 21 6.615605999999998 31 0.0 0 LINE 5 320 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.350190999999999 20 6.564016 30 0.0 11 1.232613999999998 21 6.564016 31 0.0 0 LINE 5 2DB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.268049999999998 20 6.114967 30 0.0 11 4.268049999999998 21 6.054211 31 0.0 0 LINE 5 2DA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.231456999999998 20 6.114967 30 0.0 11 4.231456999999998 21 6.054211 31 0.0 0 LINE 5 32C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.268049999999998 20 5.902955999999998 30 0.0 11 4.268049999999998 21 5.841483 31 0.0 0 LINE 5 32B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.231456999999998 20 5.902955999999998 30 0.0 11 4.231456999999998 21 5.841483 31 0.0 0 LINE 5 329 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.231456999999998 20 6.054211 30 0.0 11 4.268049999999998 21 6.054211 31 0.0 0 LINE 5 2D7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.809408 20 6.054211 30 0.0 11 3.836244 21 6.054211 31 0.0 0 LINE 5 2D6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.268049999999998 20 5.902955999999998 30 0.0 11 4.231456999999998 21 5.902955999999998 31 0.0 0 LINE 5 330 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.836244 20 5.902955999999998 30 0.0 11 3.809408 21 5.902955999999998 31 0.0 0 LINE 5 32F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.809408 20 6.054211 30 0.0 11 3.809408 21 6.114967 31 0.0 0 LINE 5 333 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.836244 20 6.054211 30 0.0 11 3.836244 21 6.114967 31 0.0 0 LINE 5 2DF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.836244 20 5.841483 30 0.0 11 3.836244 21 5.902955999999998 31 0.0 0 LINE 5 2E0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.809408 20 5.841483 30 0.0 11 3.809408 21 5.902955999999998 31 0.0 0 LINE 5 2D8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.970420999999998 20 6.200586 30 0.0 11 3.970420999999998 21 6.17375 31 0.0 0 LINE 5 2D9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.107037999999998 20 6.200586 30 0.0 11 4.107037999999998 21 6.17375 31 0.0 0 LINE 5 2E2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.17795 20 6.17375 30 0.0 11 4.107037999999998 21 6.17375 31 0.0 0 LINE 5 33A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.970420999999998 20 6.17375 30 0.0 11 3.890559999999998 21 6.17375 31 0.0 0 LINE 5 2E1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.890559999999998 20 6.200586 30 0.0 11 3.970420999999998 21 6.200586 31 0.0 0 LINE 5 33B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.107037999999998 20 6.200586 30 0.0 11 4.17795 21 6.200586 31 0.0 0 LINE 5 33D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.17795 20 6.17375 30 0.0 11 4.231456999999998 21 6.114967 31 0.0 0 LINE 5 33E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.890559999999998 20 6.17375 30 0.0 11 3.836244 21 6.114967 31 0.0 0 LINE 5 2DD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.890559999999998 20 5.771219 30 0.0 11 3.970420999999998 21 5.771219 31 0.0 0 LINE 5 341 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.107037999999998 20 5.771219 30 0.0 11 4.17795 21 5.771219 31 0.0 0 LINE 5 2DE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.173843999999998 20 5.739504 30 0.0 11 4.107037999999998 21 5.739504 31 0.0 0 LINE 5 342 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.970420999999998 20 5.739504 30 0.0 11 3.886454 21 5.739504 31 0.0 0 LINE 5 343 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.970420999999998 20 5.771219 30 0.0 11 3.970420999999998 21 5.739504 31 0.0 0 LINE 5 345 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.107037999999998 20 5.771219 30 0.0 11 4.107037999999998 21 5.739504 31 0.0 0 LINE 5 347 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.836244 20 5.841483 30 0.0 11 3.890559999999998 21 5.771219 31 0.0 0 LINE 5 348 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.231456999999998 20 5.841483 30 0.0 11 4.17795 21 5.771219 31 0.0 0 LINE 5 34F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.107412999999998 30 0.0 11 3.521799999999998 21 5.107412999999998 31 0.0 0 LINE 5 326 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.68334 20 6.865889999999998 30 0.0 11 4.637979 21 6.820528999999998 31 0.0 0 LINE 5 322 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.958679 20 6.865889999999998 30 0.0 11 5.012307999999999 21 6.812261 31 0.0 0 LINE 5 327 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 5.012307999999999 20 6.547321 30 0.0 11 4.964686 21 6.499698999999998 31 0.0 0 LINE 5 324 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.637979 20 6.537698999999999 30 0.0 11 4.675978999999998 21 6.499698999999998 31 0.0 0 LWPOLYLINE 5 359 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.68334 20 6.865889999999998 10 4.958679 20 6.865889999999998 0 LWPOLYLINE 5 35A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 5.012307999999999 20 6.812261 10 5.012307999999999 20 6.547321 0 LINE 5 35E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.637979 20 6.645997999999998 30 0.0 11 4.637979 21 6.537698999999999 31 0.0 0 LINE 5 35C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.610913 20 6.645997999999998 30 0.0 11 4.637979 21 6.645997999999998 31 0.0 0 LINE 5 35D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.610913 20 6.716422 30 0.0 11 4.637979 21 6.716422 31 0.0 0 LINE 5 303 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.637979 20 6.820528999999998 30 0.0 11 4.637979 21 6.716422 31 0.0 0 LINE 5 304 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.610913 20 6.865889999999998 30 0.0 11 4.610913 21 6.716422 31 0.0 0 LINE 5 361 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.610913 20 6.645997999999998 30 0.0 11 4.610913 21 6.499698999999998 31 0.0 0 LWPOLYLINE 5 35B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.964686 20 6.499698999999998 10 4.863308999999999 20 6.499698999999998 0 LWPOLYLINE 5 362 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.785242 20 6.499698999999998 10 4.675978999999998 20 6.499698999999998 0 LINE 5 2D1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.785242 20 6.499698999999998 30 0.0 11 4.785242 21 6.416262999999998 31 0.0 0 LINE 5 365 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.863308999999999 20 6.416262999999998 30 0.0 11 4.863308999999999 21 6.499698999999998 31 0.0 0 LINE 5 367 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.609034999999998 20 6.002978999999998 30 0.0 11 4.627576 21 6.002978999999998 31 0.0 0 LINE 5 2D4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.627576 20 5.939549999999998 30 0.0 11 4.609034999999998 21 5.939549999999998 31 0.0 0 LWPOLYLINE 5 331 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 4.268049999999998 20 6.114967 10 4.609034999999998 20 6.114967 10 4.609034999999998 20 6.002978999999998 0 LWPOLYLINE 5 368 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 4.609034999999998 20 5.939549999999998 10 4.609034999999998 20 5.841483 10 4.268049999999998 20 5.841483 0 LWPOLYLINE 5 369 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 4.627576 20 6.002978999999998 10 4.627576 20 6.416262999999998 10 4.785242 20 6.416262999999998 0 LINE 5 2D2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.863308999999999 20 5.49826 30 0.0 11 4.863308999999999 21 5.526280999999999 31 0.0 0 LINE 5 36B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.785242 20 5.526280999999999 30 0.0 11 4.785242 21 5.49826 31 0.0 0 LWPOLYLINE 5 363 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 4.863308999999999 20 6.416262999999998 10 5.007673 20 6.416262999999998 10 5.007673 20 5.526280999999999 10 4.863308999999999 20 5.526280999999999 0 LWPOLYLINE 5 36C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 4.785242 20 5.526280999999999 10 4.627576 20 5.526280999999999 10 4.627576 20 5.939549999999998 0 LINE 5 370 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.563755 20 5.44413 30 0.0 11 4.649888999999999 21 5.44413 31 0.0 0 LINE 5 371 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.543783 20 5.399455 30 0.0 11 4.543783 21 5.44413 31 0.0 0 LINE 5 372 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.543783 20 5.246368 30 0.0 11 4.543783 21 5.399455 31 0.0 0 LWPOLYLINE 5 373 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.563755 20 5.246368 10 4.563755 20 5.44413 0 LINE 5 2A1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.543783 20 4.971473999999998 30 0.0 11 4.543783 21 5.174494999999998 31 0.0 0 LWPOLYLINE 5 378 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 4.676102999999998 20 5.246368 10 4.676102999999998 20 5.49826 10 4.785242 20 5.49826 0 LWPOLYLINE 5 36F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.649888999999999 20 5.44413 10 4.649888999999999 20 5.246368 0 LINE 5 34D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.676102999999998 20 5.246368 30 0.0 11 4.649888999999999 21 5.246368 31 0.0 0 LINE 5 37A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.563755 20 5.246368 30 0.0 11 4.543783 21 5.246368 31 0.0 0 LINE 5 37D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.563755 20 5.174494999999998 30 0.0 11 4.543783 21 5.174494999999998 31 0.0 0 LINE 5 380 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.676102999999998 20 5.174494999999998 30 0.0 11 4.649888999999999 21 5.174494999999998 31 0.0 0 LWPOLYLINE 5 382 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.563755 20 5.116278 10 4.563755 20 5.174494999999998 0 LWPOLYLINE 5 383 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 4.741014999999999 20 5.092559999999998 10 4.741014999999999 20 4.936522 10 4.563755 20 4.936522 10 4.563755 20 5.116278 0 LWPOLYLINE 5 36D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 4.863308999999999 20 5.49826 10 5.200391999999999 20 5.49826 10 5.200391999999999 20 5.092559999999998 10 4.741014999999999 20 5.092559999999998 0 LINE 5 2A9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.676102999999998 20 5.092559999999998 30 0.0 11 4.613071999999998 21 5.092559999999998 31 0.0 0 LWPOLYLINE 5 384 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.676102999999998 20 5.092559999999998 10 4.676102999999998 20 5.174494999999998 0 LWPOLYLINE 5 385 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.649888999999999 20 5.116278 10 4.613071999999998 20 5.116278 0 LWPOLYLINE 5 376 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.649888999999999 20 5.174494999999998 10 4.649888999999999 20 5.116278 0 LWPOLYLINE 5 381 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.619930999999998 20 5.116278 10 4.640336 20 5.116278 0 LINE 5 387 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 5.44413 30 0.0 11 4.543783 21 5.44413 31 0.0 0 LINE 5 27B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.44413 30 0.0 11 3.869697 21 5.44413 31 0.0 0 LINE 5 38B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.985652999999998 20 5.472863999999998 30 0.0 11 3.985652999999998 21 5.454234999999998 31 0.0 0 LINE 5 38D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.081484999999998 20 5.454234999999998 30 0.0 11 4.081484999999998 21 5.472863999999998 31 0.0 0 LWPOLYLINE 5 340 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.173843999999998 20 5.739504 10 4.173843999999998 20 5.472863999999998 0 LWPOLYLINE 5 38E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.186766999999998 20 5.454234999999998 10 4.081484999999998 20 5.454234999999998 0 LINE 5 388 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.081484999999998 20 5.472863999999998 30 0.0 11 4.173843999999998 21 5.472863999999998 31 0.0 0 LINE 5 352 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.886454 20 5.472863999999998 30 0.0 11 3.985652999999998 21 5.472863999999998 31 0.0 0 LWPOLYLINE 5 38F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.886454 20 5.472863999999998 10 3.886454 20 5.739504 0 LWPOLYLINE 5 389 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.985652999999998 20 5.454234999999998 10 3.885924999999998 20 5.454234999999998 0 LWPOLYLINE 5 390 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.17795 20 6.465205999999998 10 4.17795 20 6.200586 0 LWPOLYLINE 5 336 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.890559999999998 20 6.200586 10 3.890559999999998 20 6.465205999999998 0 LINE 5 349 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.985652999999998 20 6.499698999999998 30 0.0 11 3.985652999999998 21 6.465205999999998 31 0.0 0 LINE 5 392 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.081484999999998 20 6.465205999999998 30 0.0 11 4.081484999999998 21 6.499698999999998 31 0.0 0 LWPOLYLINE 5 358 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 4.610913 20 6.499698999999998 10 4.081484999999998 20 6.499698999999998 0 LINE 5 395 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.890559999999998 20 6.465205999999998 30 0.0 11 3.985652999999998 21 6.465205999999998 31 0.0 0 LINE 5 393 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.081484999999998 20 6.465205999999998 30 0.0 11 4.17795 21 6.465205999999998 31 0.0 0 LINE 5 397 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.885924999999998 20 5.246368 30 0.0 11 3.869697 21 5.246368 31 0.0 0 LINE 5 2A4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.885924999999998 20 5.454234999999998 30 0.0 11 3.885924999999998 21 5.246368 31 0.0 0 LINE 5 399 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.869697 20 5.246368 30 0.0 11 3.869697 21 5.44413 31 0.0 0 LINE 5 39C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.885924999999998 20 5.174494999999998 30 0.0 11 3.869697 21 5.174494999999998 31 0.0 0 LINE 5 37B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 5.246368 30 0.0 11 4.186766999999998 21 5.246368 31 0.0 0 LINE 5 39D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 5.174494999999998 30 0.0 11 4.186766999999998 21 5.174494999999998 31 0.0 0 LINE 5 39F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.186766999999998 20 5.246368 30 0.0 11 4.186766999999998 21 5.454234999999998 31 0.0 0 LINE 5 2A2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 5.44413 30 0.0 11 4.214229 21 5.246368 31 0.0 0 LINE 5 2A3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.186766999999998 20 4.971473999999998 30 0.0 11 4.186766999999998 21 5.174494999999998 31 0.0 0 LINE 5 3A0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 4.971473999999998 30 0.0 11 4.543783 21 4.971473999999998 31 0.0 0 LINE 5 39E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 4.214229 20 5.174494999999998 30 0.0 11 4.214229 21 4.971473999999998 31 0.0 0 LINE 5 2A0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 4.971473999999998 30 0.0 11 3.869697 21 4.971473999999998 31 0.0 0 LINE 5 3A1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.885924999999998 20 4.971473999999998 30 0.0 11 4.186766999999998 21 4.971473999999998 31 0.0 0 LINE 5 39B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.885924999999998 20 5.174494999999998 30 0.0 11 3.885924999999998 21 4.971473999999998 31 0.0 0 LINE 5 2A5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.869697 20 4.971473999999998 30 0.0 11 3.869697 21 5.174494999999998 31 0.0 0 LINE 5 350 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.054705999999998 30 0.0 11 3.521799999999998 21 5.054705999999998 31 0.0 0 LINE 5 3A2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.054705999999998 30 0.0 11 3.541391999999998 21 4.971473999999998 31 0.0 0 LINE 5 3A3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.521799999999998 20 5.054705999999998 30 0.0 11 3.521799999999998 21 4.909673999999998 31 0.0 0 LINE 5 2A8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.521799999999998 20 5.133570999999998 30 0.0 11 3.521799999999998 21 5.107412999999998 31 0.0 0 LINE 5 29F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.44413 30 0.0 11 3.541391999999998 21 5.340262999999998 31 0.0 0 LINE 5 3A6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.273177999999998 30 0.0 11 3.541391999999998 21 5.107412999999998 31 0.0 0 LINE 5 3A7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.404884999999998 20 5.273177999999998 30 0.0 11 3.404884999999998 21 5.155383 31 0.0 0 LINE 5 287 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.404884999999998 20 5.44413 30 0.0 11 3.404884999999998 21 5.340262999999998 31 0.0 0 LINE 5 2EC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.552807 20 5.340262999999998 30 0.0 11 2.699643999999998 21 5.340262999999998 31 0.0 0 LINE 5 3A9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.404884999999998 20 5.340262999999998 30 0.0 11 3.541391999999998 21 5.340262999999998 31 0.0 0 LINE 5 2ED 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.541391999999998 20 5.273177999999998 30 0.0 11 3.404884999999998 21 5.273177999999998 31 0.0 0 LINE 5 3AA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.699643999999998 20 5.273177999999998 30 0.0 11 2.552807 21 5.273177999999998 31 0.0 0 LWPOLYLINE 5 3AB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.478844999999998 20 6.114967 10 3.809408 20 6.114967 0 LWPOLYLINE 5 3AC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.264524 20 6.114967 10 3.449501 20 6.114967 0 LWPOLYLINE 5 335 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.809408 20 5.841483 10 3.478844999999998 20 5.841483 0 LWPOLYLINE 5 3AF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.449501 20 5.841483 10 3.264524 20 5.841483 0 LINE 5 2E3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.478844999999998 20 6.114967 30 0.0 11 3.478844999999998 21 6.002978999999998 31 0.0 0 LINE 5 3B0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.478844999999998 20 5.939549999999998 30 0.0 11 3.478844999999998 21 5.841483 31 0.0 0 LINE 5 2E4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.114967 30 0.0 11 3.449501 21 6.002978999999998 31 0.0 0 LINE 5 3AE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 5.939549999999998 30 0.0 11 3.449501 21 5.841483 31 0.0 0 LINE 5 3B2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.002978999999998 30 0.0 11 3.478844999999998 21 6.002978999999998 31 0.0 0 LINE 5 3B3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.478844999999998 20 5.939549999999998 30 0.0 11 3.449501 21 5.939549999999998 31 0.0 0 LINE 5 34C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.264524 20 6.114967 30 0.0 11 3.264524 21 6.002978999999998 31 0.0 0 LINE 5 3B4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.264524 20 5.939549999999998 30 0.0 11 3.264524 21 5.841483 31 0.0 0 LINE 5 3B1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.264524 20 5.939549999999998 30 0.0 11 3.242329 21 5.939549999999998 31 0.0 0 LINE 5 3B7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.242329 20 6.002978999999998 30 0.0 11 3.264524 21 6.002978999999998 31 0.0 0 LINE 5 3B8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.499698999999998 30 0.0 11 3.449501 21 6.645997999999998 31 0.0 0 LINE 5 3BA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.716422 30 0.0 11 3.449501 21 6.865889999999998 31 0.0 0 LINE 5 3B9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.478844999999998 20 6.499698999999998 30 0.0 11 3.478844999999998 21 6.645997999999998 31 0.0 0 LINE 5 3BB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.478844999999998 20 6.716422 30 0.0 11 3.478844999999998 21 6.865889999999998 31 0.0 0 LINE 5 3BD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.716422 30 0.0 11 3.478844999999998 21 6.716422 31 0.0 0 LINE 5 3BC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.449501 20 6.645997999999998 30 0.0 11 3.478844999999998 21 6.645997999999998 31 0.0 0 LWPOLYLINE 5 394 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.985652999999998 20 6.499698999999998 10 3.478844999999998 20 6.499698999999998 0 LWPOLYLINE 5 3C1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.478844999999998 20 6.865889999999998 10 4.610913 20 6.865889999999998 0 LWPOLYLINE 5 3C2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 6 70 0 43 0.0 10 3.024554 20 6.899961 10 2.809111999999998 20 6.899961 10 2.809111999999998 20 7.169407999999998 10 3.306194999999998 20 7.169407999999998 10 3.306194999999998 20 6.899961 10 3.090943 20 6.899961 0 LWPOLYLINE 5 3C3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.090943 20 6.865889999999998 10 3.449501 20 6.865889999999998 0 LINE 5 2AC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 6.899961 30 0.0 11 3.024554 21 6.865889999999998 31 0.0 0 LINE 5 2AE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.090943 20 6.899961 30 0.0 11 3.090943 21 6.865889999999998 31 0.0 0 LWPOLYLINE 5 3C0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.449501 20 6.499698999999998 10 3.090943 20 6.499698999999998 0 LINE 5 3C9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 6.499698999999998 30 0.0 11 3.024554 21 6.465205999999998 31 0.0 0 LINE 5 3CA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.090943 20 6.499698999999998 30 0.0 11 3.090943 21 6.465205999999998 31 0.0 0 LWPOLYLINE 5 3C7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.090943 20 6.465205999999998 10 3.242329 20 6.465205999999998 0 LWPOLYLINE 5 3CD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.242329 20 6.465205999999998 10 3.242329 20 6.409078 0 LINE 5 300 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.434088999999998 20 6.336554 30 0.0 11 3.242329 21 6.336554 31 0.0 0 LINE 5 3CF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.303547 20 6.409078 30 0.0 11 3.303547 21 6.465205999999998 31 0.0 0 LINE 5 301 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.242329 20 6.409078 30 0.0 11 3.303547 21 6.409078 31 0.0 0 LINE 5 3CC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.303547 20 6.465205999999998 30 0.0 11 3.434088999999998 21 6.465205999999998 31 0.0 0 LWPOLYLINE 5 3C6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 3.024554 20 6.499698999999998 10 2.67147 20 6.499698999999998 10 2.67147 20 6.645997999999998 0 LWPOLYLINE 5 3D1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.67147 20 6.716422 10 2.67147 20 6.865889999999998 10 3.024554 20 6.865889999999998 0 LINE 5 2B0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.432172 20 6.645997999999998 30 0.0 11 1.506941 21 6.645997999999998 31 0.0 0 LINE 5 3D4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.642733 20 6.645997999999998 30 0.0 11 2.67147 21 6.645997999999998 31 0.0 0 LINE 5 3D5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.642733 20 6.716422 30 0.0 11 2.67147 21 6.716422 31 0.0 0 LWPOLYLINE 5 3D6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.859698999999998 20 6.438087 10 2.859698999999998 20 6.465205999999998 10 3.024554 20 6.465205999999998 0 LINE 5 2FE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.737864 20 6.332927999999999 30 0.0 11 2.859698999999998 21 6.332927999999999 31 0.0 0 LINE 5 2FB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.636331 20 6.438087 30 0.0 11 2.859698999999998 21 6.438087 31 0.0 0 LINE 5 2F7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.737864 20 6.332927999999999 30 0.0 11 2.737864 21 6.147992999999998 31 0.0 0 LWPOLYLINE 5 3D9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.859698999999998 20 6.308450999999998 10 2.859698999999998 20 6.332927999999999 0 LINE 5 2E6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.242329 20 6.308450999999998 30 0.0 11 3.090943 21 6.308450999999998 31 0.0 0 LINE 5 3DA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 6.308450999999998 30 0.0 11 2.859698999999998 21 6.308450999999998 31 0.0 0 LINE 5 2E5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.859698999999998 20 6.283068 30 0.0 11 3.024554 21 6.283068 31 0.0 0 LINE 5 3DB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.090943 20 6.283068 30 0.0 11 3.242329 21 6.283068 31 0.0 0 LINE 5 3C8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 6.308450999999998 30 0.0 11 3.024554 21 6.283068 31 0.0 0 LINE 5 3CB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.090943 20 6.308450999999998 30 0.0 11 3.090943 21 6.283068 31 0.0 0 LINE 5 3E3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.631797999999998 20 5.939549999999998 30 0.0 11 2.631797999999998 21 5.841483 31 0.0 0 LINE 5 2E7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.631797999999998 20 6.114967 30 0.0 11 2.631797999999998 21 6.002978999999998 31 0.0 0 LINE 5 3E8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.313600999999998 20 6.147992999999998 30 0.0 11 2.737864 21 6.147992999999998 31 0.0 0 LINE 5 3E9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.237594 20 6.114967 30 0.0 11 2.237594 21 6.002978999999998 31 0.0 0 LINE 5 3EC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.237594 20 5.939549999999998 30 0.0 11 2.237594 21 5.841483 31 0.0 0 LINE 5 3EF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.210849 20 6.002978999999998 30 0.0 11 2.237594 21 6.002978999999998 31 0.0 0 LINE 5 3F1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.237594 20 5.939549999999998 30 0.0 11 2.210849 21 5.939549999999998 31 0.0 0 LINE 5 3EE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.631797999999998 20 6.002978999999998 30 0.0 11 2.859698999999998 21 6.002978999999998 31 0.0 0 LWPOLYLINE 5 3EA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.237594 20 6.114967 10 2.631797999999998 20 6.114967 0 LWPOLYLINE 5 3F3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.859698999999998 20 6.002978999999998 10 2.859698999999998 20 6.283068 0 LINE 5 3F6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.720638999999998 20 5.939549999999998 30 0.0 11 2.631797999999998 21 5.939549999999998 31 0.0 0 LINE 5 3B6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.859698999999998 20 5.939549999999998 30 0.0 11 2.789536999999998 21 5.939549999999998 31 0.0 0 LINE 5 3F8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.807481 30 0.0 11 2.789536999999998 21 5.939549999999998 31 0.0 0 LINE 5 2E9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.720638999999998 20 5.939549999999998 30 0.0 11 2.720638999999998 21 5.807481 31 0.0 0 LWPOLYLINE 5 3F7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.789536999999998 20 5.807481 10 2.829689 20 5.807481 10 2.829689 20 5.472367 10 2.789536999999998 20 5.472367 0 LWPOLYLINE 5 3FC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.720638999999998 20 5.472367 10 2.367031 20 5.472367 10 2.367031 20 5.807481 10 2.720638999999998 20 5.807481 0 LWPOLYLINE 5 3CE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.242329 20 6.336554 10 3.242329 20 6.308450999999998 0 LWPOLYLINE 5 3FE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.242329 20 6.283068 10 3.242329 20 6.002978999999998 0 LINE 5 401 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.925183 20 6.027503 30 0.0 11 2.012647 21 6.114967 31 0.0 0 LINE 5 402 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.152429999999998 20 5.841483 30 0.0 11 2.210849 21 5.899901999999999 31 0.0 0 LINE 5 403 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.925183 20 5.918417999999999 30 0.0 11 2.002116999999999 21 5.841483 31 0.0 0 LINE 5 404 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.131067999999999 20 6.114967 30 0.0 11 2.210849 21 6.035187 31 0.0 0 LINE 5 407 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.165754999999998 20 6.719113 30 0.0 11 1.165754999999998 21 6.630874999999998 31 0.0 0 LWPOLYLINE 5 411 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.868974 20 6.761185 10 1.922299 20 6.761185 0 LWPOLYLINE 5 415 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.922299 20 6.597127 10 1.868974 20 6.597127 0 LINE 5 416 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.83398 20 6.841110999999998 30 0.0 11 1.868974 21 6.761185 31 0.0 0 LINE 5 417 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.868974 20 6.761185 30 0.0 11 1.922299 21 6.761185 31 0.0 0 LINE 5 418 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.922299 20 6.761185 30 0.0 11 1.957292999999999 21 6.841110999999998 31 0.0 0 LINE 5 419 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.957292999999999 20 6.521406999999999 30 0.0 11 1.922299 21 6.597127 31 0.0 0 LINE 5 41A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.868974 20 6.597127 30 0.0 11 1.83398 21 6.521406999999999 31 0.0 0 LWPOLYLINE 5 41B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.235615999999998 20 6.761185 10 2.28894 20 6.761185 0 LWPOLYLINE 5 41C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.28894 20 6.597127 10 2.235615999999998 20 6.597127 0 LINE 5 41D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.200620999999999 20 6.841110999999998 30 0.0 11 2.235615999999998 21 6.761185 31 0.0 0 LINE 5 41E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.235615999999998 20 6.761185 30 0.0 11 2.28894 21 6.761185 31 0.0 0 LINE 5 41F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.28894 20 6.761185 30 0.0 11 2.323934999999999 21 6.841110999999998 31 0.0 0 LINE 5 420 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.323934999999999 20 6.521406999999999 30 0.0 11 2.28894 21 6.597127 31 0.0 0 LINE 5 421 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.235615999999998 20 6.597127 30 0.0 11 2.200620999999999 21 6.521406999999999 31 0.0 0 LINE 5 426 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.546932999999999 20 6.761185 30 0.0 11 1.581927 21 6.841110999999998 31 0.0 0 LINE 5 427 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.581927 20 6.521406999999999 30 0.0 11 1.546932999999999 21 6.597127 31 0.0 0 LINE 5 42B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.569261999999999 20 6.841110999999998 30 0.0 11 2.604256 21 6.761185 31 0.0 0 LINE 5 42F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.604256 20 6.597127 30 0.0 11 2.569261999999999 21 6.521406999999999 31 0.0 0 LWPOLYLINE 5 431 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.604256 20 6.761185 10 2.642733 20 6.761185 10 2.642733 20 6.716422 0 LWPOLYLINE 5 3D3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.642733 20 6.645997999999998 10 2.642733 20 6.597127 10 2.604256 20 6.597127 0 LWPOLYLINE 5 412 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.83398 20 6.521406999999999 10 1.581927 20 6.521406999999999 0 LWPOLYLINE 5 433 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.581927 20 6.841110999999998 10 1.83398 20 6.841110999999998 0 LWPOLYLINE 5 434 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.050577999999998 20 6.521406999999999 10 1.957292999999999 20 6.521406999999999 0 LWPOLYLINE 5 438 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.323934999999999 20 6.841110999999998 10 2.569261999999999 20 6.841110999999998 0 LWPOLYLINE 5 430 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.569261999999999 20 6.521406999999999 10 2.323934999999999 20 6.521406999999999 0 LWPOLYLINE 5 439 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.200620999999999 20 6.521406999999999 10 2.108791999999998 20 6.521406999999999 0 LINE 5 2D5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.356290999999999 20 6.002978999999998 30 0.0 11 1.470920999999998 21 6.002978999999998 31 0.0 0 LINE 5 43C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.905634999999999 20 6.002978999999998 30 0.0 11 1.925183 21 6.002978999999998 31 0.0 0 LINE 5 3F0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.925183 20 5.939549999999998 30 0.0 11 1.905634999999999 21 5.939549999999998 31 0.0 0 LINE 5 43D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.470920999999998 20 5.939549999999998 30 0.0 11 1.356290999999999 21 5.939549999999998 31 0.0 0 LINE 5 406 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.905634999999999 20 6.114967 30 0.0 11 1.905634999999999 21 6.002978999999998 31 0.0 0 LINE 5 43E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.905634999999999 20 5.939549999999998 30 0.0 11 1.905634999999999 21 5.841483 31 0.0 0 LINE 5 2F6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.925183 20 6.147992999999998 30 0.0 11 2.050577999999998 21 6.147992999999998 31 0.0 0 LINE 5 440 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 6.147992999999998 30 0.0 11 2.210849 21 6.147992999999998 31 0.0 0 LWPOLYLINE 5 441 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.925183 20 6.147992999999998 10 1.925183 20 6.485793 10 2.050577999999998 20 6.485793 0 LWPOLYLINE 5 3EB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.210849 20 5.939549999999998 10 2.210849 20 5.899901999999999 0 LWPOLYLINE 5 435 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.108791999999998 20 6.485793 10 2.210849 20 6.485793 10 2.210849 20 6.147992999999998 0 LWPOLYLINE 5 444 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.210849 20 6.035187 10 2.210849 20 6.002978999999998 0 LWPOLYLINE 5 445 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.108791999999998 20 6.114967 10 2.131067999999999 20 6.114967 0 LWPOLYLINE 5 43B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.470920999999998 20 6.002978999999998 10 1.470920999999998 20 6.114967 10 1.905634999999999 20 6.114967 0 LWPOLYLINE 5 446 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.012647 20 6.114967 10 2.050577999999998 20 6.114967 0 LWPOLYLINE 5 447 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.905634999999999 20 5.841483 10 1.470920999999998 20 5.841483 10 1.470920999999998 20 5.939549999999998 0 LWPOLYLINE 5 448 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.050577999999998 20 5.841483 10 2.002116999999999 20 5.841483 0 LWPOLYLINE 5 3F4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.631797999999998 20 5.841483 10 2.237594 20 5.841483 0 LWPOLYLINE 5 449 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.152429999999998 20 5.841483 10 2.108791999999998 20 5.841483 0 LWPOLYLINE 5 442 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.925183 20 5.918417999999999 10 1.925183 20 5.939549999999998 0 LWPOLYLINE 5 44A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.925183 20 6.002978999999998 10 1.925183 20 6.027503 0 LINE 5 2F4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.210849 20 5.807481 30 0.0 11 2.108791999999998 21 5.807481 31 0.0 0 LINE 5 44B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 5.807481 30 0.0 11 1.925183 21 5.807481 31 0.0 0 LINE 5 436 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 6.147992999999998 30 0.0 11 2.050577999999998 21 6.114967 31 0.0 0 LINE 5 437 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 6.147992999999998 30 0.0 11 2.108791999999998 21 6.114967 31 0.0 0 LINE 5 44C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 5.841483 30 0.0 11 2.050577999999998 21 5.807481 31 0.0 0 LINE 5 44E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 5.472367 30 0.0 11 2.050577999999998 21 5.456914 31 0.0 0 LINE 5 44D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 5.841483 30 0.0 11 2.108791999999998 21 5.807481 31 0.0 0 LINE 5 44F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 5.472367 30 0.0 11 2.108791999999998 21 5.456914 31 0.0 0 LWPOLYLINE 5 43A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.356290999999999 20 5.939549999999998 10 1.356290999999999 20 5.524291 10 1.214617 20 5.524291 0 LINE 5 253 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.453427 20 5.496596 30 0.0 11 1.214617 21 5.496596 31 0.0 0 LINE 5 451 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.146230999999998 20 5.496596 30 0.0 11 0.8973459999999999 21 5.496596 31 0.0 0 LINE 5 30D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.214617 20 5.496596 30 0.0 11 1.214617 21 5.524291 31 0.0 0 LINE 5 452 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.214617 20 6.41633 30 0.0 11 1.214617 21 6.560417 31 0.0 0 LINE 5 30C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.146230999999998 20 6.529222999999999 30 0.0 11 1.146230999999998 21 6.41633 31 0.0 0 LINE 5 453 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.146230999999998 20 5.524291 30 0.0 11 1.146230999999998 21 5.496596 31 0.0 0 LINE 5 454 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 5.472367 30 0.0 11 1.925183 21 5.472367 31 0.0 0 LWPOLYLINE 5 276 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.947722 20 5.235732999999998 10 1.947722 20 5.456914 10 2.050577999999998 20 5.456914 0 LWPOLYLINE 5 443 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.210849 20 5.807481 10 2.210849 20 5.472367 0 LWPOLYLINE 5 458 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.210849 20 5.456914 10 2.210849 20 5.235732999999998 0 LWPOLYLINE 5 457 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.210849 20 5.456914 10 2.108791999999998 20 5.456914 0 LINE 5 2F5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.210849 20 5.472367 30 0.0 11 2.108791999999998 21 5.472367 31 0.0 0 LWPOLYLINE 5 456 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.925183 20 5.472367 10 1.925183 20 5.807481 0 LINE 5 2B2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.6511700000000002 20 7.52656 30 0.0 11 0.6511700000000002 21 7.303872 31 0.0 0 LINE 5 45F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.6511700000000002 20 7.259110999999998 30 0.0 11 0.6511700000000002 21 7.035305999999998 31 0.0 0 LINE 5 460 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.572438 30 0.0 11 1.934619999999999 21 7.781322 31 0.0 0 LWPOLYLINE 5 45E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 0.6511700000000002 20 7.572438 10 0.6511700000000002 20 7.781322 10 1.139782999999998 20 7.781322 0 LWPOLYLINE 5 461 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.175679 20 7.781322 10 1.415836999999999 20 7.781322 0 LWPOLYLINE 5 462 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.450026 20 7.781322 10 1.934619999999999 20 7.781322 0 LINE 5 2CC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.781322 30 0.0 11 1.139782999999998 21 7.705807 31 0.0 0 LINE 5 465 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.705807 30 0.0 11 1.175679 21 7.781322 31 0.0 0 LINE 5 466 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.415836999999999 20 7.705807 30 0.0 11 1.415836999999999 21 7.781322 31 0.0 0 LINE 5 467 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.705807 30 0.0 11 1.450026 21 7.781322 31 0.0 0 LINE 5 2CB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.641708 30 0.0 11 1.175679 21 7.641708 31 0.0 0 LINE 5 468 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.415836999999999 20 7.641708 30 0.0 11 1.450026 21 7.641708 31 0.0 0 LINE 5 2CA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.705807 30 0.0 11 1.415836999999999 21 7.705807 31 0.0 0 LINE 5 469 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.705807 30 0.0 11 1.139782999999998 21 7.705807 31 0.0 0 LINE 5 464 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.641708 30 0.0 11 1.139782999999998 21 7.572438 31 0.0 0 LINE 5 470 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.572438 30 0.0 11 1.450026 21 7.641708 31 0.0 0 LWPOLYLINE 5 45D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.934619999999999 20 7.572438 10 1.852572 20 7.572438 0 LWPOLYLINE 5 472 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.798727999999999 20 7.572438 10 1.450026 20 7.572438 0 LINE 5 471 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.52656 30 0.0 11 1.798727999999999 21 7.52656 31 0.0 0 LINE 5 473 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.852572 20 7.52656 30 0.0 11 1.934619999999999 21 7.52656 31 0.0 0 LINE 5 2CF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.798727999999999 20 7.572438 30 0.0 11 1.798727999999999 21 7.52656 31 0.0 0 LINE 5 474 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.798727999999999 20 7.303872 30 0.0 11 1.798727999999999 21 7.259110999999998 31 0.0 0 LINE 5 2D0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.852572 20 7.259110999999998 30 0.0 11 1.852572 21 7.303872 31 0.0 0 LINE 5 475 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.852572 20 7.52656 30 0.0 11 1.852572 21 7.572438 31 0.0 0 LINE 5 476 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.303872 30 0.0 11 1.450026 21 7.52656 31 0.0 0 LINE 5 2C6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.415836999999999 20 7.035305999999998 30 0.0 11 1.415836999999999 21 7.118653999999998 31 0.0 0 LINE 5 477 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.415836999999999 20 7.169933 30 0.0 11 1.415836999999999 21 7.641708 31 0.0 0 LINE 5 2C4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.035305999999998 30 0.0 11 1.175679 21 7.118653999999998 31 0.0 0 LINE 5 47C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.169933 30 0.0 11 1.175679 21 7.641708 31 0.0 0 LINE 5 46C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.52656 30 0.0 11 1.139782999999998 21 7.303872 31 0.0 0 LINE 5 2B3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.6511700000000002 20 7.035305999999998 30 0.0 11 1.139782999999998 21 7.035305999999998 31 0.0 0 LWPOLYLINE 5 46A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.139782999999998 20 7.572438 10 0.788516 20 7.572438 0 LWPOLYLINE 5 47F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 0.729544 20 7.572438 10 0.6511700000000002 20 7.572438 0 LINE 5 459 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.6511700000000002 20 7.52656 30 0.0 11 0.729544 21 7.52656 31 0.0 0 LINE 5 480 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.788516 20 7.52656 30 0.0 11 1.139782999999998 21 7.52656 31 0.0 0 LINE 5 2B6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.6511700000000002 20 7.303872 30 0.0 11 0.729544 21 7.303872 31 0.0 0 LINE 5 481 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.788516 20 7.303872 30 0.0 11 1.139782999999998 21 7.303872 31 0.0 0 LINE 5 47B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.259110999999998 30 0.0 11 0.788516 21 7.259110999999998 31 0.0 0 LINE 5 482 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.729544 20 7.259110999999998 30 0.0 11 0.6511700000000002 21 7.259110999999998 31 0.0 0 LINE 5 2C8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.729544 20 7.572438 30 0.0 11 0.729544 21 7.52656 31 0.0 0 LINE 5 483 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.729544 20 7.303872 30 0.0 11 0.729544 21 7.259110999999998 31 0.0 0 LINE 5 2C9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.788516 20 7.259110999999998 30 0.0 11 0.788516 21 7.303872 31 0.0 0 LINE 5 484 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.788516 20 7.52656 30 0.0 11 0.788516 21 7.572438 31 0.0 0 LINE 5 2CD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.169933 30 0.0 11 1.175679 21 7.169933 31 0.0 0 LINE 5 486 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.118653999999998 30 0.0 11 1.139782999999998 21 7.118653999999998 31 0.0 0 LINE 5 47D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.259110999999998 30 0.0 11 1.139782999999998 21 7.169933 31 0.0 0 LINE 5 487 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.139782999999998 20 7.118653999999998 30 0.0 11 1.139782999999998 21 7.035305999999998 31 0.0 0 LINE 5 479 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.303872 30 0.0 11 1.798727999999999 21 7.303872 31 0.0 0 LINE 5 488 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.852572 20 7.303872 30 0.0 11 1.934619999999999 21 7.303872 31 0.0 0 LINE 5 489 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.798727999999999 20 7.259110999999998 30 0.0 11 1.450026 21 7.259110999999998 31 0.0 0 LINE 5 2B5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.180502999999998 20 7.259110999999998 30 0.0 11 1.978208 21 7.259110999999998 31 0.0 0 LINE 5 48A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.259110999999998 30 0.0 11 1.852572 21 7.259110999999998 31 0.0 0 LINE 5 2B8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 7.259110999999998 30 0.0 11 1.978208 21 7.169933 31 0.0 0 LINE 5 48B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 7.118653999999998 30 0.0 11 1.978208 21 7.035305999999998 31 0.0 0 LINE 5 2B7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.035305999999998 30 0.0 11 1.934619999999999 21 7.118653999999998 31 0.0 0 LINE 5 485 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.415836999999999 20 7.169933 30 0.0 11 1.450026 21 7.169933 31 0.0 0 LINE 5 48D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.169933 30 0.0 11 1.978208 21 7.169933 31 0.0 0 LINE 5 2CE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 7.118653999999998 30 0.0 11 1.934619999999999 21 7.118653999999998 31 0.0 0 LINE 5 48E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.118653999999998 30 0.0 11 1.415836999999999 21 7.118653999999998 31 0.0 0 LINE 5 2C7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.035305999999998 30 0.0 11 1.450026 21 7.118653999999998 31 0.0 0 LINE 5 48F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.169933 30 0.0 11 1.450026 21 7.259110999999998 31 0.0 0 LINE 5 48C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.169933 30 0.0 11 1.934619999999999 21 7.259110999999998 31 0.0 0 LINE 5 490 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.934619999999999 20 7.303872 30 0.0 11 1.934619999999999 21 7.52656 31 0.0 0 LINE 5 491 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.450026 20 7.035305999999998 30 0.0 11 1.934619999999999 21 7.035305999999998 31 0.0 0 LINE 5 2B9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.447461999999999 20 7.01353 30 0.0 11 1.685913 21 7.01353 31 0.0 0 LINE 5 494 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.708988999999999 20 7.01353 30 0.0 11 1.950004 21 7.01353 31 0.0 0 LINE 5 2C0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.685913 20 6.869946 30 0.0 11 1.685913 21 6.921225999999998 31 0.0 0 LINE 5 496 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.685913 20 6.967378 30 0.0 11 1.685913 21 7.01353 31 0.0 0 LINE 5 2C1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.708988999999999 20 6.869946 30 0.0 11 1.708988999999999 21 6.921225999999998 31 0.0 0 LINE 5 497 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.708988999999999 20 6.967378 30 0.0 11 1.708988999999999 21 7.01353 31 0.0 0 LINE 5 2C2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.950004 20 6.869946 30 0.0 11 1.950004 21 6.921225999999998 31 0.0 0 LINE 5 498 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.950004 20 6.967378 30 0.0 11 1.950004 21 7.01353 31 0.0 0 LINE 5 2C3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 6.869946 30 0.0 11 1.978208 21 6.921225999999998 31 0.0 0 LINE 5 499 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 6.967378 30 0.0 11 1.978208 21 7.01353 31 0.0 0 LINE 5 49A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.950004 20 6.869946 30 0.0 11 1.708988999999999 21 6.869946 31 0.0 0 LINE 5 49B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.685913 20 6.869946 30 0.0 11 1.447461999999999 21 6.869946 31 0.0 0 LINE 5 2BF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 6.921225999999998 30 0.0 11 1.950004 21 6.921225999999998 31 0.0 0 LINE 5 2BE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 6.967378 30 0.0 11 1.950004 21 6.967378 31 0.0 0 LINE 5 49D 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.708988999999999 20 6.967378 30 0.0 11 1.685913 21 6.967378 31 0.0 0 LINE 5 49E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.447461999999999 20 6.967378 30 0.0 11 1.359099999999999 21 6.967378 31 0.0 0 LINE 5 49C 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.708988999999999 20 6.921225999999998 30 0.0 11 1.685913 21 6.921225999999998 31 0.0 0 LINE 5 49F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.447461999999999 20 6.921225999999998 30 0.0 11 1.359099999999999 21 6.921225999999998 31 0.0 0 LINE 5 492 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 7.035305999999998 30 0.0 11 2.050577999999998 21 7.035305999999998 31 0.0 0 LINE 5 4A0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 7.035305999999998 30 0.0 11 2.180502999999998 21 7.035305999999998 31 0.0 0 LINE 5 493 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.978208 20 7.01353 30 0.0 11 2.050577999999998 21 7.01353 31 0.0 0 LINE 5 4A1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 7.01353 30 0.0 11 2.178199 21 7.01353 31 0.0 0 LINE 5 3FF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 7.035305999999998 30 0.0 11 2.050577999999998 21 7.01353 31 0.0 0 LINE 5 400 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 7.035305999999998 30 0.0 11 2.108791999999998 21 7.01353 31 0.0 0 LINE 5 2BB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.178199 20 6.869946 30 0.0 11 2.108791999999998 21 6.869946 31 0.0 0 LINE 5 4A4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 6.869946 30 0.0 11 1.978208 21 6.869946 31 0.0 0 LWPOLYLINE 5 410 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.957292999999999 20 6.841110999999998 10 2.050577999999998 20 6.841110999999998 0 LWPOLYLINE 5 4A5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.108791999999998 20 6.841110999999998 10 2.200620999999999 20 6.841110999999998 0 LINE 5 2AF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.42334 20 6.716422 30 0.0 11 1.506941 21 6.716422 31 0.0 0 LINE 5 4A2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 6.869946 30 0.0 11 2.050577999999998 21 6.841110999999998 31 0.0 0 LINE 5 4A7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.050577999999998 20 6.521406999999999 30 0.0 11 2.050577999999998 21 6.485793 31 0.0 0 LINE 5 4A3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 6.869946 30 0.0 11 2.108791999999998 21 6.841110999999998 31 0.0 0 LINE 5 4A8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.108791999999998 20 6.521406999999999 30 0.0 11 2.108791999999998 21 6.485793 31 0.0 0 LINE 5 2BD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.447461999999999 20 6.869946 30 0.0 11 1.447461999999999 21 6.921225999999998 31 0.0 0 LINE 5 4B1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.447461999999999 20 6.967378 30 0.0 11 1.447461999999999 21 7.01353 31 0.0 0 LWPOLYLINE 5 4B2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.335906999999999 20 7.00008 10 1.359099999999999 20 7.00008 10 1.359099999999999 20 6.967378 0 LINE 5 47E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.175679 20 7.035305999999998 30 0.0 11 1.266328 21 7.035305999999998 31 0.0 0 LINE 5 4B3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.335906999999999 20 7.035305999999998 30 0.0 11 1.415836999999999 21 7.035305999999998 31 0.0 0 LWPOLYLINE 5 4B0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.359099999999999 20 6.921225999999998 10 1.359099999999999 20 6.884114999999998 10 1.335906999999999 20 6.884114999999998 0 LWPOLYLINE 5 4B4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 1.266328 20 6.884114999999998 10 1.229219 20 6.884114999999998 10 1.229219 20 7.00008 10 1.266328 20 7.00008 0 LINE 5 45A 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.266328 20 7.035305999999998 30 0.0 11 1.266328 21 7.00008 31 0.0 0 LINE 5 4B5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.266328 20 6.884114999999998 30 0.0 11 1.266328 21 6.819685999999999 31 0.0 0 LINE 5 45B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.335906999999999 20 7.035305999999998 30 0.0 11 1.335906999999999 21 7.00008 31 0.0 0 LINE 5 4B6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.335906999999999 20 6.884114999999998 30 0.0 11 1.335906999999999 21 6.803855 31 0.0 0 LINE 5 4B7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.212377 20 6.786131 30 0.0 11 1.222574999999998 21 6.775933 31 0.0 0 LINE 5 4B8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.176703 20 6.750457 30 0.0 11 1.186900999999998 21 6.740259 31 0.0 0 LINE 5 4B9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.211170999999998 20 6.563863999999998 30 0.0 11 1.221967999999999 21 6.574660999999998 31 0.0 0 LINE 5 4BA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.176217 20 6.598816999999998 30 0.0 11 1.187014999999999 21 6.609614999999998 31 0.0 0 LWPOLYLINE 5 413 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.546932999999999 20 6.597127 10 1.506941 20 6.597127 10 1.506941 20 6.645997999999998 0 LWPOLYLINE 5 4BB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.506941 20 6.716422 10 1.506941 20 6.761185 10 1.546932999999999 20 6.761185 0 LINE 5 312 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.159428 20 6.615605999999998 30 0.0 11 1.176217 21 6.598816999999998 31 0.0 0 LINE 5 4BC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.211170999999998 20 6.563863999999998 30 0.0 11 1.214617 21 6.560417 31 0.0 0 LINE 5 311 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.165754999999998 20 6.630874999999998 30 0.0 11 1.187014999999999 21 6.609614999999998 31 0.0 0 LINE 5 4BD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.221967999999999 20 6.574660999999998 30 0.0 11 1.232613999999998 21 6.564016 31 0.0 0 LINE 5 30F 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.266328 20 6.819685999999999 30 0.0 11 1.222574999999998 21 6.775933 31 0.0 0 LINE 5 4BE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.186900999999998 20 6.740259 30 0.0 11 1.165754999999998 21 6.719113 31 0.0 0 LINE 5 310 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.229014999999998 20 6.802769 30 0.0 11 1.212377 21 6.786131 31 0.0 0 LINE 5 4BF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.176703 20 6.750457 30 0.0 11 1.159428 21 6.733183 31 0.0 0 LINE 5 314 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.106638999999999 20 6.821964999999998 30 0.0 11 1.106638999999999 21 6.807567999999997 31 0.0 0 LINE 5 4C0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.106638999999999 20 6.761977 30 0.0 11 1.106638999999999 21 6.733183 31 0.0 0 LINE 5 308 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.8774840000000001 20 6.683991999999999 30 0.0 11 0.954269 21 6.683991999999999 31 0.0 0 LINE 5 4C2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.003459 20 6.683991999999999 30 0.0 11 1.071845999999998 21 6.683991999999999 31 0.0 0 LINE 5 309 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.071845999999998 20 6.663596 30 0.0 11 1.003459 21 6.663596 31 0.0 0 LINE 5 4C3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 0.954269 20 6.663596 30 0.0 11 0.8774840000000001 21 6.663596 31 0.0 0 LWPOLYLINE 5 4C4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 0.8774840000000001 20 6.683991999999999 10 0.8774840000000001 20 6.831563 10 1.071845999999998 20 6.831563 10 1.071845999999998 20 6.807567999999997 0 LWPOLYLINE 5 4C1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.071845999999998 20 6.761977 10 1.071845999999998 20 6.683991999999999 0 LWPOLYLINE 5 4C5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 1.071845999999998 20 6.663596 10 1.071845999999998 20 6.579613 0 LWPOLYLINE 5 4C6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 1.071845999999998 20 6.529222999999999 10 1.071845999999998 20 6.432042 10 0.8774840000000001 20 6.432042 10 0.8774840000000001 20 6.663596 0 LINE 5 31B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.071845999999998 20 6.579613 30 0.0 11 1.113837 21 6.579613 31 0.0 0 LINE 5 31E 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 1.113837 20 6.615605999999998 30 0.0 11 1.113837 21 6.579613 31 0.0 0 LWPOLYLINE 5 450 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 1.146230999999998 20 5.524291 10 0.9827949999999999 20 5.524291 10 0.9827949999999999 20 6.41633 10 1.146230999999998 20 6.41633 0 LWPOLYLINE 5 4C9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 1.214617 20 6.41633 10 1.356290999999999 20 6.41633 10 1.356290999999999 20 6.002978999999998 0 LINE 5 4CA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.699643999999998 20 5.44413 30 0.0 11 2.720638999999998 21 5.44413 31 0.0 0 LWPOLYLINE 5 279 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.248133999999998 20 5.235732999999998 10 2.248133999999998 20 5.44413 10 2.552807 20 5.44413 10 2.552807 20 5.340262999999998 0 LWPOLYLINE 5 4CB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.552807 20 5.273177999999998 10 2.552807 20 4.973271999999998 10 2.248133999999998 20 4.973271999999998 10 2.248133999999998 20 5.177674999999998 0 LINE 5 286 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.699643999999998 20 5.155383 30 0.0 11 2.699643999999998 21 5.273177999999998 31 0.0 0 LINE 5 4CC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.699643999999998 20 5.340262999999998 30 0.0 11 2.699643999999998 21 5.44413 31 0.0 0 LINE 5 3FA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.720638999999998 20 5.472367 30 0.0 11 2.720638999999998 21 5.44413 31 0.0 0 LINE 5 4CD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.720638999999998 20 5.155383 30 0.0 11 2.720638999999998 21 5.133570999999998 31 0.0 0 LINE 5 2EA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.133570999999998 30 0.0 11 2.789536999999998 21 5.155383 31 0.0 0 LINE 5 4CE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.44413 30 0.0 11 2.789536999999998 21 5.472367 31 0.0 0 LINE 5 2EE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.581479 20 5.133570999999998 30 0.0 11 2.720638999999998 21 5.133570999999998 31 0.0 0 LINE 5 4CF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.699643999999998 20 5.155383 30 0.0 11 2.720638999999998 21 5.155383 31 0.0 0 LWPOLYLINE 5 4D2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 2.859698999999998 20 5.675683999999998 10 2.859698999999998 20 5.939549999999998 0 LWPOLYLINE 5 3B5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.242329 20 5.939549999999998 10 3.242329 20 5.675683999999998 0 LINE 5 4D4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.927222 20 5.654929 30 0.0 11 2.927222 21 5.675683999999998 31 0.0 0 LINE 5 4D5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 5.654929 30 0.0 11 3.177306999999998 21 5.675683999999998 31 0.0 0 LINE 5 4D6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 5.44413 30 0.0 11 3.177306999999998 21 5.472367 31 0.0 0 LINE 5 4D7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.927222 20 5.44413 30 0.0 11 2.927222 21 5.472367 31 0.0 0 LINE 5 2EB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.859698999999998 20 5.675683999999998 30 0.0 11 2.927222 21 5.675683999999998 31 0.0 0 LINE 5 28B 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.859698999999998 20 5.654929 30 0.0 11 2.927222 21 5.654929 31 0.0 0 LINE 5 4DC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 5.675683999999998 30 0.0 11 3.242329 21 5.675683999999998 31 0.0 0 LINE 5 4DD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 5.654929 30 0.0 11 3.242329 21 5.654929 31 0.0 0 LWPOLYLINE 5 4D3 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 3.242329 20 5.654929 10 3.242329 20 5.472367 10 3.177306999999998 20 5.472367 0 LINE 5 4DF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 5.44413 30 0.0 11 3.404884999999998 21 5.44413 31 0.0 0 LWPOLYLINE 5 4E0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 3 70 0 43 0.0 10 2.927222 20 5.472367 10 2.859698999999998 20 5.472367 10 2.859698999999998 20 5.654929 0 LINE 5 3FD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.44413 30 0.0 11 2.927222 21 5.44413 31 0.0 0 LINE 5 4E6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.938502 20 4.818522999999999 30 0.0 11 2.938502 21 4.789642999999998 31 0.0 0 LINE 5 4E7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.167405 20 4.818522999999999 30 0.0 11 3.167405 21 4.789642999999998 31 0.0 0 LINE 5 283 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.581479 20 4.909673999999998 30 0.0 11 2.907386999999998 21 4.909673999999998 31 0.0 0 LINE 5 4EB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.927222 20 4.909673999999998 30 0.0 11 2.977863999999998 21 4.909673999999998 31 0.0 0 LINE 5 4EC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.126770999999998 20 4.909673999999998 30 0.0 11 3.177306999999998 21 4.909673999999998 31 0.0 0 LINE 5 4ED 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.195667999999998 20 4.909673999999998 30 0.0 11 3.521799999999998 21 4.909673999999998 31 0.0 0 LINE 5 4EE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.195667999999998 20 5.133570999999998 30 0.0 11 3.521799999999998 21 5.133570999999998 31 0.0 0 LINE 5 4D0 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.133570999999998 30 0.0 11 2.907386999999998 21 5.133570999999998 31 0.0 0 LINE 5 289 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.177306999999998 20 4.909673999999998 30 0.0 11 3.177306999999998 21 5.133570999999998 31 0.0 0 LINE 5 288 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.927222 20 4.909673999999998 30 0.0 11 2.927222 21 5.133570999999998 31 0.0 0 LINE 5 4D1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.789536999999998 20 5.155383 30 0.0 11 2.977863999999998 21 5.155383 31 0.0 0 LINE 5 4F4 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.126770999999998 20 5.155383 30 0.0 11 3.404884999999998 21 5.155383 31 0.0 0 LINE 5 4EF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.927222 20 5.133570999999998 30 0.0 11 2.977863999999998 21 5.133570999999998 31 0.0 0 LINE 5 4F5 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.126770999999998 20 5.133570999999998 30 0.0 11 3.177306999999998 21 5.133570999999998 31 0.0 0 LINE 5 2F1 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.977863999999998 20 5.155383 30 0.0 11 2.977863999999998 21 5.133570999999998 31 0.0 0 LINE 5 4F6 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.977863999999998 20 4.909673999999998 30 0.0 11 2.977863999999998 21 4.883771 31 0.0 0 LINE 5 2F2 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.126770999999998 20 4.883771 30 0.0 11 3.126770999999998 21 4.909673999999998 31 0.0 0 LINE 5 4F7 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.126770999999998 20 5.133570999999998 30 0.0 11 3.126770999999998 21 5.155383 31 0.0 0 LWPOLYLINE 5 4F8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 3.126770999999998 20 4.883771 10 3.318223 20 4.883771 10 3.318223 20 4.818522999999999 10 3.167405 20 4.818522999999999 0 LWPOLYLINE 5 4F9 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.107829999999998 20 4.818522999999999 10 3.090943 20 4.818522999999999 0 LWPOLYLINE 5 4FA 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 2 70 0 43 0.0 10 3.024554 20 4.818522999999999 10 3.007271999999998 20 4.818522999999999 0 LWPOLYLINE 5 4FB 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbPolyline 90 4 70 0 43 0.0 10 2.938502 20 4.818522999999999 10 2.774847999999998 20 4.818522999999999 10 2.774847999999998 20 4.883771 10 2.977863999999998 20 4.883771 0 LINE 5 4E8 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 2.938502 20 4.789642999999998 30 0.0 11 3.007271999999998 21 4.789642999999998 31 0.0 0 LINE 5 4FC 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 4.789642999999998 30 0.0 11 3.090943 21 4.789642999999998 31 0.0 0 LINE 5 4FD 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.107829999999998 20 4.789642999999998 30 0.0 11 3.167405 21 4.789642999999998 31 0.0 0 LINE 5 4FE 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.007271999999998 20 4.818522999999999 30 0.0 11 3.007271999999998 21 4.789642999999998 31 0.0 0 LINE 5 4FF 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.024554 20 4.818522999999999 30 0.0 11 3.024554 21 4.789642999999998 31 0.0 0 LINE 5 500 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.090943 20 4.818522999999999 30 0.0 11 3.090943 21 4.789642999999998 31 0.0 0 LINE 5 501 330 518 100 AcDbEntity 8 0 6 Continuous 370 -3 100 AcDbLine 10 3.107829999999998 20 4.818522999999999 30 0.0 11 3.107829999999998 21 4.789642999999998 31 0.0 0 VIEWPORT 5 5CD 102 {ACAD_XDICTIONARY 360 5CE 102 } 330 5BC 100 AcDbEntity 67 1 8 0 62 7 370 -3 348 58B 100 AcDbViewport 10 5.680555208461489 20 3.965277934637595 30 0.0 40 12.37272182674859 41 8.867483582758532 68 1 69 1 12 5.680555208461489 22 3.965277934637595 13 0.0 23 0.0 14 10.0 24 10.0 15 10.0 25 10.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 42 50.0 43 0.0 44 0.0 45 8.867483582758532 50 0.0 51 0.0 72 100 90 819232 1 281 0 71 1 74 0 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 170 0 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 524 330 0 100 AcDbDictionary 281 1 3 ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 5BB 3 ACAD_COLOR 350 59E 3 ACAD_DETAILVIEWSTYLE 350 5B7 3 ACAD_GROUP 350 525 3 ACAD_LAYOUT 350 532 3 ACAD_MATERIAL 350 56C 3 ACAD_MLEADERSTYLE 350 5B3 3 ACAD_MLINESTYLE 350 52F 3 ACAD_PLOTSETTINGS 350 531 3 ACAD_PLOTSTYLENAME 350 526 3 ACAD_SCALELIST 350 5A1 3 ACAD_SECTIONVIEWSTYLE 350 5B5 3 ACAD_TABLESTYLE 350 59F 3 ACAD_VISUALSTYLE 350 585 3 ACDB_RECOMPOSE_DATA 350 608 3 AcDbVariableDictionary 350 5E0 3 AcDsDecomposeData 350 60E 0 DICTIONARY 5 5C3 330 51A 100 AcDbDictionary 280 1 281 1 3 ACAD_LAYERSTATES 360 5C4 0 DICTIONARY 5 5D5 330 6 100 AcDbDictionary 280 1 281 1 3 ADSK_XREC_LAYER_RECONCILED 360 5D6 0 DICTIONARY 5 5D7 330 293 100 AcDbDictionary 280 1 281 1 3 ADSK_XREC_LAYER_RECONCILED 360 5D8 0 DICTIONARY 5 5CE 330 5CD 100 AcDbDictionary 280 1 281 1 3 ASDK_XREC_ANNOTATION_SCALE_INFO 360 5CF 0 XRECORD 5 5BB 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbXrecord 280 1 300 ACDMAC 300 2018 300 ACDMAC_F_S 0 DICTIONARY 5 59E 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 0 DICTIONARY 5 5B7 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 Imperial24 350 5B8 0 DICTIONARY 5 525 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 0 DICTIONARY 5 532 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 350 569 3 Default 350 4A 3 Layout1 350 5BD 0 DICTIONARY 5 56C 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 ByBlock 350 575 3 ByLayer 350 56D 3 Global 350 57D 0 DICTIONARY 5 5B3 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 Standard 350 5B4 0 DICTIONARY 5 52F 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 STANDARD 350 530 0 DICTIONARY 5 531 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 0 ACDBDICTIONARYWDFLT 5 526 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 Normal 350 527 100 AcDbDictionaryWithDefault 340 527 0 DICTIONARY 5 5A1 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 A0 350 5A2 3 A1 350 5A3 3 A2 350 5A4 3 A3 350 5A5 3 A4 350 5A6 3 A5 350 5A7 3 A6 350 5A8 3 A7 350 5A9 3 A8 350 5AA 3 A9 350 5AB 3 B0 350 5AC 3 B1 350 5AD 3 B2 350 5AE 3 B3 350 5AF 3 B4 350 5B0 3 B5 350 5B1 3 B6 350 5B2 0 DICTIONARY 5 5B5 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 Imperial24 350 5B6 0 DICTIONARY 5 59F 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 Standard 350 5A0 0 DICTIONARY 5 585 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 2dWireframe 350 58B 3 Basic 350 58A 3 Brighten 350 591 3 ColorChange 350 595 3 Conceptual 350 58E 3 Dim 350 590 3 EdgeColorOff 350 59D 3 Facepattern 350 594 3 Flat 350 586 3 FlatWithEdges 350 587 3 Gouraud 350 588 3 GouraudWithEdges 350 589 3 Hidden 350 58D 3 JitterOff 350 59B 3 Linepattern 350 593 3 OverhangOff 350 59C 3 Realistic 350 58F 3 Shaded 350 59A 3 Shaded with edges 350 599 3 Shades of Gray 350 596 3 Sketchy 350 597 3 Thicken 350 592 3 Wireframe 350 58C 3 X-Ray 350 598 0 XRECORD 5 608 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbXrecord 280 1 90 1 330 5A0 0 DICTIONARY 5 5E0 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 CANNOSCALE 350 5E6 3 CMLEADERSTYLE 350 5E2 3 CTABLESTYLE 350 5E1 3 CVIEWDETAILSTYLE 350 5E3 3 CVIEWSECTIONSTYLE 350 5E4 3 LAYEREVAL 350 5E8 3 LAYERNOTIFY 350 5E9 3 LIGHTINGUNITS 350 5E7 3 MSLTSCALE 350 5E5 0 DICTIONARY 5 60E 102 {ACAD_REACTORS 330 524 102 } 330 524 100 AcDbDictionary 281 1 3 AcDsRecords 350 610 3 AcDsSchemas 350 60F 1001 ACAD 1070 2 0 DICTIONARY 5 5C4 102 {ACAD_REACTORS 330 5C3 102 } 330 5C3 100 AcDbDictionary 281 1 0 XRECORD 5 5D6 102 {ACAD_REACTORS 330 5D5 102 } 330 5D5 100 AcDbXrecord 280 1 290 1 0 XRECORD 5 5D8 102 {ACAD_REACTORS 330 5D7 102 } 330 5D7 100 AcDbXrecord 280 1 290 1 0 XRECORD 5 5CF 102 {ACAD_REACTORS 330 5CE 102 } 330 5CE 100 AcDbXrecord 280 1 90 1 340 5A2 0 ACDBDETAILVIEWSTYLE 5 5B8 102 {ACAD_XDICTIONARY 360 613 102 } 102 {ACAD_REACTORS 330 5B7 102 } 330 5B7 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 100 AcDbDetailViewStyle 70 0 71 0 90 3 71 1 340 529 62 256 40 0.24 340 0 62 256 40 0.24 300 40 0.36 280 3 71 2 340 52E 90 25 62 256 71 3 340 529 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewDetailId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 340 52E 90 25 62 256 340 52E 90 25 62 256 280 0 0 LAYOUT 5 569 330 532 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout 70 1 71 1 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 1.000000000000000E+20 24 1.000000000000000E+20 34 1.000000000000000E+20 15 -1.000000000000000E+20 25 -1.000000000000000E+20 35 -1.000000000000000E+20 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 568 0 LAYOUT 5 4A 330 532 100 AcDbPlotSettings 1 2 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 1712 72 0 73 0 74 0 7 75 0 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Default 70 1 71 0 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 518 331 4B 0 LAYOUT 5 5BD 102 {ACAD_REACTORS 330 532 102 } 330 532 100 AcDbPlotSettings 1 2 print-UCL 4 iso-a4 6 40 4.233333587646483 41 4.233306884765625 42 4.23333740234375 43 4.23333740234375 44 209.9027862548828 45 297.0388793945312 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 1 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout1 70 1 71 2 10 -0.1666668268639272 20 -0.1666666766789955 11 11.52777724378691 21 8.097222545954187 12 0.0 22 0.0 32 0.0 14 1.000000000000000E+20 24 1.000000000000000E+20 34 1.000000000000000E+20 15 -1.000000000000000E+20 25 -1.000000000000000E+20 35 -1.000000000000000E+20 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 5BC 331 5CD 1001 ACAD_PSEXT 1000 print-UCL 1000 Xerox WorkCentre 7655, 3.81.1 1000 localhost 1000 1070 0 0 MATERIAL 5 575 102 {ACAD_XDICTIONARY 360 576 102 } 102 {ACAD_REACTORS 330 56C 102 } 330 56C 100 AcDbMaterial 1 ByBlock 72 0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 56D 102 {ACAD_XDICTIONARY 360 56E 102 } 102 {ACAD_REACTORS 330 56C 102 } 330 56C 100 AcDbMaterial 1 ByLayer 72 0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MATERIAL 5 57D 102 {ACAD_XDICTIONARY 360 57E 102 } 102 {ACAD_REACTORS 330 56C 102 } 330 56C 100 AcDbMaterial 1 Global 72 0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 0.820209973753281 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 77 0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 0.820209973753281 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 47 0.0 47 0.0 47 0.0 47 0.0 47 1.0 171 0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 0.820209973753281 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 175 0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 0.820209973753281 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 179 0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 0.820209973753281 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 0.820209973753281 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 147 0.0 147 0.0 147 0.0 147 0.0 147 1.0 0 MLEADERSTYLE 5 5B4 102 {ACAD_REACTORS 330 5B3 102 } 330 5B3 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 52C 92 -2 290 1 42 0.09 291 1 43 0.36 3 Standard 44 0.18 300 342 529 174 1 178 6 175 1 176 0 93 -1056964608 45 0.18 292 0 297 0 46 0.18 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 0 143 0.125 271 0 272 9 273 9 298 0 0 MLINESTYLE 5 530 102 {ACAD_REACTORS 330 52F 102 } 330 52F 100 AcDbMlineStyle 2 STANDARD 70 0 3 62 256 51 90.0 52 90.0 71 2 49 0.5 62 256 6 BYLAYER 49 -0.5 62 256 6 BYLAYER 0 ACDBPLACEHOLDER 5 527 102 {ACAD_REACTORS 330 526 102 } 330 526 0 SCALE 5 5A2 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1:1 140 1.0 141 1.0 290 1 0 SCALE 5 5A3 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/128" = 1'-0" 140 0.0078125 141 12.0 290 0 0 SCALE 5 5A4 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/64" = 1'-0" 140 0.015625 141 12.0 290 0 0 SCALE 5 5A5 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/32" = 1'-0" 140 0.03125 141 12.0 290 0 0 SCALE 5 5A6 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/16" = 1'-0" 140 0.0625 141 12.0 290 0 0 SCALE 5 5A7 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 3/32" = 1'-0" 140 0.09375 141 12.0 290 0 0 SCALE 5 5A8 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/8" = 1'-0" 140 0.125 141 12.0 290 0 0 SCALE 5 5A9 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 3/16" = 1'-0" 140 0.1875 141 12.0 290 0 0 SCALE 5 5AA 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/4" = 1'-0" 140 0.25 141 12.0 290 0 0 SCALE 5 5AB 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 3/8" = 1'-0" 140 0.375 141 12.0 290 0 0 SCALE 5 5AC 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1/2" = 1'-0" 140 0.5 141 12.0 290 0 0 SCALE 5 5AD 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 3/4" = 1'-0" 140 0.75 141 12.0 290 0 0 SCALE 5 5AE 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1" = 1'-0" 140 1.0 141 12.0 290 0 0 SCALE 5 5AF 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1-1/2" = 1'-0" 140 1.5 141 12.0 290 0 0 SCALE 5 5B0 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 3" = 1'-0" 140 3.0 141 12.0 290 0 0 SCALE 5 5B1 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 6" = 1'-0" 140 6.0 141 12.0 290 0 0 SCALE 5 5B2 102 {ACAD_REACTORS 330 5A1 102 } 330 5A1 100 AcDbScale 70 0 300 1'-0" = 1'-0" 140 12.0 141 12.0 290 0 0 ACDBSECTIONVIEWSTYLE 5 5B6 102 {ACAD_XDICTIONARY 360 611 102 } 102 {ACAD_REACTORS 330 5B5 102 } 330 5B5 100 AcDbModelDocViewStyle 70 0 3 Imperial24 290 0 100 AcDbSectionViewStyle 70 0 71 0 90 78 71 1 340 529 62 256 40 0.24 340 0 340 0 62 256 40 0.24 300 I, O, Q, S, X, Z 40 0.48 90 3 40 0.18 90 1 71 2 340 52E 90 25 62 256 340 52E 90 50 62 256 40 0.24 40 0.0 40 0.24 71 3 340 529 62 256 40 0.24 90 1 40 0.75 90 1 300 %<\AcVar ViewType \f "%tc1">% %<\AcVar ViewSectionStartId>%-%<\AcVar ViewSectionEndId>%\PSCALE %<\AcVar ViewScale \f "%sn">% 71 4 62 256 62 257 300 ANSI31 40 1.0 90 0 290 0 290 0 90 6 40 0.0 40 1.570796326794896 40 0.2617993877991494 40 1.308996938995747 40 -0.2617993877991494 40 1.832595714594045 0 TABLESTYLE 5 5A0 102 {ACAD_XDICTIONARY 360 5EA 102 } 102 {ACAD_REACTORS 330 59F 102 } 330 59F 100 AcDbTableStyle 280 0 3 Standard 70 0 71 0 40 0.06 41 0.06 280 0 281 0 7 Standard 140 0.18 170 2 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.25 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 0.18 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 0 VISUALSTYLE 5 58B 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 2dWireframe 70 4 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 58A 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Basic 70 7 177 3 291 1 70 58 90 1 176 1 90 0 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 591 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Brighten 70 12 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 595 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 ColorChange 70 16 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 8 420 8421504 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 8 420 8421504 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 58E 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Conceptual 70 9 177 3 291 0 70 58 90 3 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 179.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 590 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Dim 70 11 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 -50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 59D 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 EdgeColorOff 70 22 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 8 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 594 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Facepattern 70 15 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 586 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Flat 70 0 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 587 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 FlatWithEdges 70 1 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 588 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Gouraud 70 2 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 589 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 GouraudWithEdges 70 3 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 58D 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Hidden 70 6 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 40.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 59B 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 JitterOff 70 20 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 10 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 593 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Linepattern 70 14 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 7 176 1 90 7 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 59C 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 OverhangOff 70 21 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 9 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 0 40 0.0 176 0 40 1.0 176 0 90 0 176 0 62 18 176 0 90 50 176 0 90 3 176 0 62 5 420 255 176 0 290 0 176 1 90 50 176 0 90 50 176 0 90 50 176 0 290 0 176 1 90 50 176 0 62 256 176 0 40 1.0 176 0 90 2 176 0 1 strokes_ogs.tif 176 0 290 0 176 1 40 1.0 176 0 40 1.0 176 0 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 58F 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Realistic 70 8 177 3 291 0 70 58 90 2 176 1 90 3 176 1 90 0 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 59A 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Shaded 70 27 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 8 420 7895160 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 599 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Shaded with edges 70 26 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 596 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Shades of Gray 70 23 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 597 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Sketchy 70 24 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 11 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 6 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 592 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Thicken 70 13 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 12 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 58C 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 Wireframe 70 5 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 VISUALSTYLE 5 598 102 {ACAD_REACTORS 330 585 102 } 330 585 100 AcDbVisualStyle 2 X-Ray 70 25 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 1 176 1 40 0.5 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 1001 ACAD 1000 AcDbSavedByObjectVersion 1070 0 0 DICTIONARYVAR 5 5E6 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 1:1 0 DICTIONARYVAR 5 5E2 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 5E1 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 5E3 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 5E4 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 Imperial24 0 DICTIONARYVAR 5 5E8 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 1 0 DICTIONARYVAR 5 5E9 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 15 0 DICTIONARYVAR 5 5E7 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 0 0 DICTIONARYVAR 5 5E5 102 {ACAD_REACTORS 330 5E0 102 } 330 5E0 100 DictionaryVariables 280 0 1 0 0 DICTIONARY 5 610 102 {ACAD_REACTORS 330 60E 102 } 330 60E 100 AcDbDictionary 281 1 0 DICTIONARY 5 60F 102 {ACAD_REACTORS 330 60E 102 } 330 60E 100 AcDbDictionary 281 1 3 140648618144912 350 609 3 140648618144928 350 60A 3 140648618144944 350 60B 3 140648618144960 350 60C 3 140648618144976 350 60D 0 DICTIONARY 5 613 330 5B8 100 AcDbDictionary 280 1 281 1 3 ACAD_XREC_ROUNDTRIP 360 614 0 DICTIONARY 5 576 330 575 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 578 3 DIFFUSETILE 360 577 3 OPACITYTILE 360 57B 3 REFLECTIONTILE 360 57A 3 REFRACTIONTILE 360 57C 3 SPECULARTILE 360 579 0 DICTIONARY 5 56E 330 56D 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 570 3 DIFFUSETILE 360 56F 3 OPACITYTILE 360 573 3 REFLECTIONTILE 360 572 3 REFRACTIONTILE 360 574 3 SPECULARTILE 360 571 0 DICTIONARY 5 57E 330 57D 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 580 3 DIFFUSETILE 360 57F 3 OPACITYTILE 360 583 3 REFLECTIONTILE 360 582 3 REFRACTIONTILE 360 584 3 SPECULARTILE 360 581 0 DICTIONARY 5 611 330 5B6 100 AcDbDictionary 280 1 281 1 3 ACAD_XREC_ROUNDTRIP 360 612 0 DICTIONARY 5 5EA 330 5A0 100 AcDbDictionary 280 1 281 1 3 ACAD_ROUNDTRIP_2008_TABLESTYLE_CELLSTYLEMAP 360 607 0 XRECORD 5 609 102 {ACAD_REACTORS 330 60F 102 } 330 60F 100 AcDbXrecord 280 1 1 AcDb_Thumbnail_Schema 102 {ATTRRECORD 341 60A 2 AcDbDs::TreatedAsObjectData 280 1 291 1 102 ATTRRECORD} 102 {ATTRRECORD 341 60B 2 AcDbDs::Legacy 280 1 291 1 102 ATTRRECORD} 2 AcDbDs::ID 280 10 91 8 102 {ATTRRECORD 341 60C 2 AcDs:Indexable 280 1 291 1 102 ATTRRECORD} 102 {ATTRRECORD 341 60D 2 AcDbDs::HandleAttribute 280 7 282 1 102 ATTRRECORD} 2 Thumbnail_Data 280 15 91 0 0 XRECORD 5 60A 102 {ACAD_REACTORS 330 60F 102 } 330 60F 100 AcDbXrecord 280 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 XRECORD 5 60B 102 {ACAD_REACTORS 330 60F 102 } 330 60F 100 AcDbXrecord 280 1 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 XRECORD 5 60C 102 {ACAD_REACTORS 330 60F 102 } 330 60F 100 AcDbXrecord 280 1 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 XRECORD 5 60D 102 {ACAD_REACTORS 330 60F 102 } 330 60F 100 AcDbXrecord 280 1 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 XRECORD 5 614 102 {ACAD_REACTORS 330 613 102 } 330 613 100 AcDbXrecord 280 1 102 DISPLAYNAME 1 Imperial24 102 FLAGS 90 0 0 XRECORD 5 578 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 577 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 57B 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 57A 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 57C 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 579 102 {ACAD_REACTORS 330 576 102 } 330 576 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 570 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 56F 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 573 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 572 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 574 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 571 102 {ACAD_REACTORS 330 56E 102 } 330 56E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 580 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 57F 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 583 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 582 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 584 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 581 102 {ACAD_REACTORS 330 57E 102 } 330 57E 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 612 102 {ACAD_REACTORS 330 611 102 } 330 611 100 AcDbXrecord 280 1 102 DISPLAYNAME 1 Imperial24 102 FLAGS 90 0 0 CELLSTYLEMAP 5 607 102 {ACAD_REACTORS 330 5EA 102 } 330 5EA 100 AcDbCellStyleMap 90 3 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 32768 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 529 144 0.25 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 1 91 1 300 _TITLE 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 529 144 0.18 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 2 91 1 300 _HEADER 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 2 62 0 340 529 144 0.18 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 0.06 40 0.06 40 0.06 40 0.06 40 0.18 40 0.18 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 0 93 0 40 0.045 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 3 91 2 300 _DATA 309 CELLSTYLE_END 0 ENDSEC 0 SECTION 2 ACDSDATA 70 2 71 8 0 ACDSSCHEMA 90 0 1 AcDb_Thumbnail_Schema 2 AcDbDs::ID 280 10 91 8 2 Thumbnail_Data 280 15 91 0 101 ACDSRECORD 95 0 90 1 2 AcDbDs::TreatedAsObjectData 280 1 291 1 101 ACDSRECORD 95 0 90 2 2 AcDbDs::Legacy 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 3 2 AcDs:Indexable 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 4 2 AcDbDs::HandleAttribute 280 7 282 1 0 ACDSSCHEMA 90 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 ACDSSCHEMA 90 2 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 ACDSSCHEMA 90 3 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 ACDSSCHEMA 90 4 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 4A 2 Thumbnail_Data 280 15 94 1878 310 89504E470D0A1A0A0000000D4948445200000100000000AF08030000002591F0DB00000300504C5445212830FFFFFF2128300000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF0000000000000000000000000000000000000000000000000000000000002E4550F1000004114944415478DAED9D5B82A4200C45D9FF1AEF62E6A7A7AA14F20023CF9B9F6E2D143C989044D0942814CAD9024592BA79FB715900DA4F5036DDA72100025816C055B35545DF12C080 310 D3100055804690000860802B2C78C41980B20FBCB62BFCD77DB0FB1575C7120055804690000880000880000880000880000880B100A34102D85F05167D541A6704B1A6492400022000C53E2A9BB92DAD028059A69B60D049D1BB4D04309B0AAC00E04D23480004300B007BA2E42762D047AEBAE0781A00BEA6A200ABB8B91F 310 80FF7740213A9637B702F0F3E76800D99DAD6D6E08605F4F9000A802838CE02DFC9D76F5C565180CF403CA9EC6B42913F8CBA2C1F3B41224AD52AA300240E994578F18624154DD7D8FBB2E3F059CBD932E0F07A09C03E2BED2CEBE00501BFEE546BDE804DB3A026FC1FE009426406E034E03F051EDFC37B82A42F2EE9C1440 310 D65D5F5B270C95B93DF1ED9C1640E6FA4538690B01C84B4638697D012016C02E02DD0FF8E96902380E006D8006E0B451E0DEDF48A70138DC11925DE1048F870B6FC1E983A13C8F704A3004B1BDB02F1652C165F2015A7B57CA08D55CBF1B80B74AFBCD3C8F7282C93CECB7634AA9FD4000B7A7E4526FCB5392D1D2BFEEC39C 310 659F00F0D588B226DDACAD95C0ADEAD59901187703AA2A0B0170539F17009829FAA1008C3B330080B3F6280082C16C8916BB01705D576BC1B66B2100028806A01A41C773CCF5013CA8682B002DC30D01500508800008E07800F7A413019C05C09FE7EB09A09812D31746C601908EEA08E05BCC1F0135565491EA0E07602C76 310 FDBB03B4A27645AE6470A17D3565DB01B8524E70C2170094FFD7F625E119485F003FB501070280DD9E570160300034D4DD04A02AA544008100AC6735EE3BD57A2E3029809D840086AB8016C39C60048DC9176B02C82755BE0460563F20F95EB6F01E80341500DD15DE14C06D51CDA600CC094B1F6DD4CA25FF0CB4C9C2E198 310 84880E60EA8448654A2CA92B65F74A8949A97A6D5AEA5E49D18E00D6498B13C05B00BCC7100001CC0DA0F05E1610005580000880000880008602085B30311E40D3820947666B1500792ACEDDF9E5E57C0B02D0A72C55D68EE08C50B32758B16C0E5517D40E2009002CD5426DEF977BB53300F37B2CE52CEDE768C92009C51D 310 776EE3B70A9A01D80A0DF9E4A833ABA5C587F69EEF3B20098000088000260150E789CAC5570510260440151806406ED32146105275191425D25A18C043D58D0210DF24022000DA80A7006A46815BAA4D0AEAF703507AC5D715802BFBB13000EB30B8BABB02407D46C8F935B1C500C47CDB73108087B140E040828A2B218049 310 548000088000DE01E078596A72B9341E008F3EB3F40E80A8D0C305606083570710FCF1B6E7E7EB0C603E114C87110CA52D057A389CB6173CF8950008602B1BF0CD91354CE4DB6E6448140A85D255FE018C226AD45137F4BE0000000049454E44AE426082 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 5BD 2 Thumbnail_Data 280 15 94 1136 310 89504E470D0A1A0A0000000D4948445200000100000000B408030000004C80028300000300504C5445FFFFFF0000000000000000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF00000000000000000000000000000000000000000000000000000000000056B0F76B0000012B4944415478DAEDD5B10DC0201004C1EFBF4C628A30929DD080939D17A2800D6E66C76FF6844F0001DE00EBBC73B1FF0ED0BB7C8011203E824B002328801114C0080A600405308202 310 50C006082000052840011B20800014A000056C80000250800214B001020840010A50C006082000052840011B20800014A000056C80000250800214B001020840010A50C006082000052840011B20800014A000056C80000250800214B001020840010A50C006082000052840011B20800014A000056C80000250800214B001 310 020840010A50C006082000052840011B20800014A000056C80000250800214B001020840010A50C006082000052840011B20800014A000056C80000250800214B001020840010A50C006082000052840011B20C06F01CEF5FEFA060820C017207EF9000FEEB63A2E11E155860000000049454E44AE426082 0 ENDSEC 0 EOF ================================================ FILE: testdata/gallery_connected_merge_links.txt ================================================ x1 y1 x2 y2 1.32 7.24 4.88 5.24 1.16 5.28 3.28 7.12 ================================================ FILE: testdata/gallery_graph_vga.txt ================================================ Ref x y Connectivity Point First Moment Point Second Moment 65592 0.68 7.04 91 28.691513 11.32 65593 0.68 7.08 102 38.375195 22.076799 65594 0.68 7.12 135 73.011009 62.731201 65595 0.68 7.16 136 72.054672 61.1968 65596 0.68 7.2 106 42.236126 26.406401 65597 0.68 7.24 84 27.227448 11.824 65599 0.68 7.32 81 22.344883 7.3119998 65600 0.68 7.36 89 23.430403 7.4815998 65601 0.68 7.4 91 23.329962 7.2992001 65602 0.68 7.44 90 23.028296 7.2096 65603 0.68 7.48 84 22.413893 7.2863998 65604 0.68 7.52 82 23.040989 7.7199998 65606 0.68 7.6 87 38.340282 26.313601 65607 0.68 7.64 97 44.365986 32.124802 65608 0.68 7.68 108 51.783161 38.5056 65609 0.68 7.72 109 53.244698 39.591999 65610 0.68 7.76 95 38.697723 23.264 131128 0.72 7.04 102 32.769993 13.744 131129 0.72 7.08 113 40.958103 22.486401 131130 0.72 7.12 145 73.255661 59.785599 131131 0.72 7.16 143 70.484398 57.271999 131132 0.72 7.2 115 40.43277 22.9568 131133 0.72 7.24 100 27.023703 9.5056 131135 0.72 7.32 96 23.956745 7.1680002 131136 0.72 7.36 100 23.603025 6.7919998 131137 0.72 7.4 99 23.024195 6.5760002 131138 0.72 7.44 101 23.552282 6.744 131139 0.72 7.48 99 23.681519 6.9759998 131140 0.72 7.52 84 21.68857 6.8175998 131142 0.72 7.6 102 39.809086 25.363199 131143 0.72 7.64 111 45.547054 30.568001 131144 0.72 7.68 120 53.093029 36.9744 131145 0.72 7.72 122 55.905392 38.9072 131146 0.72 7.76 107 43.013672 25.2064 196664 0.76 7.04 102 30.459377 12.1008 196665 0.76 7.08 112 37.266163 19.3776 196666 0.76 7.12 149 72.022911 57.112 196667 0.76 7.16 148 68.984161 53.7952 196668 0.76 7.2 124 40.585949 21.235201 196669 0.76 7.24 117 30.89657 10.6496 196670 0.76 7.28 93 20.425934 5.5376 196671 0.76 7.32 109 24.63987 6.7328 196672 0.76 7.36 104 22.756449 6.072 196673 0.76 7.4 101 21.336105 5.552 196674 0.76 7.44 101 21.455666 5.6431999 196675 0.76 7.48 102 22.463762 6.1328001 196676 0.76 7.52 108 24.524914 6.9071999 196677 0.76 7.56 89 20.552114 6.0367999 196678 0.76 7.6 120 41.944683 23.112 196679 0.76 7.64 123 48.517162 30.854401 196680 0.76 7.68 126 54.098293 36.628799 196681 0.76 7.72 123 52.332752 34.1856 196682 0.76 7.76 105 38.426586 20.742399 262200 0.8 7.04 102 29.137228 11.4064 262201 0.8 7.08 110 33.311489 15.5616 262202 0.8 7.12 146 66.708405 51.478401 262203 0.8 7.16 141 62.477539 47.959999 262204 0.8 7.2 109 31.902433 15.9952 262205 0.8 7.24 86 19.30418 5.7951999 262207 0.8 7.32 86 18.253939 4.7839999 262208 0.8 7.36 95 18.948063 4.6799998 262209 0.8 7.4 100 19.752245 4.8271999 262210 0.8 7.44 99 19.693623 4.8992 262211 0.8 7.48 97 19.821554 5.0976 262212 0.8 7.52 84 18.721516 5.2048001 262214 0.8 7.6 91 28.888416 15.744 262215 0.8 7.64 106 38.802296 24.692801 262216 0.8 7.68 121 48.852211 32.195202 262217 0.8 7.72 117 45.911297 28.656 262218 0.8 7.76 101 32.795208 15.568 327736 0.84 7.04 92 22.003006 6.9120002 327737 0.84 7.08 94 22.683102 8.4639997 327738 0.84 7.12 137 60.210972 46.257599 327739 0.84 7.16 128 54.657177 41.9856 327740 0.84 7.2 95 25.367149 12.0608 327741 0.84 7.24 81 17.433615 4.9295998 327743 0.84 7.32 81 16.459587 4.0864 327744 0.84 7.36 83 14.9294 3.3248 327745 0.84 7.4 83 14.046597 2.9375999 327746 0.84 7.44 85 14.626451 3.1312001 327747 0.84 7.48 82 15.306084 3.6256001 327748 0.84 7.52 82 17.155693 4.4944 327750 0.84 7.6 82 23.939941 12.0352 327751 0.84 7.64 94 33.640411 21.4272 327752 0.84 7.68 109 42.131927 27.832001 327753 0.84 7.72 105 37.923157 22.9296 327754 0.84 7.76 85 21.76741 8.0607996 393257 0.88 6.44 42 8.7469444 2.3471999 393258 0.88 6.48 60 21.750759 13.072 393259 0.88 6.52 52 14.967987 8.0271997 393260 0.88 6.56 38 5.786551 1.1824 393261 0.88 6.6 36 5.377718 0.99040002 393262 0.88 6.64 32 5.0924959 0.95520002 393264 0.88 6.72 19 2.6990466 0.50400001 393265 0.88 6.76 23 3.3436391 0.63840002 393266 0.88 6.8 41 15.748744 11.216 393272 0.88 7.04 87 19.072384 5.4000001 393273 0.88 7.08 89 19.278217 6.4335999 393274 0.88 7.12 133 56.964733 42.820801 393275 0.88 7.16 126 51.609089 38.284801 393276 0.88 7.2 91 22.262644 9.2992001 393277 0.88 7.24 82 17.050226 4.5455999 393279 0.88 7.32 78 15.038219 3.52 393280 0.88 7.36 76 12.657201 2.5504 393281 0.88 7.4 77 11.78551 2.1296 393282 0.88 7.44 74 11.138371 1.9904 393283 0.88 7.48 76 12.657201 2.5504 393284 0.88 7.52 79 15.342851 3.6127999 393286 0.88 7.6 77 19.342884 7.9136 393287 0.88 7.64 95 33.131908 20.52 393288 0.88 7.68 104 38.88245 24.937599 393289 0.88 7.72 100 34.074253 19.812799 393290 0.88 7.76 80 17.995335 5.3839998 458760 0.92 5.12 165 66.93367 33.513599 458761 0.92 5.16 183 85.820915 58.868801 458762 0.92 5.2 188 92.159378 70.945602 458763 0.92 5.24 176 77.418388 53.990398 458764 0.92 5.28 162 58.95348 29.9216 458765 0.92 5.32 158 54.271576 24.651199 458766 0.92 5.36 154 52.546402 23.444799 458767 0.92 5.4 148 49.678761 20.870399 458768 0.92 5.44 148 51.960201 22.4608 458769 0.92 5.48 146 53.062256 22.820801 458793 0.92 6.44 39 6.8312845 1.576 458794 0.92 6.48 63 21.049376 11.9184 458795 0.92 6.52 61 18.974976 10.8656 458796 0.92 6.56 43 6.1693482 1.2431999 458797 0.92 6.6 39 5.2229948 0.87840003 458798 0.92 6.64 34 4.710113 0.78399998 458800 0.92 6.72 23 2.7589223 0.44319999 458801 0.92 6.76 26 3.3965585 0.60159999 458802 0.92 6.8 50 20.402479 15.1504 458808 0.92 7.04 86 18.348515 4.9503999 458809 0.92 7.08 85 16.344223 4.1072001 458810 0.92 7.12 132 54.408939 39.214401 458811 0.92 7.16 124 49.052952 35.003201 458812 0.92 7.2 87 18.252306 5.7312002 458813 0.92 7.24 82 16.702732 4.2672 458815 0.92 7.32 75 13.818519 3.0064001 458816 0.92 7.36 74 11.961161 2.296 458817 0.92 7.4 71 10.338152 1.7664 458818 0.92 7.44 74 11.186681 2.0128 458819 0.92 7.48 75 12.361161 2.4560001 458820 0.92 7.52 75 13.795877 2.9888 458822 0.92 7.6 73 15.458254 4.5840001 458823 0.92 7.64 96 32.269508 18.8832 458824 0.92 7.68 106 38.398075 23.4496 458825 0.92 7.72 96 30.719749 16.9056 458826 0.92 7.76 77 16.528574 4.6464 524296 0.96 5.12 170 65.611618 31.686399 524297 0.96 5.16 185 80.567383 52.260799 524298 0.96 5.2 190 87.514908 65.3424 524299 0.96 5.24 178 72.879311 49.139198 524300 0.96 5.28 165 55.563362 27.107201 524301 0.96 5.32 158 49.380257 21.0224 524302 0.96 5.36 154 47.384045 19.467199 524303 0.96 5.4 154 49.08913 20.5168 524304 0.96 5.44 147 46.757408 18.3888 524305 0.96 5.48 147 49.904499 20.448 524329 0.96 6.44 39 6.4416518 1.3728 524330 0.96 6.48 46 7.9989877 2.0544 524331 0.96 6.52 66 20.554316 11.4752 524332 0.96 6.56 45 6.0541601 1.128 524333 0.96 6.6 43 5.1857195 0.75040001 524334 0.96 6.64 41 5.1097188 0.75199997 524335 0.96 6.68 41 5.6790199 0.94400001 524336 0.96 6.72 37 5.1659374 0.93440002 524337 0.96 6.76 36 5.5656357 1.1727999 524338 0.96 6.8 62 24.947359 17.566401 524344 0.96 7.04 83 17.354012 4.5071998 524345 0.96 7.08 85 16.445538 4.0672002 524346 0.96 7.12 132 53.135281 36.686401 524347 0.96 7.16 125 48.64756 33.326401 524348 0.96 7.2 84 16.055588 3.9375999 524349 0.96 7.24 81 16.333506 4.0256 524351 0.96 7.32 74 13.893401 3.1024001 524352 0.96 7.36 71 11.475163 2.2272 524353 0.96 7.4 71 10.798904 1.9967999 524354 0.96 7.44 71 10.798904 1.9967999 524355 0.96 7.48 74 12.493398 2.5792 524356 0.96 7.52 74 13.893401 3.1024001 524358 0.96 7.6 71 14.112141 3.536 524359 0.96 7.64 98 32.997417 18.627199 524360 0.96 7.68 107 37.744858 21.912001 524361 0.96 7.72 96 29.768179 15.5696 524362 0.96 7.76 73 14.958081 3.9247999 589832 1 5.12 174 65.324028 31.7024 589833 1 5.16 191 80.142052 50.982399 589834 1 5.2 196 86.54007 63.283199 589835 1 5.24 185 71.888695 46.6544 589836 1 5.28 168 52.231857 23.878401 589837 1 5.32 162 46.649288 18.4704 589838 1 5.36 155 43.29681 16.132799 589839 1 5.4 152 43.631756 16.4608 589840 1 5.44 147 43.177715 15.8464 589841 1 5.48 146 45.879856 17.52 589843 1 5.56 212 107.25992 67.764801 589844 1 5.6 216 101.99606 61.403198 589845 1 5.64 220 100.21715 60.7136 589846 1 5.68 230 100.38043 58.627201 589847 1 5.72 241 106.37511 65.305603 589848 1 5.76 241 99.900703 55.569599 589849 1 5.8 252 105.71748 60.641602 589850 1 5.84 256 105.91825 59.209599 589851 1 5.88 264 109.86177 61.683201 589852 1 5.92 281 125.52368 78.787201 589853 1 5.96 414 484.10068 1121.304 589854 1 6 427 514.89673 1218.8016 589855 1 6.04 253 99.349129 51.179199 589856 1 6.08 240 90.816658 44.7328 589857 1 6.12 233 88.308632 43.911999 589858 1 6.16 229 89.718727 47.023998 589859 1 6.2 225 91.70388 50.416 589860 1 6.24 224 95.526314 54.923199 589861 1 6.28 222 99.456749 59.547199 589862 1 6.32 221 105.13754 66.409599 589863 1 6.36 218 109.76509 72.201599 589864 1 6.4 218 116.79842 80.283203 589865 1 6.44 38 6.3326063 1.3472 589866 1 6.48 39 5.4957714 1.008 589867 1 6.52 68 19.654495 9.8448 589868 1 6.56 47 6.4240294 1.1440001 589869 1 6.6 42 5.0604815 0.72000003 589870 1 6.64 43 5.5340395 0.83359998 589871 1 6.68 41 5.8814182 1.0048 589872 1 6.72 39 5.7991133 1.112 589873 1 6.76 38 6.1722555 1.3552001 589874 1 6.8 69 27.144375 17.591999 589880 1 7.04 83 17.990992 4.8112001 589881 1 7.08 85 16.966961 4.2816 589882 1 7.12 131 51.405739 33.8176 589883 1 7.16 127 48.663898 31.766399 589884 1 7.2 84 16.444794 4.0560002 589885 1 7.24 77 15.48338 3.7423999 589887 1 7.32 71 13.650023 3.1487999 589888 1 7.36 71 12.374516 2.688 589889 1 7.4 71 11.717723 2.4576001 589890 1 7.44 71 11.717723 2.4576001 589891 1 7.48 71 12.374516 2.688 589892 1 7.52 74 14.837963 3.6256001 589894 1 7.6 72 14.669329 3.6896 589895 1 7.64 99 33.070095 17.879999 589896 1 7.68 109 37.3717 20.3248 589897 1 7.72 92 25.653166 11.376 589898 1 7.76 76 16.4391 4.4688001 655368 1.04 5.12 185 70.707703 36.068802 655369 1.04 5.16 200 82.991837 52.3008 655370 1.04 5.2 203 87.04554 61.891201 655371 1.04 5.24 191 71.526306 45.0224 655372 1.04 5.28 174 50.286263 20.8176 655373 1.04 5.32 163 43.158165 15.6176 655374 1.04 5.36 158 40.13126 13.1984 655375 1.04 5.4 154 40.521576 13.8096 655376 1.04 5.44 149 40.65221 13.8448 655377 1.04 5.48 149 45.182354 16.939199 655379 1.04 5.56 213 104.11543 64.856003 655380 1.04 5.6 219 99.478401 58.495998 655381 1.04 5.64 228 97.976906 54.903999 655382 1.04 5.68 238 99.395859 54.068802 655383 1.04 5.72 244 98.362595 51.804798 655384 1.04 5.76 243 94.415054 48.214401 655385 1.04 5.8 249 96.081779 49.919998 655386 1.04 5.84 251 94.582077 47.883202 655387 1.04 5.88 263 103.27004 56.969601 655388 1.04 5.92 278 114.54057 66.804802 655389 1.04 5.96 422 479.3187 1093.4528 655390 1.04 6 435 512.56006 1198.8096 655391 1.04 6.04 260 99.806122 52.195202 655392 1.04 6.08 245 89.754799 44.1744 655393 1.04 6.12 237 86.903336 43.299198 655394 1.04 6.16 230 85.214706 43.187199 655395 1.04 6.2 226 87.20829 46.649601 655396 1.04 6.24 224 91.479836 51.872002 655397 1.04 6.28 224 97.737518 59.113602 655398 1.04 6.32 221 102.05476 64.420799 655399 1.04 6.36 222 110.06548 73.523201 655400 1.04 6.4 220 115.99121 80.251198 655401 1.04 6.44 36 6.2744389 1.3408 655402 1.04 6.48 36 5.3756485 1.0064 655403 1.04 6.52 65 18.366755 8.4927998 655404 1.04 6.56 57 14.743288 7.4591999 655405 1.04 6.6 37 5.0503135 0.81279999 655406 1.04 6.64 31 4.4612322 0.74400002 655408 1.04 6.72 18 2.0062213 0.2608 655409 1.04 6.76 29 4.2443638 0.83520001 655410 1.04 6.8 62 22.122965 12.3728 655416 1.04 7.04 78 17.31529 4.7168002 655417 1.04 7.08 82 16.922358 4.3968 655418 1.04 7.12 134 51.703262 32.113602 655419 1.04 7.16 129 48.897488 30.327999 655420 1.04 7.2 83 17.000641 4.3712001 655421 1.04 7.24 78 17.008938 4.5071998 655423 1.04 7.32 71 14.932616 3.8399999 655424 1.04 7.36 71 13.714247 3.3792 655425 1.04 7.4 71 13.088058 3.1487999 655426 1.04 7.44 71 13.088058 3.1487999 655427 1.04 7.48 71 13.714247 3.3792 655428 1.04 7.52 72 15.301398 3.9760001 655430 1.04 7.6 69 14.367953 3.6784 655431 1.04 7.64 101 33.710976 17.348801 655432 1.04 7.68 111 38.165024 19.993601 655433 1.04 7.72 89 23.107052 8.8240004 655434 1.04 7.76 74 16.567806 4.6016002 720904 1.08 5.12 201 85.265106 52.6576 720905 1.08 5.16 219 96.503235 64.750397 720906 1.08 5.2 221 97.311829 68.9888 720907 1.08 5.24 208 80.383865 50.900799 720908 1.08 5.28 186 54.491756 22.559999 720909 1.08 5.32 175 46.611843 17.1024 720910 1.08 5.36 170 43.306866 14.6224 720911 1.08 5.4 157 38.037258 11.4528 720912 1.08 5.44 154 40.53104 13.4224 720913 1.08 5.48 151 44.117947 15.9408 720915 1.08 5.56 217 103.57859 64.193604 720916 1.08 5.6 233 103.64909 60.2896 720917 1.08 5.64 249 107.57411 60.627201 720918 1.08 5.68 250 102.89072 55.972801 720919 1.08 5.72 247 96.681618 50.2416 720920 1.08 5.76 246 91.196266 44.812801 720921 1.08 5.8 239 83.17421 38.007999 720922 1.08 5.84 246 84.507332 37.819199 720923 1.08 5.88 255 88.889984 40.588799 720924 1.08 5.92 271 100.64622 50.7808 720925 1.08 5.96 420 464.32104 1053.4784 720926 1.08 6 438 502.4375 1162.8032 720927 1.08 6.04 262 97.8004 51.7584 720928 1.08 6.08 249 89.923332 45.880001 720929 1.08 6.12 244 89.665329 46.944 720930 1.08 6.16 240 90.501976 48.556801 720931 1.08 6.2 236 90.68074 49.062401 720932 1.08 6.24 229 91.16906 51.459202 720933 1.08 6.28 223 92.68647 54.448002 720934 1.08 6.32 222 99.409882 61.992001 720935 1.08 6.36 221 106.10816 69.472 720936 1.08 6.4 220 113.45081 77.686401 720940 1.08 6.56 71 20.965086 9.7296 720946 1.08 6.8 58 19.021942 9.3984003 720952 1.08 7.04 75 17.761301 5.1423998 720953 1.08 7.08 81 18.331873 5.2160001 720954 1.08 7.12 139 52.725243 30.7488 720955 1.08 7.16 133 49.985279 29.2656 720956 1.08 7.2 79 17.34952 4.7792001 720957 1.08 7.24 73 17.017426 4.848 720959 1.08 7.32 71 16.617079 4.7616 720960 1.08 7.36 71 15.479453 4.3007998 720961 1.08 7.4 71 14.896123 4.0704002 720962 1.08 7.44 71 14.896123 4.0704002 720963 1.08 7.48 71 15.479453 4.3007998 720964 1.08 7.52 71 16.617079 4.7616 720966 1.08 7.6 64 14.093885 3.8624001 720967 1.08 7.64 104 34.644493 16.924801 720968 1.08 7.68 117 39.738735 19.649599 720969 1.08 7.72 81 18.180265 5.0896001 720970 1.08 7.76 71 17.073963 5.1023998 786440 1.12 5.12 222 105.24494 74.950401 786441 1.12 5.16 240 115.82227 85.521599 786442 1.12 5.2 253 123.48015 94.019203 786443 1.12 5.24 241 108.07349 77.270401 786444 1.12 5.28 224 83.020248 47.596802 786445 1.12 5.32 215 73.595093 38.5728 786446 1.12 5.36 203 62.694839 28.452801 786447 1.12 5.4 186 50.151707 17.6096 786448 1.12 5.44 170 43.757755 13.9776 786449 1.12 5.48 152 41.806175 14.0688 786451 1.12 5.56 242 113.68269 70.447998 786452 1.12 5.6 262 117.61987 69.388802 786453 1.12 5.64 258 109.08047 61.127998 786454 1.12 5.68 253 101.17253 54.131199 786455 1.12 5.72 246 92.258011 46.4496 786456 1.12 5.76 244 87.631058 42.244801 786457 1.12 5.8 244 84.167381 38.785599 786458 1.12 5.84 247 82.466782 36.235199 786459 1.12 5.88 253 84.713264 37.368 786460 1.12 5.92 273 96.743423 45.743999 786461 1.12 5.96 426 458.5546 1023.6816 786462 1.12 6 442 494.19498 1128.5728 786463 1.12 6.04 258 88.356987 40.793598 786464 1.12 6.08 246 82.552757 37.849602 786465 1.12 6.12 241 82.612152 39.492802 786466 1.12 6.16 239 86.160301 44.464001 786467 1.12 6.2 244 95.288597 54.080002 786468 1.12 6.24 242 98.977119 58.5168 786469 1.12 6.28 243 104.77968 64.435204 786470 1.12 6.32 241 109.4513 69.924797 786471 1.12 6.36 228 109.72643 73.9328 786472 1.12 6.4 225 117.03373 82.486397 786476 1.12 6.56 62 18.218618 7.9503999 786477 1.12 6.6 20 5.7555542 2.3664 786481 1.12 6.76 26 9.8878822 7.0176001 786482 1.12 6.8 52 15.839282 7.1055999 786488 1.12 7.04 71 18.672298 5.9136 786489 1.12 7.08 72 17.730001 5.4608002 786490 1.12 7.12 146 54.847942 30.200001 786491 1.12 7.16 138 51.301807 28.3536 786492 1.12 7.2 72 17.730001 5.4608002 786493 1.12 7.24 71 18.672298 5.9136 786495 1.12 7.32 71 18.672298 5.9136 786496 1.12 7.36 71 17.640558 5.4527998 786497 1.12 7.4 71 17.111734 5.2224002 786498 1.12 7.44 71 17.111734 5.2224002 786499 1.12 7.48 71 17.640558 5.4527998 786500 1.12 7.52 71 18.672298 5.9136 786502 1.12 7.6 59 14.904503 4.6240001 786503 1.12 7.64 96 29.163681 12.432 786504 1.12 7.68 126 42.3022 19.742399 786505 1.12 7.72 79 20.070566 6.2848001 786506 1.12 7.76 60 15.316328 4.7936001 851976 1.16 5.12 247 137.85081 120.576 851977 1.16 5.16 270 151.72148 132.2672 851978 1.16 5.2 292 165.85542 144.75681 851979 1.16 5.24 287 154.61871 129.496 851980 1.16 5.28 276 134.90776 104.0944 851981 1.16 5.32 274 129.03339 95.625603 851982 1.16 5.36 281 130.14626 92.582397 851983 1.16 5.4 293 133.61781 90.351997 851984 1.16 5.44 308 140.19199 90.9888 851985 1.16 5.48 338 153.3654 94.945602 851986 1.16 5.52 323 145.52142 87.147202 851987 1.16 5.56 291 130.96355 77.620796 851988 1.16 5.6 270 117.02744 67.513603 851989 1.16 5.64 256 105.24823 58.243198 851990 1.16 5.68 251 98.281158 52.102402 851991 1.16 5.72 247 92.117355 46.6432 851992 1.16 5.76 246 87.953003 42.596802 851993 1.16 5.8 245 84.261154 39.119999 851994 1.16 5.84 244 81.195435 36.302399 851995 1.16 5.88 253 83.914749 37.035198 851996 1.16 5.92 272 93.959808 43.112 851997 1.16 5.96 430 453.24344 995.08478 851998 1.16 6 445 490.14673 1106.0176 851999 1.16 6.04 257 86.69474 39.7728 852000 1.16 6.08 244 81.058929 37.406399 852001 1.16 6.12 240 81.971413 39.647999 852002 1.16 6.16 239 84.279007 42.436798 852003 1.16 6.2 237 87.589386 46.651199 852004 1.16 6.24 236 91.037178 50.579201 852005 1.16 6.28 236 96.239716 56.395199 852006 1.16 6.32 235 100.86439 61.4944 852007 1.16 6.36 243 113.20556 73.472 852008 1.16 6.4 243 119.58923 80.463997 852009 1.16 6.44 230 124.9934 88.265602 852010 1.16 6.48 202 120.33929 91.358398 852011 1.16 6.52 186 112.75641 89.536003 852012 1.16 6.56 205 121.87601 97.833603 852013 1.16 6.6 147 104.7407 93.800003 852017 1.16 6.76 57 24.833809 15.8864 852018 1.16 6.8 44 9.9302855 3.1168001 852026 1.16 7.12 163 64.784515 34.340801 852027 1.16 7.16 144 52.896118 27.5376 852040 1.16 7.68 161 54.438843 23.993601 917512 1.2 5.12 246 137.57756 120.8672 917513 1.2 5.16 266 145.94574 125.0512 917514 1.2 5.2 291 163.59375 141.66879 917515 1.2 5.24 292 157.85568 132.1456 917516 1.2 5.28 281 139.88554 109.5632 917517 1.2 5.32 288 139.58795 104.5824 917518 1.2 5.36 294 140.4044 101.4096 917519 1.2 5.4 306 143.38818 98.267197 917520 1.2 5.44 326 151.76048 99.255997 917521 1.2 5.48 343 154.67224 95.127998 917522 1.2 5.52 324 146.0336 87.472 917523 1.2 5.56 283 126.25783 74.622398 917524 1.2 5.6 266 114.69285 65.886398 917525 1.2 5.64 256 105.75358 58.568001 917526 1.2 5.68 251 98.867958 52.4944 917527 1.2 5.72 246 92.229454 46.787201 917528 1.2 5.76 246 88.418091 42.8592 917529 1.2 5.8 244 84.38665 39.264 917530 1.2 5.84 244 81.63163 36.543999 917531 1.2 5.88 249 81.821136 35.728001 917532 1.2 5.92 267 90.160553 40.088001 917533 1.2 5.96 431 446.59192 965.71362 917534 1.2 6 448 484.36115 1074.9744 917535 1.2 6.04 253 84.029564 37.750401 917536 1.2 6.08 243 80.949265 37.364799 917537 1.2 6.12 239 81.516022 39.057598 917538 1.2 6.16 237 84.236641 42.568001 917539 1.2 6.2 236 87.061523 45.857601 917540 1.2 6.24 236 91.572906 50.911999 917541 1.2 6.28 235 95.593376 55.372799 917542 1.2 6.32 235 101.39097 61.849602 917543 1.2 6.36 235 107.81452 69.081596 917544 1.2 6.4 236 115.03149 77.115196 917545 1.2 6.44 224 120.73614 85.5616 917546 1.2 6.48 204 122.0304 92.711998 917547 1.2 6.52 206 128.2571 101.7552 917548 1.2 6.56 209 127.82599 104.0576 917549 1.2 6.6 225 138.94206 115.36 917550 1.2 6.64 296 281.39178 393.31039 917551 1.2 6.68 408 566.22046 1167.9471 917552 1.2 6.72 284 336.39551 594.68323 917553 1.2 6.76 150 103.21446 103.5504 917554 1.2 6.8 104 81.547478 91.2304 917560 1.2 7.04 123 48.489231 23.683201 917561 1.2 7.08 136 51.483582 24.532801 917562 1.2 7.12 211 81.96315 41.385601 917563 1.2 7.16 214 79.477837 38.636799 917564 1.2 7.2 145 46.551247 19.3232 917565 1.2 7.24 133 37.725071 13.4416 917566 1.2 7.28 125 32.879261 10.5744 917567 1.2 7.32 127 33.38826 10.8032 917568 1.2 7.36 126 33.146534 10.9888 917569 1.2 7.4 129 34.862225 12.0784 917570 1.2 7.44 130 36.19965 13.2736 917571 1.2 7.48 133 39.013191 15.4656 917572 1.2 7.52 133 40.155506 16.511999 917573 1.2 7.56 139 45.493504 20.4928 917574 1.2 7.6 153 56.11797 28.1824 917575 1.2 7.64 196 75.505066 38.720001 917576 1.2 7.68 223 89.657806 47.004799 917577 1.2 7.72 166 71.787148 41.1152 917578 1.2 7.76 143 65.271507 38.875198 983048 1.24 5.12 226 111.19139 83.587196 983049 1.24 5.16 244 115.20014 82.891197 983050 1.24 5.2 269 131.98523 98.745598 983051 1.24 5.24 258 117.84138 83.568001 983052 1.24 5.28 238 93.102699 56.872002 983053 1.24 5.32 228 83.389168 47.502399 983054 1.24 5.36 219 74.208733 37.777599 983055 1.24 5.4 200 58.768185 23.524799 983056 1.24 5.44 179 46.988922 14.9984 983057 1.24 5.48 153 41.388813 13.384 983059 1.24 5.56 241 114.04466 70.736 983060 1.24 5.6 253 112.82687 66.112 983061 1.24 5.64 253 107.04154 59.937599 983062 1.24 5.68 251 100.87364 53.915199 983063 1.24 5.72 247 94.982964 48.672001 983064 1.24 5.76 243 88.497856 42.731201 983065 1.24 5.8 243 85.190964 39.4352 983066 1.24 5.84 241 81.150291 35.723202 983067 1.24 5.88 241 79.221191 34.001598 983068 1.24 5.92 260 86.263924 36.848 983069 1.24 5.96 430 439.03693 935.7392 983070 1.24 6 444 474.38684 1040.9856 983071 1.24 6.04 243 78.911758 34.075199 983072 1.24 6.08 235 78.057892 35.360001 983073 1.24 6.12 233 80.854286 39.060799 983074 1.24 6.16 233 84.477333 43.348801 983075 1.24 6.2 232 88.26947 47.9856 983076 1.24 6.24 232 93.976311 54.705601 983077 1.24 6.28 232 98.922691 60.209599 983078 1.24 6.32 231 104.93917 67.223999 983079 1.24 6.36 229 111.31284 74.912003 983080 1.24 6.4 225 118.26382 83.3936 983085 1.24 6.6 104 43.611366 27.625601 983086 1.24 6.64 182 145.63892 183.8288 983087 1.24 6.68 342 482.53427 1052.408 983088 1.24 6.72 237 254.80272 457.22079 983089 1.24 6.76 119 58.939407 44.348801 983093 1.24 6.92 56 19.161268 9.5200005 983094 1.24 6.96 64 24.614416 13.7424 983095 1.24 7 27 5.9395099 1.7312 983096 1.24 7.04 122 46.055771 22.236799 983097 1.24 7.08 140 49.332321 22.590401 983098 1.24 7.12 215 81.874825 40.316799 983099 1.24 7.16 217 80.37545 38.715199 983100 1.24 7.2 162 49.517242 19.7696 983101 1.24 7.24 141 39.438698 14.2912 983102 1.24 7.28 136 36.811031 13.0736 983103 1.24 7.32 134 35.556854 12.4656 983104 1.24 7.36 133 35.167522 12.48 983105 1.24 7.4 133 35.704964 13.1248 983106 1.24 7.44 134 37.18478 14.4752 983107 1.24 7.48 134 38.123543 15.3792 983108 1.24 7.52 138 41.564789 18.019199 983109 1.24 7.56 141 44.655117 20.534401 983110 1.24 7.6 159 54.966751 27.019199 983111 1.24 7.64 197 75.319725 38.248001 983112 1.24 7.68 226 91.852943 48.383999 983113 1.24 7.72 182 76.349548 43.209599 983114 1.24 7.76 148 67.077255 41.273602 1048584 1.28 5.12 209 93.102089 62.768002 1048585 1.28 5.16 217 89.114914 55.596802 1048586 1.28 5.2 245 106.78829 71.027199 1048587 1.28 5.24 230 88.319824 51.944 1048588 1.28 5.28 196 57.961826 24.448 1048589 1.28 5.32 182 47.71101 16.6448 1048590 1.28 5.36 173 42.742016 13.232 1048591 1.28 5.4 165 40.523712 12.0752 1048592 1.28 5.44 158 40.868656 12.7616 1048593 1.28 5.48 150 42.373661 14.2864 1048595 1.28 5.56 214 102.63988 62.616001 1048596 1.28 5.6 226 100.09044 56.753601 1048597 1.28 5.64 236 99.220131 53.332802 1048598 1.28 5.68 239 95.853226 49.156799 1048599 1.28 5.72 235 89.537338 43.737598 1048600 1.28 5.76 238 87.294296 40.855999 1048601 1.28 5.8 234 82.135612 36.68 1048602 1.28 5.84 235 80.193428 34.782398 1048603 1.28 5.88 233 77.306694 32.566399 1048604 1.28 5.92 251 83.852402 35.529598 1048605 1.28 5.96 428 432.6178 907.65442 1048606 1.28 6 442 470.89304 1020.136 1048607 1.28 6.04 234 77.957451 34.4576 1048608 1.28 6.08 229 78.982841 36.689602 1048609 1.28 6.12 229 81.513191 39.556801 1048610 1.28 6.16 228 84.608826 43.396801 1048611 1.28 6.2 226 86.842445 46.264 1048612 1.28 6.24 226 91.560692 51.551998 1048613 1.28 6.28 225 96.369446 56.9408 1048614 1.28 6.32 222 101.70502 63.504002 1048615 1.28 6.36 221 108.27577 70.984001 1048616 1.28 6.4 219 114.38089 78.006401 1048621 1.28 6.6 132 68.690628 51.454399 1048622 1.28 6.64 207 143.63159 142.1248 1048623 1.28 6.68 371 499.48904 1044.0352 1048624 1.28 6.72 248 227.57787 347.01279 1048625 1.28 6.76 149 69.554604 45.5952 1048626 1.28 6.8 136 66.618172 44.636799 1048627 1.28 6.84 145 73.476318 49.832001 1048628 1.28 6.88 121 56.253052 35.812801 1048629 1.28 6.92 142 63.874481 36.979198 1048630 1.28 6.96 162 71.059273 39.633598 1048631 1.28 7 135 52.015049 25.959999 1048632 1.28 7.04 148 51.471992 23.6224 1048633 1.28 7.08 166 55.420589 23.856001 1048634 1.28 7.12 234 88.156425 42.119999 1048635 1.28 7.16 228 84.057312 39.763199 1048636 1.28 7.2 175 53.544636 21.0256 1048637 1.28 7.24 147 40.873219 14.9568 1048638 1.28 7.28 139 37.449818 13.4544 1048639 1.28 7.32 138 36.900146 13.3536 1048640 1.28 7.36 138 37.113739 13.7744 1048641 1.28 7.4 138 37.787434 14.6288 1048642 1.28 7.44 139 39.226917 16.0128 1048643 1.28 7.48 139 40.738644 17.683201 1048644 1.28 7.52 141 43.232285 19.915199 1048645 1.28 7.56 146 47.168365 22.915199 1048646 1.28 7.6 162 55.673046 28.040001 1048647 1.28 7.64 201 78.53611 41.547199 1048648 1.28 7.68 229 95.11747 51.694401 1048649 1.28 7.72 189 79.816925 45.9072 1048650 1.28 7.76 151 68.058823 42.790401 1114120 1.32 5.12 182 70.116104 38.315201 1114121 1.32 5.16 195 67.469933 32.398399 1114122 1.32 5.2 226 87.010475 49.745602 1114123 1.32 5.24 212 73.673073 38.233601 1114124 1.32 5.28 179 47.304089 16.1472 1114125 1.32 5.32 168 41.540936 12.8416 1114126 1.32 5.36 164 40.57835 12.3152 1114127 1.32 5.4 157 39.820122 12.3136 1114128 1.32 5.44 152 40.880169 13.3136 1114129 1.32 5.48 147 42.7761 14.8096 1114131 1.32 5.56 208 102.36168 62.4352 1114132 1.32 5.6 215 98.448242 56.524799 1114133 1.32 5.64 220 94.703163 51.3232 1114134 1.32 5.68 226 93.009445 47.881599 1114135 1.32 5.72 231 91.326996 44.980801 1114136 1.32 5.76 231 87.690491 41.439999 1114137 1.32 5.8 232 85.2547 38.852798 1114138 1.32 5.84 231 82.473885 36.476799 1114139 1.32 5.88 230 80.176353 34.614399 1114140 1.32 5.92 232 79.473091 33.911999 1114141 1.32 5.96 428 428.37463 881.52478 1114142 1.32 6 443 466.76746 991.65601 1114143 1.32 6.04 228 80.650223 36.6912 1114144 1.32 6.08 227 81.790878 38.337601 1114145 1.32 6.12 226 83.452751 40.443199 1114146 1.32 6.16 226 87.262276 44.952 1114147 1.32 6.2 225 90.326309 48.636799 1114148 1.32 6.24 224 95.340904 54.867199 1114149 1.32 6.28 222 99.427879 59.774399 1114150 1.32 6.32 222 106.40266 68.003197 1114151 1.32 6.36 222 113.03217 75.639999 1114152 1.32 6.4 220 118.75793 82.367996 1114157 1.32 6.6 125 66.421387 51.248001 1114158 1.32 6.64 194 119.09392 99.211197 1114159 1.32 6.68 381 495.27811 1013.448 1114160 1.32 6.72 222 153.69417 154.79201 1114161 1.32 6.76 134 62.4729 41.855999 1114162 1.32 6.8 122 56.932026 37.403198 1114163 1.32 6.84 125 57.596317 35.848 1114164 1.32 6.88 132 61.76355 37.944 1114165 1.32 6.92 163 75.791054 45.419201 1114166 1.32 6.96 188 88.060272 53.433601 1114167 1.32 7 162 75.290657 48.504002 1114168 1.32 7.04 159 62.77639 36.352001 1114169 1.32 7.08 164 54.729908 23.6304 1114170 1.32 7.12 235 87.942726 41.4688 1114171 1.32 7.16 230 84.276009 39.302399 1114172 1.32 7.2 175 53.388916 20.937599 1114173 1.32 7.24 150 41.781322 15.2704 1114174 1.32 7.28 141 38.018353 13.6176 1114175 1.32 7.32 138 36.92532 13.3728 1114176 1.32 7.36 139 37.527416 13.944 1114177 1.32 7.4 137 37.50066 14.5472 1114178 1.32 7.44 138 38.960922 15.9424 1114179 1.32 7.48 139 40.888668 17.775999 1114180 1.32 7.52 141 43.463345 20.073601 1114181 1.32 7.56 146 47.31134 23.032 1114182 1.32 7.6 161 55.668659 28.156799 1114183 1.32 7.64 202 78.641563 41.534401 1114184 1.32 7.68 229 95.039886 51.6432 1114185 1.32 7.72 190 80.14769 46.019199 1114186 1.32 7.76 150 67.770378 42.707199 1179656 1.36 5.12 170 59.568604 27.475201 1179657 1.36 5.16 186 59.43066 24.624001 1179658 1.36 5.2 221 82.084381 44.030399 1179659 1.36 5.24 201 63.314827 26.819201 1179660 1.36 5.28 166 43.148964 14.064 1179661 1.36 5.32 163 41.788754 13.2096 1179662 1.36 5.36 156 40.355309 12.848 1179663 1.36 5.4 150 40.130451 13.1568 1179664 1.36 5.44 148 42.268894 14.6064 1179665 1.36 5.48 149 46.076447 16.846399 1179677 1.36 5.96 427 424.7395 856.65277 1179678 1.36 6 380 441.20587 955.65277 1179693 1.36 6.6 86 36.484356 23.952 1179694 1.36 6.64 143 69.055405 47.563202 1179695 1.36 6.68 331 446.42902 954.2912 1179696 1.36 6.72 130 61.522186 45.057598 1179697 1.36 6.76 45 7.919024 1.8784 1179702 1.36 6.96 81 28.399715 14.1872 1179704 1.36 7.04 123 46.49823 22.419201 1179705 1.36 7.08 140 49.672371 22.854401 1179706 1.36 7.12 229 90.67083 47.7216 1179707 1.36 7.16 240 99.617096 58.9072 1179708 1.36 7.2 170 59.986076 32.6208 1179709 1.36 7.24 148 44.573105 19.1824 1179710 1.36 7.28 141 38.716789 13.8336 1179711 1.36 7.32 135 36.006298 12.6304 1179712 1.36 7.36 133 35.388229 12.6496 1179713 1.36 7.4 135 36.867722 13.8016 1179714 1.36 7.44 136 38.251236 15.0672 1179715 1.36 7.48 136 39.525829 16.363199 1179716 1.36 7.52 140 43.300285 19.3424 1179717 1.36 7.56 144 47.16922 22.382401 1179718 1.36 7.6 160 57.462002 29.382401 1179719 1.36 7.64 201 78.48597 41.177601 1179720 1.36 7.68 229 93.863861 50.284801 1179721 1.36 7.72 181 77.797424 45.487999 1179722 1.36 7.76 151 69.687874 43.947201 1245187 1.4 4.92 42 10.417987 3.576 1245188 1.4 4.96 42 9.2337847 2.9024 1245189 1.4 5 42 8.3405771 2.3664 1245190 1.4 5.04 45 8.9505377 2.4560001 1245191 1.4 5.08 58 12.344558 3.3296001 1245192 1.4 5.12 179 61.151897 26.8032 1245193 1.4 5.16 182 57.639931 23.233601 1245194 1.4 5.2 219 80.398125 41.292801 1245195 1.4 5.24 188 56.081787 21.0208 1245196 1.4 5.28 166 46.143532 15.8352 1245197 1.4 5.32 156 42.973881 14.5408 1245198 1.4 5.36 155 43.596321 14.9776 1245199 1.4 5.4 152 44.38921 15.704 1245200 1.4 5.44 149 45.984169 16.983999 1245201 1.4 5.48 149 49.333725 19.143999 1245213 1.4 5.96 289 362.39203 803.15997 1245214 1.4 6 296 401.52319 915.71838 1245230 1.4 6.64 88 25.849367 10.1696 1245231 1.4 6.68 327 434.84845 920.24957 1245232 1.4 6.72 86 26.045444 11.0544 1245238 1.4 6.96 50 16.939228 8.0640001 1245240 1.4 7.04 123 48.747078 23.927999 1245241 1.4 7.08 136 52.084644 25.0016 1245242 1.4 7.12 213 80.430267 38.1744 1245243 1.4 7.16 220 79.317871 35.936001 1245244 1.4 7.2 147 47.4258 19.7216 1245245 1.4 7.24 136 39.925068 14.8896 1245246 1.4 7.28 147 54.313828 34.947201 1245247 1.4 7.32 144 53.348759 36.188801 1245248 1.4 7.36 139 45.266205 25.497601 1245249 1.4 7.4 134 40.167675 18.913601 1245250 1.4 7.44 130 36.19965 13.2736 1245251 1.4 7.48 132 38.587986 15.2848 1245252 1.4 7.52 137 43.072994 18.7008 1245253 1.4 7.56 141 47.125225 21.857599 1245254 1.4 7.6 153 56.67968 28.5984 1245255 1.4 7.64 193 74.230766 38.187199 1245256 1.4 7.68 227 91.081612 47.9216 1245257 1.4 7.72 166 72.843925 42.150398 1245258 1.4 7.76 147 67.652451 40.462399 1310723 1.44 4.92 53 14.966986 5.8256001 1310724 1.44 4.96 58 15.419645 5.7168002 1310725 1.44 5 70 22.676468 11.5968 1310726 1.44 5.04 100 36.472126 19.1504 1310727 1.44 5.08 150 54.785149 25.799999 1310728 1.44 5.12 165 59.108219 26.041599 1310729 1.44 5.16 161 54.014061 22.3328 1310730 1.44 5.2 217 80.499725 40.547199 1310731 1.44 5.24 172 52.289356 19.625601 1310732 1.44 5.28 154 46.425999 17.024 1310733 1.44 5.32 154 46.648079 17.0928 1310734 1.44 5.36 151 46.328548 17.1136 1310735 1.44 5.4 150 47.680454 18.084801 1310736 1.44 5.44 149 49.8955 19.672001 1310737 1.44 5.48 149 53.050331 21.832001 1310749 1.44 5.96 268 347.24921 773.9776 1310750 1.44 6 272 384.58774 882.5072 1310767 1.44 6.68 339 432.88809 899.40961 1310774 1.44 6.96 54 16.141594 7.0144 1310778 1.44 7.12 149 54.254265 25.247999 1310779 1.44 7.16 143 49.218288 22.3328 1310792 1.44 7.68 144 46.916862 20.499201 1376259 1.48 4.92 59 21.449614 12.296 1376260 1.48 4.96 77 32.645191 20.784 1376261 1.48 5 78 30.294525 17.431999 1376262 1.48 5.04 75 26.076345 12.4912 1376264 1.48 5.12 31 7.9562602 2.7664001 1376265 1.48 5.16 42 10.491853 3.4463999 1376266 1.48 5.2 195 78.081009 40.409599 1376267 1.48 5.24 63 21.245878 10.696 1376283 1.48 5.88 88 32.133827 16.995199 1376284 1.48 5.92 112 60.299961 54.708801 1376285 1.48 5.96 263 336.78943 747.2912 1376286 1.48 6 284 378.37604 854.23041 1376287 1.48 6.04 89 32.786522 18.4624 1376288 1.48 6.08 82 26.918541 12.1744 1376303 1.48 6.68 345 424.33478 867.51038 1376308 1.48 6.88 32 6.0233135 1.5312001 1376309 1.48 6.92 44 10.319736 3.7823999 1376310 1.48 6.96 55 14.817451 6.0064001 1376311 1.48 7 33 6.6905565 1.832 1376312 1.48 7.04 81 24.144417 9.1728001 1376313 1.48 7.08 83 23.289831 8.5103998 1376314 1.48 7.12 142 48.784927 22.68 1376315 1.48 7.16 135 45.952545 21.291201 1376316 1.48 7.2 82 23.409365 8.7264004 1376317 1.48 7.24 80 23.538675 8.7872 1376319 1.48 7.32 71 18.672298 5.9136 1376320 1.48 7.36 71 17.640558 5.4527998 1376321 1.48 7.4 71 17.111734 5.2224002 1376322 1.48 7.44 71 17.111734 5.2224002 1376323 1.48 7.48 71 17.640558 5.4527998 1376324 1.48 7.52 72 19.104965 6.1008 1376326 1.48 7.6 61 15.138167 4.6528001 1376327 1.48 7.64 102 32.652061 14.488 1376328 1.48 7.68 123 41.494232 19.455999 1376329 1.48 7.72 82 20.283421 6.1855998 1376330 1.48 7.76 62 15.90697 5.0528002 1441795 1.52 4.92 69 29.836424 19.060801 1441796 1.52 4.96 72 30.148283 18.6896 1441797 1.52 5 60 19.974895 10.0096 1441798 1.52 5.04 42 10.739431 4.6143999 1441800 1.52 5.12 34 8.0922527 2.9568 1441801 1.52 5.16 108 38.321426 17.4032 1441802 1.52 5.2 173 69.179703 35.827202 1441803 1.52 5.24 90 27.271202 10.3648 1441819 1.52 5.88 85 26.072828 11.5984 1441820 1.52 5.92 125 57.490608 45.028801 1441821 1.52 5.96 258 328.18991 722.13599 1441822 1.52 6 282 372.82413 833.58398 1441823 1.52 6.04 89 29.179459 15.4368 1441824 1.52 6.08 80 22.520805 8.5439997 1441837 1.52 6.6 249 258.19824 422.97119 1441838 1.52 6.64 291 354.75665 722.50879 1441839 1.52 6.68 350 418.0278 839.58081 1441840 1.52 6.72 296 341.0491 672.70239 1441841 1.52 6.76 243 264.82916 453.92801 1441844 1.52 6.88 33 5.3463125 1.1984 1441845 1.52 6.92 45 9.7776852 3.3487999 1441846 1.52 6.96 56 14.085178 5.3407998 1441847 1.52 7 34 5.8544292 1.424 1441848 1.52 7.04 84 22.699131 7.8495998 1441849 1.52 7.08 91 23.144194 7.7184 1441850 1.52 7.12 135 46.039051 22.1248 1441851 1.52 7.16 130 43.464912 20.576 1441852 1.52 7.2 90 22.396355 7.3712001 1441853 1.52 7.24 80 21.188469 7.2816 1441855 1.52 7.32 71 16.617079 4.7616 1441856 1.52 7.36 71 15.479453 4.3007998 1441857 1.52 7.4 71 14.896123 4.0704002 1441858 1.52 7.44 71 14.896123 4.0704002 1441859 1.52 7.48 72 15.856812 4.4432001 1441860 1.52 7.52 72 17.017078 4.9215999 1441862 1.52 7.6 67 14.759789 4.0208001 1441863 1.52 7.64 102 33.809765 16.4272 1441864 1.52 7.68 114 39.028557 19.467199 1441865 1.52 7.72 80 17.924141 5.0240002 1441866 1.52 7.76 72 17.330088 5.1680002 1507331 1.56 4.92 55 19.384987 9.8304005 1507332 1.56 4.96 56 19.041708 9.6767998 1507333 1.56 5 49 14.817757 7.2416 1507334 1.56 5.04 34 5.1768894 1.1792001 1507335 1.56 5.08 47 11.980098 5.0911999 1507336 1.56 5.12 60 19.768717 9.4960003 1507337 1.56 5.16 82 30.850124 15.0352 1507338 1.56 5.2 187 70.128418 34.537601 1507339 1.56 5.24 83 25.144419 9.7600002 1507355 1.56 5.88 86 23.537201 9.1887999 1507356 1.56 5.92 128 52.324951 35.703999 1507357 1.56 5.96 255 320.36963 697.77917 1507358 1.56 6 279 364.2807 805.88641 1507359 1.56 6.04 97 30.145798 14.9648 1507360 1.56 6.08 79 19.716049 6.744 1507373 1.56 6.6 256 247.30463 393.91199 1507374 1.56 6.64 308 352.36646 700.72803 1507375 1.56 6.68 341 403.74146 806.86078 1507376 1.56 6.72 303 334.56653 648.84961 1507377 1.56 6.76 255 251.64864 414.01761 1507380 1.56 6.88 35 5.4053993 1.1328 1507381 1.56 6.92 44 8.8297749 2.8176 1507382 1.56 6.96 57 13.521199 4.7663999 1507383 1.56 7 33 4.8911719 0.98879999 1507384 1.56 7.04 89 22.59363 7.3856001 1507385 1.56 7.08 91 21.454315 6.7584 1507386 1.56 7.12 135 45.790794 22.7328 1507387 1.56 7.16 128 41.85854 20.1968 1507388 1.56 7.2 92 21.333698 6.5071998 1507389 1.56 7.24 87 21.345631 6.8000002 1507391 1.56 7.32 72 15.301398 3.9760001 1507392 1.56 7.36 71 13.714247 3.3792 1507393 1.56 7.4 71 13.088058 3.1487999 1507394 1.56 7.44 71 13.088058 3.1487999 1507395 1.56 7.48 72 14.058339 3.4976001 1507396 1.56 7.52 72 15.301398 3.9760001 1507398 1.56 7.6 69 14.38336 3.6847999 1507399 1.56 7.64 100 32.941559 16.7568 1507400 1.56 7.68 111 37.828407 19.6752 1507401 1.56 7.72 88 23.215038 9.2816 1507402 1.56 7.76 75 16.691599 4.5999999 1572869 1.6 5 106 33.540142 12.8672 1572870 1.6 5.04 107 30.979067 11.024 1572871 1.6 5.08 107 28.700459 9.6000004 1572872 1.6 5.12 107 26.962923 8.5248003 1572873 1.6 5.16 120 34.218254 13.8896 1572874 1.6 5.2 188 65.33342 31.360001 1572875 1.6 5.24 126 35.454872 15.08 1572876 1.6 5.28 111 28.607075 9.8479996 1572877 1.6 5.32 108 27.579021 8.8992004 1572878 1.6 5.36 107 28.906731 9.8079996 1572879 1.6 5.4 106 30.775557 11.08 1572880 1.6 5.44 105 33.095074 12.6864 1572891 1.6 5.88 92 23.914549 8.5551996 1572892 1.6 5.92 128 47.565628 28.489599 1572893 1.6 5.96 253 313.45911 674.4848 1572894 1.6 6 277 356.535 779.16479 1572895 1.6 6.04 102 29.904795 13.5808 1572896 1.6 6.08 80 18.453127 5.8000002 1572908 1.6 6.56 149 70.874908 50.177601 1572909 1.6 6.6 263 238.03102 367.18561 1572910 1.6 6.64 311 347.41339 684.33759 1572911 1.6 6.68 337 391.76797 775.95203 1572912 1.6 6.72 306 329.27002 629.23358 1572913 1.6 6.76 261 240.27705 382.0752 1572914 1.6 6.8 136 57.111465 34.755199 1572915 1.6 6.84 110 38.981159 18.876801 1572916 1.6 6.88 33 4.6216531 0.84640002 1572917 1.6 6.92 45 8.6902657 2.5616 1572918 1.6 6.96 58 13.140449 4.3056002 1572919 1.6 7 33 4.7784972 0.93120003 1572920 1.6 7.04 88 20.590557 6.1631999 1572921 1.6 7.08 90 19.80237 5.8304 1572922 1.6 7.12 132 44.50029 22.9568 1572923 1.6 7.16 126 40.586376 20.041599 1572924 1.6 7.2 93 20.631918 6.0528002 1572925 1.6 7.24 89 20.796692 6.2463999 1572927 1.6 7.32 74 14.837963 3.6256001 1572928 1.6 7.36 72 12.686926 2.7855999 1572929 1.6 7.4 71 11.717723 2.4576001 1572930 1.6 7.44 72 12.006167 2.5408001 1572931 1.6 7.48 73 13.112132 2.9663999 1572932 1.6 7.52 72 13.989435 3.2639999 1572934 1.6 7.6 72 14.727295 3.72 1572935 1.6 7.64 100 33.323078 17.944 1572936 1.6 7.68 107 36.607193 20.0128 1572937 1.6 7.72 93 27.004366 12.648 1572938 1.6 7.76 74 15.634545 4.1343999 1638405 1.64 5 104 30.228973 10.8096 1638406 1.64 5.04 104 27.305202 9.0383997 1638407 1.64 5.08 111 28.036549 9.1552 1638408 1.64 5.12 111 25.956234 7.8720002 1638409 1.64 5.16 132 36.346493 14.768 1638410 1.64 5.2 179 60.948643 29.4592 1638411 1.64 5.24 156 47.01733 20.636801 1638412 1.64 5.28 113 25.170645 7.4159999 1638413 1.64 5.32 110 25.870001 7.9439998 1638414 1.64 5.36 108 26.879467 8.6927996 1638415 1.64 5.4 106 28.628239 9.9055996 1638416 1.64 5.44 105 31.102196 11.4848 1638427 1.64 5.88 94 23.992495 8.4432001 1638428 1.64 5.92 125 43.138798 23.3424 1638429 1.64 5.96 253 307.89032 652.4176 1638430 1.64 6 278 352.75854 760.00641 1638431 1.64 6.04 104 29.407681 12.7568 1638432 1.64 6.08 81 18.045052 5.4768 1638444 1.64 6.56 144 57.998772 32.8368 1638445 1.64 6.6 266 227.04224 336.66241 1638446 1.64 6.64 314 341.94354 663.04962 1638447 1.64 6.68 333 380.26965 746.05762 1638448 1.64 6.72 307 322.71463 608.48962 1638449 1.64 6.76 273 236.95343 361.0416 1638450 1.64 6.8 133 50.103779 27.867201 1638451 1.64 6.84 104 31.712662 13.048 1638452 1.64 6.88 31 4.7147136 0.98879999 1638453 1.64 6.92 46 8.7453232 2.4096 1638454 1.64 6.96 59 12.948497 3.9807999 1638455 1.64 7 30 4.3493905 0.86720002 1638456 1.64 7.04 91 20.792582 6.0288 1638457 1.64 7.08 91 19.30509 5.4496002 1638458 1.64 7.12 131 44.178627 23.636801 1638459 1.64 7.16 125 39.764809 20.049601 1638460 1.64 7.2 93 19.760447 5.5423999 1638461 1.64 7.24 89 19.733002 5.5215998 1638463 1.64 7.32 73 13.555484 2.9935999 1638464 1.64 7.36 74 12.493398 2.5792 1638465 1.64 7.4 72 11.032143 2.0511999 1638466 1.64 7.44 73 11.423811 2.1984 1638467 1.64 7.48 72 11.758007 2.3072 1638468 1.64 7.52 75 14.467733 3.4159999 1638470 1.64 7.6 72 14.480923 3.6719999 1638471 1.64 7.64 97 32.189903 18.132799 1638472 1.64 7.68 105 36.462269 21.060801 1638473 1.64 7.72 95 29.151518 15.1136 1638474 1.64 7.76 76 15.959687 4.2495999 1703941 1.68 5 105 29.200998 10.1936 1703942 1.68 5.04 107 27.045214 8.8079996 1703943 1.68 5.08 109 25.14806 7.5455999 1703944 1.68 5.12 113 24.302929 6.8080001 1703945 1.68 5.16 153 46.73637 22.5776 1703946 1.68 5.2 174 57.118546 27.3424 1703947 1.68 5.24 160 49.564838 22.819201 1703948 1.68 5.28 114 23.127714 6.0447998 1703949 1.68 5.32 112 24.111921 6.7680001 1703950 1.68 5.36 108 25.181557 7.7375998 1703951 1.68 5.4 105 26.410864 8.5872002 1703952 1.68 5.44 102 27.662252 9.3168001 1703963 1.68 5.88 99 25.978851 9.4768 1703964 1.68 5.92 123 39.686211 19.396799 1703965 1.68 5.96 253 302.30261 630.64478 1703966 1.68 6 277 345.99835 734.73279 1703967 1.68 6.04 104 28.348246 11.6176 1703968 1.68 6.08 87 20.595198 6.816 1703980 1.68 6.56 142 52.088741 26.739201 1703981 1.68 6.6 272 220.76434 315.83359 1703982 1.68 6.64 319 339.36288 649.55042 1703983 1.68 6.68 332 371.40356 721.13599 1703984 1.68 6.72 310 321.1333 604.36481 1703985 1.68 6.76 273 226.19142 331.97281 1703986 1.68 6.8 131 44.717018 22.5264 1703987 1.68 6.84 101 27.331169 9.5696001 1703988 1.68 6.88 29 5.1940899 1.2464 1703989 1.68 6.92 38 6.1805968 1.3712 1703990 1.68 6.96 63 13.561599 3.9424 1703991 1.68 7 28 4.8462081 1.128 1703992 1.68 7.04 92 20.882935 6.0560002 1703993 1.68 7.08 96 20.797064 5.9583998 1703994 1.68 7.12 132 45.530884 25.5296 1703995 1.68 7.16 124 39.94175 21.1408 1703996 1.68 7.2 99 23.633528 8.4560003 1703997 1.68 7.24 90 19.842379 5.5408001 1703999 1.68 7.32 75 13.918261 3.0880001 1704000 1.68 7.36 74 12.024062 2.3408 1704001 1.68 7.4 75 11.386681 2.0527999 1704002 1.68 7.44 73 10.989633 1.9984 1704003 1.68 7.48 75 12.480132 2.5488 1704004 1.68 7.52 76 14.21991 3.1744001 1704006 1.68 7.6 76 17.451048 6.0079999 1704007 1.68 7.64 94 31.444889 18.5296 1704008 1.68 7.68 104 37.434654 22.972799 1704009 1.68 7.72 98 31.624578 17.375999 1704010 1.68 7.76 77 16.366362 4.5232 1769477 1.72 5 104 27.828571 9.3520002 1769478 1.72 5.04 107 26.115921 8.2687998 1769479 1.72 5.08 109 23.909519 6.8368001 1769480 1.72 5.12 115 23.969769 6.48 1769481 1.72 5.16 157 52.41098 30.694401 1769482 1.72 5.2 172 56.30455 27.428801 1769483 1.72 5.24 161 50.035015 23.524799 1769484 1.72 5.28 117 23.370098 6.0159998 1769485 1.72 5.32 111 22.800392 6.1040001 1769486 1.72 5.36 110 24.599094 7.2128 1769487 1.72 5.4 103 24.164181 7.2416 1769488 1.72 5.44 101 26.450563 8.6176004 1769499 1.72 5.88 99 26.225559 9.7440004 1769500 1.72 5.92 119 36.350471 16.476801 1769501 1.72 5.96 253 296.9805 609.47357 1769502 1.72 6 278 341.36322 712.56317 1769503 1.72 6.04 100 25.783735 9.8319998 1769504 1.72 6.08 89 21.901335 7.6575999 1769516 1.72 6.56 136 45.587566 21.0112 1769517 1.72 6.6 276 216.16621 300.0704 1769518 1.72 6.64 320 331.69208 625.56641 1769519 1.72 6.68 335 364.71262 695.82721 1769520 1.72 6.72 309 313.14508 582.6192 1769521 1.72 6.76 274 218.25392 310.328 1769522 1.72 6.8 130 41.241798 18.681601 1769523 1.72 6.84 96 24.043129 7.5888 1769524 1.72 6.88 32 6.4472461 1.7728 1769525 1.72 6.92 43 7.6804147 1.8559999 1769526 1.72 6.96 62 13.317303 3.8640001 1769527 1.72 7 32 6.3409433 1.704 1769528 1.72 7.04 99 23.866726 7.3807998 1769529 1.72 7.08 100 23.496498 8.1087999 1769530 1.72 7.12 134 46.609406 26.844801 1769531 1.72 7.16 126 41.599094 22.995199 1769532 1.72 7.2 102 26.495483 11.4896 1769533 1.72 7.24 90 19.942865 5.6431999 1769535 1.72 7.32 78 15.039348 3.5248001 1769536 1.72 7.36 78 13.208932 2.7456 1769537 1.72 7.4 78 12.398946 2.4128001 1769538 1.72 7.44 79 12.46011 2.3648 1769539 1.72 7.48 78 13.548032 2.9584 1769540 1.72 7.52 80 15.901108 3.9119999 1769542 1.72 7.6 80 21.251511 9.5472002 1769543 1.72 7.64 93 31.716228 19.288 1769544 1.72 7.68 106 39.049652 24.7792 1769545 1.72 7.72 102 34.570621 19.812799 1769546 1.72 7.76 80 18.046577 5.4335999 1835013 1.76 5 101 26.05162 8.3039999 1835014 1.76 5.04 107 25.628706 7.8592 1835015 1.76 5.08 111 24.651609 7.1184001 1835016 1.76 5.12 121 27.610903 9.0112 1835017 1.76 5.16 162 57.684177 37.942402 1835018 1.76 5.2 171 55.9403 27.5616 1835019 1.76 5.24 159 49.683365 23.7952 1835020 1.76 5.28 121 25.352613 7.0479999 1835021 1.76 5.32 114 23.753483 6.4015999 1835022 1.76 5.36 105 22.397604 6.1664 1835023 1.76 5.4 103 23.960836 7.0416002 1835024 1.76 5.44 100 25.66605 8.1183996 1835035 1.76 5.88 96 25.94153 10.0576 1835036 1.76 5.92 117 34.954933 15.296 1835037 1.76 5.96 253 291.51703 588.4624 1835038 1.76 6 281 339.24445 694.93439 1835039 1.76 6.04 98 25.734337 10.1456 1835040 1.76 6.08 91 23.990833 9.1087999 1835052 1.76 6.56 124 37.176418 14.7504 1835053 1.76 6.6 275 204.99234 273.18719 1835054 1.76 6.64 325 330.60281 615.20319 1835055 1.76 6.68 340 358.13306 670.29279 1835056 1.76 6.72 308 307.33923 568.32642 1835057 1.76 6.76 278 211.53795 287.45441 1835058 1.76 6.8 122 36.062725 15.272 1835059 1.76 6.84 91 21.8431 6.4784002 1835060 1.76 6.88 33 5.4359469 1.2496001 1835061 1.76 6.92 46 9.0090227 2.5552001 1835062 1.76 6.96 59 12.71044 3.8271999 1835063 1.76 7 35 5.8348846 1.3552001 1835064 1.76 7.04 97 23.469893 7.3104 1835065 1.76 7.08 108 28.393246 11.2704 1835066 1.76 7.12 141 50.746086 30.087999 1835067 1.76 7.16 132 44.860577 25.608 1835068 1.76 7.2 108 29.933138 13.9648 1835069 1.76 7.24 88 19.7896 5.7328 1835071 1.76 7.32 80 16.159086 3.9935999 1835072 1.76 7.36 85 15.91521 3.8144 1835073 1.76 7.4 88 15.695617 3.5072 1835074 1.76 7.44 90 16.425106 3.7872 1835075 1.76 7.48 85 15.936421 3.8080001 1835076 1.76 7.52 82 17.138847 4.4752002 1835078 1.76 7.6 82 24.284025 12.528 1835079 1.76 7.64 98 34.506317 21.625601 1835080 1.76 7.68 110 41.497154 26.8256 1835081 1.76 7.72 106 38.104664 22.912001 1835082 1.76 7.76 86 22.483219 8.5567999 1900549 1.8 5 100 26.4561 8.6496 1900550 1.8 5.04 102 23.898556 6.9679999 1900551 1.8 5.08 110 24.664074 6.9856 1900552 1.8 5.12 129 34.880669 14.5136 1900553 1.8 5.16 161 56.145508 34.743999 1900554 1.8 5.2 171 56.466873 28.131201 1900555 1.8 5.24 160 50.736176 24.6336 1900556 1.8 5.28 127 29.618959 9.6831999 1900557 1.8 5.32 110 22.760733 5.9359999 1900558 1.8 5.36 104 22.435322 6.0544 1900559 1.8 5.4 101 23.589909 6.8319998 1900560 1.8 5.44 99 25.783669 8.1775999 1900571 1.8 5.88 98 28.379307 11.672 1900572 1.8 5.92 110 31.884623 13.44 1900573 1.8 5.96 255 287.25287 568.5968 1900574 1.8 6 282 334.46167 672.2688 1900575 1.8 6.04 99 27.694965 11.672 1900576 1.8 6.08 90 25.715246 10.8512 1900588 1.8 6.56 111 31.011696 11.2704 1900589 1.8 6.6 277 199.17665 257.48639 1900590 1.8 6.64 327 325.68964 598.82562 1900591 1.8 6.68 344 355.06354 655.96802 1900592 1.8 6.72 313 301.82709 547.06079 1900593 1.8 6.76 276 203.60538 270.92801 1900594 1.8 6.8 112 32.74004 14.088 1900595 1.8 6.84 88 22.689419 7.4496002 1900596 1.8 6.88 35 5.268044 1.056 1900597 1.8 6.92 47 9.388896 2.8064001 1900598 1.8 6.96 58 12.74391 4.0496001 1900599 1.8 7 39 6.6145105 1.512 1900600 1.8 7.04 114 33.698605 13.3504 1900601 1.8 7.08 128 40.336849 18.996799 1900602 1.8 7.12 157 59.214581 35.335999 1900603 1.8 7.16 155 55.868698 32.0448 1900604 1.8 7.2 138 41.540627 19.5536 1900605 1.8 7.24 123 30.408176 9.7088003 1900606 1.8 7.28 65 14.382514 4.1360002 1900607 1.8 7.32 109 23.232391 6 1900608 1.8 7.36 107 21.784542 5.4144001 1900609 1.8 7.4 105 20.855827 5.1087999 1900610 1.8 7.44 105 20.937033 5.1728001 1900611 1.8 7.48 106 21.799471 5.5711999 1900612 1.8 7.52 109 23.548716 6.3392 1900613 1.8 7.56 59 13.16826 4.0128002 1900614 1.8 7.6 122 39.86166 20.7696 1900615 1.8 7.64 126 46.456577 27.948799 1900616 1.8 7.68 132 53.049545 34.032001 1900617 1.8 7.72 128 50.90974 31.184 1900618 1.8 7.76 109 36.358337 17.318399 1966085 1.84 5 99 26.850645 8.7040005 1966086 1.84 5.04 100 24.458662 7.2736001 1966087 1.84 5.08 108 26.779778 9.2159996 1966088 1.84 5.12 127 35.266022 14.5696 1966089 1.84 5.16 150 45.680565 21.374399 1966090 1.84 5.2 171 57.256329 28.7712 1966091 1.84 5.24 163 53.083187 26.041599 1966092 1.84 5.28 129 33.709217 12.8064 1966093 1.84 5.32 106 22.898537 6.1231999 1966094 1.84 5.36 102 22.927736 6.296 1966095 1.84 5.4 100 24.672245 7.4271998 1966096 1.84 5.44 99 27.050997 8.8559999 1966107 1.84 5.88 97 30.470633 13.5824 1966108 1.84 5.92 111 34.395092 15.3888 1966109 1.84 5.96 260 284.88397 550.59363 1966110 1.84 6 285 331.16534 651.99042 1966111 1.84 6.04 96 28.830515 12.9936 1966112 1.84 6.08 84 25.357422 11.24 1966124 1.84 6.56 94 27.003283 10.392 1966125 1.84 6.6 279 194.35161 242.76801 1966126 1.84 6.64 333 321.65436 579.19843 1966127 1.84 6.68 350 350.92413 635.12958 1966128 1.84 6.72 317 299.18933 534.95038 1966129 1.84 6.76 274 194.16458 248.25121 1966130 1.84 6.8 93 28.727888 13.7808 1966132 1.84 6.88 38 6.2843246 1.4016 1966133 1.84 6.92 47 9.7038107 3.0752001 1966134 1.84 6.96 58 13.296454 4.5167999 1966135 1.84 7 40 6.6949558 1.4848 1966136 1.84 7.04 107 32.256802 12.96 1966137 1.84 7.08 125 42.16502 21.742399 1966138 1.84 7.12 155 60.218964 36.9664 1966139 1.84 7.16 154 57.981598 34.787201 1966140 1.84 7.2 135 43.48848 22.1168 1966141 1.84 7.24 125 33.053497 11.2848 1966142 1.84 7.28 107 25.425043 7.2031999 1966143 1.84 7.32 110 24.544771 6.5872002 1966144 1.84 7.36 102 21.595726 5.6064 1966145 1.84 7.4 101 20.972654 5.3983998 1966146 1.84 7.44 101 21.091574 5.4896002 1966147 1.84 7.48 102 21.915285 5.8559999 1966148 1.84 7.52 107 23.942425 6.5696001 1966149 1.84 7.56 103 25.240126 7.9456 1966150 1.84 7.6 120 41.738804 23.448 1966151 1.84 7.64 122 47.411034 29.937599 1966152 1.84 7.68 127 53.163315 35.3088 1966153 1.84 7.72 127 54.339512 35.659199 1966154 1.84 7.76 109 40.036774 21.5072 2031621 1.88 5 98 28.47743 9.6543999 2031622 1.88 5.04 100 26.474697 8.2959995 2031623 1.88 5.08 105 28.455574 10.5104 2031624 1.88 5.12 121 37.4762 17.430401 2031625 1.88 5.16 148 48.271687 23.496 2031626 1.88 5.2 178 60.292068 30.108801 2031627 1.88 5.24 161 52.860703 25.995199 2031628 1.88 5.28 122 35.239731 15.0976 2031629 1.88 5.32 106 26.174126 8.1744003 2031630 1.88 5.36 100 24.396278 7.0799999 2031631 1.88 5.4 100 26.684328 8.4560003 2031632 1.88 5.44 100 29.367298 10.0928 2031643 1.88 5.88 85 28.823233 13.672 2031644 1.88 5.92 105 36.08765 17.7216 2031645 1.88 5.96 271 284.88239 534.18402 2031646 1.88 6 291 331.03284 636.43518 2031647 1.88 6.04 89 30.737764 15.7184 2031648 1.88 6.08 81 27.145617 12.8144 2031661 1.88 6.6 276 184.20358 215.608 2031662 1.88 6.64 336 317.6022 563.86078 2031663 1.88 6.68 353 344.26614 611.34082 2031664 1.88 6.72 320 295.76074 521.44159 2031665 1.88 6.76 262 185.78323 230.26559 2031668 1.88 6.88 36 6.1236434 1.4112 2031669 1.88 6.92 46 9.9162254 3.3504 2031670 1.88 6.96 56 13.305697 4.8207998 2031671 1.88 7 46 10.687746 3.8432 2031672 1.88 7.04 96 28.237085 10.6816 2031673 1.88 7.08 109 37.478687 20.3696 2031674 1.88 7.12 144 56.910702 36.84 2031675 1.88 7.16 139 54.334923 34.9184 2031676 1.88 7.2 116 39.979095 22.5968 2031677 1.88 7.24 85 23.883541 9.0240002 2031679 1.88 7.32 82 20.204309 6.0511999 2031680 1.88 7.36 96 22.505251 6.4847999 2031681 1.88 7.4 96 22.107399 6.3248 2031682 1.88 7.44 95 21.712606 6.1855998 2031683 1.88 7.48 93 22.221878 6.5823998 2031684 1.88 7.52 83 21.09626 6.5247998 2031686 1.88 7.6 94 37.365715 24.559999 2031687 1.88 7.64 102 42.217468 29.1472 2031688 1.88 7.68 109 48.096294 34.571201 2031689 1.88 7.72 112 50.42522 35.9776 2031690 1.88 7.76 96 35.598904 20.099199 2097162 1.92 5.2 201 67.989166 33.211201 2097181 1.92 5.96 281 284.27429 518.04163 2097182 1.92 6 289 327.13849 616.2384 2097197 1.92 6.6 278 173.26363 188.62241 2097198 1.92 6.64 338 311.96161 543.48322 2097199 1.92 6.68 357 340.14005 592.12799 2097200 1.92 6.72 327 292.79022 504.04639 2097201 1.92 6.76 270 177.71747 208.10561 2097204 1.92 6.88 33 6.2336969 1.6016001 2097205 1.92 6.92 48 11.146693 3.9647999 2097206 1.92 6.96 59 15.541656 6.2416 2097207 1.92 7 33 6.6905565 1.832 2097208 1.92 7.04 91 28.672241 11.3232 2097209 1.92 7.08 101 37.928616 21.792 2097210 1.92 7.12 140 58.013214 38.756802 2097211 1.92 7.16 137 56.931339 38.3344 2097212 1.92 7.2 101 41.643024 27.3216 2097213 1.92 7.24 85 28.036398 12.4784 2097215 1.92 7.32 80 21.99575 7.1968002 2097216 1.92 7.36 79 20.201742 6.3456001 2097217 1.92 7.4 86 21.884943 6.8576002 2097218 1.92 7.44 88 22.62866 7.1616001 2097219 1.92 7.48 82 21.420656 6.8927999 2097220 1.92 7.52 82 23.021715 7.7231998 2097222 1.92 7.6 86 37.489185 25.532801 2097223 1.92 7.64 98 44.414448 32.102402 2097224 1.92 7.68 104 49.48093 36.644798 2097225 1.92 7.72 109 53.157696 39.5536 2097226 1.92 7.76 95 39.239952 24.120001 2162693 1.96 5 110 39.920303 18.7248 2162694 1.96 5.04 111 36.994022 16.257601 2162695 1.96 5.08 113 35.361492 14.792 2162696 1.96 5.12 133 50.736244 30.208 2162697 1.96 5.16 148 62.688541 44.700802 2162698 1.96 5.2 205 72.598892 37.3344 2162699 1.96 5.24 141 36.297443 11.68 2162700 1.96 5.28 107 26.263237 8.1104002 2162701 1.96 5.32 102 25.007254 7.7136002 2162702 1.96 5.36 102 26.610947 8.7728004 2162703 1.96 5.4 96 26.51631 9.2256002 2162704 1.96 5.44 91 27.06925 9.7840004 2162705 1.96 5.48 72 18.980307 6.2736001 2162706 1.96 5.52 75 18.038202 5.5664001 2162707 1.96 5.56 75 16.364847 4.5696001 2162708 1.96 5.6 80 16.92267 4.4784002 2162709 1.96 5.64 81 17.221333 4.6128001 2162710 1.96 5.68 85 19.726995 5.9632001 2162711 1.96 5.72 81 20.35327 6.9903998 2162712 1.96 5.76 80 22.439497 8.8495998 2162713 1.96 5.8 83 26.678169 11.7392 2162716 1.96 5.92 97 32.592308 16.1392 2162717 1.96 5.96 280 281.72928 502.0784 2162718 1.96 6 296 324.54831 597.87842 2162719 1.96 6.04 74 21.185783 8.3056002 2162722 1.96 6.16 77 22.41048 8.6303997 2162723 1.96 6.2 77 20.162447 7.1184001 2162724 1.96 6.24 82 19.800385 6.3792 2162725 1.96 6.28 83 19.184225 5.8592 2162726 1.96 6.32 81 17.617865 4.9424 2162727 1.96 6.36 85 20.31863 6.5472002 2162728 1.96 6.4 83 21.311005 7.4768 2162729 1.96 6.44 72 17.018276 5.1343999 2162730 1.96 6.48 72 18.980307 6.2736001 2162732 1.96 6.56 184 100.2803 85.260803 2162733 1.96 6.6 278 163.8279 164.92 2162734 1.96 6.64 339 308.28836 529.08643 2162735 1.96 6.68 364 336.99185 571.76959 2162736 1.96 6.72 332 292.57672 493.8576 2162737 1.96 6.76 276 166.83261 176.8688 2162738 1.96 6.8 173 92.199066 76.5728 2162739 1.96 6.84 118 41.931713 18.867201 2162742 1.96 6.96 71 20.761024 8.8048 2162746 1.96 7.12 113 54.289612 40.416 2162747 1.96 7.16 134 59.605541 41.964802 2228229 2 5 111 40.659767 20.854401 2228230 2 5.04 114 37.4846 17.153601 2228231 2 5.08 114 34.044781 14.3616 2228232 2 5.12 139 48.850243 27.027201 2228233 2 5.16 171 64.671761 40.131199 2228234 2 5.2 198 76.011169 45.454399 2228235 2 5.24 162 47.443104 19.728001 2228236 2 5.28 125 30.794863 9.8448 2228237 2 5.32 114 27.402746 8.4848003 2228238 2 5.36 104 25.143894 7.8800001 2228239 2 5.4 97 23.653833 7.3200002 2228240 2 5.44 90 24.419842 8.2016001 2228241 2 5.48 76 20.466681 7.7872 2228242 2 5.52 79 17.924244 5.4527998 2228243 2 5.56 85 17.818701 4.9376001 2228244 2 5.6 92 19.968998 5.7616 2228245 2 5.64 94 21.843006 7.1696 2228246 2 5.68 98 24.54838 8.8752003 2228247 2 5.72 98 26.629082 10.6064 2228248 2 5.76 94 28.408993 12.5392 2228249 2 5.8 89 29.495028 14.0352 2228251 2 5.88 87 25.399734 9.8895998 2228252 2 5.92 119 37.875122 16.2992 2228253 2 5.96 293 284.00552 488.728 2228254 2 6 310 327.03973 584.3584 2228255 2 6.04 96 26.366732 9.8095999 2228256 2 6.08 73 20.246466 7.6384001 2228258 2 6.16 79 22.093275 8.4960003 2228259 2 6.2 89 23.173359 8.4560003 2228260 2 6.24 90 21.391472 7.1343999 2228261 2 6.28 91 20.484171 6.3856001 2228262 2 6.32 90 19.628683 5.8671999 2228263 2 6.36 89 19.283873 5.6208 2228264 2 6.4 90 20.785023 6.4671998 2228265 2 6.44 89 23.490685 8.448 2228266 2 6.48 76 20.575188 7.8895998 2228268 2 6.56 194 92.469322 68.771202 2228269 2 6.6 285 159.87183 150.69279 2228270 2 6.64 352 309.03357 514.0752 2228271 2 6.68 374 334.96548 552.47998 2228272 2 6.72 340 294.10104 485.59039 2228273 2 6.76 282 161.97426 159.77119 2228274 2 6.8 190 87.811859 64.727997 2228275 2 6.84 121 39.456356 16.4928 2228276 2 6.88 29 4.8961244 1.08 2228277 2 6.92 60 16.335417 6.3903999 2228278 2 6.96 79 23.211899 9.8224001 2228279 2 7 36 8.0005789 2.4288001 2228280 2 7.04 29 4.2823467 0.72799999 2228281 2 7.08 32 4.0847077 0.60479999 2228282 2 7.12 123 57.08083 43.734402 2228283 2 7.16 127 59.629173 44.944 2228284 2 7.2 37 5.8038549 1.168 2228285 2 7.24 40 8.8077078 2.7679999 2293765 2.04 5 134 74.655685 71.681602 2293766 2.04 5.04 139 69.089783 60.136002 2293767 2.04 5.08 142 64.216743 52.302399 2293768 2.04 5.12 159 66.225967 48.369598 2293769 2.04 5.16 194 85.424156 62.827202 2293770 2.04 5.2 220 103.32905 77.975998 2293771 2.04 5.24 184 70.973579 45.414398 2293772 2.04 5.28 153 46.023476 21.382401 2293773 2.04 5.32 136 36.30093 13.4336 2293774 2.04 5.36 125 32.022083 10.88 2293775 2.04 5.4 114 27.555025 8.2992001 2293776 2.04 5.44 98 24.019798 7.4288001 2293777 2.04 5.48 102 42.813881 30.8064 2293778 2.04 5.52 129 46.813576 28.628799 2293779 2.04 5.56 133 46.413982 26.535999 2293780 2.04 5.6 131 44.488884 24.216 2293781 2.04 5.64 131 43.646503 23.0144 2293782 2.04 5.68 123 37.386662 16.704 2293783 2.04 5.72 117 34.943401 15.5056 2293784 2.04 5.76 111 32.838509 14.536 2293785 2.04 5.8 93 30.814243 15.0208 2293787 2.04 5.88 121 42.077148 21.5504 2293788 2.04 5.92 160 57.061874 27.7456 2293789 2.04 5.96 329 302.06073 487.82721 2293790 2.04 6 350 345.94989 581.54718 2293791 2.04 6.04 139 48.130466 23.728001 2293792 2.04 6.08 113 39.215134 20.8272 2293794 2.04 6.16 102 35.857304 20.247999 2293795 2.04 6.2 110 35.003597 18.3696 2293796 2.04 6.24 115 35.517448 17.3808 2293797 2.04 6.28 117 35.62397 17.087999 2293798 2.04 6.32 128 44.468655 26.120001 2293799 2.04 6.36 127 46.050823 29.1616 2293800 2.04 6.4 126 46.283455 30.118401 2293801 2.04 6.44 129 50.70475 35.134399 2293802 2.04 6.48 104 49.171303 39.9744 2293804 2.04 6.56 213 87.989754 54.347198 2293805 2.04 6.6 309 164.61203 144.55521 2293806 2.04 6.64 383 323.78207 517.52802 2293807 2.04 6.68 400 346.32837 545.57599 2293808 2.04 6.72 370 310.27881 486.88321 2293809 2.04 6.76 314 181.96284 172.576 2293810 2.04 6.8 216 104.75198 83.0784 2293811 2.04 6.84 154 70.988571 55.849602 2293812 2.04 6.88 54 13.969804 4.9439998 2293813 2.04 6.92 84 22.507929 8.5087996 2293814 2.04 6.96 96 29.211536 12.7632 2293815 2.04 7 56 16.001844 7.0864 2293816 2.04 7.04 30 3.9217474 0.60479999 2293817 2.04 7.08 49 7.6117167 1.6447999 2293818 2.04 7.12 132 64.113037 49.916801 2293819 2.04 7.16 139 70.363998 54.5952 2293820 2.04 7.2 66 20.17219 10.7664 2293821 2.04 7.24 61 24.034628 16.339199 2359301 2.08 5 140 89.178246 106.8192 2359302 2.08 5.04 144 86.597389 101.264 2359303 2.08 5.08 161 89.297523 98.152 2359304 2.08 5.12 173 89.888542 93.968002 2359305 2.08 5.16 204 106.62606 105.088 2359306 2.08 5.2 245 141.67859 137.91521 2359307 2.08 5.24 211 109.78284 103.9632 2359308 2.08 5.28 180 83.301079 77.574402 2359309 2.08 5.32 175 81.785873 74.950401 2359310 2.08 5.36 171 79.140343 71.134399 2359311 2.08 5.4 174 79.907494 68.912003 2359312 2.08 5.44 181 80.494835 66.014397 2359313 2.08 5.48 187 80.558868 63.6768 2359314 2.08 5.52 177 79.014824 61.700802 2359315 2.08 5.56 169 76.21579 59.169601 2359316 2.08 5.6 161 71.684547 55.220798 2359317 2.08 5.64 157 70.12706 53.764801 2359318 2.08 5.68 154 68.081177 51.091202 2359319 2.08 5.72 154 68.053848 49.939201 2359320 2.08 5.76 159 69.41954 49.264 2359321 2.08 5.8 168 71.818077 48.737598 2359322 2.08 5.84 177 76.555298 49.9888 2359323 2.08 5.88 181 79.60157 51.374401 2359324 2.08 5.92 206 91.585045 57.318401 2359325 2.08 5.96 360 326.33109 499.02719 2359326 2.08 6 385 371.35223 590.36798 2359327 2.08 6.04 185 82.286728 52.484798 2359328 2.08 6.08 174 76.432861 49.287998 2359329 2.08 6.12 178 75.893166 48.923199 2359330 2.08 6.16 166 72.165901 48.472 2359331 2.08 6.2 159 69.575966 48.0928 2359332 2.08 6.24 152 66.923538 47.655998 2359333 2.08 6.28 149 65.81337 48.497601 2359334 2.08 6.32 149 65.67643 49.1856 2359335 2.08 6.36 149 65.871277 49.911999 2359336 2.08 6.4 150 66.308228 50.526402 2359337 2.08 6.44 157 68.673302 51.934399 2359338 2.08 6.48 171 73.634361 55.358398 2359339 2.08 6.52 236 100.42136 67.2192 2359340 2.08 6.56 256 114.98533 79.512001 2359341 2.08 6.6 350 194.10223 161.6288 2359342 2.08 6.64 421 359.96951 550.40637 2359343 2.08 6.68 425 370.25702 564.79199 2359344 2.08 6.72 397 337.42932 513.79041 2359345 2.08 6.76 326 186.69667 170.65601 2359346 2.08 6.8 222 98.901466 75.222397 2359347 2.08 6.84 189 84.594917 68.835197 2359348 2.08 6.88 137 68.860207 65.795197 2359349 2.08 6.92 138 75.5821 73.990402 2359350 2.08 6.96 146 82.2967 81.288002 2359351 2.08 7 121 69.863831 76.846397 2359352 2.08 7.04 117 69.892143 80.582397 2359353 2.08 7.08 114 71.953468 85.310402 2359354 2.08 7.12 184 128.3018 140.29601 2359355 2.08 7.16 179 129.79042 145.48959 2359356 2.08 7.2 112 79.37368 100.7408 2359357 2.08 7.24 100 77.669327 103.9776 2424837 2.12 5 133 71.801277 66.491203 2424838 2.12 5.04 139 69.060364 60.056 2424839 2.12 5.08 148 66.837822 52.688 2424840 2.12 5.12 157 64.488396 46.585602 2424841 2.12 5.16 192 82.185387 58.142399 2424842 2.12 5.2 232 115.39113 90.076797 2424843 2.12 5.24 187 76.510239 52.112 2424844 2.12 5.28 152 45.777275 21.316799 2424845 2.12 5.32 138 37.462227 14.0768 2424846 2.12 5.36 124 31.479498 10.52 2424847 2.12 5.4 114 27.555025 8.2992001 2424848 2.12 5.44 98 24.019798 7.4288001 2424849 2.12 5.48 102 41.739704 29.3808 2424850 2.12 5.52 128 45.991562 27.854401 2424851 2.12 5.56 132 45.855312 26.052799 2424852 2.12 5.6 130 43.537373 23.489599 2424853 2.12 5.64 128 41.241177 20.844801 2424854 2.12 5.68 123 37.209629 16.5648 2424855 2.12 5.72 116 34.29842 15.0896 2424856 2.12 5.76 111 32.838509 14.536 2424857 2.12 5.8 93 30.814243 15.0208 2424859 2.12 5.88 122 42.213745 21.2528 2424860 2.12 5.92 159 57.539261 28.8064 2424861 2.12 5.96 327 293.11151 457.0528 2424862 2.12 6 350 338.32288 548.6944 2424863 2.12 6.04 134 46.746914 23.396799 2424864 2.12 6.08 114 40.609035 22.1024 2424866 2.12 6.16 105 36.963699 20.662399 2424867 2.12 6.2 110 34.535542 17.614401 2424868 2.12 6.24 113 33.954453 16.1408 2424869 2.12 6.28 117 34.976231 16.2416 2424870 2.12 6.32 125 41.704193 23.164801 2424871 2.12 6.36 127 45.438385 28.4496 2424872 2.12 6.4 125 45.362587 29.270399 2424873 2.12 6.44 127 49.167938 33.7584 2424874 2.12 6.48 102 46.729992 36.993599 2424876 2.12 6.56 197 69.768814 32.8368 2424877 2.12 6.6 306 149.74509 106.4064 2424878 2.12 6.64 388 320.78146 491.95999 2424879 2.12 6.68 401 338.81396 513.0816 2424880 2.12 6.72 373 306.29239 462.29599 2424881 2.12 6.76 304 157.34274 121.9168 2424882 2.12 6.8 195 84.032906 60.529598 2424883 2.12 6.84 158 73.568115 58.4352 2424884 2.12 6.88 60 16.015747 5.6336002 2424885 2.12 6.92 83 24.141743 10.1424 2424886 2.12 6.96 93 30.897537 14.8256 2424887 2.12 7 64 18.660824 7.9664001 2424888 2.12 7.04 35 5.6108823 1.1776 2424889 2.12 7.08 55 11.071246 3.3584001 2424890 2.12 7.12 127 68.909927 58.487999 2424891 2.12 7.16 129 71.71521 60.903999 2424892 2.12 7.2 77 26.489727 14.0592 2424893 2.12 7.24 68 25.926464 16.681601 2490373 2.16 5 110 39.382359 19.433599 2490374 2.16 5.04 116 39.060928 18.416 2490375 2.16 5.08 118 36.635838 16.056 2490376 2.16 5.12 125 36.000813 14.1776 2490377 2.16 5.16 160 52.733555 26.3696 2490378 2.16 5.2 215 94.393799 64.8592 2490379 2.16 5.24 174 63.712208 38.5504 2490380 2.16 5.28 127 32.327065 10.864 2490381 2.16 5.32 117 29.393942 9.7279997 2490382 2.16 5.36 105 25.809628 8.3232002 2490383 2.16 5.4 99 24.648048 7.8175998 2490384 2.16 5.44 89 24.29335 8.1856003 2490385 2.16 5.48 76 20.466681 7.7872 2490386 2.16 5.52 79 17.924244 5.4527998 2490387 2.16 5.56 86 18.484432 5.3807998 2490388 2.16 5.6 90 19.322777 5.5296001 2490389 2.16 5.64 94 21.843006 7.1696 2490390 2.16 5.68 96 23.902161 8.6431999 2490391 2.16 5.72 96 25.722212 10.1936 2490392 2.16 5.76 96 28.999216 12.6304 2490393 2.16 5.8 89 29.495028 14.0352 2490395 2.16 5.88 84 25.890617 10.8112 2490396 2.16 5.92 118 39.995693 19.212799 2490397 2.16 5.96 293 268.75092 429.12799 2490398 2.16 6 310 311.20053 516.39038 2490399 2.16 6.04 93 27.482956 11.2416 2490400 2.16 6.08 75 21.836847 8.5872002 2490402 2.16 6.16 79 22.093275 8.4960003 2490403 2.16 6.2 92 24.449011 9.0047998 2490404 2.16 6.24 91 21.816679 7.3151999 2490405 2.16 6.28 91 20.484171 6.3856001 2490406 2.16 6.32 89 19.084623 5.5711999 2490407 2.16 6.36 90 19.677826 5.776 2490408 2.16 6.4 90 20.810917 6.4944 2490409 2.16 6.44 88 22.952539 8.1583996 2490410 2.16 6.48 75 20.049068 7.6128001 2490412 2.16 6.56 168 61.781628 31.1408 2490413 2.16 6.6 279 136.63336 96.6576 2490414 2.16 6.64 361 306.23697 473.97281 2490415 2.16 6.68 379 321.98416 488.336 2490416 2.16 6.72 352 293.013 447.84799 2490417 2.16 6.76 273 133.3428 94.924797 2490418 2.16 6.8 161 56.290684 26.6432 2490419 2.16 6.84 126 41.77129 17.6528 2490420 2.16 6.88 36 7.4910388 2.0192001 2490421 2.16 6.92 62 21.87215 11.1136 2490422 2.16 6.96 76 28.231615 14.9424 2490423 2.16 7 46 11.753185 3.8527999 2490424 2.16 7.04 37 7.2004895 1.8448 2490425 2.16 7.08 53 13.739306 5.3007998 2490426 2.16 7.12 113 66.988457 60.980801 2490427 2.16 7.16 109 65.056038 59.8368 2490428 2.16 7.2 61 17.38118 7.1631999 2490429 2.16 7.24 47 10.978067 3.4175999 2555909 2.2 5 113 42.029846 20.236799 2555910 2.2 5.04 113 38.414845 17.2672 2555911 2.2 5.08 116 37.204807 15.944 2555912 2.2 5.12 118 35.474571 14.232 2555913 2.2 5.16 134 48.33107 27.260799 2555914 2.2 5.2 218 93.742989 62.9744 2555915 2.2 5.24 165 62.776459 39.903999 2555916 2.2 5.28 111 28.723185 9.6239996 2555917 2.2 5.32 104 26.315592 8.5696001 2555918 2.2 5.36 105 28.512197 9.9968004 2555919 2.2 5.4 98 27.693491 9.9535999 2555920 2.2 5.44 92 27.720402 10.208 2555921 2.2 5.48 72 18.980307 6.2736001 2555922 2.2 5.52 75 18.038202 5.5664001 2555923 2.2 5.56 75 16.364847 4.5696001 2555924 2.2 5.6 79 16.578577 4.3600001 2555925 2.2 5.64 81 17.221333 4.6128001 2555926 2.2 5.68 82 18.363094 5.3232002 2555927 2.2 5.72 84 21.715763 7.6304002 2555928 2.2 5.76 79 21.642504 8.2144003 2555929 2.2 5.8 82 25.930908 11.1808 2555932 2.2 5.92 94 37.022778 21.4576 2555933 2.2 5.96 280 260.80179 418.40161 2555934 2.2 6 297 302.47021 498.55679 2555935 2.2 6.04 77 24.45722 10.6784 2555938 2.2 6.16 77 22.41048 8.6303997 2555939 2.2 6.2 77 20.162447 7.1184001 2555940 2.2 6.24 85 21.245399 7.0816002 2555941 2.2 6.28 83 19.184225 5.8592 2555942 2.2 6.32 81 17.617865 4.9424 2555943 2.2 6.36 84 20.014 6.4544001 2555944 2.2 6.4 83 21.311005 7.4768 2555945 2.2 6.44 72 17.018276 5.1343999 2555946 2.2 6.48 72 18.980307 6.2736001 2555948 2.2 6.56 146 59.417389 34.028801 2555949 2.2 6.6 265 128.44019 88.660797 2555950 2.2 6.64 355 301.33881 459.28961 2555951 2.2 6.68 375 321.34589 482.1232 2555952 2.2 6.72 347 289.32343 436.65759 2555953 2.2 6.76 267 130.33327 91.145599 2555954 2.2 6.8 143 54.44194 28.1968 2555955 2.2 6.84 119 42.222919 18.952 2621450 2.24 5.2 202 84.652992 57.161598 2621467 2.24 5.88 78 25.895033 12.512 2621468 2.24 5.92 119 84.370705 110.9232 2621469 2.24 5.96 276 257.06857 409.7616 2621470 2.24 6 294 297.31488 483.71841 2621471 2.24 6.04 80 27.622271 14.904 2621472 2.24 6.08 72 22.196745 10.0976 2621485 2.24 6.6 262 127.48661 86.440002 2621486 2.24 6.64 354 295.53598 434.9184 2621487 2.24 6.68 372 316.90759 466.7088 2621488 2.24 6.72 349 287.5694 424.39359 2621489 2.24 6.76 247 123.65753 85.820801 2686981 2.28 5 84 23.211514 7.5952001 2686982 2.28 5.04 86 21.663166 6.5440001 2686983 2.28 5.08 86 19.688118 5.4095998 2686984 2.28 5.12 87 18.261698 4.5616002 2686985 2.28 5.16 111 26.696648 9.0207996 2686986 2.28 5.2 182 77.99823 55.9296 2686987 2.28 5.24 157 57.453087 34.0144 2686988 2.28 5.28 175 99.033318 89.540802 2686989 2.28 5.32 171 98.229385 89.463997 2686990 2.28 5.36 139 61.185558 41.478401 2686991 2.28 5.4 112 40.286095 21.372801 2686992 2.28 5.44 94 28.659739 11.0352 2687003 2.28 5.88 79 23.500954 10.7184 2687004 2.28 5.92 126 66.872566 71.289597 2687005 2.28 5.96 263 251.60129 400.74399 2687006 2.28 6 289 291.47525 467.99841 2687007 2.28 6.04 86 26.192947 12.9488 2687008 2.28 6.08 70 17.86659 6.664 2687021 2.28 6.6 255 124.92155 84.081596 2687022 2.28 6.64 347 278.71524 384.66559 2687023 2.28 6.68 373 315.67099 454.37601 2687024 2.28 6.72 348 288.46765 417.8432 2687025 2.28 6.76 239 120.48944 82.9776 2752517 2.32 5 85 22.023762 6.9488001 2752518 2.32 5.04 85 19.515556 5.5664001 2752519 2.32 5.08 88 18.479792 4.8112001 2752520 2.32 5.12 97 19.965464 5.112 2752521 2.32 5.16 108 21.574352 5.224 2752522 2.32 5.2 167 71.883057 54.649601 2752523 2.32 5.24 164 63.913261 41.419201 2752524 2.32 5.28 188 99.227203 85.456001 2752525 2.32 5.32 175 95.433533 84.222397 2752526 2.32 5.36 138 56.511669 36.529598 2752527 2.32 5.4 108 33.706818 15.3984 2752528 2.32 5.44 93 25.81868 9.1359997 2752539 2.32 5.88 86 23.378195 9.4608002 2752540 2.32 5.92 118 50.599609 43.639999 2752541 2.32 5.96 258 250.10574 397.39999 2752542 2.32 6 286 286.75342 453.58401 2752543 2.32 6.04 90 25.158506 11.6272 2752544 2.32 6.08 74 16.805161 5.2463999 2752546 2.32 6.16 102 31.047518 11.5488 2752547 2.32 6.2 105 31.124329 11.8848 2752548 2.32 6.24 112 34.870495 15.0704 2752549 2.32 6.28 120 40.177811 19.5312 2752550 2.32 6.32 136 54.215992 32.528 2752551 2.32 6.36 140 57.908974 35.528 2752552 2.32 6.4 142 60.458412 37.2752 2752553 2.32 6.44 134 55.885948 33.366402 2752554 2.32 6.48 118 43.341579 20.8992 2752556 2.32 6.56 119 45.353798 24.9888 2752557 2.32 6.6 255 124.69859 83.939201 2752558 2.32 6.64 345 267.16428 347.77121 2752559 2.32 6.68 370 312.37186 440.31201 2752560 2.32 6.72 348 289.70126 411.25601 2752561 2.32 6.76 250 122.13171 82.950401 2752562 2.32 6.8 117 45.499245 26.7264 2818053 2.36 5 85 21.170202 6.5359998 2818054 2.36 5.04 88 19.809267 5.6896 2818055 2.36 5.08 94 20.11404 5.6160002 2818056 2.36 5.12 98 19.376902 4.8927999 2818057 2.36 5.16 108 21.485765 5.5999999 2818058 2.36 5.2 159 68.333122 54.387199 2818059 2.36 5.24 165 66.732353 45.876801 2818060 2.36 5.28 194 98.245445 81.496002 2818061 2.36 5.32 184 96.21595 81.136002 2818062 2.36 5.36 141 54.049385 32.819199 2818063 2.36 5.4 101 27.076134 10.424 2818064 2.36 5.44 88 21.92823 6.7184 2818075 2.36 5.88 84 20.133968 7.0847998 2818076 2.36 5.92 114 39.15403 23.112 2818077 2.36 5.96 255 246.96518 389.15839 2818078 2.36 6 282 280.18747 437.34079 2818079 2.36 6.04 91 24.42363 10.9664 2818080 2.36 6.08 72 14.299877 3.5632 2818082 2.36 6.16 100 27.15284 9.0095997 2818083 2.36 6.2 105 28.232088 10.0448 2818084 2.36 6.24 111 30.729425 12.0864 2818085 2.36 6.28 120 36.371861 16.576 2818086 2.36 6.32 136 49.887554 28.6768 2818087 2.36 6.36 140 53.443562 31.408001 2818088 2.36 6.4 143 56.591671 33.396801 2818089 2.36 6.44 134 51.857227 29.604799 2818090 2.36 6.48 115 37.895733 16.5952 2818092 2.36 6.56 131 44.555428 20.968 2818093 2.36 6.6 252 121.90993 80.806396 2818094 2.36 6.64 339 257.42096 321.53601 2818095 2.36 6.68 371 312.40714 430.72479 2818096 2.36 6.72 345 286.63297 398.95679 2818097 2.36 6.76 247 119.73451 80.523201 2818098 2.36 6.8 124 40.670734 19.5536 2818099 2.36 6.84 101 30.889687 12.8016 2883589 2.4 5 87 21.76808 6.8192 2883590 2.4 5.04 92 21.417067 6.5056 2883591 2.4 5.08 95 20.425541 5.8512001 2883592 2.4 5.12 98 19.338196 4.9871998 2883593 2.4 5.16 110 23.548876 7.2672 2883594 2.4 5.2 149 63.79744 53.396801 2883595 2.4 5.24 166 72.14373 55.459202 2883596 2.4 5.28 196 96.457588 77.075203 2883597 2.4 5.32 192 96.139763 77.020798 2883598 2.4 5.36 138 49.180237 27.649599 2883599 2.4 5.4 99 24.355532 8.1968002 2883600 2.4 5.44 89 22.076612 6.8239999 2883601 2.4 5.48 99 28.338076 9.3936005 2883602 2.4 5.52 99 26.283968 8.2575998 2883603 2.4 5.56 98 24.314575 7.2336001 2883604 2.4 5.6 98 23.407227 6.7584 2883605 2.4 5.64 99 24.140123 7.6767998 2883606 2.4 5.68 106 29.500341 11.568 2883607 2.4 5.72 107 31.035128 12.4 2883608 2.4 5.76 111 36.073177 16.4576 2883609 2.4 5.8 117 43.332603 22.2864 2883611 2.4 5.88 81 17.579962 5.1231999 2883612 2.4 5.92 116 38.129456 19.742399 2883613 2.4 5.96 254 246.81224 385.8176 2883614 2.4 6 281 277.85074 426.63199 2883615 2.4 6.04 88 21.146307 8.0847998 2883616 2.4 6.08 73 13.954205 3.2576001 2883618 2.4 6.16 98 23.925661 7.0640001 2883619 2.4 6.2 103 24.620855 7.7663999 2883620 2.4 6.24 108 26.172426 9.0640001 2883621 2.4 6.28 118 31.93001 13.32 2883622 2.4 6.32 136 46.120518 25.264 2883623 2.4 6.36 141 50.217499 28.203199 2883624 2.4 6.4 143 52.627251 29.5632 2883625 2.4 6.44 135 48.889046 26.559999 2883626 2.4 6.48 112 33.37841 13.2912 2883628 2.4 6.56 140 46.455849 20.4496 2883629 2.4 6.6 250 122.30885 81.734398 2883630 2.4 6.64 333 246.16293 295.42719 2883631 2.4 6.68 376 315.11633 423.06079 2883632 2.4 6.72 346 286.73163 391.32321 2883633 2.4 6.76 245 119.48609 80.689598 2883634 2.4 6.8 133 42.102222 18.5056 2883635 2.4 6.84 102 27.904093 9.9904003 2949125 2.44 5 91 24.069202 7.9791999 2949126 2.44 5.04 93 22.6196 7.2512002 2949127 2.44 5.08 95 20.936886 6.1152 2949128 2.44 5.12 99 20.556149 5.6399999 2949129 2.44 5.16 108 25.568607 9.5120001 2949130 2.44 5.2 146 65.384041 57.155201 2949131 2.44 5.24 157 69.650795 57.556801 2949132 2.44 5.28 199 95.012352 72.447998 2949133 2.44 5.32 196 96.458672 74.358398 2949134 2.44 5.36 136 44.814804 22.3088 2949135 2.44 5.4 93 21.479176 6.4112 2949136 2.44 5.44 91 23.507652 7.6128001 2949137 2.44 5.48 99 25.868111 7.9408002 2949138 2.44 5.52 99 23.656672 6.8048 2949139 2.44 5.56 99 22.028542 5.9888 2949140 2.44 5.6 101 22.955265 7.2704 2949141 2.44 5.64 104 24.870157 8.7679996 2949142 2.44 5.68 107 27.143057 10.2272 2949143 2.44 5.72 110 30.178013 12.1952 2949144 2.44 5.76 117 37.633255 18.0592 2949145 2.44 5.8 117 41.247566 21.555201 2949147 2.44 5.88 79 16.4041 4.3280001 2949148 2.44 5.92 113 36.26059 18.2752 2949149 2.44 5.96 255 248.32645 383.55841 2949150 2.44 6 281 275.1554 414.90399 2949151 2.44 6.04 87 20.586992 7.6176 2949152 2.44 6.08 72 13.940583 3.3840001 2949154 2.44 6.16 98 22.458633 6.2016001 2949155 2.44 6.2 100 21.186428 5.6799998 2949156 2.44 6.24 106 22.930782 6.9520001 2949157 2.44 6.28 116 28.086861 10.4752 2949158 2.44 6.32 135 42.002838 21.3664 2949159 2.44 6.36 141 46.87661 24.9328 2949160 2.44 6.4 143 49.256073 26.190399 2949161 2.44 6.44 135 45.918346 23.6224 2949162 2.44 6.48 108 28.810131 9.9407997 2949164 2.44 6.56 151 53.251259 25.142401 2949165 2.44 6.6 244 119.00291 79.587196 2949166 2.44 6.64 327 238.09438 278.47839 2949167 2.44 6.68 378 314.86804 412.784 2949168 2.44 6.72 341 267.39624 334.8576 2949169 2.44 6.76 236 114.9444 78.233597 2949170 2.44 6.8 139 45.787209 20.9408 2949171 2.44 6.84 105 28.342794 9.7296 3014661 2.48 5 93 26.343472 9.3439999 3014662 2.48 5.04 94 23.997847 7.848 3014663 2.48 5.08 96 22.414553 6.7584 3014664 2.48 5.12 99 21.962479 6.3392 3014665 2.48 5.16 110 28.677963 11.6144 3014666 2.48 5.2 143 68.010849 61.513599 3014667 2.48 5.24 138 61.245945 54.243198 3014668 2.48 5.28 201 93.792572 68.136002 3014669 2.48 5.32 205 99.893875 73.563202 3014670 2.48 5.36 119 33.049381 12.7136 3014671 2.48 5.4 95 23.788391 7.7168002 3014672 2.48 5.44 90 24.336477 8.2096004 3014673 2.48 5.48 99 23.890995 6.8080001 3014674 2.48 5.52 99 21.55685 5.6719999 3014675 2.48 5.56 99 19.836058 4.8559999 3014676 2.48 5.6 102 21.354502 6.5888 3014677 2.48 5.64 107 24.065447 8.2287998 3014678 2.48 5.68 110 26.175636 9.4927998 3014679 2.48 5.72 117 32.794746 14.5872 3014680 2.48 5.76 118 36.913143 18.593599 3014681 2.48 5.8 120 41.129978 21.5984 3014683 2.48 5.88 80 17.537695 5.0159998 3014684 2.48 5.92 115 39.088902 21.027201 3014685 2.48 5.96 257 250.46022 381.34879 3014686 2.48 6 280 271.25156 401.6976 3014687 2.48 6.04 87 22.522314 9.8752003 3014688 2.48 6.08 73 15.164352 4.0879998 3014690 2.48 6.16 96 20.586645 5.1968002 3014691 2.48 6.2 98 19.164841 4.5728002 3014692 2.48 6.24 104 20.403437 5.3263998 3014693 2.48 6.28 114 25.351692 8.5888004 3014694 2.48 6.32 132 36.997169 16.7808 3014695 2.48 6.36 141 44.165913 22.1168 3014696 2.48 6.4 144 46.904133 23.440001 3014697 2.48 6.44 135 43.542473 21.120001 3014698 2.48 6.48 102 24.23518 7.0128002 3014700 2.48 6.56 153 57.65152 29.739201 3014701 2.48 6.6 232 113.18958 76.792 3014702 2.48 6.64 316 216.93454 229.54559 3014703 2.48 6.68 387 319.26297 406.25919 3014704 2.48 6.72 336 250.19733 290.2048 3014705 2.48 6.76 228 110.93597 76.228798 3014706 2.48 6.8 143 50.915245 26.024 3014707 2.48 6.84 109 30.73826 11.0784 3080197 2.52 5 92 27.492918 9.9807997 3080198 2.52 5.04 92 24.954393 8.4015999 3080199 2.52 5.08 98 25.468073 8.3456001 3080200 2.52 5.12 98 23.871679 7.408 3080201 2.52 5.16 112 33.886379 16.351999 3080202 2.52 5.2 143 72.09565 66.588799 3080203 2.52 5.24 133 62.650902 56.481602 3080204 2.52 5.28 209 96.720192 66.649597 3080205 2.52 5.32 213 102.5191 71.6912 3080206 2.52 5.36 98 24.545853 7.9744 3080207 2.52 5.4 95 26.026886 9.0752001 3080208 2.52 5.44 92 27.531065 10.1632 3080209 2.52 5.48 99 22.448984 5.9952002 3080210 2.52 5.52 99 20.027828 4.8592 3080211 2.52 5.56 99 18.23999 4.0432 3080212 2.52 5.6 108 23.114809 7.7536001 3080213 2.52 5.64 112 24.451399 8.1904001 3080214 2.52 5.68 117 29.080223 11.8704 3080215 2.52 5.72 121 34.797466 17.0704 3080216 2.52 5.76 121 36.525146 17.945601 3080217 2.52 5.8 118 36.525784 17 3080219 2.52 5.88 77 17.906757 5.5823998 3080220 2.52 5.92 113 40.990875 24.180799 3080221 2.52 5.96 260 252.92873 378.81921 3080222 2.52 6 281 270.72192 393.29599 3080223 2.52 6.04 85 22.815947 10.3744 3080224 2.52 6.08 72 16.118212 4.8080001 3080226 2.52 6.16 95 19.840269 4.8207998 3080227 2.52 6.2 97 18.326664 4.1264 3080228 2.52 6.24 102 18.849606 4.4303999 3080229 2.52 6.28 111 22.382889 6.3776002 3080230 2.52 6.32 131 34.457516 14.3072 3080231 2.52 6.36 142 42.616314 20.027201 3080232 2.52 6.4 144 44.738503 20.958401 3080233 2.52 6.44 135 41.774498 19.052799 3080234 2.52 6.48 97 21.706116 5.6960001 3080236 2.52 6.56 152 60.740761 33.8176 3080237 2.52 6.6 220 109.53291 77.198402 3080238 2.52 6.64 306 195.06593 186.5696 3080239 2.52 6.68 400 325.23215 400.6608 3080240 2.52 6.72 327 236.74025 265.18079 3080241 2.52 6.76 219 108.00165 76.419197 3080242 2.52 6.8 143 53.766697 29.2736 3080243 2.52 6.84 107 32.848911 13.4768 3145740 2.56 5.28 193 96.018463 65.720001 3145741 2.56 5.32 223 106.57522 70.559998 3145745 2.56 5.48 100 22.015041 5.7024002 3145746 2.56 5.52 99 19.094389 4.3663998 3145747 2.56 5.56 104 20.665718 5.9424 3145748 2.56 5.6 111 23.1805 7.4032001 3145749 2.56 5.64 120 28.053198 10.6688 3145750 2.56 5.68 122 31.910679 14.4912 3145751 2.56 5.72 120 31.543627 13.9184 3145752 2.56 5.76 116 30.527962 12.5392 3145753 2.56 5.8 115 31.318863 11.5856 3145755 2.56 5.88 77 20.508144 7.8783998 3145756 2.56 5.92 107 42.286747 28.382401 3145757 2.56 5.96 264 255.88359 376.22079 3145758 2.56 6 283 269.96823 384.19199 3145759 2.56 6.04 85 26.858656 14.1808 3145760 2.56 6.08 72 18.031601 5.9856 3145762 2.56 6.16 95 20.142962 4.9903998 3145763 2.56 6.2 96 18.240326 4.1264 3145764 2.56 6.24 98 17.296539 3.6656001 3145765 2.56 6.28 107 20.187422 4.9823999 3145766 2.56 6.32 129 32.257652 12.2928 3145767 2.56 6.36 142 41.14254 18.08 3145768 2.56 6.4 145 43.569824 19.076799 3145769 2.56 6.44 135 40.618332 17.420799 3145770 2.56 6.48 92 20.469498 5.2575998 3145772 2.56 6.56 147 63.753483 38.316799 3145773 2.56 6.6 206 107.17625 79.827202 3145774 2.56 6.64 279 159.04871 130.0768 3145775 2.56 6.68 413 329.58594 395.19199 3145776 2.56 6.72 311 206.54886 204.6944 3145777 2.56 6.76 208 107.22983 79.923203 3145778 2.56 6.8 139 58.079079 35.065601 3145779 2.56 6.84 110 39.836937 19.856001 3211267 2.6 4.92 98 48.64201 36.0256 3211268 2.6 4.96 95 43.277508 29.6112 3211269 2.6 5 82 29.831656 16.628799 3211270 2.6 5.04 66 18.134392 7.6672001 3211271 2.6 5.08 57 14.110662 5.5760002 3211272 2.6 5.12 47 9.1046562 2.0480001 3211276 2.6 5.28 172 89.331169 61.200001 3211277 2.6 5.32 204 103.39691 67.7472 3211281 2.6 5.48 101 22.249674 5.8256001 3211282 2.6 5.52 100 19.163813 4.3488002 3211283 2.6 5.56 113 24.38604 7.6592002 3211284 2.6 5.6 121 27.538715 9.7376003 3211285 2.6 5.64 125 31.26116 13.1584 3211286 2.6 5.68 124 30.814224 12.776 3211287 2.6 5.72 116 26.17038 8.6960001 3211288 2.6 5.76 115 27.651682 9.2639999 3211289 2.6 5.8 113 29.450909 10.232 3211291 2.6 5.88 79 24.460316 10.5664 3211292 2.6 5.92 105 48.894188 38.396801 3211293 2.6 5.96 267 258.28711 373.12961 3211294 2.6 6 285 269.24326 375.68961 3211295 2.6 6.04 84 30.326359 17.601601 3211296 2.6 6.08 72 20.171656 7.3376002 3211298 2.6 6.16 93 20.431986 5.3039999 3211299 2.6 6.2 95 18.749771 4.4432001 3211300 2.6 6.24 96 17.480474 3.8448 3211301 2.6 6.28 103 19.029057 4.3712001 3211302 2.6 6.32 127 31.005703 11.04 3211303 2.6 6.36 143 40.692532 16.752001 3211304 2.6 6.4 145 42.608047 17.496 3211305 2.6 6.44 133 38.505741 15.0032 3211306 2.6 6.48 89 21.076752 5.6960001 3211309 2.6 6.6 193 108.80457 85.924797 3211310 2.6 6.64 257 136.99849 101.128 3211311 2.6 6.68 434 340.03873 402.28961 3211312 2.6 6.72 268 142.80251 104.4944 3211313 2.6 6.76 190 106.15475 84.361603 3276803 2.64 4.92 89 39.030582 28.2768 3276804 2.64 4.96 100 45.446362 32.950401 3276805 2.64 5 104 45.810898 31.0256 3276806 2.64 5.04 87 29.249048 15.3072 3276807 2.64 5.08 63 15.819238 6.4640002 3276808 2.64 5.12 47 7.9607825 1.5872 3276812 2.64 5.28 175 86.442856 56.364799 3276813 2.64 5.32 205 100.8286 63.350399 3276817 2.64 5.48 103 23.44799 6.4000001 3276818 2.64 5.52 111 25.572342 8.1071997 3276819 2.64 5.56 128 31.362982 11.1584 3276820 2.64 5.6 131 33.340488 13.3296 3276821 2.64 5.64 125 28.586546 10.0576 3276822 2.64 5.68 117 24.177649 6.8656001 3276823 2.64 5.72 117 25.811478 7.8544002 3276824 2.64 5.76 116 28.05913 9.2335997 3276825 2.64 5.8 116 31.020525 10.8896 3276829 2.64 5.96 269 257.93427 365.048 3276830 2.64 6 279 267.87546 368.20319 3276834 2.64 6.16 93 21.876867 6.1135998 3276835 2.64 6.2 93 19.774544 5.1216002 3276836 2.64 6.24 95 18.680397 4.5103998 3276837 2.64 6.28 98 18.644131 4.3424001 3276838 2.64 6.32 121 27.859432 8.4720001 3276839 2.64 6.36 144 40.846245 15.8976 3276840 2.64 6.4 145 42.221409 16.382401 3276845 2.64 6.6 180 112.16918 93.377602 3276846 2.64 6.64 183 109.00253 89.897598 3276847 2.64 6.68 451 341.84482 396.02719 3276848 2.64 6.72 185 107.38881 87.731201 3276849 2.64 6.76 172 108.93419 91.822403 3342339 2.68 4.92 68 16.231276 5.3600001 3342340 2.68 4.96 83 28.388485 17.971201 3342341 2.68 5 101 41.172039 28.590401 3342342 2.68 5.04 114 47.761585 31.385599 3342343 2.68 5.08 106 38.255936 20.491199 3342344 2.68 5.12 53 9.8327141 2.7360001 3342348 2.68 5.28 208 96.584366 58.201599 3342349 2.68 5.32 231 105.43041 61.998402 3342353 2.68 5.48 104 24.78664 7.1087999 3342354 2.68 5.52 140 38.764961 14.3152 3342355 2.68 5.56 140 36.986313 13.7792 3342356 2.68 5.6 129 28.843645 8.5791998 3342357 2.68 5.64 125 26.718136 7.4352002 3342358 2.68 5.68 124 27.455744 8.1456003 3342359 2.68 5.72 121 28.394812 9.1775999 3342360 2.68 5.76 122 32.382023 12.0912 3342361 2.68 5.8 121 35.528988 14.176 3342365 2.68 5.96 269 260.9852 362.992 3342366 2.68 6 269 263.84412 360.03839 3342370 2.68 6.16 93 23.828762 7.224 3342371 2.68 6.2 93 21.847223 6.2319999 3342372 2.68 6.24 93 20.44768 5.5408001 3342373 2.68 6.28 95 19.957327 5.1919999 3342374 2.68 6.32 112 25.204681 7.0464001 3342375 2.68 6.36 145 41.330524 15.3424 3342376 2.68 6.4 144 42.226788 15.7232 3342379 2.68 6.52 246 162.1927 154.55521 3342380 2.68 6.56 256 180.69125 191.7504 3342381 2.68 6.6 267 198.45714 225.9744 3342382 2.68 6.64 294 232.48856 300.12 3342383 2.68 6.68 457 346.3465 400.44958 3342384 2.68 6.72 293 225.49335 287.52802 3342385 2.68 6.76 266 197.77563 226.744 3342386 2.68 6.8 258 183.93323 197.68159 3342387 2.68 6.84 243 162.47705 158.35361 3407875 2.72 4.92 86 31.022507 18.2416 3407876 2.72 4.96 88 29.352249 16.4704 3407877 2.72 5 91 28.34428 14.9472 3407878 2.72 5.04 119 48.332653 31.846399 3407879 2.72 5.08 148 62.577179 38.535999 3407880 2.72 5.12 176 70.439438 37.915199 3407881 2.72 5.16 241 110.62124 63.755199 3407882 2.72 5.2 236 104.97357 59.617599 3407883 2.72 5.24 226 97.36895 54.023998 3407884 2.72 5.28 259 108.34807 59.5312 3407885 2.72 5.32 264 111.97591 61.7024 3407886 2.72 5.36 225 100.81319 62.6464 3407887 2.72 5.4 220 106.24221 75.436798 3407888 2.72 5.44 208 101.02329 69.496002 3407889 2.72 5.48 188 58.596161 22.3456 3407890 2.72 5.52 161 46.732681 17.4048 3407891 2.72 5.56 142 36.218613 11.8112 3407892 2.72 5.6 137 34.348446 11.456 3407893 2.72 5.64 134 33.812729 11.7664 3407894 2.72 5.68 132 34.142315 12.472 3407895 2.72 5.72 132 36.046364 14.0032 3407896 2.72 5.76 129 36.989223 15.0144 3407897 2.72 5.8 128 39.44965 16.889601 3407901 2.72 5.96 310 286.4483 377.23999 3407902 2.72 6 314 289.42984 372.87201 3407906 2.72 6.16 92 26.002573 8.5760002 3407907 2.72 6.2 92 24.211964 7.6016002 3407908 2.72 6.24 92 22.958916 6.9247999 3407909 2.72 6.28 93 22.41054 6.5616002 3407910 2.72 6.32 96 22.667059 6.5279999 3407911 2.72 6.36 144 41.810989 15.1216 3407912 2.72 6.4 143 42.580166 15.504 3407915 2.72 6.52 241 147.74417 133.74561 3407916 2.72 6.56 262 174.20126 178.008 3407917 2.72 6.6 278 193.54166 214.84 3407918 2.72 6.64 339 248.11678 300.37119 3407919 2.72 6.68 451 344.42502 397.18561 3407920 2.72 6.72 353 258.95291 306.55359 3407921 2.72 6.76 277 194.16962 216.08 3407922 2.72 6.8 256 172.25639 178.9872 3407923 2.72 6.84 241 150.56526 140.424 3473411 2.76 4.92 97 38.222267 23.8736 3473412 2.76 4.96 97 35.21537 21.134399 3473413 2.76 5 99 33.788208 19.32 3473414 2.76 5.04 103 33.022175 17.591999 3473415 2.76 5.08 106 32.294415 15.9456 3473416 2.76 5.12 166 68.0877 40.543999 3473417 2.76 5.16 281 121.87315 68.416 3473418 2.76 5.2 265 112.50618 61.156799 3473419 2.76 5.24 256 104.76728 55.414398 3473420 2.76 5.28 281 112.43497 58.971199 3473421 2.76 5.32 284 114.44407 59.993599 3473422 2.76 5.36 267 111.49501 65.422401 3473423 2.76 5.4 257 113.30338 74.876801 3473424 2.76 5.44 275 120.11343 75.907204 3473425 2.76 5.48 171 50.516453 18.1952 3473426 2.76 5.52 149 40.779076 13.6848 3473427 2.76 5.56 145 39.255268 13.4112 3473428 2.76 5.6 142 38.608486 13.6496 3473429 2.76 5.64 140 38.307564 13.9168 3473430 2.76 5.68 140 39.751347 15.2464 3473431 2.76 5.72 138 41.198982 16.816 3473432 2.76 5.76 137 42.997688 18.2864 3473433 2.76 5.8 137 45.90205 20.649599 3473434 2.76 5.84 104 40.100235 20.5856 3473435 2.76 5.88 80 34.294888 19.867201 3473436 2.76 5.92 96 41.426548 24.2976 3473437 2.76 5.96 339 300.6102 381.67841 3473438 2.76 6 340 301.94342 375.94879 3473447 2.76 6.36 135 41.202343 15.0608 3473448 2.76 6.4 140 42.740696 15.5952 3473451 2.76 6.52 244 138.44972 116.2112 3473452 2.76 6.56 269 167.47571 164.93919 3473453 2.76 6.6 290 189.93753 200.73759 3473454 2.76 6.64 362 262.75052 307.9296 3473455 2.76 6.68 447 341.43793 391.95679 3473456 2.76 6.72 371 271.96927 316.992 3473457 2.76 6.76 285 189.21687 204.9696 3473458 2.76 6.8 261 163.38513 163.24159 3473459 2.76 6.84 241 138.76552 120.3728 3538945 2.8 4.84 26 6.7065015 2.2368 3538946 2.8 4.88 26 6.5531263 2.1472001 3538947 2.8 4.92 83 28.496723 15.6704 3538948 2.8 4.96 80 23.925625 12.1648 3538949 2.8 5 78 21.16482 10.2432 3538950 2.8 5.04 72 15.67489 5.7856002 3538951 2.8 5.08 62 9.9602785 2.184 3538952 2.8 5.12 50 7.4355497 1.304 3538953 2.8 5.16 260 124.12385 74.337601 3538954 2.8 5.2 275 117.29893 64.307198 3538955 2.8 5.24 280 112.5738 58.2896 3538956 2.8 5.28 289 112.39914 56.792 3538957 2.8 5.32 280 107.39648 54.017601 3538958 2.8 5.36 285 117.72711 67.961601 3538959 2.8 5.4 259 107.3278 65.120003 3538960 2.8 5.44 206 93.585457 61.366402 3538961 2.8 5.48 106 31.140366 10.648 3538962 2.8 5.52 117 31.289972 9.9152002 3538963 2.8 5.56 126 34.094898 11.168 3538964 2.8 5.6 129 35.049408 11.6688 3538965 2.8 5.64 132 37.212387 13.1856 3538966 2.8 5.68 133 39.371006 15.104 3538967 2.8 5.72 133 41.114185 16.6112 3538968 2.8 5.76 131 42.996151 18.4464 3538969 2.8 5.8 126 45.285759 20.7376 3538973 2.8 5.96 294 272.00146 357.16479 3538974 2.8 6 322 281.62576 353.504 3538983 2.8 6.36 117 36.949284 13.9008 3538984 2.8 6.4 133 42.106956 15.8176 3538987 2.8 6.52 247 129.5679 101.3136 3538988 2.8 6.56 268 157.72998 148.89439 3538989 2.8 6.6 297 185.45547 189.7664 3538990 2.8 6.64 379 275.80621 319.26721 3538991 2.8 6.68 444 340.36185 391.10721 3538992 2.8 6.72 382 281.42587 325 3538993 2.8 6.76 291 184.13937 192.4608 3538994 2.8 6.8 266 157.36371 150.59039 3538995 2.8 6.84 246 131.83324 106.7088 3604481 2.84 4.84 27 6.093677 1.8368 3604482 2.84 4.88 26 5.6515098 1.6752 3604483 2.84 4.92 57 11.497465 2.8975999 3604484 2.84 4.96 56 9.8414907 2.2 3604485 2.84 5 54 8.3163071 1.592 3604486 2.84 5.04 52 7.6277027 1.3744 3604487 2.84 5.08 50 7.4611697 1.3424 3604488 2.84 5.12 47 7.9607825 1.5872 3604489 2.84 5.16 277 136.71858 87.1744 3604490 2.84 5.2 277 124.14661 73.121597 3604491 2.84 5.24 296 121.54653 65.060799 3604492 2.84 5.28 302 117.67924 59.284801 3604493 2.84 5.32 289 109.03543 53.807999 3604494 2.84 5.36 292 120.48146 70.7472 3604495 2.84 5.4 241 97.944984 59.056 3604496 2.84 5.44 209 90.072014 56.2384 3604509 2.84 5.96 357 292.26901 361.384 3604510 2.84 6 388 323.79016 380.65759 3604519 2.84 6.36 108 33.510082 12.7024 3604520 2.84 6.4 123 40.08849 15.7376 3604523 2.84 6.52 245 119.31032 85.467201 3604524 2.84 6.56 273 150.6747 133.26401 3604525 2.84 6.6 302 180.11603 176.5936 3604526 2.84 6.64 389 281.88303 322.81281 3604527 2.84 6.68 452 344.49945 394.25601 3604528 2.84 6.72 390 287.9043 332.4848 3604529 2.84 6.76 298 178.45212 177.5264 3604530 2.84 6.8 270 149.62213 135.3024 3604531 2.84 6.84 240 118.1138 87.705597 3604533 2.84 6.92 83 22.786308 7.4144001 3604534 2.84 6.96 83 21.408356 6.7424002 3604535 2.84 7 85 21.418526 6.7600002 3604536 2.84 7.04 91 24.370354 8.4879999 3604537 2.84 7.08 95 27.755751 10.9856 3604538 2.84 7.12 96 29.312677 11.8704 3604539 2.84 7.16 100 33.079517 14.008 3670017 2.88 4.84 30 5.9509678 1.5728 3670018 2.88 4.88 28 5.2330184 1.3487999 3670019 2.88 4.92 54 11.487489 2.8831999 3670020 2.88 4.96 52 9.7762432 2.2176001 3670021 2.88 5 50 8.514657 1.744 3670022 2.88 5.04 50 8.4282379 1.7072001 3670023 2.88 5.08 48 8.4430065 1.7728 3670024 2.88 5.12 47 9.1046562 2.0480001 3670025 2.88 5.16 312 163.02496 111.3744 3670026 2.88 5.2 314 151.51718 96.8144 3670027 2.88 5.24 326 146.46187 87.718399 3670028 2.88 5.28 344 146.73788 82.524803 3670029 2.88 5.32 332 133.28098 70.120003 3670030 2.88 5.36 316 131.34325 76.972801 3670031 2.88 5.4 247 96.807465 55.708801 3670032 2.88 5.44 216 89.959999 53.062401 3670033 2.88 5.48 150 64.653793 34.686401 3670034 2.88 5.52 207 86.033112 43.936001 3670035 2.88 5.56 199 76.41256 35.590401 3670036 2.88 5.6 176 65.001961 28.9664 3670037 2.88 5.64 152 61.369392 30.2528 3670038 2.88 5.68 177 74.408974 38.4464 3670039 2.88 5.72 202 76.720749 35.785599 3670040 2.88 5.76 245 94.979286 44.507198 3670041 2.88 5.8 256 97.916206 45.203201 3670042 2.88 5.84 268 105.376 51.0144 3670043 2.88 5.88 290 124.66447 69.939201 3670044 2.88 5.92 344 187.12149 148.88161 3670045 2.88 5.96 503 376.34308 419.7536 3670046 2.88 6 514 384.3222 422.47681 3670047 2.88 6.04 318 166.44257 119.4352 3670048 2.88 6.08 302 156.61765 111.2592 3670049 2.88 6.12 296 160.57521 119.816 3670050 2.88 6.16 295 167.1246 129.6032 3670051 2.88 6.2 294 176.49124 143.27521 3670052 2.88 6.24 289 182.5011 153.976 3670053 2.88 6.28 288 191.16454 166.7536 3670054 2.88 6.32 71 22.495737 9.7200003 3670055 2.88 6.36 110 35.567551 14.4432 3670056 2.88 6.4 120 39.479145 16.062401 3670057 2.88 6.44 116 38.260769 15.3984 3670059 2.88 6.52 247 113.14834 75.171204 3670060 2.88 6.56 276 142.98814 118.4576 3670061 2.88 6.6 312 179.97034 169.392 3670062 2.88 6.64 397 287.1626 326.19519 3670063 2.88 6.68 452 343.83701 392.6976 3670064 2.88 6.72 402 292.3714 333.94241 3670065 2.88 6.76 310 180.29175 172.1328 3670066 2.88 6.8 269 140.29514 119.2512 3670067 2.88 6.84 241 110.88404 75.633598 3670069 2.88 6.92 83 20.4732 6.0704002 3670070 2.88 6.96 84 19.183294 5.4447999 3670071 2.88 7 89 20.759233 6.368 3670072 2.88 7.04 96 24.871632 9.1232004 3670073 2.88 7.08 97 25.77951 9.5951996 3670074 2.88 7.12 102 29.413937 11.5408 3670075 2.88 7.16 102 31.487103 12.8192 3735553 2.92 4.84 34 5.8792844 1.3376 3735554 2.92 4.88 28 4.5862141 1.0304 3735561 2.92 5.16 358 212.15204 171.88161 3735562 2.92 5.2 379 210.00166 162.07359 3735563 2.92 5.24 398 209.23906 153.424 3735564 2.92 5.28 422 212.07173 147.45599 3735565 2.92 5.32 414 198.07924 130.6416 3735566 2.92 5.36 428 213.42834 149.5696 3735567 2.92 5.4 375 167.29056 101.1056 3735568 2.92 5.44 236 93.123802 52.246399 3735569 2.92 5.48 273 135.15883 88.478401 3735570 2.92 5.52 320 146.57327 85.662399 3735571 2.92 5.56 314 140.19608 79.2864 3735572 2.92 5.6 301 132.3887 73.584 3735573 2.92 5.64 237 94.256035 46.361599 3735574 2.92 5.68 198 79.710411 41.547199 3735575 2.92 5.72 310 131.13956 69.406403 3735576 2.92 5.76 324 140.14577 77.084801 3735577 2.92 5.8 326 141.29926 78.660797 3735578 2.92 5.84 322 140.28928 79.876801 3735579 2.92 5.88 330 148.23357 89.142403 3735580 2.92 5.92 374 199.45123 153.99519 3735581 2.92 5.96 520 386.2941 426.78241 3735582 2.92 6 528 392.22583 428.31201 3735583 2.92 6.04 331 170.52539 123.1584 3735584 2.92 6.08 309 158.33998 114.616 3735585 2.92 6.12 308 164.93591 124.9456 3735586 2.92 6.16 304 170.90851 134.80479 3735587 2.92 6.2 300 177.83286 146.2592 3735588 2.92 6.24 292 182.70215 156.056 3735589 2.92 6.28 290 191.18771 169.0656 3735590 2.92 6.32 90 28.14035 11.672 3735591 2.92 6.36 121 41.322639 18.1152 3735592 2.92 6.4 120 39.718739 16.719999 3735593 2.92 6.44 119 40.707737 17.417601 3735595 2.92 6.52 246 106.26759 64.956802 3735596 2.92 6.56 277 134.53978 103.4864 3735597 2.92 6.6 316 175.88043 159.17599 3735598 2.92 6.64 410 299.52469 342.104 3735599 2.92 6.68 456 343.86163 389.88321 3735600 2.92 6.72 405 293.24362 333.58081 3735601 2.92 6.76 320 178.73674 162.84801 3735602 2.92 6.8 271 133.84842 107.1408 3735603 2.92 6.84 241 103.35139 64.139198 3735605 2.92 6.92 83 18.575243 4.9952002 3735606 2.92 6.96 87 18.707726 5.3072 3735607 2.92 7 97 22.903288 7.6799998 3735608 2.92 7.04 102 24.907566 8.7552004 3735609 2.92 7.08 104 26.486828 9.592 3735610 2.92 7.12 105 28.274229 10.5248 3735611 2.92 7.16 103 29.388485 11.184 3801088 2.96 4.8 85 41.581909 29.2064 3801089 2.96 4.84 58 13.859875 4.7536001 3801090 2.96 4.88 30 4.5404897 0.89279997 3801091 2.96 4.92 193 129.37222 117.2784 3801092 2.96 4.96 192 116.09351 98.3424 3801093 2.96 5 186 101.59654 79.564796 3801094 2.96 5.04 172 81.4235 56.063999 3801095 2.96 5.08 127 39.823441 15.872 3801096 2.96 5.12 92 27.770664 11.2768 3801097 2.96 5.16 382 235.87764 206.4128 3801098 2.96 5.2 420 239.7036 198.6656 3801099 2.96 5.24 435 237.36275 188.4384 3801100 2.96 5.28 455 238.19411 178.72 3801101 2.96 5.32 447 223.56174 159.5744 3801102 2.96 5.36 467 241.29996 178.06081 3801103 2.96 5.4 468 236.99042 168.29601 3801104 2.96 5.44 450 216.2874 144.16319 3801105 2.96 5.48 405 188.88159 117.4624 3801106 2.96 5.52 374 170.54704 102.6848 3801107 2.96 5.56 362 161.16765 93.444801 3801108 2.96 5.6 356 155.45341 87.601601 3801109 2.96 5.64 352 150.75609 82.908798 3801110 2.96 5.68 352 149.30342 81.737602 3801111 2.96 5.72 350 148.8269 81.806396 3801112 2.96 5.76 343 145.94128 80.6912 3801113 2.96 5.8 339 144.5766 81.065598 3801114 2.96 5.84 337 143.96118 82.239998 3801115 2.96 5.88 339 147.61288 87.367996 3801116 2.96 5.92 397 206.3087 154.8752 3801117 2.96 5.96 539 395.32129 430.9584 3801118 2.96 6 540 396.14984 428.86081 3801119 2.96 6.04 334 165.94984 117.4064 3801120 2.96 6.08 316 157.32072 113.0928 3801121 2.96 6.12 312 163.14531 122.9376 3801122 2.96 6.16 308 168.91061 132.6864 3801123 2.96 6.2 305 175.74461 143.5296 3801124 2.96 6.24 297 181.3558 153.93919 3801125 2.96 6.28 291 188.44608 165.8096 3801126 2.96 6.32 104 33.364124 13.9712 3801127 2.96 6.36 125 41.763016 18.164801 3801128 2.96 6.4 139 47.316441 20.624001 3801129 2.96 6.44 130 46.336147 21.084801 3801131 2.96 6.52 249 102.71947 58.257599 3801132 2.96 6.56 277 126.43604 89.457603 3801133 2.96 6.6 325 175.80861 153.2128 3801134 2.96 6.64 419 304.79086 346.74399 3801135 2.96 6.68 459 343.69019 387.80161 3801136 2.96 6.72 414 295.46216 332.00961 3801137 2.96 6.76 338 186.93533 164.0448 3801138 2.96 6.8 293 141.04265 105.7984 3801139 2.96 6.84 255 110.78763 68.323196 3801141 2.96 6.92 83 17.128313 4.1887999 3801142 2.96 6.96 100 23.130611 7.3568001 3801143 2.96 7 106 24.39456 7.9424 3801144 2.96 7.04 109 25.525942 8.4848003 3801145 2.96 7.08 107 25.276199 8.3936005 3801146 2.96 7.12 107 27.00593 9.4239998 3801147 2.96 7.16 108 29.962065 11.1632 3866624 3 4.8 269 285.2059 384.064 3866625 3 4.84 306 286.14209 368.616 3866626 3 4.88 316 281.14218 351.73761 3866627 3 4.92 310 273.35226 332.5968 3866628 3 4.96 312 263.85147 309.83679 3866629 3 5 322 259.8038 294.31039 3866630 3 5.04 332 252.69942 273.3168 3866631 3 5.08 345 246.62799 253.92641 3866632 3 5.12 374 249.69357 243.4688 3866633 3 5.16 444 264.87527 236.3136 3866634 3 5.2 457 263.85822 226.2016 3866635 3 5.24 465 258.03333 211.2928 3866636 3 5.28 477 255.05229 198.79201 3866637 3 5.32 469 244.33694 187.384 3866638 3 5.36 484 255.58507 195.84801 3866639 3 5.4 481 246.41516 180.75681 3866640 3 5.44 466 227.62523 158.5632 3866641 3 5.48 428 200.38931 132.008 3866642 3 5.52 408 190.89244 123.6544 3866643 3 5.56 393 181.09453 115.0656 3866644 3 5.6 373 168.28201 104.6224 3866645 3 5.64 369 164.16472 100.4464 3866646 3 5.68 365 159.90039 96.188797 3866647 3 5.72 358 156.15387 93.7808 3866648 3 5.76 357 155.86826 93.590401 3866649 3 5.8 353 153.51762 92.344002 3866650 3 5.84 352 155.09401 94.873596 3866651 3 5.88 356 158.59486 98.5504 3866652 3 5.92 410 208.02751 150.216 3866653 3 5.96 547 397.59076 430.3584 3866654 3 6 550 397.54211 425.90079 3866655 3 6.04 345 165.2907 112.7184 3866656 3 6.08 331 162.29266 114.8864 3866657 3 6.12 324 166.16064 123.1776 3866658 3 6.16 318 169.6765 131.0864 3866659 3 6.2 308 172.95802 140.13921 3866660 3 6.24 306 181.82072 152.93919 3866661 3 6.28 293 187.83348 164.7776 3866662 3 6.32 111 35.56448 14.9712 3866663 3 6.36 155 51.711483 22.249599 3866664 3 6.4 184 68.285156 31.9744 3866665 3 6.44 185 75.544006 39.409599 3866667 3 6.52 251 96.904282 49.8288 3866668 3 6.56 280 119.34347 76.624001 3866669 3 6.6 344 183.02953 153.0768 3866670 3 6.64 446 321.07849 356.39679 3866671 3 6.68 497 375.69952 419.1568 3866672 3 6.72 463 339.43518 376.8544 3866673 3 6.76 392 235.65625 216.6208 3866674 3 6.8 346 186.42545 155.37601 3866675 3 6.84 314 167.43939 139.81599 3866677 3 6.92 99 21.90798 6.0256 3866678 3 6.96 117 27.258326 8.4175997 3866679 3 7 118 26.564445 8.0880003 3866680 3 7.04 113 24.881172 7.5567999 3866681 3 7.08 111 25.387308 8.1280003 3866682 3 7.12 111 27.838657 9.8559999 3866683 3 7.16 122 46.272751 35.766399 3932160 3.04 4.8 300 306.1478 405.21759 3932161 3.04 4.84 320 299.5354 383.90561 3932162 3.04 4.88 326 291.02536 363.00641 3932163 3.04 4.92 317 279.61249 341.9024 3932164 3.04 4.96 321 271.3609 322.09921 3932165 3.04 5 329 265.8786 305.0528 3932166 3.04 5.04 339 259.02194 286.44321 3932167 3.04 5.08 375 268.3595 279.59201 3932168 3.04 5.12 408 269.8913 265.90561 3932169 3.04 5.16 456 277.92145 257.24799 3932170 3.04 5.2 459 270.13348 241.696 3932171 3.04 5.24 468 265.42044 228.4496 3932172 3.04 5.28 478 262.75681 217.336 3932173 3.04 5.32 474 253.80664 205.7744 3932174 3.04 5.36 492 264.13156 211.27679 3932175 3.04 5.4 492 260.94006 203.70239 3932176 3.04 5.44 474 238.14188 176.0368 3932177 3.04 5.48 444 215.88725 153.2832 3932178 3.04 5.52 418 200.89526 140.26241 3932179 3.04 5.56 404 193.81007 133.39841 3932180 3.04 5.6 396 187.50414 126.7472 3932181 3.04 5.64 385 179.59515 119.5456 3932182 3.04 5.68 376 171.62955 112.3072 3932183 3.04 5.72 367 166.64774 108.1744 3932184 3.04 5.76 366 165.46899 106.4592 3932185 3.04 5.8 366 165.85594 106.4912 3932186 3.04 5.84 366 165.61865 106.4048 3932187 3.04 5.88 367 166.86472 107.7472 3932188 3.04 5.92 421 212.84048 151.0224 3932189 3.04 5.96 567 413.94699 444.96799 3932190 3.04 6 569 414.15894 442.37439 3932191 3.04 6.04 367 182.38228 128.2368 3932192 3.04 6.08 353 179.01418 129.6944 3932193 3.04 6.12 351 184.35657 137.70399 3932194 3.04 6.16 346 187.8327 144.6608 3932195 3.04 6.2 346 194.46359 154.0704 3932196 3.04 6.24 346 201.18672 164.336 3932197 3.04 6.28 358 212.4406 177.3904 3932198 3.04 6.32 393 239.18513 200.5632 3932199 3.04 6.36 380 243.6611 213.416 3932200 3.04 6.4 373 245.28171 222.8448 3932201 3.04 6.44 368 244.07941 227.6848 3932202 3.04 6.48 369 243.03621 232.216 3932203 3.04 6.52 431 271.83929 255.4704 3932204 3.04 6.56 443 289.05621 281.936 3932205 3.04 6.6 490 349.74985 365.2384 3932206 3.04 6.64 579 486.22412 579.52161 3932207 3.04 6.68 618 535.16101 647.20001 3932208 3.04 6.72 565 481.20602 587.50403 3932209 3.04 6.76 483 365.36923 417.08801 3932210 3.04 6.8 432 306.61496 348.7168 3932211 3.04 6.84 407 281.94812 326.86401 3932212 3.04 6.88 356 259.74207 320.87521 3932213 3.04 6.92 282 224.78014 308.26559 3932214 3.04 6.96 259 218.97029 315.37921 3932215 3.04 7 247 214.1096 317.09439 3932216 3.04 7.04 238 211.9409 321.4256 3932217 3.04 7.08 232 212.01784 328.0144 3932218 3.04 7.12 226 209.70573 327.16641 3932219 3.04 7.16 222 212.46121 336.21921 3997696 3.08 4.8 297 303.10629 401.19519 3997697 3.08 4.84 316 295.11691 378.4512 3997698 3.08 4.88 324 287.88385 358.95041 3997699 3.08 4.92 314 276.25323 337.832 3997700 3.08 4.96 319 269.50211 319.76001 3997701 3.08 5 326 263.26926 302.33759 3997702 3.08 5.04 352 269.14133 294.09439 3997703 3.08 5.08 369 265.4147 277.82559 3997704 3.08 5.12 402 268.10809 265.43359 3997705 3.08 5.16 447 272.81335 253.97279 3997706 3.08 5.2 455 267.15765 239.6192 3997707 3.08 5.24 463 263.10223 227.0896 3997708 3.08 5.28 478 262.97372 217.4512 3997709 3.08 5.32 477 255.58261 206.26401 3997710 3.08 5.36 493 264.64627 210.8416 3997711 3.08 5.4 488 257.13675 198.8528 3997712 3.08 5.44 467 234.63095 174.0096 3997713 3.08 5.48 436 211.99486 151.1264 3997714 3.08 5.52 420 202.09621 141.024 3997715 3.08 5.56 404 193.03607 132.71201 3997716 3.08 5.6 392 186.21957 126.4448 3997717 3.08 5.64 387 182.71283 122.4976 3997718 3.08 5.68 385 179.71841 118.8912 3997719 3.08 5.72 373 171.39308 111.7968 3997720 3.08 5.76 368 168.05602 108.9632 3997721 3.08 5.8 367 167.604 108.488 3997722 3.08 5.84 368 169.01961 110.008 3997723 3.08 5.88 371 171.03979 111.8784 3997724 3.08 5.92 415 203.6002 138.0192 3997725 3.08 5.96 574 419.28796 449.4368 3997726 3.08 6 571 415.51892 443.40961 3997727 3.08 6.04 375 188.35931 133.28 3997728 3.08 6.08 357 183.07394 133.9088 3997729 3.08 6.12 352 186.59917 140.7952 3997730 3.08 6.16 351 191.35672 147.8976 3997731 3.08 6.2 350 197.88655 157.8 3997732 3.08 6.24 350 204.04774 167.1904 3997733 3.08 6.28 358 214.15875 179.8624 3997734 3.08 6.32 387 239.15179 202.976 3997735 3.08 6.36 369 239.0824 211.744 3997736 3.08 6.4 362 238.38428 216.6848 3997737 3.08 6.44 362 240.58443 224.13921 3997738 3.08 6.48 375 248.6382 233.8096 3997739 3.08 6.52 429 267.45822 250.0208 3997740 3.08 6.56 446 289.85107 281.40161 3997741 3.08 6.6 493 350.22226 364.064 3997742 3.08 6.64 583 487.20367 577.44958 3997743 3.08 6.68 624 539.53442 651.18878 3997744 3.08 6.72 568 478.31674 578.36157 3997745 3.08 6.76 481 356.44235 398.53439 3997746 3.08 6.8 419 286.80704 315.71359 3997747 3.08 6.84 394 261.37863 290.46881 3997748 3.08 6.88 318 226.71831 272.77759 3997749 3.08 6.92 282 211.39117 274.7088 3997750 3.08 6.96 254 204.65642 282.34079 3997751 3.08 7 243 204.45125 293.1264 3997752 3.08 7.04 237 206.15927 304.11359 3997753 3.08 7.08 233 208.21883 313.60959 3997754 3.08 7.12 229 211.37726 324.74399 3997755 3.08 7.16 227 216.45682 337.50879 4063232 3.12 4.8 247 246.4873 316.37439 4063233 3.12 4.84 273 240.50584 294.71841 4063234 3.12 4.88 281 234.4556 278.48959 4063235 3.12 4.92 271 222.22125 257.30881 4063236 3.12 4.96 287 228.27834 255.37601 4063237 3.12 5 304 232.91679 250.2464 4063238 3.12 5.04 313 227.80765 234.112 4063239 3.12 5.08 336 235.28737 231.79041 4063240 3.12 5.12 353 232.49414 218.30881 4063241 3.12 5.16 425 245.85609 210.9904 4063242 3.12 5.2 430 241.84695 201.8688 4063243 3.12 5.24 440 238.49185 190.44321 4063244 3.12 5.28 453 237.72368 181.9856 4063245 3.12 5.32 454 233.30954 174.44 4063246 3.12 5.36 473 244.03697 181.1008 4063247 3.12 5.4 470 237.36023 170.2128 4063248 3.12 5.44 452 219.23354 151.304 4063249 3.12 5.48 412 191.60184 124.9424 4063250 3.12 5.52 399 185.56627 119.4672 4063251 3.12 5.56 378 173.86888 109.96 4063252 3.12 5.6 376 170.61494 106.0528 4063253 3.12 5.64 372 167.78447 103.3648 4063254 3.12 5.68 371 166.4176 102.2128 4063255 3.12 5.72 365 163.99062 100.7472 4063256 3.12 5.76 359 160.41261 98.526398 4063257 3.12 5.8 354 156.70488 95.270401 4063258 3.12 5.84 348 152.16412 91.513603 4063259 3.12 5.88 355 155.51407 94.015999 4063260 3.12 5.92 388 181.09587 116.1984 4063261 3.12 5.96 556 401.72137 430.8848 4063262 3.12 6 550 395.73163 423.65121 4063263 3.12 6.04 349 168.6797 116.4256 4063264 3.12 6.08 323 159.94722 115.52 4063265 3.12 6.12 319 164.16309 123.4976 4063266 3.12 6.16 312 168.40761 132.57761 4063267 3.12 6.2 303 171.78307 140.7424 4063268 3.12 6.24 301 180.11104 153.0992 4063269 3.12 6.28 290 186.83986 165.37601 4063270 3.12 6.32 115 41.985519 21.104 4063271 3.12 6.36 142 50.748955 24.8944 4063272 3.12 6.4 167 64.232712 32.617599 4063273 3.12 6.44 158 67.213646 37.175999 4063275 3.12 6.52 241 87.386703 39.969601 4063276 3.12 6.56 274 106.20513 57.431999 4063277 3.12 6.6 333 171.00977 135.37601 4063278 3.12 6.64 446 320.51633 350.26401 4063279 3.12 6.68 505 387.19986 434.23361 4063280 3.12 6.72 464 337.05276 366.90561 4063281 3.12 6.76 390 229.02234 201.5984 4063282 3.12 6.8 333 170.82875 134.56799 4063283 3.12 6.84 297 153.19315 123.4096 4063285 3.12 6.92 93 19.674591 5.1567998 4063286 3.12 6.96 123 29.640238 9.5391998 4063287 3.12 7 114 25.315889 7.6528001 4063288 3.12 7.04 112 24.913868 7.7487998 4063289 3.12 7.08 111 25.320509 8.0704002 4063290 3.12 7.12 110 26.996445 9.2032003 4063291 3.12 7.16 108 28.932966 10.56 4128768 3.16 4.8 42 13.327939 5.7839999 4128769 3.16 4.84 39 6.889689 1.5776 4128770 3.16 4.88 29 4.73382 1.0592 4128771 3.16 4.92 168 104.91836 88.203201 4128772 3.16 4.96 168 91.781197 70.092796 4128773 3.16 5 150 67.815201 43.0784 4128774 3.16 5.04 127 48.152073 25.881599 4128775 3.16 5.08 113 38.803425 19.087999 4128776 3.16 5.12 69 19.397087 7.7600002 4128777 3.16 5.16 355 215.65956 186.3136 4128778 3.16 5.2 375 211.64218 174.64799 4128779 3.16 5.24 396 210.51851 163.48959 4128780 3.16 5.28 416 213.29005 156.7616 4128781 3.16 5.32 420 211.78104 152.424 4128782 3.16 5.36 436 220.36288 157.12959 4128783 3.16 5.4 425 206.77844 139.5824 4128784 3.16 5.44 413 192.6102 124.3616 4128785 3.16 5.48 362 168.94011 106.16 4128786 3.16 5.52 351 160.44887 97.444801 4128787 3.16 5.56 353 159.13219 93.531197 4128788 3.16 5.6 348 154.98006 89.2192 4128789 3.16 5.64 350 152.74246 84.956802 4128790 3.16 5.68 346 148.50285 82.171204 4128791 3.16 5.72 340 146.15814 81.227203 4128792 3.16 5.76 337 146.00421 82.6064 4128793 3.16 5.8 333 144.77597 83.649597 4128794 3.16 5.84 333 143.80528 83.420799 4128795 3.16 5.88 340 148.97957 88.5056 4128796 3.16 5.92 363 165.87131 104.3856 4128797 3.16 5.96 546 394.01614 422.9888 4128798 3.16 6 536 385.72137 414.896 4128799 3.16 6.04 333 160.13019 109.2224 4128800 3.16 6.08 310 152.57179 108.7024 4128801 3.16 6.12 305 157.37149 117.232 4128802 3.16 6.16 301 163.42891 127.32 4128803 3.16 6.2 300 172.11256 139.4464 4128804 3.16 6.24 293 178.54353 150.536 4128805 3.16 6.28 289 186.43147 162.8528 4128806 3.16 6.32 112 43.682781 23.568001 4128807 3.16 6.36 119 45.730396 24.8304 4128808 3.16 6.4 121 47.800858 26.420799 4128809 3.16 6.44 109 44.055561 24.5872 4128811 3.16 6.52 236 88.245117 42.123199 4128812 3.16 6.56 262 103.58092 56.768002 4128813 3.16 6.6 326 166.77905 130.99361 4128814 3.16 6.64 431 310.00848 340.59521 4128815 3.16 6.68 480 370.276 420.2496 4128816 3.16 6.72 427 304.66785 333.16 4128817 3.16 6.76 337 178.358 144.0032 4128818 3.16 6.8 273 115.20872 68.985603 4128819 3.16 6.84 243 96.810638 52.190399 4128821 3.16 6.92 83 17.128313 4.1887999 4128822 3.16 6.96 97 21.272156 6.2336001 4128823 3.16 7 111 27.025276 9.3535995 4128824 3.16 7.04 110 26.065348 8.7952003 4128825 3.16 7.08 107 25.454184 8.5727997 4128826 3.16 7.12 105 26.04426 8.9535999 4128827 3.16 7.16 106 28.961067 10.608 4194305 3.2 4.84 30 5.7652979 1.4912 4194306 3.2 4.88 27 5.0522752 1.3135999 4194307 3.2 4.92 75 26.693171 14.4528 4194308 3.2 4.96 83 32.136166 19.524799 4194309 3.2 5 77 25.613506 13.4784 4194310 3.2 5.04 68 17.73901 6.552 4194311 3.2 5.08 68 18.388031 6.9200001 4194312 3.2 5.12 68 19.094198 7.0704002 4194313 3.2 5.16 326 189.39143 154.87041 4194314 3.2 5.2 335 180.91406 139.9456 4194315 3.2 5.24 340 169.00072 119.7968 4194316 3.2 5.28 347 156.54019 96.582397 4194317 3.2 5.32 343 150.37836 90.086403 4194318 3.2 5.36 333 142.24568 83.118401 4194319 3.2 5.4 265 97.877777 48.865601 4194320 3.2 5.44 204 77.11097 40.420799 4194321 3.2 5.48 208 106.26859 73.059196 4194322 3.2 5.52 248 103.83669 55.268799 4194323 3.2 5.56 251 99.81015 48.624001 4194324 3.2 5.6 241 96.757286 48.048 4194325 3.2 5.64 184 76.418167 40.326401 4194326 3.2 5.68 180 72.889717 37.633598 4194327 3.2 5.72 251 101.16173 52.2528 4194328 3.2 5.76 283 115.87157 60.712002 4194329 3.2 5.8 300 127.66702 71.083199 4194330 3.2 5.84 312 136.29858 79.152 4194331 3.2 5.88 326 148.26349 90.889603 4194332 3.2 5.92 351 168.81058 112.9264 4194333 3.2 5.96 538 389.75046 420.35519 4194334 3.2 6 526 381.0748 412.71841 4194335 3.2 6.04 320 157.44823 108.408 4194336 3.2 6.08 303 152.73003 108.7696 4194337 3.2 6.12 296 155.50166 115.5184 4194338 3.2 6.16 296 163.6087 126.7648 4194339 3.2 6.2 295 171.69041 138.35361 4194340 3.2 6.24 288 177.28717 148.6192 4194341 3.2 6.28 288 187.5023 162.936 4194342 3.2 6.32 101 42.141998 24.523199 4194343 3.2 6.36 104 42.948174 25.419201 4194344 3.2 6.4 103 42.006329 24.8992 4194345 3.2 6.44 93 39.828022 23.740801 4194347 3.2 6.52 230 87.913895 43.980801 4194348 3.2 6.56 255 102.92833 58.041599 4194349 3.2 6.6 313 158.90723 123.3424 4194350 3.2 6.64 428 305.2117 329.35681 4194351 3.2 6.68 488 383.7525 436.328 4194352 3.2 6.72 422 303.99194 332.65921 4194353 3.2 6.76 316 165.76581 133.7552 4194354 3.2 6.8 252 102.16079 59.1488 4194355 3.2 6.84 229 86.95871 43.279999 4194357 3.2 6.92 83 18.575243 4.9952002 4194358 3.2 6.96 86 18.24155 4.9552002 4194359 3.2 7 98 23.307735 7.8175998 4194360 3.2 7.04 106 27.177498 10.0816 4194361 3.2 7.08 103 26.312174 9.5967999 4194362 3.2 7.12 105 28.274229 10.5248 4194363 3.2 7.16 103 29.424183 11.2224 4259841 3.24 4.84 27 6.0168109 1.7920001 4259842 3.24 4.88 27 5.832253 1.7104 4259843 3.24 4.92 71 21.333469 10.1584 4259844 3.24 4.96 81 28.698267 16.9648 4259845 3.24 5 81 26.454065 14.4048 4259846 3.24 5.04 72 18.256544 7.2351999 4259847 3.24 5.08 70 17.251848 6.1167998 4259848 3.24 5.12 69 17.703981 6.1872001 4259849 3.24 5.16 275 137.60223 91.332802 4259850 3.24 5.2 274 127.27692 79.689598 4259851 3.24 5.24 275 117.72443 68.344002 4259852 3.24 5.28 280 110.39739 58.041599 4259853 3.24 5.32 272 107.02144 58.6464 4259854 3.24 5.36 260 100.69891 53.703999 4259855 3.24 5.4 215 77.945946 39.755199 4259856 3.24 5.44 195 77.610741 43.625599 4259857 3.24 5.48 128 52.066845 26.740801 4259858 3.24 5.52 173 69.55941 34.926399 4259859 3.24 5.56 172 64.802238 30.246401 4259860 3.24 5.6 157 57.638287 25.9984 4259861 3.24 5.64 142 58.275364 29.686399 4259862 3.24 5.68 174 72.292641 36.848 4259863 3.24 5.72 191 70.891571 31.915199 4259864 3.24 5.76 227 88.659538 43.513599 4259865 3.24 5.8 245 97.323059 49.073601 4259866 3.24 5.84 259 103.53677 52.870399 4259867 3.24 5.88 282 121.46165 68.430397 4259868 3.24 5.92 311 151.72411 102.344 4259869 3.24 5.96 525 377.97293 410.08319 4259870 3.24 6 511 370.18506 403.18561 4259871 3.24 6.04 298 147.75584 99.7136 4259872 3.24 6.08 287 145.1375 101.1264 4259873 3.24 6.12 283 148.22972 107.0688 4259874 3.24 6.16 282 155.47636 117.5696 4259875 3.24 6.2 280 164.30658 131.0304 4259876 3.24 6.24 284 177.65083 148.83681 4259877 3.24 6.28 282 185.34163 160.6432 4259878 3.24 6.32 89 41.818237 26.312 4259879 3.24 6.36 96 40.436947 24.856001 4259880 3.24 6.4 97 42.221485 26.504 4259881 3.24 6.44 87 40.034889 25.028799 4259883 3.24 6.52 229 91.553207 48.7808 4259884 3.24 6.56 250 104.68884 62.9328 4259885 3.24 6.6 300 151.96605 118.9456 4259886 3.24 6.64 418 296.58411 316.95999 4259887 3.24 6.68 494 390.99408 442.4512 4259888 3.24 6.72 416 303.50266 332.92319 4259889 3.24 6.76 305 159.99535 129.94881 4259890 3.24 6.8 250 105.62165 64.900803 4259891 3.24 6.84 227 91.348122 50.1936 4259893 3.24 6.92 83 20.4732 6.0704002 4259894 3.24 6.96 84 19.183294 5.4447999 4259895 3.24 7 90 21.136593 6.5103998 4259896 3.24 7.04 97 25.44014 9.4463997 4259897 3.24 7.08 105 30.302172 12.344 4259898 3.24 7.12 100 28.700823 11.272 4259899 3.24 7.16 100 30.329388 12.056 4325377 3.28 4.84 26 6.6675682 2.2096 4325378 3.28 4.88 26 6.5166049 2.1328001 4325379 3.28 4.92 67 16.109274 5.7407999 4325380 3.28 4.96 79 24.191868 12.7184 4325381 3.28 5 84 26.795893 14.72 4325382 3.28 5.04 75 18.343124 7.3376002 4325383 3.28 5.08 70 15.504112 5.0367999 4325384 3.28 5.12 69 16.066582 5.1536002 4325385 3.28 5.16 242 113.23853 69.006401 4325386 3.28 5.2 231 97.006844 53.731201 4325387 3.28 5.24 231 89.743546 46.231998 4325388 3.28 5.28 244 91.149643 45.248001 4325389 3.28 5.32 250 99.231262 55.019199 4325390 3.28 5.36 236 92.355324 49.454399 4325391 3.28 5.4 194 72.953621 39.428799 4325392 3.28 5.44 187 76.101768 43.548801 4325403 3.28 5.88 44 10.038424 3.0864 4325404 3.28 5.92 104 46.874172 31.5504 4325405 3.28 5.96 348 284.89667 348.78879 4325406 3.28 6 340 279.56198 342.44159 4325407 3.28 6.04 62 20.797184 10.968 4325408 3.28 6.08 38 7.4723382 1.9152 4325415 3.28 6.36 92 42.082451 27.617599 4325416 3.28 6.4 87 42.028797 27.992001 4325419 3.28 6.52 226 95.450111 54.820801 4325420 3.28 6.56 242 105.59325 67.059196 4325421 3.28 6.6 290 149.43929 120.7184 4325422 3.28 6.64 407 289.14459 310.24481 4325423 3.28 6.68 503 400.80969 451.27521 4325424 3.28 6.72 420 307.24136 335.78561 4325425 3.28 6.76 291 152.99718 127.0768 4325426 3.28 6.8 245 109.38222 73.422401 4325427 3.28 6.84 220 92.002289 53.076801 4325429 3.28 6.92 83 22.786308 7.4144001 4325430 3.28 6.96 83 21.408356 6.7424002 4325431 3.28 7 85 21.686769 7.1487999 4325432 3.28 7.04 90 24.00281 8.368 4325433 3.28 7.08 96 28.436926 11.4496 4325434 3.28 7.12 102 33.125443 14.4032 4325435 3.28 7.16 100 33.578781 14.5904 4390915 3.32 4.92 66 14.990209 5.2031999 4390916 3.32 4.96 73 18.611401 8.4736004 4390917 3.32 5 85 25.633595 13.5424 4390918 3.32 5.04 81 20.973816 9.2720003 4390919 3.32 5.08 71 14.538219 4.3151999 4390920 3.32 5.12 71 15.570145 4.6367998 4390921 3.32 5.16 215 96.697273 55.492802 4390922 3.32 5.2 209 87.671967 48.099201 4390923 3.32 5.24 209 81.504868 42.265598 4390924 3.32 5.28 230 88.296219 45.4384 4390925 3.32 5.32 240 98.161697 55.152 4390926 3.32 5.36 219 87.66909 47.380798 4390927 3.32 5.4 184 73.970482 42.9744 4390928 3.32 5.44 181 77.149773 45.563202 4390939 3.32 5.88 58 14.61967 5.0960002 4390940 3.32 5.92 115 40.677982 19.937599 4390941 3.32 5.96 318 275.23666 347.33441 4390942 3.32 6 305 262.57748 335.11041 4390943 3.32 6.04 82 24.917185 10.4352 4390944 3.32 6.08 73 33.350075 25.6304 4390951 3.32 6.36 87 42.554436 29.0832 4390952 3.32 6.4 86 44.204044 31.132799 4390953 3.32 6.44 9 0.67803377 0.056000002 4390955 3.32 6.52 226 100.44596 60.798401 4390956 3.32 6.56 239 110.97665 75.731201 4390957 3.32 6.6 275 147.229 126.8944 4390958 3.32 6.64 400 285.42752 308.70721 4390959 3.32 6.68 511 403.04703 446.608 4390960 3.32 6.72 412 296.58502 318.10559 4390961 3.32 6.76 282 154.54916 136.1696 4390962 3.32 6.8 237 112.16035 80.5504 4390963 3.32 6.84 221 98.028473 60.2048 4456451 3.36 4.92 69 15.808177 5.4559999 4456452 3.36 4.96 68 13.359553 4.0208001 4456453 3.36 5 86 25.114708 12.7104 4456454 3.36 5.04 87 23.729494 10.9536 4456455 3.36 5.08 72 13.885287 3.7423999 4456456 3.36 5.12 72 15.037488 4.1408 4456457 3.36 5.16 198 89.29718 50.431999 4456458 3.36 5.2 196 84.911949 47.492802 4456459 3.36 5.24 191 78.324951 42.464001 4456460 3.36 5.28 224 89.980637 48.547199 4456461 3.36 5.32 240 102.23216 58.2784 4456462 3.36 5.36 190 77.044121 42.475201 4456463 3.36 5.4 180 77.433578 46.313599 4456464 3.36 5.44 174 77.778572 47.454399 4456475 3.36 5.88 69 18.826794 7.1279998 4456476 3.36 5.92 98 30.655605 13.488 4456477 3.36 5.96 312 273.68289 350.03519 4456478 3.36 6 296 259.03159 337.02881 4456479 3.36 6.04 74 19.497139 7.2096 4456480 3.36 6.08 59 17.626604 7.888 4456487 3.36 6.36 86 45.378212 32.491199 4456488 3.36 6.4 82 45.096119 33.5536 4456489 3.36 6.44 12 1.1826197 0.16159999 4456491 3.36 6.52 219 104.75481 68.358398 4456492 3.36 6.56 235 117.89436 87.9776 4456493 3.36 6.6 260 147.96555 135.6864 4456494 3.36 6.64 386 269.81708 289.6528 4456495 3.36 6.68 521 405.2955 442.91199 4456496 3.36 6.72 402 286.02222 306.0864 4456497 3.36 6.76 269 154.95058 144.8736 4456498 3.36 6.8 236 119.02737 89.931198 4456499 3.36 6.84 216 102.58612 67.292801 4521987 3.4 4.92 65 14.051261 4.5344 4521988 3.4 4.96 71 14.987683 4.8319998 4521989 3.4 5 80 19.29541 7.8144002 4521990 3.4 5.04 91 25.207209 11.512 4521991 3.4 5.08 74 14.03632 3.5583999 4521992 3.4 5.12 71 13.962708 3.4400001 4521993 3.4 5.16 189 88.361374 50.763199 4521994 3.4 5.2 187 85.483803 49.832001 4521995 3.4 5.24 187 82.760773 47.348801 4521996 3.4 5.28 223 93.70871 52.366402 4521997 3.4 5.32 240 107.04491 63.015999 4521998 3.4 5.36 180 80.270615 47.3344 4521999 3.4 5.4 178 83.948471 54.700802 4522000 3.4 5.44 175 83.726578 52.9408 4522011 3.4 5.88 62 17.826691 7.2431998 4522012 3.4 5.92 79 20.414181 7.2607999 4522013 3.4 5.96 314 273.72491 353.00479 4522014 3.4 6 295 263.09473 347.19839 4522015 3.4 6.04 65 17.114332 6.5296001 4522016 3.4 6.08 57 16.266886 6.6528001 4522023 3.4 6.36 83 46.978073 35.073601 4522024 3.4 6.4 82 48.138897 37.248001 4522025 3.4 6.44 18 3.034009 0.70719999 4522027 3.4 6.52 215 109.43261 75.3936 4522028 3.4 6.56 226 122.3838 97.0784 4522029 3.4 6.6 255 155.66858 150.8848 4522030 3.4 6.64 364 254.77324 279.9664 4522031 3.4 6.68 532 407.7717 441.65121 4522032 3.4 6.72 383 267.93436 286.78079 4522033 3.4 6.76 257 158.68805 155.528 4522034 3.4 6.8 229 126.30561 102.7536 4522035 3.4 6.84 217 111.39352 77.7136 4587523 3.44 4.92 59 11.272802 2.8192 4587524 3.44 4.96 66 13.404613 4.0640001 4587525 3.44 5 73 14.911999 4.4400001 4587526 3.44 5.04 94 25.628658 10.8448 4587527 3.44 5.08 85 19.23628 6.2543998 4587528 3.44 5.12 70 13.510636 3.1503999 4587532 3.44 5.28 184 87.265923 53.387199 4587533 3.44 5.32 225 107.50577 65.248001 4587547 3.44 5.88 55 16.347317 6.7343998 4587548 3.44 5.92 61 17.929689 7.4432001 4587549 3.44 5.96 320 274.43207 356.784 4587550 3.44 6 305 271.99124 359.05759 4587551 3.44 6.04 59 17.108496 6.9679999 4587552 3.44 6.08 54 16.288822 6.8671999 4587563 3.44 6.52 214 116.50597 84.760002 4587564 3.44 6.56 227 132.735 111.3808 4587565 3.44 6.6 246 162.22377 163.20959 4587566 3.44 6.64 284 209.13023 251.856 4587567 3.44 6.68 541 406.59702 437.60159 4587568 3.44 6.72 296 208.37917 242.5984 4587569 3.44 6.76 249 166.24361 168.9968 4587570 3.44 6.8 230 136.85611 117.6336 4587571 3.44 6.84 216 119.03523 88.265602 4653059 3.48 4.92 53 9.7860441 2.1456001 4653060 3.48 4.96 55 9.6227465 2.1631999 4653061 3.48 5 65 12.731128 3.4576001 4653062 3.48 5.04 104 29.844608 12.288 4653063 3.48 5.08 107 28.701813 10.7264 4653064 3.48 5.12 67 12.803747 2.8943999 4653068 3.48 5.28 175 87.678726 57.439999 4653069 3.48 5.32 214 105.90837 66.776001 4653083 3.48 5.88 153 91.236832 75.337601 4653084 3.48 5.92 173 111.46124 98.939201 4653085 3.48 5.96 319 273.52127 361.29919 4653086 3.48 6 321 279.25226 368.31201 4653087 3.48 6.04 170 106.83343 92.526398 4653088 3.48 6.08 153 93.950623 81.172798 4653099 3.48 6.52 279 184.00923 156.0896 4653100 3.48 6.56 280 182.20584 155.1792 4653101 3.48 6.6 279 178.2612 150.56 4653102 3.48 6.64 279 176.21028 148.1264 4653103 3.48 6.68 546 401.89478 430.09439 4653104 3.48 6.72 279 175.60222 146.9856 4653105 3.48 6.76 281 179.05898 150.448 4653106 3.48 6.8 283 183.84343 155.7536 4653107 3.48 6.84 285 189.1093 160.8672 4718595 3.52 4.92 53 11.153886 2.7504001 4718596 3.52 4.96 53 10.258481 2.4047999 4718597 3.52 5 53 9.7986956 2.2320001 4718598 3.52 5.04 53 9.7986956 2.2320001 4718599 3.52 5.08 136 36.515694 12.8288 4718600 3.52 5.12 53 11.153886 2.7504001 4718604 3.52 5.28 197 101.64323 68.876801 4718605 3.52 5.32 228 108.93305 69.020798 4718619 3.52 5.88 154 84.795479 66.756798 4718620 3.52 5.92 185 107.9444 91.236801 4718621 3.52 5.96 315 273.60031 367.36639 4718622 3.52 6 320 278.55991 373.29761 4718623 3.52 6.04 176 102.96487 85.7584 4718624 3.52 6.08 150 82.604904 65.092796 4718635 3.52 6.52 279 174.56334 142.79359 4718636 3.52 6.56 281 173.94872 143.8768 4718637 3.52 6.6 285 170.19998 137.8992 4718638 3.52 6.64 350 199.14301 153.2128 4718639 3.52 6.68 529 395.41711 427.35999 4718640 3.52 6.72 365 207.49899 157.99519 4718641 3.52 6.76 286 170.35776 137.4144 4718642 3.52 6.8 284 174.69962 142.6832 4718643 3.52 6.84 284 178.73549 146.6992 4784133 3.56 5 113 37.637146 15.3488 4784134 3.56 5.04 115 34.503574 12.9872 4784135 3.56 5.08 154 42.56052 14.6336 4784136 3.56 5.12 132 36.775688 13.6352 4784137 3.56 5.16 152 70.46386 58.822399 4784138 3.56 5.2 167 88.366745 81.705597 4784139 3.56 5.24 183 104.89032 102.5216 4784140 3.56 5.28 234 106.96112 70.217598 4784141 3.56 5.32 233 107.29855 69.996803 4784142 3.56 5.36 114 32.078686 11.4752 4784143 3.56 5.4 114 35.139694 13.5712 4784144 3.56 5.44 111 36.618893 14.8096 4784155 3.56 5.88 154 75.37542 53.497601 4784156 3.56 5.92 191 104.98361 84.700798 4784157 3.56 5.96 315 274.51901 374.3056 4784158 3.56 6 322 280.11679 380.64001 4784159 3.56 6.04 181 99.676407 80.113602 4784160 3.56 6.08 151 74.961555 54.513599 4784171 3.56 6.52 283 167.9126 132.4944 4784172 3.56 6.56 286 166.22685 131.70399 4784173 3.56 6.6 297 164.85274 126.8512 4784174 3.56 6.64 368 210.00127 162.336 4784175 3.56 6.68 510 386.5878 425.73441 4784176 3.56 6.72 406 261.6387 241.1024 4784177 3.56 6.76 302 167.18726 127.6304 4784178 3.56 6.8 290 169.08952 133.6544 4784179 3.56 6.84 288 171.28506 134.8208 4849669 3.6 5 114 35.091648 13.5728 4849670 3.6 5.04 123 34.921398 12.784 4849671 3.6 5.08 144 38.394089 12.9232 4849672 3.6 5.12 143 36.483582 11.7696 4849673 3.6 5.16 158 62.884594 46.462399 4849674 3.6 5.2 171 84.542656 75.841599 4849675 3.6 5.24 186 101.04 96.783997 4849676 3.6 5.28 228 104.20677 71.198402 4849677 3.6 5.32 226 105.26564 72.255997 4849678 3.6 5.36 131 36.904808 13.7936 4849679 3.6 5.4 115 32.951805 12.2096 4849680 3.6 5.44 112 34.515949 13.2928 4849691 3.6 5.88 156 68.553345 43.372799 4849692 3.6 5.92 203 107.34419 82.113602 4849693 3.6 5.96 313 273.23203 379.952 4849694 3.6 6 325 282.0802 388.90881 4849695 3.6 6.04 186 96.419052 73.776001 4849696 3.6 6.08 146 63.308136 39.528 4849707 3.6 6.52 284 159.94545 121.0656 4849708 3.6 6.56 293 160.14421 120.928 4849709 3.6 6.6 307 162.11749 118.656 4849710 3.6 6.64 396 245.95044 220.4416 4849711 3.6 6.68 495 376.45529 422.52802 4849712 3.6 6.72 418 283.85822 285.47519 4849713 3.6 6.76 313 164.95998 119.7632 4849714 3.6 6.8 299 163.69766 123.0592 4849715 3.6 6.84 289 162.56738 121.9584 4915205 3.64 5 117 34.660728 12.9792 4915206 3.64 5.04 126 34.173012 11.968 4915207 3.64 5.08 142 36.938423 12.208 4915208 3.64 5.12 143 35.345108 11.1696 4915209 3.64 5.16 161 57.077602 36.708801 4915210 3.64 5.2 179 82.745964 70.935997 4915211 3.64 5.24 202 105.2439 95.414398 4915212 3.64 5.28 223 102.25796 72.734398 4915213 3.64 5.32 216 100.42537 71.982399 4915214 3.64 5.36 152 48.425785 21.9296 4915215 3.64 5.4 115 30.590506 10.6592 4915216 3.64 5.44 109 31.153164 11.192 4915227 3.64 5.88 151 59.021183 31.881599 4915228 3.64 5.92 210 106.3511 77.425598 4915229 3.64 5.96 315 273.56274 386.92319 4915230 3.64 6 324 281.64362 395.70239 4915231 3.64 6.04 195 96.881264 70.246399 4915232 3.64 6.08 146 56.138435 29.788799 4915243 3.64 6.52 289 153.36447 109.8448 4915244 3.64 6.56 298 155.55373 112.1152 4915245 3.64 6.6 319 162.93791 114.3536 4915246 3.64 6.64 408 266.7323 262.7648 4915247 3.64 6.68 481 367.09738 422.88321 4915248 3.64 6.72 428 297.8053 312.62561 4915249 3.64 6.76 323 165.63701 115.9424 4915250 3.64 6.8 304 159.0667 114.2512 4915251 3.64 6.84 296 158.13094 113.5072 4980741 3.68 5 115 31.84926 11.024 4980742 3.68 5.04 131 35.147251 11.9856 4980743 3.68 5.08 141 36.435745 12.0448 4980744 3.68 5.12 142 34.554558 10.8448 4980745 3.68 5.16 160 51.591976 29.384001 4980746 3.68 5.2 183 81.420792 67.038399 4980747 3.68 5.24 219 109.21953 93.384003 4980748 3.68 5.28 221 101.8166 75.070396 4980749 3.68 5.32 215 101.41496 75.440002 4980750 3.68 5.36 165 57.301041 29.283199 4980751 3.68 5.4 116 29.788738 10 4980752 3.68 5.44 108 29.181211 9.8319998 4980763 3.68 5.88 147 53.296783 26.1712 4980764 3.68 5.92 221 108.55283 75.374397 4980765 3.68 5.96 322 276.4371 395.84161 4980766 3.68 6 332 285.353 405.4592 4980767 3.68 6.04 206 98.509697 67.695999 4980768 3.68 6.08 141 49.791374 23.7904 4980779 3.68 6.52 290 147.28296 100.8576 4980780 3.68 6.56 304 151.8914 104.3744 4980781 3.68 6.6 329 165.65765 114.112 4980782 3.68 6.64 411 275.94928 288.4592 4980783 3.68 6.68 469 357.26855 422.10239 4980784 3.68 6.72 432 311.68463 352.74081 4980785 3.68 6.76 332 167.49342 114.6304 4980786 3.68 6.8 310 155.25868 106.3856 4980787 3.68 6.84 302 154.88715 106.1232 5046277 3.72 5 118 33.841423 12.3792 5046278 3.72 5.04 129 34.548061 11.728 5046279 3.72 5.08 140 36.499531 12.1664 5046280 3.72 5.12 141 34.567535 11.0064 5046281 3.72 5.16 155 41.453159 15.7424 5046282 3.72 5.2 198 87.227699 67.772797 5046283 3.72 5.24 230 114.69283 94.8144 5046284 3.72 5.28 219 102.88044 78.811203 5046285 3.72 5.32 214 102.34213 78.692802 5046286 3.72 5.36 164 59.806667 33.16 5046287 3.72 5.4 120 32.692966 12.0528 5046288 3.72 5.44 107 28.217854 9.1264 5046299 3.72 5.88 135 43.395359 18.096001 5046300 3.72 5.92 231 110.6135 74.047997 5046301 3.72 5.96 331 280.10056 405.60321 5046302 3.72 6 344 290.0437 414.82239 5046303 3.72 6.04 214 99.142281 64.971199 5046304 3.72 6.08 128 39.405678 15.5552 5046315 3.72 6.52 295 144.21135 94.32 5046316 3.72 6.56 309 149.26927 98.400002 5046317 3.72 6.6 335 166.22925 112.6432 5046318 3.72 6.64 414 280.33197 301.01599 5046319 3.72 6.68 463 351.0303 421.0896 5046320 3.72 6.72 436 323.82007 392.28961 5046321 3.72 6.76 339 168.24883 113.0608 5046322 3.72 6.8 318 155.04358 102.1008 5046323 3.72 6.84 305 150.08501 97.8256 5111813 3.76 5 121 37.404617 15.0848 5111814 3.76 5.04 132 38.353199 14.464 5111815 3.76 5.08 136 36.413818 12.5728 5111816 3.76 5.12 146 37.00024 12.0064 5111817 3.76 5.16 153 39.571491 13.8912 5111818 3.76 5.2 209 92.075829 69.183998 5111819 3.76 5.24 244 121.80574 97.644798 5111820 3.76 5.28 220 105.93861 83.608002 5111821 3.76 5.32 207 103.07091 82.9552 5111822 3.76 5.36 160 61.18861 36.084801 5111823 3.76 5.4 124 36.65136 15.1152 5111824 3.76 5.44 107 29.307137 9.8752003 5111835 3.76 5.88 122 37.137108 14.6672 5111836 3.76 5.92 240 112.77154 74.070396 5111837 3.76 5.96 347 286.68719 417.47198 5111838 3.76 6 358 296.58817 427.6416 5111839 3.76 6.04 224 100.75686 63.495998 5111840 3.76 6.08 114 33.854713 12.7936 5111851 3.76 6.52 299 141.98611 89.512001 5111852 3.76 6.56 314 147.59059 93.528 5111853 3.76 6.6 337 164.26064 109.52 5111854 3.76 6.64 417 286.9361 320.12799 5111855 3.76 6.68 453 343.44788 423.0816 5111856 3.76 6.72 432 319.89462 395.4624 5111857 3.76 6.76 344 168.46283 112.0896 5111858 3.76 6.8 323 154.02339 98.537598 5111859 3.76 6.84 313 149.66727 93.575996 5177349 3.8 5 109 31.196402 10.6544 5177350 3.8 5.04 126 37.119129 13.9024 5177351 3.8 5.08 139 41.659462 16.3696 5177352 3.8 5.12 141 37.751297 13.0432 5177353 3.8 5.16 155 40.686817 14.4128 5177354 3.8 5.2 224 98.344856 70.321602 5177355 3.8 5.24 253 126.09697 98.214401 5177356 3.8 5.28 217 107.69743 87.603203 5177357 3.8 5.32 197 102.33067 86.049599 5177358 3.8 5.36 161 66.170029 41.585602 5177359 3.8 5.4 128 42.895687 20.6224 5177360 3.8 5.44 111 34.124973 13.4512 5177371 3.8 5.88 74 21.538057 8.9119997 5177372 3.8 5.92 256 119.12682 78.294403 5177373 3.8 5.96 364 292.68958 429.51041 5177374 3.8 6 377 304.03152 440.52481 5177375 3.8 6.04 238 102.69073 61.422401 5177376 3.8 6.08 68 17.727894 6.0960002 5177387 3.8 6.52 303 140.48882 85.760002 5177388 3.8 6.56 319 148.98289 93.767998 5177389 3.8 6.6 338 163.131 108.5744 5177390 3.8 6.64 422 296.21005 346.5376 5177391 3.8 6.68 449 339.70905 427.8208 5177392 3.8 6.72 431 318.48309 402.37759 5177393 3.8 6.76 349 169.20963 111.9536 5177394 3.8 6.8 334 157.92419 99.395203 5177395 3.8 6.84 318 148.97647 90.487999 5242885 3.84 5 108 33.18716 12.0224 5242886 3.84 5.04 113 33.364342 12.0176 5242887 3.84 5.08 117 33.362137 11.9808 5242888 3.84 5.12 132 37.969395 14.1136 5242889 3.84 5.16 169 51.739338 21.5168 5242890 3.84 5.2 249 107.68726 73.529602 5242891 3.84 5.24 266 132.55066 100.816 5242892 3.84 5.28 203 108.31637 92.385597 5242893 3.84 5.32 190 104.76852 91.313599 5242894 3.84 5.36 158 70.562195 47.4272 5242895 3.84 5.4 130 49.633965 27.2768 5242896 3.84 5.44 110 36.539612 15.456 5242906 3.84 5.84 175 73.942566 41.2528 5242907 3.84 5.88 192 83.670395 49.5536 5242908 3.84 5.92 287 129.009 84.5728 5242909 3.84 5.96 377 297.99008 442.24799 5242910 3.84 6 388 308.68948 453.31839 5242911 3.84 6.04 268 108.88148 61.371201 5242912 3.84 6.08 187 81.851807 48.812801 5242923 3.84 6.52 308 140.70105 83.739197 5242924 3.84 6.56 324 149.95047 93.710403 5242925 3.84 6.6 343 163.86635 108.5312 5242926 3.84 6.64 424 307.28412 383.55521 5242927 3.84 6.68 451 341.42999 438.616 5242928 3.84 6.72 430 313.43472 399.44159 5242929 3.84 6.76 354 170.25734 112.2816 5242930 3.84 6.8 339 158.73792 99.094398 5242931 3.84 6.84 323 149.0965 88.708801 5308426 3.88 5.2 293 123.93092 79.9552 5308427 3.88 5.24 278 137.9413 102.7584 5308441 3.88 5.8 171 69.020195 35.774399 5308442 3.88 5.84 194 78.37896 43.075199 5308443 3.88 5.88 221 87.895699 48.6544 5308444 3.88 5.92 301 137.89575 94.939201 5308445 3.88 5.96 389 304.30341 456.36801 5308446 3.88 6 396 312.4252 464.72159 5308447 3.88 6.04 272 107.62782 58.720001 5308448 3.88 6.08 222 90.24276 51.558399 5308449 3.88 6.12 195 84.316086 49.7248 5308450 3.88 6.16 172 73.635239 41.383999 5308459 3.88 6.52 309 139.67505 82.152 5308460 3.88 6.56 325 148.6674 92.311996 5308461 3.88 6.6 345 163.41258 108.1808 5308462 3.88 6.64 429 317.90216 420.3056 5308463 3.88 6.68 454 342.99234 449.16479 5308464 3.88 6.72 429 310.61417 402.83679 5308465 3.88 6.76 358 171.02823 112.8048 5308466 3.88 6.8 347 162.11028 101.0112 5308467 3.88 6.84 334 155.43756 92.924797 5373957 3.92 5 150 73.670654 50.235199 5373958 3.92 5.04 149 65.661499 40.649601 5373959 3.92 5.08 153 62.911175 36.849602 5373960 3.92 5.12 159 60.251488 32.660801 5373961 3.92 5.16 210 88.878517 56.787201 5373962 3.92 5.2 286 132.76213 90.401604 5373963 3.92 5.24 265 122.39809 84.777603 5373964 3.92 5.28 150 44.697933 19.510401 5373965 3.92 5.32 127 34.569172 11.9024 5373966 3.92 5.36 119 33.554199 12.1136 5373967 3.92 5.4 108 31.571213 11.8128 5373968 3.92 5.44 99 31.342567 12.2672 5373969 3.92 5.48 107 43.202358 23.304001 5373970 3.92 5.52 110 39.581543 19.408001 5373971 3.92 5.56 120 40.167877 17.763201 5373972 3.92 5.6 124 40.048847 16.768 5373973 3.92 5.64 122 38.610867 15.7536 5373974 3.92 5.68 116 37.749878 16.0224 5373975 3.92 5.72 88 29.603874 13.4864 5373977 3.92 5.8 192 78.458076 43.134399 5373978 3.92 5.84 215 84.097046 45.220798 5373979 3.92 5.88 260 103.63313 57.129601 5373980 3.92 5.92 332 159.71315 117.008 5373981 3.92 5.96 419 324.58228 481.96161 5373982 3.92 6 430 335.95377 493.11359 5373983 3.92 6.04 302 127.30866 74.436798 5373984 3.92 6.08 261 109.38262 64.6912 5373985 3.92 6.12 223 95.992752 58.588799 5373986 3.92 6.16 192 86.876244 54.348801 5373988 3.92 6.24 103 34.957153 15.456 5373989 3.92 6.28 124 41.605167 17.787201 5373990 3.92 6.32 131 44.179832 18.812799 5373991 3.92 6.36 139 49.607708 22.2432 5373992 3.92 6.4 131 51.785755 26.467199 5373993 3.92 6.44 106 42.808647 23.443199 5373995 3.92 6.52 316 143.47762 85.1856 5373996 3.92 6.56 332 151.53909 95.012802 5373997 3.92 6.6 353 165.08064 109.2576 5373998 3.92 6.64 434 320.62326 434.1264 5373999 3.92 6.68 457 344.6965 459.79999 5374000 3.92 6.72 437 316.72379 416.3504 5374001 3.92 6.76 374 182.48108 122.9776 5374002 3.92 6.8 364 175.40744 113.352 5374003 3.92 6.84 355 170.86453 105.9072 5439493 3.96 5 185 117.08573 112.1152 5439494 3.96 5.04 191 112.57703 102.7488 5439495 3.96 5.08 197 105.93747 90.097603 5439496 3.96 5.12 204 97.703293 74.008003 5439497 3.96 5.16 261 130.72487 96.532799 5439498 3.96 5.2 297 152.69493 113.3136 5439499 3.96 5.24 273 128.67374 88.870399 5439500 3.96 5.28 198 70.046379 34.835201 5439501 3.96 5.32 170 53.941669 23.452801 5439502 3.96 5.36 145 42.912868 17.004801 5439503 3.96 5.4 122 32.501381 11.088 5439504 3.96 5.44 102 29.026098 10.304 5439505 3.96 5.48 153 85.296722 67.243202 5439506 3.96 5.52 175 86.432487 62.627201 5439507 3.96 5.56 191 89.74118 61.571201 5439508 3.96 5.6 194 84.298515 51.915199 5439509 3.96 5.64 190 76.86618 42.6096 5439510 3.96 5.68 171 60.687313 27.739201 5439511 3.96 5.72 141 48.196354 21.4816 5439513 3.96 5.8 225 89.903557 49.743999 5439514 3.96 5.84 278 115.30897 64.2976 5439515 3.96 5.88 332 145.04651 84.304001 5439516 3.96 5.92 400 208.79576 161.0544 5439517 3.96 5.96 483 370.88358 528.08801 5439518 3.96 6 490 379.14676 537.09277 5439519 3.96 6.04 363 165.97176 102.08 5439520 3.96 6.08 325 145.84183 89.228798 5439521 3.96 6.12 277 120.31478 72.9552 5439522 3.96 6.16 220 97.325882 61.363201 5439524 3.96 6.24 148 48.530956 20.2048 5439525 3.96 6.28 174 65.999504 33.8288 5439526 3.96 6.32 197 88.172066 56.905602 5439527 3.96 6.36 200 96.457352 67.919998 5439528 3.96 6.4 208 108.07849 81.5168 5439529 3.96 6.44 202 115.37553 91.830399 5439531 3.96 6.52 321 143.32928 84.496002 5439532 3.96 6.56 347 156.30609 98.302399 5439533 3.96 6.6 375 176.51581 117.7232 5439534 3.96 6.64 459 337.15005 455.4592 5439535 3.96 6.68 486 366.6636 487.15201 5439536 3.96 6.72 466 340.78439 444.74881 5439537 3.96 6.76 408 211.69891 151.90559 5439538 3.96 6.8 399 210.28708 152.4064 5439539 3.96 6.84 393 212.45503 156.064 5505029 4 5 221 165.45439 185.3392 5505030 4 5.04 229 161.80005 175.1456 5505031 4 5.08 241 160.19992 166.4976 5505032 4 5.12 258 161.24843 159.7424 5505033 4 5.16 310 194.51041 183.4832 5505034 4 5.2 344 221.51744 207.45441 5505035 4 5.24 341 205.2357 181.5984 5505036 4 5.28 286 158.2099 134.3568 5505037 4 5.32 265 142.50206 118.7968 5505038 4 5.36 258 136.15849 110.08 5505039 4 5.4 249 129.25566 101.6464 5505040 4 5.44 249 125.07973 94.492798 5505041 4 5.48 250 121.78426 88.390404 5505042 4 5.52 238 115.8061 82.091202 5505043 4 5.56 237 113.90524 78.416 5505044 4 5.6 236 110.88589 73.686401 5505045 4 5.64 242 111.31292 71.192001 5505046 4 5.68 249 111.78013 68.705597 5505047 4 5.72 260 112.25354 66.116798 5505048 4 5.76 282 117.07362 65.849602 5505049 4 5.8 293 121.7231 67.7808 5505050 4 5.84 310 127.08616 69.265602 5505051 4 5.88 363 161.99287 95.816002 5505052 4 5.92 414 220.96396 179.81599 5505053 4 5.96 490 377.1395 544.74561 5505054 4 6 498 385.00595 552.94562 5505055 4 6.04 379 176.48697 112.7952 5505056 4 6.08 354 160.30405 98.262398 5505057 4 6.12 305 128.18185 74.446404 5505058 4 6.16 289 123.01432 74.047997 5505059 4 6.2 272 119.01837 74.419197 5505060 4 6.24 248 115.15382 76.793602 5505061 4 6.28 239 114.16952 79.110397 5505062 4 6.32 228 113.31559 82.870399 5505063 4 6.36 227 115.73747 87.203201 5505064 4 6.4 233 120.86758 93.515198 5505065 4 6.44 255 133.23369 102.8464 5505066 4 6.48 334 178.95193 136.328 5505067 4 6.52 474 257.5593 195.4064 5505068 4 6.56 480 269.66663 215.0192 5505069 4 6.6 487 282.43597 234.9408 5505070 4 6.64 553 437.64215 581.55841 5505071 4 6.68 569 463.68814 617.95679 5505072 4 6.72 540 431.9949 570.9552 5505073 4 6.76 475 297.66382 270.85919 5505074 4 6.8 462 292.99069 269.37921 5505075 4 6.84 449 288.84985 267.944 5570565 4.04 5 226 169.46622 189.64481 5570566 4.04 5.04 236 166.9639 180.0096 5570567 4.04 5.08 248 165.63522 171.216 5570568 4.04 5.12 265 165.21123 162.3744 5570569 4.04 5.16 307 191.85428 181.63361 5570570 4.04 5.2 347 225.13086 212.25281 5570571 4.04 5.24 338 202.77597 178.88 5570572 4.04 5.28 289 160.00456 136.23039 5570573 4.04 5.32 272 146.90936 122.2992 5570574 4.04 5.36 261 137.57834 111.4464 5570575 4.04 5.4 258 132.72009 104.0336 5570576 4.04 5.44 257 128.58575 97.300797 5570577 4.04 5.48 257 125.27472 91.257599 5570578 4.04 5.52 254 123.02786 86.451202 5570579 4.04 5.56 249 119.0877 81.137604 5570580 4.04 5.6 247 116.26254 76.776001 5570581 4.04 5.64 253 115.63113 73.295998 5570582 4.04 5.68 261 115.89314 70.547203 5570583 4.04 5.72 279 119.4416 69.321602 5570584 4.04 5.76 288 119.10681 66.964798 5570585 4.04 5.8 297 121.75052 67.318398 5570586 4.04 5.84 312 126.3956 68.300797 5570587 4.04 5.88 364 163.61322 97.9776 5570588 4.04 5.92 420 230.38477 199.79201 5570589 4.04 5.96 494 382.50961 561.52319 5570590 4.04 6 501 389.88315 569.4624 5570591 4.04 6.04 387 181.46663 118.744 5570592 4.04 6.08 361 164.21957 101.552 5570593 4.04 6.12 306 126.65654 72.761597 5570594 4.04 6.16 289 121.38583 72.585602 5570595 4.04 6.2 274 118.78155 73.915199 5570596 4.04 6.24 268 120.91976 78.590401 5570597 4.04 6.28 238 113.24891 78.68 5570598 4.04 6.32 235 116.26037 84.414398 5570599 4.04 6.36 232 117.85336 88.519997 5570600 4.04 6.4 239 123.75728 95.662399 5570601 4.04 6.44 261 133.78737 102.9392 5570602 4.04 6.48 366 185.87395 136.06081 5570603 4.04 6.52 481 262.01947 200.776 5570604 4.04 6.56 487 275.28873 221.8736 5570605 4.04 6.6 489 284.27887 238.4016 5570606 4.04 6.64 556 443.81863 599.19202 5570607 4.04 6.68 566 463.72784 628.71039 5570608 4.04 6.72 539 434.52194 584.21118 5570609 4.04 6.76 480 305.80246 285.72321 5570610 4.04 6.8 466 297.93945 276.21759 5570611 4.04 6.84 456 296.29083 276.64319 5636101 4.08 5 226 169.37532 188.7856 5636102 4.08 5.04 232 165.11362 178.62399 5636103 4.08 5.08 246 164.02502 169.67039 5636104 4.08 5.12 276 178.13734 175.78239 5636105 4.08 5.16 303 188.34338 179.05119 5636106 4.08 5.2 351 226.74525 212.9216 5636107 4.08 5.24 332 196.33717 172.01601 5636108 4.08 5.28 285 157.63307 135.1344 5636109 4.08 5.32 275 151.81807 127.736 5636110 4.08 5.36 249 132.66187 109.5984 5636111 4.08 5.4 245 129.65561 104.7456 5636112 4.08 5.44 242 125.59612 97.798401 5636113 4.08 5.48 234 120.2196 91.334396 5636114 4.08 5.52 234 117.21037 85.7696 5636115 4.08 5.56 236 115.60161 81.905602 5636116 4.08 5.6 241 115.46832 78.487999 5636117 4.08 5.64 248 115.23258 74.896004 5636118 4.08 5.68 253 114.50205 71.499199 5636119 4.08 5.72 268 118.02531 71.225601 5636120 4.08 5.76 290 123.14875 71.047997 5636121 4.08 5.8 300 127.12801 71.982399 5636122 4.08 5.84 315 132.60551 74.024002 5636123 4.08 5.88 368 169.48622 103.9744 5636124 4.08 5.92 430 246.19586 227.9024 5636125 4.08 5.96 497 391.44199 583.22717 5636126 4.08 6 505 399.48822 591.59839 5636127 4.08 6.04 391 188.57324 126.8368 5636128 4.08 6.08 362 168.52315 106.2112 5636129 4.08 6.12 310 132.42831 77.928001 5636130 4.08 6.16 294 127.83385 78.015999 5636131 4.08 6.2 284 127.00666 80.620796 5636132 4.08 6.24 257 121.75768 82.401604 5636133 4.08 6.28 251 122.72186 86.468803 5636134 4.08 6.32 237 120.19675 89.199997 5636135 4.08 6.36 238 124.23988 95.675201 5636136 4.08 6.4 240 128.13878 101.4288 5636137 4.08 6.44 265 143.87019 114.632 5636138 4.08 6.48 316 190.69547 159.2608 5636139 4.08 6.52 474 266.84833 213.024 5636140 4.08 6.56 478 275.44342 229.0224 5636141 4.08 6.6 490 294.9534 262.9584 5636142 4.08 6.64 552 445.46164 613.39362 5636143 4.08 6.68 568 472.28613 653.48322 5636144 4.08 6.72 539 438.18146 598.27838 5636145 4.08 6.76 484 318.10138 313.42401 5636146 4.08 6.8 469 304.20184 288.2496 5636147 4.08 6.84 458 301.13504 286.3248 5701637 4.12 5 161 88.065269 72.468803 5701638 4.12 5.04 161 78.387856 56.952 5701639 4.12 5.08 168 74.913773 50.8592 5701640 4.12 5.12 198 90.744408 62.915199 5701641 4.12 5.16 223 100.22327 69.463997 5701642 4.12 5.2 268 132.9408 98.529602 5701643 4.12 5.24 248 104.4622 63.3312 5701644 4.12 5.28 182 63.699406 32.075199 5701645 4.12 5.32 155 50.391361 23.8752 5701646 4.12 5.36 131 37.566898 14.8752 5701647 4.12 5.4 117 32.165054 11.4128 5701648 4.12 5.44 101 29.515745 10.8608 5701649 4.12 5.48 153 86.781372 69.915199 5701650 4.12 5.52 165 84.91188 64.820801 5701651 4.12 5.56 176 81.621719 55.708801 5701652 4.12 5.6 181 78.428665 49.2048 5701653 4.12 5.64 180 71.164207 38.683201 5701654 4.12 5.68 166 58.658363 26.739201 5701655 4.12 5.72 137 46.550293 20.6896 5701657 4.12 5.8 217 85.843216 46.577599 5701658 4.12 5.84 267 108.36539 58.913601 5701659 4.12 5.88 331 149.47006 91.849602 5701660 4.12 5.92 413 245.20995 247.14079 5701661 4.12 5.96 477 385.18423 594.39362 5701662 4.12 6 486 393.4194 602.39838 5701663 4.12 6.04 369 178.6145 122.5456 5701664 4.12 6.08 321 145.57776 90.811203 5701665 4.12 6.12 265 113.95901 68.608002 5701666 4.12 6.16 215 95.404579 60.5504 5701668 4.12 6.24 145 47.128368 19.340799 5701669 4.12 6.28 166 59.400635 27.2512 5701670 4.12 6.32 188 81.995392 50.894402 5701671 4.12 6.36 195 95.115013 67.412804 5701672 4.12 6.4 201 104.11246 77.019203 5701673 4.12 6.44 185 109.25976 90.844803 5701675 4.12 6.52 326 156.40135 105.1872 5701676 4.12 6.56 346 165.61223 116.392 5701677 4.12 6.6 361 182.82162 149.2128 5701678 4.12 6.64 434 333.6077 495.93921 5701679 4.12 6.68 461 363.35349 533.12 5701680 4.12 6.72 439 329.82837 471.3728 5701681 4.12 6.76 393 215.23076 186.55521 5701682 4.12 6.8 381 196.49121 142.37759 5701683 4.12 6.84 374 196.57542 141.5248 5767173 4.16 5 142 65.945488 41.7584 5767174 4.16 5.04 144 62.031853 37.236801 5767175 4.16 5.08 145 57.827065 32.579201 5767176 4.16 5.12 162 71.846611 47.998402 5767177 4.16 5.16 195 83.580711 57.030399 5767178 4.16 5.2 253 111.21772 74.756798 5767179 4.16 5.24 228 87.13903 47.9408 5767180 4.16 5.28 145 47.597496 22.766399 5767181 4.16 5.32 136 45.349697 21.9632 5767182 4.16 5.36 129 44.938625 22.952 5767183 4.16 5.4 108 32.534645 12.616 5767184 4.16 5.44 101 32.726177 13.1536 5767185 4.16 5.48 108 44.398624 24.448 5767186 4.16 5.52 111 40.359379 19.8144 5767187 4.16 5.56 110 35.026638 14.7344 5767188 4.16 5.6 120 39.162704 16.7904 5767189 4.16 5.64 121 39.326359 16.743999 5767190 4.16 5.68 112 36.203457 15.4176 5767191 4.16 5.72 83 26.558512 11.5936 5767193 4.16 5.8 191 79.883835 44.459202 5767194 4.16 5.84 212 84.571281 45.6096 5767195 4.16 5.88 265 113.1783 69.467201 5767196 4.16 5.92 359 219.05226 250.504 5767197 4.16 5.96 422 352.45587 584.64478 5767198 4.16 6 429 360.37619 592.86877 5767199 4.16 6.04 318 147.02336 101.2272 5767200 4.16 6.08 258 110.61761 67.167999 5767201 4.16 6.12 218 92.674591 54.8368 5767202 4.16 6.16 195 90.388054 57.240002 5767204 4.16 6.24 101 34.777298 15.688 5767205 4.16 6.28 123 42.524769 18.799999 5767206 4.16 6.32 131 45.948868 20.489599 5767207 4.16 6.36 139 50.996998 23.604799 5767208 4.16 6.4 132 52.454231 26.9216 5767209 4.16 6.44 102 40.242054 21.136 5767211 4.16 6.52 326 161.78127 114.1424 5767212 4.16 6.56 336 165.1707 120.3552 5767213 4.16 6.6 357 190.96338 171.1888 5767214 4.16 6.64 418 328.46304 502.57599 5767215 4.16 6.68 440 356.59857 544.34241 5767216 4.16 6.72 414 315.03564 467.952 5767217 4.16 6.76 374 209.02258 196.9088 5767218 4.16 6.8 361 182.35919 132.2896 5767219 4.16 6.84 360 185.48325 132.0784 5832714 4.2 5.2 267 111.08842 71.167999 5832715 4.2 5.24 197 76.277283 41.7248 5832730 4.2 5.84 184 74.762497 39.4384 5832731 4.2 5.88 221 96.870323 62.327999 5832732 4.2 5.92 335 215.7368 274.74719 5832733 4.2 5.96 389 339.23871 591.96161 5832734 4.2 6 394 344.5383 597.44958 5832735 4.2 6.04 290 130.81938 91.118401 5832736 4.2 6.08 213 89.157845 52.748798 5832737 4.2 6.12 190 82.602676 47.857601 5832747 4.2 6.52 326 165.80527 120.8592 5832748 4.2 6.56 337 170.68326 128.5808 5832749 4.2 6.6 356 201.09894 196.0704 5832750 4.2 6.64 412 330.11472 514.57922 5832751 4.2 6.68 435 361.34894 564.6944 5832752 4.2 6.72 409 316.79568 478.66241 5832753 4.2 6.76 371 219.94376 230.7088 5832754 4.2 6.8 347 174.92305 129.4016 5832755 4.2 6.84 343 175.53416 127.2976 5898245 4.24 5 100 29.432169 10.1104 5898246 4.24 5.04 109 33.32774 13.6464 5898247 4.24 5.08 120 39.281815 18.9536 5898248 4.24 5.12 130 43.879318 22.232 5898249 4.24 5.16 174 60.726379 30.6336 5898250 4.24 5.2 227 93.268677 60.3344 5898251 4.24 5.24 213 78.183037 40.996799 5898252 4.24 5.28 136 44.146149 21.547199 5898253 4.24 5.32 115 31.675648 11.752 5898254 4.24 5.36 105 27.410803 8.8207998 5898255 4.24 5.4 99 26.403931 8.3456001 5898256 4.24 5.44 100 29.556654 10.2208 5898268 4.24 5.92 327 226.07339 313.664 5898269 4.24 5.96 379 342.07089 611.98077 5898270 4.24 6 385 347.09174 616.11841 5898271 4.24 6.04 284 132.12675 95.510399 5898283 4.24 6.52 323 168.14743 127.1136 5898284 4.24 6.56 333 172.10799 133.30721 5898285 4.24 6.6 359 216.17926 231.2832 5898286 4.24 6.64 410 336.0787 534.05121 5898287 4.24 6.68 433 368.46088 587.42877 5898288 4.24 6.72 403 320.29135 495.608 5898289 4.24 6.76 370 226.68704 248.48959 5898290 4.24 6.8 347 180.93201 139.808 5898291 4.24 6.84 341 178.30933 133.0032 5963781 4.28 5 101 27.776957 9.1168003 5963782 4.28 5.04 101 24.927849 7.4752002 5963783 4.28 5.08 132 41.090939 18.632 5963784 4.28 5.12 151 48.945183 23.740801 5963785 4.28 5.16 171 55.987751 27.395201 5963786 4.28 5.2 207 81.966827 51.779202 5963787 4.28 5.24 205 73.530777 37.996799 5963788 4.28 5.28 147 43.889133 19.695999 5963789 4.28 5.32 119 28.863575 9.1711998 5963790 4.28 5.36 105 24.446136 7.0447998 5963791 4.28 5.4 101 25.049604 7.5696001 5963792 4.28 5.44 101 27.907068 9.224 5963803 4.28 5.88 85 26.684565 11.544 5963804 4.28 5.92 306 234.69208 357.1824 5963805 4.28 5.96 369 346.85681 633.97278 5963806 4.28 6 375 350.68781 637.09601 5963807 4.28 6.04 253 127.02579 100.0368 5963808 4.28 6.08 81 25.97006 11.5248 5963819 4.28 6.52 326 175.62921 138.26241 5963820 4.28 6.56 332 176.64764 141.54559 5963821 4.28 6.6 360 227.67424 259.90079 5963822 4.28 6.64 406 340.30609 549.07843 5963823 4.28 6.68 431 374.60123 607.888 5963824 4.28 6.72 401 324.87747 509.2272 5963825 4.28 6.76 367 233.79533 268.1712 5963826 4.28 6.8 343 183.34531 146.31841 5963827 4.28 6.84 338 182.40436 142.0224 6029317 4.32 5 113 33.072563 12.4432 6029318 4.32 5.04 115 30.512991 10.5968 6029319 4.32 5.08 126 34.017452 13.2464 6029320 4.32 5.12 146 43.317387 19.4272 6029321 4.32 5.16 204 93.96833 76.508797 6029322 4.32 5.2 199 74.461731 43.763199 6029323 4.32 5.24 200 70.972908 36.492802 6029324 4.32 5.28 149 40.737537 16.3248 6029325 4.32 5.32 125 29.022747 8.7648001 6029326 4.32 5.36 108 23.870008 6.592 6029327 4.32 5.4 105 25.177837 7.4703999 6029328 4.32 5.44 101 26.710073 8.6096001 6029339 4.32 5.88 133 43.602909 18.3568 6029340 4.32 5.92 296 242.15787 386.54401 6029341 4.32 5.96 352 348.90652 655.41919 6029342 4.32 6 356 351.93237 658.3056 6029343 4.32 6.04 243 127.67693 106.296 6029344 4.32 6.08 136 45.930676 20.004801 6029355 4.32 6.52 324 180.12865 147.4496 6029356 4.32 6.56 332 183.05551 152.7056 6029357 4.32 6.6 360 236.25809 278.23999 6029358 4.32 6.64 406 348.27011 570.87842 6029359 4.32 6.68 428 381.009 629.64001 6029360 4.32 6.72 400 329.20084 519.61761 6029361 4.32 6.76 367 242.24318 287.1008 6029362 4.32 6.8 340 187.72357 155.5696 6029363 4.32 6.84 335 187.72534 153.5056 6094853 4.36 5 115 32.928185 12.0272 6094854 4.36 5.04 114 28.351187 8.9919996 6094855 4.36 5.08 117 26.826647 7.9520001 6094856 4.36 5.12 144 40.038036 16.684799 6094857 4.36 5.16 201 89.973602 71.790398 6094858 4.36 5.2 194 69.31813 37.551998 6094859 4.36 5.24 200 70.336067 35.812801 6094860 4.36 5.28 145 37.248024 13.8496 6094861 4.36 5.32 121 26.648153 7.6687999 6094862 4.36 5.36 114 25.778414 7.5120001 6094863 4.36 5.4 107 25.610348 7.7456002 6094864 4.36 5.44 104 27.325058 8.8191996 6094875 4.36 5.88 153 53.67907 24.2176 6094876 4.36 5.92 295 249.49899 405.69281 6094877 4.36 5.96 337 351.19833 677.45441 6094878 4.36 6 341 353.40298 679.62878 6094879 4.36 6.04 239 130.80273 114.6432 6094880 4.36 6.08 145 49.995213 22.143999 6094891 4.36 6.52 319 182.7356 154.3856 6094892 4.36 6.56 329 186.2841 159.28799 6094893 4.36 6.6 361 245.0983 296.65439 6094894 4.36 6.64 407 355.77783 588.44958 6094895 4.36 6.68 428 391.04211 656.64801 6094896 4.36 6.72 398 334.92273 534.5376 6094897 4.36 6.76 370 254.26639 311.0112 6094898 4.36 6.8 339 192.65126 164.2944 6094899 4.36 6.84 331 191.39301 162.416 6160389 4.4 5 112 30.96237 10.6128 6160390 4.4 5.04 116 29.624048 9.7664003 6160391 4.4 5.08 120 28.221235 8.6591997 6160392 4.4 5.12 137 36.00132 13.9728 6160393 4.4 5.16 199 86.054825 65.857597 6160394 4.4 5.2 195 69.567558 36.875198 6160395 4.4 5.24 199 69.428581 35.0224 6160396 4.4 5.28 137 32.897663 11.1216 6160397 4.4 5.32 121 26.701374 7.7712002 6160398 4.4 5.36 116 27.003815 8.2496004 6160399 4.4 5.4 111 27.701252 8.9007998 6160400 4.4 5.44 105 28.02039 9.2784004 6160411 4.4 5.88 169 65.875565 33.52 6160412 4.4 5.92 286 253.49394 424.2016 6160413 4.4 5.96 331 356.86954 701.61603 6160414 4.4 6 331 356.37314 701.01758 6160415 4.4 6.04 231 132.81898 123.768 6160416 4.4 6.08 162 61.890392 30.8976 6160427 4.4 6.52 320 192.26317 170.528 6160428 4.4 6.56 327 191.96828 169.7088 6160429 4.4 6.6 363 258.77274 326.37759 6160430 4.4 6.64 405 363.65207 611.33282 6160431 4.4 6.68 430 401.91199 684.41443 6160432 4.4 6.72 398 341.07672 548.34723 6160433 4.4 6.76 368 264.02289 337.02719 6160434 4.4 6.8 336 196.82739 172.0432 6160435 4.4 6.84 326 194.93544 170.7888 6225925 4.44 5 111 31.884279 11.4512 6225926 4.44 5.04 117 31.191889 10.7104 6225927 4.44 5.08 119 28.695505 8.9952002 6225928 4.44 5.12 123 28.469143 8.9024 6225929 4.44 5.16 195 82.17366 61.0896 6225930 4.44 5.2 195 68.182961 34.062401 6225931 4.44 5.24 199 69.878426 35.1824 6225932 4.44 5.28 135 33.131821 11.6656 6225933 4.44 5.32 120 27.276447 8.1456003 6225934 4.44 5.36 114 27.670517 8.9104004 6225935 4.44 5.4 114 30.199787 10.3376 6225936 4.44 5.44 108 30.529306 10.752 6225947 4.44 5.88 169 69.207413 37.675201 6225948 4.44 5.92 283 260.10785 444.78241 6225949 4.44 5.96 326 362.24142 725.66718 6225950 4.44 6 329 363.40445 726.07037 6225951 4.44 6.04 225 134.24167 129.696 6225952 4.44 6.08 164 67.14035 36.580799 6225963 4.44 6.52 314 196.16574 179.8416 6225964 4.44 6.56 323 197.88448 181.4944 6225965 4.44 6.6 363 267.3703 345.87039 6225966 4.44 6.64 406 370.56467 626.8432 6225967 4.44 6.68 432 413.07578 712.90723 6225968 4.44 6.72 397 349.25906 570.03998 6225969 4.44 6.76 368 274.95758 362.29919 6225970 4.44 6.8 332 201.53105 182.06239 6225971 4.44 6.84 324 202.86435 184.73599 6291461 4.48 5 113 34.848801 13.3504 6291462 4.48 5.04 114 31.880829 11.3248 6291463 4.48 5.08 119 30.851049 10.2912 6291464 4.48 5.12 122 29.63176 9.3839998 6291465 4.48 5.16 188 78.624237 57.796799 6291466 4.48 5.2 202 72.784462 36.5984 6291467 4.48 5.24 201 71.295197 35.875198 6291468 4.48 5.28 126 33.017735 12.8496 6291469 4.48 5.32 116 27.761574 8.6688004 6291470 4.48 5.36 115 29.873531 10.1024 6291471 4.48 5.4 113 31.715975 11.3792 6291472 4.48 5.44 108 32.547211 12.1872 6291483 4.48 5.88 174 76.612839 45.467201 6291484 4.48 5.92 284 268.90042 467.28961 6291485 4.48 5.96 326 370.31882 752.07843 6291486 4.48 6 330 371.98257 752.77283 6291487 4.48 6.04 229 144.992 148.84641 6291488 4.48 6.08 169 74.357368 43.996799 6291499 4.48 6.52 314 204.57845 193.60001 6291500 4.48 6.56 318 202.94313 191.9632 6291501 4.48 6.6 361 278.01318 371.02719 6291502 4.48 6.64 406 377.67078 643.43201 6291503 4.48 6.68 431 422.06061 738.32483 6291504 4.48 6.72 400 358.49643 587.5072 6291505 4.48 6.76 367 283.78668 383.74719 6291506 4.48 6.8 323 204.91855 191.632 6291507 4.48 6.84 322 209.15439 195.6944 6356997 4.52 5 112 37.037148 14.9888 6356998 4.52 5.04 113 34.333866 12.9712 6356999 4.52 5.08 112 30.941305 10.7552 6357000 4.52 5.12 133 50.809017 37.510399 6357001 4.52 5.16 151 60.359173 44.801601 6357002 4.52 5.2 210 76.868217 38.532799 6357003 4.52 5.24 199 71.943649 36.604801 6357004 4.52 5.28 127 37.182869 15.6608 6357005 4.52 5.32 113 30.153872 10.28 6357006 4.52 5.36 113 31.989243 11.4672 6357007 4.52 5.4 110 33.171955 12.5632 6357008 4.52 5.44 110 36.106644 14.5472 6357019 4.52 5.88 180 87.496834 57.745602 6357020 4.52 5.92 289 279.39331 491.28799 6357021 4.52 5.96 328 379.33331 779.53601 6357022 4.52 6 334 381.28098 779.76642 6357023 4.52 6.04 234 154.06967 162.8784 6357024 4.52 6.08 174 86.327347 59.852798 6357035 4.52 6.52 309 211.89519 207.0304 6357036 4.52 6.56 314 209.3764 203.80161 6357037 4.52 6.6 354 289.15295 400.42239 6357038 4.52 6.64 407 384.19479 657.26398 6357039 4.52 6.68 439 437.18692 771.10083 6357040 4.52 6.72 403 369.09366 611.41278 6357041 4.52 6.76 363 298.44095 422.46881 6357042 4.52 6.8 324 221.27254 224.16319 6357043 4.52 6.84 313 213.7773 207.1104 6422538 4.56 5.2 223 83.248642 41.5424 6422539 4.56 5.24 178 68.536537 36.481602 6422555 4.56 5.88 176 95.444275 72.457603 6422556 4.56 5.92 299 293.95441 518.896 6422557 4.56 5.96 343 392.0264 808.16803 6422558 4.56 6 344 392.77533 808.31519 6422559 4.56 6.04 233 162.32092 178.9792 6422560 4.56 6.08 172 96.405861 76.7808 6422571 4.56 6.52 306 219.26566 219.41119 6422572 4.56 6.56 311 222.48582 229.5248 6422573 4.56 6.6 348 301.68768 434.6528 6422574 4.56 6.64 405 392.16751 676.61603 6422575 4.56 6.68 450 453.44873 805.3136 6422576 4.56 6.72 402 377.23257 633.71039 6422577 4.56 6.76 356 311.76816 457.99841 6422578 4.56 6.8 315 227.97002 239.49921 6422579 4.56 6.84 308 220.57246 219.784 6488068 4.6 4.96 68 25.342285 12.0864 6488069 4.6 5 78 30.417561 15.4496 6488070 4.6 5.04 68 23.030581 10.6224 6488071 4.6 5.08 42 9.1876049 2.8896 6488072 4.6 5.12 48 12.655054 4.6448002 6488073 4.6 5.16 121 39.643505 16.3104 6488074 4.6 5.2 213 84.75589 43.987202 6488075 4.6 5.24 170 68.420494 38.385601 6488076 4.6 5.28 44 8.063261 1.8992 6488077 4.6 5.32 26 4.0178785 0.83359998 6488078 4.6 5.36 23 3.8602643 0.912 6488079 4.6 5.4 22 4.1480699 1.0928 6488080 4.6 5.44 22 4.8933415 1.4400001 6488091 4.6 5.88 159 99.488785 87.751999 6488092 4.6 5.92 273 299.83093 547.49762 6488093 4.6 5.96 397 419.13861 843.55518 6488094 4.6 6 387 422.02542 848.98718 6488095 4.6 6.04 193 153.06657 186.8576 6488096 4.6 6.08 156 97.300621 86.102402 6488107 4.6 6.52 304 228.21217 234.5744 6488108 4.6 6.56 311 239.59021 263.72961 6488109 4.6 6.6 341 315.17841 467.6864 6488110 4.6 6.64 389 397.65375 701.45758 6488111 4.6 6.68 463 468.7627 839.54559 6488112 4.6 6.72 395 386.44653 661.12158 6488113 4.6 6.76 347 327.69431 501.9584 6488114 4.6 6.8 316 246.69366 277.85281 6488115 4.6 6.84 309 232.49518 238.4752 6553604 4.64 4.96 101 59.18145 47.790401 6553605 4.64 5 79 30.290758 15.7552 6553606 4.64 5.04 80 30.676332 15.04 6553607 4.64 5.08 39 10.798943 4.3248 6553608 4.64 5.12 38 9.8691807 3.2 6553609 4.64 5.16 89 32.254169 15.5808 6553610 4.64 5.2 212 83.828842 43.982399 6553611 4.64 5.24 169 70.059296 40.824001 6553612 4.64 5.28 48 11.352739 3.5711999 6553613 4.64 5.32 35 7.0392237 1.9263999 6553614 4.64 5.36 28 5.3873882 1.4304 6553615 4.64 5.4 23 4.4248018 1.1568 6553616 4.64 5.44 24 5.7206497 1.7872 6553619 4.64 5.56 240 129.23502 88.150398 6553620 4.64 5.6 247 124.67947 80.843201 6553621 4.64 5.64 255 122.22733 75.508797 6553622 4.64 5.68 264 121.43034 71.984001 6553623 4.64 5.72 273 122.24762 70.465599 6553624 4.64 5.76 268 114.8168 63.4944 6553625 4.64 5.8 267 110.01385 58.187199 6553626 4.64 5.84 265 105.78947 54.035198 6553627 4.64 5.88 266 104.1961 51.993599 6553628 4.64 5.92 266 101.82307 49.712002 6553629 4.64 5.96 530 486.02512 904.32159 6553630 4.64 6 517 483.37317 904.39362 6553631 4.64 6.04 263 100.76785 49.451199 6553632 4.64 6.08 259 100.15928 49.7728 6553633 4.64 6.12 258 101.60239 51.632 6553634 4.64 6.16 255 103.77785 55.383999 6553635 4.64 6.2 250 105.37714 58.7808 6553636 4.64 6.24 247 108.3482 63.147202 6553637 4.64 6.28 243 111.52805 67.619202 6553638 4.64 6.32 244 119.10101 76.278397 6553639 4.64 6.36 242 124.90104 83.3088 6553640 4.64 6.4 243 133.44257 93.017601 6553644 4.64 6.56 86 21.017136 5.9871998 6553645 4.64 6.6 86 19.644417 5.3072 6553646 4.64 6.64 86 18.818968 4.9056001 6553647 4.64 6.68 470 481.22058 873.01282 6553648 4.64 6.72 96 22.665855 6.6799998 6553649 4.64 6.76 96 25.354136 8.6767998 6553650 4.64 6.8 99 28.99967 11.0304 6619140 4.68 4.96 116 76.496078 70.070396 6619141 4.68 5 122 72.880157 62.2048 6619142 4.68 5.04 147 77.532501 58.3088 6619143 4.68 5.08 186 85.038689 53.366402 6619144 4.68 5.12 188 81.034576 46.048 6619145 4.68 5.16 186 73.813782 38.003201 6619146 4.68 5.2 255 104.20734 57.335999 6619147 4.68 5.24 258 105.37385 58.863998 6619148 4.68 5.28 170 54.604095 21.4848 6619149 4.68 5.32 165 51.228039 19.176001 6619150 4.68 5.36 159 49.167332 18.1936 6619151 4.68 5.4 154 48.720772 18.327999 6619152 4.68 5.44 150 49.658947 19.361601 6619153 4.68 5.48 147 51.928902 21.203199 6619155 4.68 5.56 243 129.09261 89.127998 6619156 4.68 5.6 257 127.25648 83.0112 6619157 4.68 5.64 267 124.83909 76.934402 6619158 4.68 5.68 276 123.72148 72.865601 6619159 4.68 5.72 271 115.44196 65.028801 6619160 4.68 5.76 270 109.92471 58.953602 6619161 4.68 5.8 270 106.49425 55.32 6619162 4.68 5.84 269 102.16472 50.948799 6619163 4.68 5.88 274 102.4071 50.228802 6619164 4.68 5.92 286 103.2551 48.728001 6619165 4.68 5.96 531 494.51569 934.56158 6619166 4.68 6 505 480.48798 926.31842 6619167 4.68 6.04 271 98.462234 47.096001 6619168 4.68 6.08 265 98.019562 47.945599 6619169 4.68 6.12 264 100.35928 50.799999 6619170 4.68 6.16 263 103.26722 54.388802 6619171 4.68 6.2 259 105.16183 57.756802 6619172 4.68 6.24 254 107.08556 61.292801 6619173 4.68 6.28 249 110.68029 66.848 6619174 4.68 6.32 246 117.08631 75.289597 6619175 4.68 6.36 245 123.35952 82.472 6619176 4.68 6.4 244 131.17125 91.638397 6619179 4.68 6.52 85 20.604757 5.8031998 6619180 4.68 6.56 86 18.7687 4.8720002 6619181 4.68 6.6 92 18.73526 4.5535998 6619182 4.68 6.64 178 68.29129 40.9072 6619183 4.68 6.68 460 492.63138 909.49438 6619184 4.68 6.72 214 95.186333 63.534401 6619185 4.68 6.76 108 28.651815 10.8672 6619186 4.68 6.8 112 35.156937 16.0336 6619187 4.68 6.84 114 41.505768 21.865601 6684676 4.72 4.96 65 35.133587 30.753599 6684677 4.72 5 99 66.120819 64.288002 6684678 4.72 5.04 126 81.993675 75.2528 6684679 4.72 5.08 184 98.092308 75.619202 6684680 4.72 5.12 220 102.6207 69.431999 6684681 4.72 5.16 229 99.171417 62.3456 6684682 4.72 5.2 275 123.76847 78.659203 6684683 4.72 5.24 276 120.74655 74.398399 6684684 4.72 5.28 193 64.193718 28.673599 6684685 4.72 5.32 181 55.958279 22.028799 6684686 4.72 5.36 172 50.440639 18.030399 6684687 4.72 5.4 164 47.884727 16.809601 6684688 4.72 5.44 154 46.856709 17.003201 6684689 4.72 5.48 147 48.212299 18.5152 6684691 4.72 5.56 250 127.4764 85.569603 6684692 4.72 5.6 274 131.18167 82.865601 6684693 4.72 5.64 284 129.80994 78.926399 6684694 4.72 5.68 279 121.1924 70.676804 6684695 4.72 5.72 275 113.68239 63.4464 6684696 4.72 5.76 278 110.60752 59.510399 6684697 4.72 5.8 276 105.55979 54.476799 6684698 4.72 5.84 276 102.26431 50.916801 6684699 4.72 5.88 282 101.94955 49.4608 6684700 4.72 5.92 304 110.66743 53.161598 6684701 4.72 5.96 524 498.63336 962.88159 6684702 4.72 6 498 477.83334 944.90082 6684703 4.72 6.04 281 99.655411 47.3936 6684704 4.72 6.08 273 98.293877 47.694401 6684705 4.72 6.12 272 101.05534 50.956799 6684706 4.72 6.16 267 101.45684 52.662399 6684707 4.72 6.2 267 105.67683 57.439999 6684708 4.72 6.24 265 109.35533 62.212799 6684709 4.72 6.28 261 112.79687 67.167999 6684710 4.72 6.32 251 115.44904 72.878403 6684711 4.72 6.36 244 118.9511 78.155197 6684712 4.72 6.4 243 126.9421 87.222397 6684715 4.72 6.52 88 19.925976 5.2783999 6684716 4.72 6.56 91 18.500883 4.4928002 6684717 4.72 6.6 111 23.400408 6.1135998 6684718 4.72 6.64 215 99.329002 70.584 6684719 4.72 6.68 462 505.23071 939.67358 6684720 4.72 6.72 257 142.36018 120.2928 6684721 4.72 6.76 144 49.295589 26.784 6684722 4.72 6.8 140 57.718628 38.499199 6684723 4.72 6.84 144 67.546402 49.398399 6750216 4.76 5.12 241 126.05138 99.3312 6750217 4.76 5.16 260 124.89553 90.249603 6750218 4.76 5.2 301 149.76447 107.1792 6750219 4.76 5.24 310 151.97447 107.1696 6750220 4.76 5.28 240 98.890892 60.124802 6750221 4.76 5.32 234 91.720634 52.326401 6750222 4.76 5.36 221 80.477577 41.3344 6750223 4.76 5.4 203 66.210129 28.233601 6750224 4.76 5.44 177 51.461433 17.900801 6750225 4.76 5.48 153 46.268379 16.571199 6750227 4.76 5.56 292 146.60869 98.015999 6750228 4.76 5.6 300 142.25043 90.667198 6750229 4.76 5.64 293 132.57094 81.751999 6750230 4.76 5.68 289 124.36207 73.528 6750231 4.76 5.72 286 117.16612 65.848 6750232 4.76 5.76 283 110.3746 58.919998 6750233 4.76 5.8 281 105.49039 54.054401 6750234 4.76 5.84 282 101.87502 49.788799 6750235 4.76 5.88 290 103.27867 49.473598 6750236 4.76 5.92 318 118.70315 59.260799 6750237 4.76 5.96 524 506.61371 993.6944 6750238 4.76 6 501 485.95761 974.85602 6750239 4.76 6.04 291 102.16702 48.129601 6750240 4.76 6.08 281 99.622826 47.982399 6750241 4.76 6.12 276 100.24689 49.9408 6750242 4.76 6.16 279 105.59521 55.254398 6750243 4.76 6.2 278 108.91234 59.006401 6750244 4.76 6.24 276 113.43774 64.968002 6750245 4.76 6.28 277 119.35275 71.499199 6750246 4.76 6.32 275 124.84217 78.371201 6750247 4.76 6.36 265 127.31407 84.0336 6750248 4.76 6.4 249 130.39983 91.5056 6750251 4.76 6.52 90 19.351294 4.9152002 6750252 4.76 6.56 119 27.59627 8.1440001 6750253 4.76 6.6 155 47.836914 21.5888 6750254 4.76 6.64 279 157.22244 130.89439 6750255 4.76 6.68 492 547.95569 1007.3264 6750256 4.76 6.72 323 235.73404 273.04001 6750257 4.76 6.76 198 94.422012 69.400002 6750258 4.76 6.8 177 88.234642 69.0448 6750259 4.76 6.84 170 93.665993 79.620796 6815752 4.8 5.12 263 159.85904 149.56799 6815753 4.8 5.16 296 170.63861 152.12959 6815754 4.8 5.2 337 199.5562 175.5152 6815755 4.8 5.24 356 208.22437 179.6304 6815756 4.8 5.28 305 162.67145 133.48 6815757 4.8 5.32 297 154.84575 123.48 6815758 4.8 5.36 308 157.63011 120.4064 6815759 4.8 5.4 322 161.47871 117.9776 6815760 4.8 5.44 338 168.22293 117.9712 6815761 4.8 5.48 365 178.1993 118.4832 6815762 4.8 5.52 372 176.33803 112.5472 6815763 4.8 5.56 337 158.6853 100.2336 6815764 4.8 5.6 308 140.68845 87.193604 6815765 4.8 5.64 295 128.88879 77.203201 6815766 4.8 5.68 289 121.40872 70.515198 6815767 4.8 5.72 284 114.04677 63.563202 6815768 4.8 5.76 282 108.58732 57.982399 6815769 4.8 5.8 284 105.49833 53.987202 6815770 4.8 5.84 287 103.8661 51.465599 6815771 4.8 5.88 292 103.55003 49.675201 6815772 4.8 5.92 331 131.87375 73.582397 6815773 4.8 5.96 519 512.55774 1024.6016 6815774 4.8 6 500 493.67084 1005.7088 6815775 4.8 6.04 299 106.83577 51.619202 6815776 4.8 6.08 285 100.41935 48.195202 6815777 4.8 6.12 282 102.10297 50.886398 6815778 4.8 6.16 280 104.44841 54.1008 6815779 4.8 6.2 281 108.43563 58.246399 6815780 4.8 6.24 280 112.68504 63.363201 6815781 4.8 6.28 282 118.8515 69.857597 6815782 4.8 6.32 284 125.54445 77.057602 6815783 4.8 6.36 289 133.24413 84.452797 6815784 4.8 6.4 296 142.41209 93.569603 6815785 4.8 6.44 288 148.97034 102.744 6815786 4.8 6.48 275 147.69745 107.12 6815787 4.8 6.52 274 144.17676 108.08 6815788 4.8 6.56 266 143.27884 112.5472 6815789 4.8 6.6 278 154.35132 125.0736 6815790 4.8 6.64 370 263.66269 266.16479 6815791 4.8 6.68 542 619.04669 1116.88 6815792 4.8 6.72 398 358.71567 509.4144 6815793 4.8 6.76 252 156.59021 147.0448 6815794 4.8 6.8 217 138.35579 136.9872 6815795 4.8 6.84 208 138.56532 141.552 6881288 4.84 5.12 270 162.44919 150.7632 6881289 4.84 5.16 296 171.38646 153.6528 6881290 4.84 5.2 338 200.93681 178.056 6881291 4.84 5.24 354 208.82271 182.0912 6881292 4.84 5.28 310 165.11208 135.60001 6881293 4.84 5.32 309 162.0493 129.38721 6881294 4.84 5.36 316 163.07828 125.2048 6881295 4.84 5.4 336 170.44125 124.5024 6881296 4.84 5.44 354 175.2309 121.04 6881297 4.84 5.48 376 178.02142 115.3264 6881298 4.84 5.52 354 165.15269 104.392 6881299 4.84 5.56 318 147.57974 92.110397 6881300 4.84 5.6 307 138.2617 83.655998 6881301 4.84 5.64 299 130.10788 76.228798 6881302 4.84 5.68 295 123.26687 69.662399 6881303 4.84 5.72 289 116.03209 63.348801 6881304 4.84 5.76 288 110.99865 58.1632 6881305 4.84 5.8 289 108.04501 55.001598 6881306 4.84 5.84 289 105.15712 51.9744 6881307 4.84 5.88 297 107.43253 52.558399 6881308 4.84 5.92 334 139.45978 83.872002 6881309 4.84 5.96 513 518.62866 1056.0192 6881310 4.84 6 493 497.91345 1034.64 6881311 4.84 6.04 302 110.50415 55.030399 6881312 4.84 6.08 284 99.370766 47.097599 6881313 4.84 6.12 281 100.59311 49.2896 6881314 4.84 6.16 278 102.07783 51.580799 6881315 4.84 6.2 278 105.88176 55.756802 6881316 4.84 6.24 279 110.23824 60.051201 6881317 4.84 6.28 279 115.27534 65.700798 6881318 4.84 6.32 282 121.21204 71.260803 6881319 4.84 6.36 286 128.93832 79.056 6881320 4.84 6.4 292 137.32787 87.444801 6881321 4.84 6.44 295 147.93527 97.942398 6881322 4.84 6.48 303 156.05125 107.5904 6881323 4.84 6.52 295 156.31007 114.176 6881324 4.84 6.56 283 154.22353 118.4128 6881325 4.84 6.6 295 168.70222 135.65601 6881326 4.84 6.64 387 302.0123 347.6048 6881327 4.84 6.68 528 619.30365 1143.9041 6881328 4.84 6.72 401 380.50388 563.33917 6881329 4.84 6.76 257 161.88014 149.496 6881330 4.84 6.8 223 140.52336 135.5696 6881331 4.84 6.84 210 139.3932 140.2384 6946824 4.88 5.12 257 141.64993 120.3952 6946825 4.88 5.16 281 150.26085 122.7664 6946826 4.88 5.2 303 161.89883 129.03999 6946827 4.88 5.24 311 161.76492 126.2768 6946828 4.88 5.28 266 112.8196 73.441597 6946829 4.88 5.32 253 100.08851 60.153599 6946830 4.88 5.36 240 89.044327 49.6576 6946831 4.88 5.4 231 80.087898 40.056 6946832 4.88 5.44 205 60.688377 23.132799 6946833 4.88 5.48 164 43.486481 13.672 6946835 4.88 5.56 272 134.31546 90.212799 6946836 4.88 5.6 289 135.49271 86.049599 6946837 4.88 5.64 293 130.97589 79.513603 6946838 4.88 5.68 294 126.60983 74.350403 6946839 4.88 5.72 295 122.78362 69.580803 6946840 4.88 5.76 297 119.6748 65.524803 6946841 4.88 5.8 298 116.93443 62.254398 6946842 4.88 5.84 303 117.17518 61.233601 6946843 4.88 5.88 310 120.48535 63.566399 6946844 4.88 5.92 348 155.85977 100.624 6946845 4.88 5.96 515 530.81659 1091.5472 6946846 4.88 6 500 513.60162 1072.4944 6946847 4.88 6.04 316 125.67477 68.892799 6946848 4.88 6.08 296 111.03088 56.944 6946849 4.88 6.12 287 108.10593 56.335999 6946850 4.88 6.16 287 111.29408 60.097599 6946851 4.88 6.2 282 112.0092 62.200001 6946852 4.88 6.24 281 115.49922 66.169601 6946853 4.88 6.28 283 121.77474 72.839996 6946854 4.88 6.32 278 124.10552 76.328003 6946855 4.88 6.36 275 129.79068 83.731201 6946856 4.88 6.4 247 128.29137 89.172798 6946859 4.88 6.52 106 26.908369 8.9231997 6946860 4.88 6.56 157 51.603809 23.820801 6946861 4.88 6.6 220 102.92867 69.919998 6946862 4.88 6.64 335 285.27963 408.80481 6946863 4.88 6.68 461 559.37195 1099.36 6946864 4.88 6.72 369 364.23532 585.56641 6946865 4.88 6.76 241 140.84627 118.1152 6946866 4.88 6.8 206 115.38745 96.347198 6946867 4.88 6.84 195 116.85154 105.3888 7012360 4.92 5.12 230 108.00648 76.294403 7012361 4.92 5.16 251 117.99065 84.099197 7012362 4.92 5.2 270 131.07155 97.688004 7012363 4.92 5.24 273 127.94871 93.627197 7012364 4.92 5.28 220 73.31044 36.515202 7012365 4.92 5.32 202 58.96883 24.593599 7012366 4.92 5.36 186 48.671913 17.121599 7012367 4.92 5.4 171 40.873589 11.9072 7012368 4.92 5.44 162 39.592537 11.5888 7012369 4.92 5.48 149 39.862839 12.6608 7012371 4.92 5.56 251 130.53703 89.6912 7012372 4.92 5.6 257 123.22181 79.692802 7012373 4.92 5.64 269 121.00531 73.795197 7012374 4.92 5.68 278 119.66403 69.259201 7012375 4.92 5.72 284 118.34278 65.984001 7012376 4.92 5.76 291 118.19249 63.942402 7012377 4.92 5.8 292 115.62484 61.0368 7012378 4.92 5.84 295 114.63945 59.180801 7012379 4.92 5.88 310 125.05551 67.897598 7012380 4.92 5.92 348 162.54489 108.936 7012381 4.92 5.96 512 541.94452 1128.5439 7012382 4.92 6 496 523.48602 1107.5424 7012383 4.92 6.04 311 126.7425 70.939201 7012384 4.92 6.08 292 112.47406 58.9888 7012385 4.92 6.12 284 109.8588 58.380798 7012386 4.92 6.16 283 112.37938 61.476799 7012387 4.92 6.2 276 111.71053 62.382401 7012388 4.92 6.24 276 117.58091 69.788803 7012389 4.92 6.28 270 119.89943 74.0336 7012390 4.92 6.32 264 124.45248 81.457603 7012391 4.92 6.36 253 128.1942 88.721603 7012392 4.92 6.4 250 134.58475 96.367996 7012395 4.92 6.52 104 29.111048 10.768 7012396 4.92 6.56 120 36.916149 16.865601 7012397 4.92 6.6 166 75.649811 56.534401 7012398 4.92 6.64 283 275.92596 477.52481 7012399 4.92 6.68 394 511.87451 1080.0225 7012400 4.92 6.72 330 359.38165 653.77118 7012401 4.92 6.76 210 116.03286 93.817596 7012402 4.92 6.8 176 86.394363 62.619202 7012403 4.92 6.84 170 86.674629 65.062401 7077896 4.96 5.12 209 86.039223 51.743999 7077897 4.96 5.16 228 96.948875 62.632 7077898 4.96 5.2 238 104.89588 73.804802 7077899 4.96 5.24 245 106.74608 76.195198 7077900 4.96 5.28 198 59.028324 25.867201 7077901 4.96 5.32 181 46.04565 15.8048 7077902 4.96 5.36 171 41.134903 12.8944 7077903 4.96 5.4 162 37.735302 10.712 7077904 4.96 5.44 154 37.751087 11.2032 7077905 4.96 5.48 149 40.127056 12.9312 7077907 4.96 5.56 246 129.5233 88.019203 7077908 4.96 5.6 251 123.91936 80.903999 7077909 4.96 5.64 257 119.45538 74.025597 7077910 4.96 5.68 261 114.51888 67.080002 7077911 4.96 5.72 272 114.72202 64.279999 7077912 4.96 5.76 276 112.81989 60.870399 7077913 4.96 5.8 282 113.08817 59.265598 7077914 4.96 5.84 292 116.79713 60.6688 7077915 4.96 5.88 309 130.1626 72.828796 7077916 4.96 5.92 347 170.13162 119.2768 7077917 4.96 5.96 503 548.42926 1161.3328 7077918 4.96 6 489 531.71515 1141.4368 7077919 4.96 6.04 314 137.36725 82.876801 7077920 4.96 6.08 293 119.52432 65.766403 7077921 4.96 6.12 288 118.62825 66.486397 7077922 4.96 6.16 279 116.49083 66.795197 7077923 4.96 6.2 272 115.82111 68.064003 7077924 4.96 6.24 269 119.67442 73.835197 7077925 4.96 6.28 260 120.4241 77.371201 7077926 4.96 6.32 253 124.13023 83.470398 7077927 4.96 6.36 252 130.40561 90.566399 7077928 4.96 6.4 251 138.06085 99.260803 7077931 4.96 6.52 107 34.091934 14.464 7077932 4.96 6.56 122 43.965176 23.774401 7077933 4.96 6.6 165 86.33255 72.222397 7077934 4.96 6.64 270 284.69412 513.0672 7077935 4.96 6.68 360 495.96912 1088.4784 7077936 4.96 6.72 312 383.74921 788.24158 7077937 4.96 6.76 189 104.42886 86.888 7077938 4.96 6.8 155 67.842087 42.032001 7077939 4.96 6.84 147 64.659386 39.5952 7143432 5 5.12 189 68.636925 34.023998 7143433 5 5.16 216 89.221336 56.4576 7143434 5 5.2 226 98.96167 71.188797 7143435 5 5.24 232 101.87588 75.4608 7143436 5 5.28 186 53.807076 23.259199 7143437 5 5.32 174 44.387531 15.5552 7143438 5 5.36 169 42.096661 14.008 7143439 5 5.4 154 36.043404 10.4048 7143440 5 5.44 151 38.073978 11.8448 7143441 5 5.48 149 41.081272 13.6992 7143443 5 5.56 245 133.34746 91.801598 7143444 5 5.6 248 125.6116 81.503998 7143445 5 5.64 251 119.75078 73.9216 7143446 5 5.68 255 115.75961 68.262398 7143447 5 5.72 259 112.22642 62.9776 7143448 5 5.76 267 112.24181 60.4496 7143449 5 5.8 276 113.61813 59.228802 7143450 5 5.84 282 115.62297 60.240002 7143451 5 5.88 301 130.9525 74.512001 7143452 5 5.92 343 177.44749 130.9088 7143453 5 5.96 493 554.69794 1194.1104 7143454 5 6 486 543.25946 1177.9088 7143455 5 6.04 315 146.83084 94.209602 7143456 5 6.08 294 127.83262 73.7024 7143457 5 6.12 280 118.61005 66.388802 7143458 5 6.16 274 118.74092 68.940804 7143459 5 6.2 268 119.36779 71.756798 7143460 5 6.24 264 123.28454 78.499199 7143461 5 6.28 258 126.53695 84.209602 7143462 5 6.32 256 131.9953 91.326401 7143463 5 6.36 253 136.09894 96.580803 7143464 5 6.4 252 143.91705 106.3952 7143468 5 6.56 128 53.558598 32.971199 7143469 5 6.6 163 94.442467 84.971199 7143470 5 6.64 267 302.33621 563.38397 7143471 5 6.68 344 495.42938 1114.4032 7143472 5 6.72 302 399.29959 866.32159 7143473 5 6.76 180 106.47968 94.809601 7143474 5 6.8 144 64.892883 41.603199 7208968 5.04 5.12 186 68.448418 33.913601 7208969 5.04 5.16 210 88.598213 57.796799 7208970 5.04 5.2 216 95.460991 70.734398 7208971 5.04 5.24 221 99.247009 76.7136 7208972 5.04 5.28 181 54.241177 24.7472 7208973 5.04 5.32 170 44.713936 16.280001 7208974 5.04 5.36 162 41.733135 14.7968 7208975 5.04 5.4 157 40.557556 13.8384 7208976 5.04 5.44 150 39.606411 13.1008 7208977 5.04 5.48 148 42.008072 14.4656 7274504 5.08 5.12 178 65.381821 31.8368 7274505 5.08 5.16 204 88.90271 60.107201 7274506 5.08 5.2 211 96.756683 74.345596 7274507 5.08 5.24 218 102.59463 82.335999 7274508 5.08 5.28 182 60.685886 32.502399 7274509 5.08 5.32 168 47.817688 19.2288 7274510 5.08 5.36 161 44.476276 17.096001 7274511 5.08 5.4 155 42.468616 15.5856 7274512 5.08 5.44 149 41.282612 14.3184 7274513 5.08 5.48 149 44.779373 16.417601 7340040 5.12 5.12 176 67.550606 34.030399 7340041 5.12 5.16 202 92.958344 65.968002 7340042 5.12 5.2 208 100.16633 79.643204 7340043 5.12 5.24 217 106.7597 87.222397 7340044 5.12 5.28 179 66.32412 40.952 7340045 5.12 5.32 166 50.768524 21.846399 7340046 5.12 5.36 161 48.456814 20.256001 7340047 5.12 5.4 155 46.412476 18.7952 7340048 5.12 5.44 152 46.928383 18.7904 7340049 5.12 5.48 150 48.432838 19.1696 7405576 5.16 5.12 175 71.363174 37.822399 7405577 5.16 5.16 203 100.44492 75.209602 7405578 5.16 5.2 208 106.25475 86.979202 7405579 5.16 5.24 211 109.9676 93.344002 7405580 5.16 5.28 178 70.961754 45.743999 7405581 5.16 5.32 162 52.822296 23.739201 7405582 5.16 5.36 161 52.753807 23.452801 7405583 5.16 5.4 155 50.853527 22.3216 7405584 5.16 5.44 150 49.344448 20.68 7405585 5.16 5.48 148 50.383991 20.6336 7471112 5.2 5.12 175 76.092041 41.928001 7471113 5.2 5.16 205 109.62108 86.564796 7471114 5.2 5.2 202 109.21878 92.599998 7471115 5.2 5.24 209 115.41135 100.6688 7471116 5.2 5.28 179 78.552864 53.811199 7471117 5.2 5.32 162 58.598862 28.823999 7471118 5.2 5.36 158 56.123917 26.478399 7471119 5.2 5.4 156 56.065971 26.128 7471120 5.2 5.44 153 56.01944 25.872 7471121 5.2 5.48 149 55.871475 25.5184 ================================================ FILE: testdata/gallery_two_pointmaps.graph ================================================ [File too large to display: 22.4 MB] ================================================ FILE: testdata/isovists.csv ================================================ id,x,y,angle,viewAngle 1,1.77,6.6,180,60 2,3.1,5.6,90,90 ================================================ FILE: testdata/rooms.dxf ================================================ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1032 9 $ACADMAINTVER 90 29 9 $DWGCODEPAGE 3 ANSI_1252 9 $LASTSAVEDBY 1 petros 9 $REQUIREDVERSIONS 160 0 9 $INSBASE 10 0.0 20 0.0 30 0.0 9 $EXTMIN 10 -2.310064731883713 20 -1.263672883888023 30 0.0 9 $EXTMAX 10 20.0 20 11.0 30 0.0 9 $LIMMIN 10 0.0 20 0.0 9 $LIMMAX 10 420.0 20 297.0 9 $ORTHOMODE 70 0 9 $REGENMODE 70 1 9 $FILLMODE 70 1 9 $QTEXTMODE 70 0 9 $MIRRTEXT 70 0 9 $LTSCALE 40 1.0 9 $ATTMODE 70 1 9 $TEXTSIZE 40 2.5 9 $TRACEWID 40 1.0 9 $TEXTSTYLE 7 Standard 9 $CLAYER 8 0 9 $CELTYPE 6 ByLayer 9 $CECOLOR 62 256 9 $CELTSCALE 40 1.0 9 $DISPSILH 70 0 9 $DIMSCALE 40 1.0 9 $DIMASZ 40 2.5 9 $DIMEXO 40 0.625 9 $DIMDLI 40 3.75 9 $DIMRND 40 0.0 9 $DIMDLE 40 0.0 9 $DIMEXE 40 1.25 9 $DIMTP 40 0.0 9 $DIMTM 40 0.0 9 $DIMTXT 40 2.5 9 $DIMCEN 40 2.5 9 $DIMTSZ 40 0.0 9 $DIMTOL 70 0 9 $DIMLIM 70 0 9 $DIMTIH 70 0 9 $DIMTOH 70 0 9 $DIMSE1 70 0 9 $DIMSE2 70 0 9 $DIMTAD 70 1 9 $DIMZIN 70 8 9 $DIMBLK 1 9 $DIMASO 70 1 9 $DIMSHO 70 1 9 $DIMPOST 1 9 $DIMAPOST 1 9 $DIMALT 70 0 9 $DIMALTD 70 3 9 $DIMALTF 40 0.03937007874016 9 $DIMLFAC 40 1.0 9 $DIMTOFL 70 1 9 $DIMTVP 40 0.0 9 $DIMTIX 70 0 9 $DIMSOXD 70 0 9 $DIMSAH 70 0 9 $DIMBLK1 1 9 $DIMBLK2 1 9 $DIMSTYLE 2 ISO-25 9 $DIMCLRD 70 0 9 $DIMCLRE 70 0 9 $DIMCLRT 70 0 9 $DIMTFAC 40 1.0 9 $DIMGAP 40 0.625 9 $DIMJUST 70 0 9 $DIMSD1 70 0 9 $DIMSD2 70 0 9 $DIMTOLJ 70 0 9 $DIMTZIN 70 8 9 $DIMALTZ 70 0 9 $DIMALTTZ 70 0 9 $DIMUPT 70 0 9 $DIMDEC 70 2 9 $DIMTDEC 70 2 9 $DIMALTU 70 2 9 $DIMALTTD 70 3 9 $DIMTXSTY 7 Standard 9 $DIMAUNIT 70 0 9 $DIMADEC 70 0 9 $DIMALTRND 40 0.0 9 $DIMAZIN 70 0 9 $DIMDSEP 70 44 9 $DIMATFIT 70 3 9 $DIMFRAC 70 0 9 $DIMLDRBLK 1 9 $DIMLUNIT 70 2 9 $DIMLWD 70 -2 9 $DIMLWE 70 -2 9 $DIMTMOVE 70 0 9 $DIMFXL 40 1.0 9 $DIMFXLON 70 0 9 $DIMJOGANG 40 0.7853981633974483 9 $DIMTFILL 70 0 9 $DIMTFILLCLR 70 0 9 $DIMARCSYM 70 0 9 $DIMLTYPE 6 9 $DIMLTEX1 6 9 $DIMLTEX2 6 9 $DIMTXTDIRECTION 70 0 9 $LUNITS 70 2 9 $LUPREC 70 4 9 $SKETCHINC 40 1.0 9 $FILLETRAD 40 0.0 9 $AUNITS 70 0 9 $AUPREC 70 0 9 $MENU 1 . 9 $ELEVATION 40 0.0 9 $PELEVATION 40 0.0 9 $THICKNESS 40 0.0 9 $LIMCHECK 70 0 9 $CHAMFERA 40 0.0 9 $CHAMFERB 40 0.0 9 $CHAMFERC 40 0.0 9 $CHAMFERD 40 0.0 9 $SKPOLY 70 0 9 $TDCREATE 40 2459008.008020833 9 $TDUCREATE 40 2459007.883020833 9 $TDUPDATE 40 2459008.016388889 9 $TDUUPDATE 40 2459007.891388889 9 $TDINDWG 40 0.0083680556 9 $TDUSRTIMER 40 0.0083680556 9 $USRTIMER 70 1 9 $ANGBASE 50 0.0 9 $ANGDIR 70 0 9 $PDMODE 70 0 9 $PDSIZE 40 0.0 9 $PLINEWID 40 0.0 9 $SPLFRAME 70 0 9 $SPLINETYPE 70 6 9 $SPLINESEGS 70 8 9 $HANDSEED 5 2BC 9 $SURFTAB1 70 6 9 $SURFTAB2 70 6 9 $SURFTYPE 70 6 9 $SURFU 70 6 9 $SURFV 70 6 9 $UCSBASE 2 9 $UCSNAME 2 9 $UCSORG 10 0.0 20 0.0 30 0.0 9 $UCSXDIR 10 1.0 20 0.0 30 0.0 9 $UCSYDIR 10 0.0 20 1.0 30 0.0 9 $UCSORTHOREF 2 9 $UCSORTHOVIEW 70 0 9 $UCSORGTOP 10 0.0 20 0.0 30 0.0 9 $UCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $UCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $UCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $UCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $UCSORGBACK 10 0.0 20 0.0 30 0.0 9 $PUCSBASE 2 9 $PUCSNAME 2 9 $PUCSORG 10 0.0 20 0.0 30 0.0 9 $PUCSXDIR 10 1.0 20 0.0 30 0.0 9 $PUCSYDIR 10 0.0 20 1.0 30 0.0 9 $PUCSORTHOREF 2 9 $PUCSORTHOVIEW 70 0 9 $PUCSORGTOP 10 0.0 20 0.0 30 0.0 9 $PUCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $PUCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $PUCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $PUCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $PUCSORGBACK 10 0.0 20 0.0 30 0.0 9 $USERI1 70 0 9 $USERI2 70 0 9 $USERI3 70 0 9 $USERI4 70 0 9 $USERI5 70 0 9 $USERR1 40 0.0 9 $USERR2 40 0.0 9 $USERR3 40 0.0 9 $USERR4 40 0.0 9 $USERR5 40 0.0 9 $WORLDVIEW 70 1 9 $SHADEDGE 70 3 9 $SHADEDIF 70 70 9 $TILEMODE 70 1 9 $MAXACTVP 70 64 9 $PINSBASE 10 0.0 20 0.0 30 0.0 9 $PLIMCHECK 70 0 9 $PEXTMIN 10 0.0 20 0.0 30 0.0 9 $PEXTMAX 10 0.0 20 0.0 30 0.0 9 $PLIMMIN 10 0.0 20 0.0 9 $PLIMMAX 10 12.0 20 9.0 9 $UNITMODE 70 0 9 $VISRETAIN 70 1 9 $PLINEGEN 70 0 9 $PSLTSCALE 70 1 9 $TREEDEPTH 70 3020 9 $CMLSTYLE 2 Standard 9 $CMLJUST 70 0 9 $CMLSCALE 40 20.0 9 $PROXYGRAPHICS 70 1 9 $MEASUREMENT 70 1 9 $CELWEIGHT 370 -1 9 $ENDCAPS 280 0 9 $JOINSTYLE 280 0 9 $LWDISPLAY 290 0 9 $INSUNITS 70 4 9 $HYPERLINKBASE 1 9 $STYLESHEET 1 9 $XEDIT 290 1 9 $CEPSNTYPE 380 0 9 $PSTYLEMODE 290 1 9 $FINGERPRINTGUID 2 {BC3393AD-5A4F-A848-A35A-79F4AADFFA65} 9 $VERSIONGUID 2 {AD94D4D6-9452-9646-8FBB-DD3C75F1AFBD} 9 $EXTNAMES 290 1 9 $PSVPSCALE 40 0.0 9 $OLESTARTUP 290 0 9 $SORTENTS 280 127 9 $INDEXCTL 280 0 9 $HIDETEXT 280 1 9 $XCLIPFRAME 280 2 9 $HALOGAP 280 0 9 $OBSCOLOR 70 257 9 $OBSLTYPE 280 0 9 $INTERSECTIONDISPLAY 280 0 9 $INTERSECTIONCOLOR 70 257 9 $DIMASSOC 280 2 9 $PROJECTNAME 1 9 $CAMERADISPLAY 290 0 9 $LENSLENGTH 40 50.0 9 $CAMERAHEIGHT 40 0.0 9 $STEPSPERSEC 40 2.0 9 $STEPSIZE 40 6.0 9 $3DDWFPREC 40 2.0 9 $PSOLWIDTH 40 5.0 9 $PSOLHEIGHT 40 80.0 9 $LOFTANG1 40 1.570796326794896 9 $LOFTANG2 40 1.570796326794896 9 $LOFTMAG1 40 0.0 9 $LOFTMAG2 40 0.0 9 $LOFTPARAM 70 7 9 $LOFTNORMALS 280 1 9 $LATITUDE 40 37.795 9 $LONGITUDE 40 -122.394 9 $NORTHDIRECTION 40 0.0 9 $TIMEZONE 70 -8000 9 $LIGHTGLYPHDISPLAY 280 1 9 $TILEMODELIGHTSYNCH 280 1 9 $CMATERIAL 347 EC 9 $SOLIDHIST 280 0 9 $SHOWHIST 280 1 9 $DWFFRAME 280 2 9 $DGNFRAME 280 0 9 $REALWORLDSCALE 290 1 9 $INTERFERECOLOR 62 1 9 $INTERFEREOBJVS 345 F9 9 $INTERFEREVPVS 346 F6 9 $CSHADOW 280 0 9 $SHADOWPLANELOCATION 40 0.0 0 ENDSEC 0 SECTION 2 CLASSES 0 CLASS 1 ACDBDICTIONARYWDFLT 2 AcDbDictionaryWithDefault 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 DICTIONARYVAR 2 AcDbDictionaryVar 3 ObjectDBX Classes 90 0 91 11 280 0 281 0 0 CLASS 1 TABLESTYLE 2 AcDbTableStyle 3 ObjectDBX Classes 90 4095 91 1 280 0 281 0 0 CLASS 1 MATERIAL 2 AcDbMaterial 3 ObjectDBX Classes 90 1153 91 3 280 0 281 0 0 CLASS 1 VISUALSTYLE 2 AcDbVisualStyle 3 ObjectDBX Classes 90 4095 91 24 280 0 281 0 0 CLASS 1 SCALE 2 AcDbScale 3 ObjectDBX Classes 90 1153 91 17 280 0 281 0 0 CLASS 1 MLEADERSTYLE 2 AcDbMLeaderStyle 3 ACDB_MLEADERSTYLE_CLASS 90 4095 91 2 280 0 281 0 0 CLASS 1 CELLSTYLEMAP 2 AcDbCellStyleMap 3 ObjectDBX Classes 90 1152 91 2 280 0 281 0 0 CLASS 1 EXACXREFPANELOBJECT 2 ExAcXREFPanelObject 3 EXAC_ESW 90 1025 91 0 280 0 281 0 0 CLASS 1 NPOCOLLECTION 2 AcDbImpNonPersistentObjectsCollection 3 ObjectDBX Classes 90 1153 91 0 280 0 281 0 0 CLASS 1 LAYER_INDEX 2 AcDbLayerIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 SPATIAL_INDEX 2 AcDbSpatialIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 IDBUFFER 2 AcDbIdBuffer 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 ACDBSECTIONVIEWSTYLE 2 AcDbSectionViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 ACDBDETAILVIEWSTYLE 2 AcDbDetailViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 SORTENTSTABLE 2 AcDbSortentsTable 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 8 330 0 100 AcDbSymbolTable 70 1 0 VPORT 5 EA 330 8 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *Active 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 8.2397260662309 22 3.866729587880248 13 0.0 23 0.0 14 10.0 24 10.0 15 10.0 25 10.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 17.36427794278347 41 1.188055908513341 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 1000 73 1 74 3 75 0 76 1 77 0 78 0 281 0 65 1 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 348 F5 60 3 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 1001 ACAD_NAV_VCDISPLAY 1070 3 0 ENDTAB 0 TABLE 2 LTYPE 5 5 330 0 100 AcDbSymbolTable 70 1 0 LTYPE 5 14 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByBlock 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 15 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByLayer 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 16 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 Continuous 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 2 102 {ACAD_XDICTIONARY 360 1FF 102 } 330 0 100 AcDbSymbolTable 70 1 0 LAYER 5 10 102 {ACAD_XDICTIONARY 360 13C 102 } 330 2 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 62 7 6 Continuous 370 -3 390 F 347 EE 348 0 0 ENDTAB 0 TABLE 2 STYLE 5 3 330 0 100 AcDbSymbolTable 70 2 0 STYLE 5 11 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Standard 70 0 40 0.0 41 1.0 50 0.0 71 0 42 2.5 3 arial.ttf 4 1001 ACAD 1000 Arial 1071 34 0 STYLE 5 132 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Annotative 70 0 40 0.0 41 1.0 50 0.0 71 0 42 2.5 3 arial.ttf 4 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 1001 ACAD 1000 Arial 1071 34 0 ENDTAB 0 TABLE 2 VIEW 5 6 330 0 100 AcDbSymbolTable 70 2 0 ENDTAB 0 TABLE 2 UCS 5 7 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 9 330 0 100 AcDbSymbolTable 70 8 0 APPID 5 12 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 APPID 5 9E 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_PSEXT 70 0 0 APPID 5 133 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnoPO 70 0 0 APPID 5 134 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnotative 70 0 0 APPID 5 135 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_DSTYLE_DIMJAG 70 0 0 APPID 5 136 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_DSTYLE_DIMTALN 70 0 0 APPID 5 165 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_MLEADERVER 70 0 0 APPID 5 217 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_NAV_VCDISPLAY 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 A 330 0 100 AcDbSymbolTable 70 3 100 AcDbDimStyleTable 71 2 340 27 340 137 0 DIMSTYLE 105 1B0 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Standard 70 0 340 11 0 DIMSTYLE 105 137 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Annotative 70 0 40 0.0 41 2.5 42 0.625 43 3.75 44 1.25 73 0 74 0 77 1 78 8 140 2.5 141 2.5 143 0.03937007874016 147 0.625 171 3 172 1 271 2 272 2 274 3 278 44 283 0 284 8 340 11 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 1001 ACAD_DSTYLE_DIMJAG 1070 388 1040 1.5 1001 ACAD_DSTYLE_DIMTALN 1070 392 1070 0 0 DIMSTYLE 105 27 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 ISO-25 70 0 41 2.5 42 0.625 43 3.75 44 1.25 73 0 74 0 77 1 78 8 140 2.5 141 2.5 143 0.03937007874016 147 0.625 171 3 172 1 271 2 272 2 274 3 278 44 283 0 284 8 340 11 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 1 330 0 100 AcDbSymbolTable 70 1 0 BLOCK_RECORD 5 1F 102 {ACAD_XDICTIONARY 360 1CE 102 } 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Model_Space 340 22 70 0 280 1 281 0 0 BLOCK_RECORD 5 D2 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space 340 D3 70 0 280 1 281 0 0 BLOCK_RECORD 5 D6 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space0 340 D7 70 0 280 1 281 0 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 20 330 1F 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *Model_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Model_Space 1 0 ENDBLK 5 21 330 1F 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 D4 330 D2 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space 1 0 ENDBLK 5 D5 330 D2 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 BLOCK 5 D8 330 D6 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space0 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space0 1 0 ENDBLK 5 D9 330 D6 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LWPOLYLINE 5 276 330 1F 100 AcDbEntity 8 0 100 AcDbPolyline 90 2 70 0 43 0.0 10 6.0 20 11.0 10 9.0 20 11.0 0 LINE 5 277 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.0 20 1.000000000000001 30 0.0 11 9.0 21 2.000000000000001 31 0.0 0 LINE 5 278 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 11.0 30 0.0 11 6.0 21 10.0 31 0.0 0 LINE 5 27F 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.0 20 8.0 30 0.0 11 9.0 21 11.0 31 0.0 0 LINE 5 280 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.0 20 3.000000000000001 30 0.0 11 9.0 21 7.0 31 0.0 0 LINE 5 284 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 9.0 30 0.0 11 6.0 21 6.5 31 0.0 0 LINE 5 285 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.999999999999998 20 2.0 30 0.0 11 5.999999999999998 21 1.0 31 0.0 0 LINE 5 289 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 5.5 30 0.0 11 5.999999999999999 21 3.0 31 0.0 0 LINE 5 293 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.900000000000001 20 5.5 30 0.0 11 5.899999999999999 21 4.049999999999998 31 0.0 0 LINE 5 294 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.9 20 9.0 30 0.0 11 5.9 21 8.05 31 0.0 0 LINE 5 295 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.9 20 11.0 30 0.0 11 5.9 21 10.0 31 0.0 0 LINE 5 298 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 3.000000000000001 30 0.0 11 9.099999999999999 21 5.95 31 0.0 0 LINE 5 299 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 1.000000000000001 30 0.0 11 9.099999999999999 21 2.000000000000001 31 0.0 0 LINE 5 29A 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 8.0 30 0.0 11 9.099999999999999 21 11.0 31 0.0 0 LINE 5 29B 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.899999999999999 20 3.95 30 0.0 11 1.0 21 3.95 31 0.0 0 LINE 5 29C 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.9 20 4.049999999999999 30 0.0 11 1.0 21 4.049999999999999 31 0.0 0 LINE 5 29D 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.899999999999999 20 7.95 30 0.0 11 1.0 21 7.950000000000003 31 0.0 0 LINE 5 29E 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.899999999999999 20 8.05 30 0.0 11 1.0 21 8.050000000000004 31 0.0 0 LINE 5 29F 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 6.049999999999999 30 0.0 11 14.0 21 6.049999999999999 31 0.0 0 LINE 5 2A0 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 5.95 30 0.0 11 14.0 21 5.95 31 0.0 0 LINE 5 2A1 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.899999999999998 20 2.0 30 0.0 11 5.899999999999998 21 1.0 31 0.0 0 LINE 5 2A2 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 7.0 30 0.0 11 9.0 21 7.0 31 0.0 0 LINE 5 2A3 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 8.0 30 0.0 11 9.000000000000001 21 8.0 31 0.0 0 LINE 5 2A4 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 3.000000000000001 30 0.0 11 9.0 21 3.000000000000001 31 0.0 0 LINE 5 2A5 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 2.000000000000001 30 0.0 11 9.0 21 2.000000000000001 31 0.0 0 LINE 5 2A6 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.999999999999998 20 2.0 30 0.0 11 5.899999999999998 21 2.0 31 0.0 0 LINE 5 2A7 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.999999999999999 20 3.0 30 0.0 11 5.9 21 3.0 31 0.0 0 LINE 5 2A8 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 5.5 30 0.0 11 5.900000000000001 21 5.5 31 0.0 0 LINE 5 2A9 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 6.5 30 0.0 11 5.899999999999999 21 6.5 31 0.0 0 LINE 5 2AB 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 9.0 30 0.0 11 5.899999999999999 21 9.0 31 0.0 0 LINE 5 2AC 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 6.0 20 10.0 30 0.0 11 5.9 21 10.0 31 0.0 0 LINE 5 2AD 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.899999999999999 20 3.95 30 0.0 11 5.899999999999999 21 3.0 31 0.0 0 LINE 5 2AE 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 5.9 20 7.95 30 0.0 11 5.9 21 6.5 31 0.0 0 LINE 5 2AF 330 1F 100 AcDbEntity 8 0 100 AcDbLine 10 9.099999999999999 20 6.049999999999999 30 0.0 11 9.099999999999999 21 7.0 31 0.0 0 LWPOLYLINE 5 2B0 330 1F 100 AcDbEntity 8 0 100 AcDbPolyline 90 4 70 0 43 0.0 10 9.099999999999999 20 11.0 10 14.0 20 11.0 10 14.0 20 1.0 10 9.099999999999999 20 1.0 0 LWPOLYLINE 5 2B1 330 1F 100 AcDbEntity 8 0 100 AcDbPolyline 90 2 70 0 43 0.0 10 9.0 20 1.0 10 5.999999999999998 20 1.0 0 LWPOLYLINE 5 2B2 330 1F 100 AcDbEntity 8 0 100 AcDbPolyline 90 4 70 0 43 0.0 10 5.899999999999998 20 1.0 10 1.0 20 1.0 10 1.0 20 11.0 10 5.900000000000001 20 11.0 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 281 1 3 ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 216 3 ACAD_COLOR 350 6B 3 ACAD_DETAILVIEWSTYLE 350 21B 3 ACAD_GROUP 350 D 3 ACAD_LAYOUT 350 1A 3 ACAD_MATERIAL 350 6A 3 ACAD_MLEADERSTYLE 350 12D 3 ACAD_MLINESTYLE 350 17 3 ACAD_PLOTSETTINGS 350 19 3 ACAD_PLOTSTYLENAME 350 E 3 ACAD_SCALELIST 350 10C 3 ACAD_SECTIONVIEWSTYLE 350 219 3 ACAD_TABLESTYLE 350 7E 3 ACAD_VISUALSTYLE 350 EF 3 ACDB_RECOMPOSE_DATA 350 2BB 3 AcDbVariableDictionary 350 5E 0 DICTIONARY 5 1FF 330 2 100 AcDbDictionary 280 1 281 1 3 ACAD_LAYERSTATES 360 200 0 DICTIONARY 5 13C 330 10 100 AcDbDictionary 280 1 281 1 0 DICTIONARY 5 1CE 330 1F 100 AcDbDictionary 280 1 281 1 3 ACAD_SORTENTS 360 27B 0 XRECORD 5 216 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 300 ACDMAC 300 2018 300 ACDMAC_F_S 0 DICTIONARY 5 6B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 21B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Metric50 350 21C 0 DICTIONARY 5 D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 1A 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Layout1 350 D3 3 Layout2 350 D7 3 Model 350 22 0 DICTIONARY 5 6A 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 ByBlock 350 ED 3 ByLayer 350 EC 3 Global 350 EE 0 DICTIONARY 5 12D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Annotative 350 13B 3 Standard 350 12E 0 DICTIONARY 5 17 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 18 0 DICTIONARY 5 19 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 ACDBDICTIONARYWDFLT 5 E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Normal 350 F 100 AcDbDictionaryWithDefault 340 F 0 DICTIONARY 5 10C 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 A0 350 10D 3 A1 350 1BE 3 A2 350 1BF 3 A3 350 1C0 3 A4 350 1C1 3 A5 350 1C2 3 A6 350 1C3 3 A7 350 1C4 3 A8 350 1C5 3 A9 350 1C6 3 B0 350 1C7 3 B1 350 1C8 3 B2 350 1C9 3 B3 350 1CA 3 B4 350 1CB 3 B5 350 1CC 3 B6 350 1CD 0 DICTIONARY 5 219 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Metric50 350 21A 0 DICTIONARY 5 7E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 7F 0 DICTIONARY 5 EF 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 2dWireframe 350 F5 3 Basic 350 F4 3 Brighten 350 FB 3 ColorChange 350 FF 3 Conceptual 350 F8 3 Dim 350 FA 3 EdgeColorOff 350 1E6 3 Facepattern 350 FE 3 Flat 350 F0 3 FlatWithEdges 350 F1 3 Gouraud 350 F2 3 GouraudWithEdges 350 F3 3 Hidden 350 F7 3 JitterOff 350 1E4 3 Linepattern 350 FD 3 OverhangOff 350 1E5 3 Realistic 350 F9 3 Shaded 350 1F3 3 Shaded with edges 350 1F2 3 Shades of Gray 350 1EF 3 Sketchy 350 1F0 3 Thicken 350 FC 3 Wireframe 350 F6 3 X-Ray 350 1F1 0 XRECORD 5 2BB 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 90 1 330 7F 0 DICTIONARY 5 5E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 CANNOSCALE 350 146 3 CENTEREXE 350 259 3 CENTERLTYPEFILE 350 25A 3 CMLEADERSTYLE 350 145 3 CTABLESTYLE 350 84 3 CVIEWDETAILSTYLE 350 227 3 CVIEWSECTIONSTYLE 350 228 3 DIMASSOC 350 5F 3 HIDETEXT 350 63 3 LAYEREVAL 350 1AE 3 LAYERNOTIFY 350 1AF 0 DICTIONARY 5 200 102 {ACAD_REACTORS 330 1FF 102 } 330 1FF 100 AcDbDictionary 281 1 0 SORTENTSTABLE 5 27B 102 {ACAD_REACTORS 330 1CE 102 } 330 1CE 100 AcDbSortentsTable 330 1F 331 2A6 5 2AD 331 280 5 282 331 2AB 5 2B1 331 2A5 5 2AC 331 2A4 5 2AB 331 295 5 294 331 277 5 27F 331 2A9 5 2B0 331 285 5 2A0 331 294 5 297 331 276 5 276 331 2A8 5 2AF 331 29B 5 2A5 331 284 5 295 331 29A 5 286 331 2AF 5 284 331 2AE 5 299 331 299 5 280 331 2AD 5 29F 331 289 5 29C 331 298 5 283 331 2AC 5 2B2 331 29F 5 2A3 331 29E 5 2A6 331 278 5 293 331 29D 5 2A7 331 2B2 5 27E 331 27F 5 285 331 29C 5 2A4 331 2B1 5 27D 331 2A3 5 2A9 331 2B0 5 27C 331 2A2 5 2A8 331 293 5 29D 331 2A0 5 2A2 331 2A7 5 2AE 0 ACDBDETAILVIEWSTYLE 5 21C 102 {ACAD_REACTORS 330 21B 102 } 330 21B 100 AcDbModelDocViewStyle 70 0 3 Metric50 290 0 300 Metric50 90 0 100 AcDbDetailViewStyle 70 0 71 0 90 3 71 1 340 11 62 256 40 5.0 340 0 62 256 40 5.0 300 40 0.0 280 1 71 2 340 16 90 25 62 256 71 3 340 11 62 256 40 5.0 90 0 40 15.0 90 1 300 %<\AcVar ViewDetailId>% (%<\AcVar ViewScale \f "%sn">%) 71 4 340 16 90 25 62 256 340 16 90 25 62 256 280 0 0 LAYOUT 5 D3 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 C:\Documents and Settings\basas\Application Data\Autodesk\AutoCAD 2005\R16.1\enu\plotters\Default Windows System Printer.pc3 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout1 70 1 71 1 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 D2 0 LAYOUT 5 D7 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 C:\Documents and Settings\basas\Application Data\Autodesk\AutoCAD 2005\R16.1\enu\plotters\Default Windows System Printer.pc3 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout2 70 1 71 2 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 D6 0 LAYOUT 5 22 102 {ACAD_XDICTIONARY 360 205 102 } 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 none_device 4 ISO_A4_(210.00_x_297.00_MM) 6 40 7.5 41 20.0 42 7.5 43 20.0 44 210.0 45 297.0 46 11.54999923706054 47 -13.65000009536743 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 8.704084754739808 70 11952 72 1 73 0 74 0 7 75 0 147 0.1148885871608098 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Model 70 1 71 0 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 1F 331 EA 1001 ACAD_PSEXT 1000 None 1000 None 1000 Not applicable 1000 The layout will not be plotted unless a new plotter configuration name is selected. 1070 0 0 MATERIAL 5 ED 102 {ACAD_XDICTIONARY 360 1F9 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 ByBlock 94 63 0 MATERIAL 5 EC 102 {ACAD_XDICTIONARY 360 1F7 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 ByLayer 94 63 0 MATERIAL 5 EE 102 {ACAD_XDICTIONARY 360 173 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 Global 43 0.0007999999797903 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0007999999797903 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 49 0.0007999999797903 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0007999999797903 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 142 0.0007999999797903 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0007999999797903 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 144 0.0007999999797903 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0007999999797903 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 94 63 1001 ACAD 1070 -1 1070 3 1070 0 1000 1071 0 1070 0 0 MLEADERSTYLE 5 13B 102 {ACAD_REACTORS 330 12D 102 } 330 12D 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 14 92 -2 290 1 42 2.0 291 1 43 8.0 3 Standard 44 4.0 300 342 11 174 1 178 1 175 1 176 0 93 -1056964608 45 4.0 292 0 297 0 46 4.0 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 1 143 3.75 271 0 272 9 273 9 298 0 0 MLEADERSTYLE 5 12E 102 {ACAD_REACTORS 330 12D 102 } 330 12D 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 14 92 -2 290 1 42 2.0 291 1 43 8.0 3 Standard 44 4.0 300 342 11 174 1 178 1 175 1 176 0 93 -1056964608 45 4.0 292 0 297 0 46 4.0 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 0 143 3.75 271 0 272 9 273 9 298 0 0 MLINESTYLE 5 18 102 {ACAD_REACTORS 330 17 102 } 330 17 100 AcDbMlineStyle 2 STANDARD 70 0 3 62 256 51 90.0 52 90.0 71 2 49 0.5 62 256 6 BYLAYER 49 -0.5 62 256 6 BYLAYER 0 ACDBPLACEHOLDER 5 F 102 {ACAD_REACTORS 330 E 102 } 330 E 0 SCALE 5 10D 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:1 140 1.0 141 1.0 290 1 0 SCALE 5 1BE 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:2 140 1.0 141 2.0 290 0 0 SCALE 5 1BF 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:4 140 1.0 141 4.0 290 0 0 SCALE 5 1C0 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:5 140 1.0 141 5.0 290 0 0 SCALE 5 1C1 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:8 140 1.0 141 8.0 290 0 0 SCALE 5 1C2 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:10 140 1.0 141 10.0 290 0 0 SCALE 5 1C3 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:16 140 1.0 141 16.0 290 0 0 SCALE 5 1C4 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:20 140 1.0 141 20.0 290 0 0 SCALE 5 1C5 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:30 140 1.0 141 30.0 290 0 0 SCALE 5 1C6 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:40 140 1.0 141 40.0 290 0 0 SCALE 5 1C7 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:50 140 1.0 141 50.0 290 0 0 SCALE 5 1C8 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:100 140 1.0 141 100.0 290 0 0 SCALE 5 1C9 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 2:1 140 2.0 141 1.0 290 0 0 SCALE 5 1CA 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 4:1 140 4.0 141 1.0 290 0 0 SCALE 5 1CB 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 8:1 140 8.0 141 1.0 290 0 0 SCALE 5 1CC 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 10:1 140 10.0 141 1.0 290 0 0 SCALE 5 1CD 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 100:1 140 100.0 141 1.0 290 0 0 ACDBSECTIONVIEWSTYLE 5 21A 102 {ACAD_REACTORS 330 219 102 } 330 219 100 AcDbModelDocViewStyle 70 0 3 Metric50 290 0 300 Metric50 90 0 100 AcDbSectionViewStyle 70 0 71 0 90 102 71 1 340 11 62 256 40 5.0 340 0 340 0 62 256 40 5.0 300 I, O, Q, S, X, Z 40 10.0 90 0 40 2.5 90 0 71 2 340 16 90 25 62 256 340 16 90 50 62 256 40 5.0 40 2.5 40 5.0 71 3 340 11 62 256 40 5.0 90 0 40 15.0 90 1 300 %<\AcVar ViewSectionStartId>%-%<\AcVar ViewSectionEndId>% (%<\AcVar ViewScale \f "%sn">%) 71 4 62 256 62 257 300 ANSI31 40 1.0 90 0 290 0 290 0 90 6 40 0.0 40 1.570796326794896 40 0.2617993877991494 40 1.308996938995747 40 -0.2617993877991494 40 1.832595714594046 0 TABLESTYLE 5 7F 102 {ACAD_XDICTIONARY 360 162 102 } 102 {ACAD_REACTORS 330 7E 102 } 330 7E 100 AcDbTableStyle 280 0 3 Standard 70 0 71 0 40 1.5 41 1.5 280 0 281 0 7 Standard 140 4.5 170 2 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 6.0 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 4.5 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 0 VISUALSTYLE 5 F5 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 2dWireframe 70 4 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F4 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Basic 70 7 177 3 291 1 70 58 90 1 176 1 90 0 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FB 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Brighten 70 12 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FF 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 ColorChange 70 16 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 8 420 8421504 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 8 420 8421504 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F8 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Conceptual 70 9 177 3 291 0 70 58 90 3 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FA 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Dim 70 11 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 -50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E6 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 EdgeColorOff 70 22 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 8 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FE 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Facepattern 70 15 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F0 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Flat 70 0 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F1 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 FlatWithEdges 70 1 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F2 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Gouraud 70 2 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F3 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 GouraudWithEdges 70 3 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F7 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Hidden 70 6 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 40.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E4 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 JitterOff 70 20 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 10 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FD 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Linepattern 70 14 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 7 176 1 90 7 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E5 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 OverhangOff 70 21 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 9 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F9 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Realistic 70 8 177 3 291 0 70 58 90 2 176 1 90 3 176 1 90 0 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F3 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shaded 70 27 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 8 420 7895160 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F2 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shaded with edges 70 26 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1EF 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shades of Gray 70 23 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F0 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Sketchy 70 24 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 11 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 6 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FC 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Thicken 70 13 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 12 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F6 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Wireframe 70 5 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F1 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 X-Ray 70 25 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 1 176 1 40 0.5 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 DICTIONARYVAR 5 146 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 1:1 0 DICTIONARYVAR 5 259 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 3.500000 0 DICTIONARYVAR 5 25A 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 acadiso.lin 0 DICTIONARYVAR 5 145 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 84 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 227 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 Metric50 0 DICTIONARYVAR 5 228 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 Metric50 0 DICTIONARYVAR 5 5F 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 2 0 DICTIONARYVAR 5 63 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 1 0 DICTIONARYVAR 5 1AE 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 0 0 DICTIONARYVAR 5 1AF 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 0 0 DICTIONARY 5 205 330 22 100 AcDbDictionary 280 1 281 1 0 DICTIONARY 5 1F9 330 ED 100 AcDbDictionary 280 1 281 1 3 FBXASSET 360 1FA 0 DICTIONARY 5 1F7 330 EC 100 AcDbDictionary 280 1 281 1 3 FBXASSET 360 1F8 0 DICTIONARY 5 173 330 EE 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 175 3 DIFFUSETILE 360 174 3 FBXASSET 360 1FB 3 OPACITYTILE 360 176 3 REFLECTIONTILE 360 177 0 DICTIONARY 5 162 330 7F 100 AcDbDictionary 280 1 281 1 3 ACAD_ROUNDTRIP_2008_TABLESTYLE_CELLSTYLEMAP 360 2BA 0 XRECORD 5 1FA 102 {ACAD_REACTORS 330 1F9 102 } 330 1F9 100 AcDbXrecord 280 1 70 1 90 429727718 1 D62C5603-E3A1-4AEA-B7FB-FE5D8D0755AF 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623B853B8169EB0000007C01000008000000636F72652E786D6C8D90416EC3201045AF62CDB6C206821CC7C244919D9CA01740401C94182C03558F5F9C3852BBEB6A467FFE9B197D7EFC9E1EC5975982F5AE035262288C535E5B377690E21535501C055FBC8FBF6C503839990E 310 5619041F179FE64D52DE45E362569DD7661365082642A11EB9E920A89B99642953CC8E702F67A9EE7234257977194EC9EAE275C4EABCCF5EAD5940D4AC6F0E35A568B8F43562CD7046CD199FD07E60174276A7BE677B5EADB0E0D14EEFFB6A31321A0D82627C4084204C3F096B71DD52F6819B16635EADF63F509AF53FA164 310 5DDCD1EDDD17164090FCC8732078B56691CB33A85CD7DCC40F504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF32603847 310 2BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623BDBABAAF470010000D40300000C0000006662782F636F72652E786D6CC553D16E823014FD95A6AF4B694182CC941A83FA05FB810A9511A125A5257EFE2E82712ECEB8A7F100CD39F7F69E734AF9FADC366850B6 310 AF8DCE7018308C942E4C59EB2AC3DE1D498AD15A706B8CFB56869196ADCAF00863C12B6B7C374385D14E6907A836A59A41D9F7CA615434B0C8705F7CAA5606D23BA8E84F41278B93AC54100640439DE0BDB320004D43C63716C7C399D30917DCFBBA9CD9BA8469F5B156168B24CED3F7248AC8769F27244EB73B92EED8862C 310 B7F13E0C179B3C8F979C8ECD82BBBABDAA2BAC924E9558448CBD9330242CFA08E3154B5651FCC6D215639C8EE5774DBE2B5F6CF2B5768B68963BB5F5588420E442FC700B1139D4CB01F450C1E918227C2E09DF070D8140C84E1E9AAB8F1340832A9CB13130A5F1376A908D57309505ECF2A0DF179C4E9D30F5B239B87E3823 310 7A79C6F31DE1A8A5AEC08474B03C7837EAE4938639B44E5932B833D2C6B6B279CDC613877FA26EE21F4A2A4C63EC7F29A2F301D1F9F7A0E37D145F504B0304140006080800CC70623B9C113CC27E0000009D0000000B0000006662782F636E782E786D6C4DCCDF0A83201C86E15B91DFB94BFB330DD428C8FB886521330DA7 310 6397BF1A1DECE883878F57749FCDA1B7892F1BBC047A23808C7F84D9FA55424E0BE6803A256208E9EF06C84F9B91703228B1C690F78B66B34CD9A5439DF5CF0BFBF65E35BCA1B8D6A5C6F540381E886698B5741C695F9503EBA150A2F8958E3DC3EA0B504B0304140006080800CC70623B7DF2F77C2A010000120200003100 310 00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636F72652E786D6C8D51DB8EC22014FC15C2939B0D2DB4B45643319AE817EC0F6041255A68B86CFCFC856D4D76DF7CE190393373060EDB3DC707F856CE6B6B7A480A0C81328395DA5C7B18C3057510EC3873D686 310 3F34088C18550F330C39BB3A1BA7051AAC09CA84841A2BD5020AEF55806078A44B0FFD7053A328440C89E1EFC52486BBB8AA8214A99D789CF9E05200300FC927E4FB4D5B375D43103D5527440FB843077C5AA3F5861C8F645F5787F59E95B390B318B55CE45AA638FAA2957BD7248B390B7A7CC51F9C124149C82B8C378810 310 84AB2F42B7B8DD56F413775B8C5999E9FF4471926F8AA236A1AE96B8B3CC434E5839373893369E1FAF30EA395917409EB7F26AF8801C171837A4A6AC9C89E9F9C9B1A58BA30FD6A5EF5DDDCF894B9AD9B6A59C957943A9FCAE2FD5BC4DFE03504B0304140006080800CC70623BAD7543B64E01000033030000300000006662 310 782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C789FEE 310 6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5C89177 310 38143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05E20750 310 4B0304140006080800CC70623BE75B7789680500003C100000340000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F6F626A656374732E786D6CAD575B8F9B3818FD2B887D06C22499CB8AA1CA655245D5B455A356FB305264C061D8018C6C3393D95FBFC7600890 310 A4CD5EF210B0B1BFEBF98E3F7B1FF6596ABC522E1296DF9BAE3D320D9A872C4AF2F8DE2CE5CEBA358D0FBEC719939D65A691938CDE9B6ADAF4BD98B3B2D05311DD91329583D9D5FC0F438434A7A611A644887B5384CF34233629258BA878B12322891DEFF6B66BD70BFB62634E8AE781D082709A4B588AF91C528CDA28B73F 310 1C998EEF39EABBEFA97FBD6A7C7E9553F9D3D79FE442923C3C523610337627CB87ABE99D359D4CC6D6E4FACAB5E6ABF9D2726FC6A3C5F56271377BB88362213924694B38DD99FE47C48627A1E7D49F5A8BB5E1A74C0A599ED3B0F21F1E56366B89112D681E218F0915D0D6F17AD41FBA2A369DCF6335D62ABBD39779D5DDD1 310 11D4D8DE3CBB96B2E04FB8202E41051754A1AA8E8F76B4C6DFE810B580B1547F4B84911149794252234D024EF8BBE963A95AE27B3D310A9D5C215C7960FAEE415ED75694C6AFB17BCACA5D99A60A9AA65F217B0BFC53292ACB92BF283FAD0D3621576592CB5BED907C2FA8E9DF794E35E97BEA31BED21FEB401ABB94C44839 310 DCACBF0E1C5DA8DA5B2F4DFFD32AD86F543D9E565E7056502E157C00AD2671CD534549AB752FCA9CDA00677A313F04E51B22FF19E57B300579E3C97EB29F682D92935CEC18CF901B7B54FD8C51F362B56FC72FE0B3C1EAE335EDCCBF5AEC39ADB17DC238973F804BA5E6F6BFE7AF1FB32E523BE9F3BD571418E3631DCA4D48 310 5250CF639223210A9446CA30052EDF057BD35F8329C1ECD84552BF0DC8D18BE7BCE23BFE6BD960AB4A7DE79923A103BEBD80F911CBAA2C60DB19B01CF164A5583B772EE6D3FFA56666CBCDA74DC97724A48F9A58967497E489C4D979006FD7A05E227A1EBDD0F737C623387A9C844D3709995625106D157315F8B8392CD4E0 310 A0B9A720C4BE9829CEF37EA1E13111214D53925356365ADA634861B52519DD27A00AEB808EAF0628E6F435519D446F45CF2C9CF5214F0A15B2F6D06B79DA3EE3CBF7F56780D2F4E7EF73A0F5E5B02A38D07DC852C6B7C1FBB6664213E0C39E3EBA7FF4E1AD23EA2829407C85E586727488B751B2DB9502BC7B228A3FD68B6E 310 A65A22397E690AA8D158D7E404EC8CDA235CC3B7D1898680131CEC2CDF2638C65196279577750F15884AEE19F94199155B92B13297978469D4F8D358DF0AEF7631E28DC8F0D9F437D5D39A83B2231A1D52D543813A824EF8D44BCFF2FA6A31BD1E8DAD87F1CCB526B3879935BF59CDADD5C37479BB1CDD4CA7B3556B516589 310 EF352754B706114D9C885EC9131DE6EFEB43D99AFE2391C2F958179413D7CFEF6B1B6DB1E7600F00DE6E5C67454A339A4BA2E0FBA85ED26F045D454F463DBFCE484C2F90F2E5E3666003662ED8F755951A7D1BECD5B30B550B2785C8E7320B7292A4838DDA71BBC863ED7613CAF659337A3354231D4FF4A182A54904C2898C 310 98B28C4AD0CE056CCF332A80986E571EE9DBC305BB5FEB7E509220A58D25CF042D712A806AC0AD0C657FDEF80D2D9CEAA2EE4D1C76F60BFE74219A06527D6F82DF6412526107381E55E353090704D085B52408A8913C4ED159D79BDA71BB4BC506F4831350EB6F975CD22D69BF7AC49B91A2C0A9DDA3D5CA36AD20FC478E37 310 E61844E2352865EBCB61A275A65283CAAA9DD27703B4102F5AF51EF5F573B75CBB5AD38BC845F7A49F82A0966A49C2E3EA5EA0ECD326CD965F1DB402C6FA8B51A4658C5C5E2EC9E214602E55810345408596591009A82E7E7FFACA19EEA299B14A0081A705CB3296EBC14CDF658DCD336EA6D1136881AAEB87B81AB9EE53D5 310 F5EB8BC8362082DA24122F98680A4E7930C01A0079749CEA14382A0783E5EBA5A10F8C098456A03D6A4AEB6BB881E2513747552A5DB22C7EDAF83BD5528081A365F7FF06504B0304140006080000CC70623B000000000000000000000000350000006662782F41393633353835312D344632462D344230382D423046372D37 310 39314545314133324237412F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F747269616E676C65732E62696E636660600000504B0304140006080000CC7062 310 3B000000000000000000000000370000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F41393633353835312D344632462D344230382D4230 310 46372D3739314545314133324237412F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE6 310 07FB144396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623BEDD1DC58FD000000A00100003B0000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F7265736F75726365732F 310 636F72652E786D6C8D504B6E833010BD0A9A6D65B00922041947112427E8052C33A156828DFCA97AFC9A40A576D7CDCCE87D344F8F9FBFE667F689CE6B6B3A6039850C8DB2A336530731DC4903D95970676DF82583CCC8193B5861107C72362E3BA4AC096842428D1D7107A5F7182053CF7474E0D507CE32973124857FE48B 310 540F3961CEF244279DE03EB81420DB9EAC1384436FA353E879B1B182C7A8C75DA3C7F453DF353A1075D537A7BA6464B8F535A99AE14A9A2BBD90E350DD183B5CFABE3AF262350B1EF4FC9351399401471025A527C218A1E53BAB5A5AB765F5469B96525EACF23FA6B88CFF34456DC2A1DCE36E360F82A5202F42F062ED2BAD 310 579969AFDD8A6F504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B 310 436F6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623B853B8169EB0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000094020000636E782E786D6C504B 310 01021400140006080800CC70623BDBABAAF470010000D40300000C00000000000000000000000000180300006662782F636F72652E786D6C504B01021400140006080800CC70623B9C113CC27E0000009D0000000B00000000000000000000000000B20400006662782F636E782E786D6C504B01021400140006080800CC70 310 623B7DF2F77C2A010000120200003100000000000000000000000000590500006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D2060000 310 6662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636E782E786D6C504B01021400140006080800CC70623BE75B7789680500003C10000034000000000000000000000000006E0800006662782F41393633353835312D344632462D344230382D423046372D3739314545 310 314133324237412F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000280E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F76657274696365732E62696E504B01021400140006 310 080800CC70623BF270F133060000000400000036000000000000000000000000007B0E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F747269616E676C65732E62696E504B01021400140006080000CC70623B0000000000000000000000003700000000000000 310 000000000000D50E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD1900000004101000036000000000000000000000000002A0F00006662782F41393633353835312D344632 310 462D344230382D423046372D3739314545314133324237412F6469726563746F72792E786D6C504B01021400140006080800CC70623BEDD1DC58FD000000A00100003B000000000000000000000000000E1000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F7265 310 736F75726365732F636F72652E786D6C504B0506000000000E000E0080040000641100000000 0 XRECORD 5 1F8 102 {ACAD_REACTORS 330 1F7 102 } 330 1F7 100 AcDbXrecord 280 1 70 1 90 429727718 1 30362254-06B7-45E0-A893-8CFA70E3D6BC 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623B1EC5D7A3EB0000007C01000008000000636F72652E786D6C8D90416EC3201045AF82665B6103C6756C6122AB4D4ED00B204C5C94182C03558F5F9C3852BBEB6A467FFE9B197D71FC9E6FE8CBACC17AD7032D0820E3B41FAD9B7A48F1820F808E52ACDEC75F36404ECDA687 310 4D0629A6D5A76597B477D1B89855E747B38B2A041301E95B6E7A08FAD3CCAA50296647B8168BD2573599823EBB0CA76447F43862C7BCCF5EAC59410E4DDD9C7973C2755553CCCFA4C603E3040F1565ED3B1FDE4E432BCA0D9622DAF9795FAF464533826484B498524CD807E51D79ED187F21878E10516EF63F505AC67F42C9 310 BA58B1FDDD071640D2FCC87D2045B96591CB3DA85CB7DCE40F504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF32603847 310 2BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623B8C9102E971010000D40300000C0000006662782F636F72652E786D6CC5535B6E833010BC8AE5DF0A6C08340F1947A84D4ED00B38C6A128602363A31CBFCB234A53A551FA553EC09AD9F5CE8C31DB9E9B1AF5CA 310 7695D1198E428A91D2D214952E33ECDD315861B4E5CC1AE3BE9561A445A3323CC098B3D21ADFCE9034DA29ED00D5A6503328BA4E398C640D8B0C77F253352214DE4145770A5B214FA2546114020D759C75CE8200340D19DE981F0F6746269C33EFAB6266AB02A655C74A59CCF365BADC27CB5D902ED22848F6340DF238A141 310 BE88E2F57B92BFEDF23523433367AE6A2EEAA455C2A902F398D2751045018D3FA264435F3771F242571B4A1919CA6F9A7C5B3CD9E42BED16F12C776AEB308F40C848FC700B1139D4891EF410CEC810227CC6846F8386402064270EF5C5C709A05E49676C024C61FC95EA45ED154CA5211D1FF4FB8291A913A68E9B83EBBB33 310 E2A7673CDE118E5AE8124C0807CB8377834E366998436B950D7A7746DAD846D4CFD978E0F04FD455FC5D49D2D4C6FE9722321F10997F0F32DC47FE05504B0304140006080800CC70623BFFEA85907E0000009D0000000B0000006662782F636E782E786D6C4DCCD10A83201886E15B91FFDC95D95A811AB6F23E625948A6C3 310 E9D8E5AF46073BFAE0E1E365ED67B3E8ADC3CB78C7815C7240DA3DFC64DCC221C519D7805AC182F7F1EF06C88D9BE6703008B6049F9E274D7A1E938DBB5AE3D6131B2589BA0D3D965551E0B2EA732C9B9A624AAEB41E3A557677029960D9AFB4EF11165F504B0304140006080800CC70623B4FEEA4082C0100001202000031 310 0000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636F72652E786D6C8D515B6EC32010BC0AE2AB55850DD871ED0813254D72825EC00192A2C460F1A872FC42ED48ED5F7E00CDCECCCEB26C731F6FE05B39AFADE921293004CA082BB5B9F43086336A21D870E6AC 310 0D7F68109861543DCC30E4ECE26C9C164858139409093556AA051CBC570102714B8F1E7AF1A5C6A11862480C7F2DA6415C878B2A4891CA89C7990F2E050073937C42DE1DB7E4F87ED8A36D4329AA9B3D46DBAEAD504556557BD81DEBDD0761E52CE42C462D17B996298E3E6BE59E35C962CE821E1FF18553435012728A7187 310 0841987E927A8D9B35ADDF70BBC6989599FE4F1427F9A4286A132ABAC49D651EF234CD5CE04CDA78BA3DC2A8FB645D00B9DF8B57E215725C60BCA2A463E54C4CE327C7A65E1C7DB02E7DEFCBF594B864C5CA6CDBD49C957943E9FA5D5FBAF336F90F504B0304140006080800CC70623BAD7543B64E01000033030000300000 310 006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C 310 789FEE6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5 310 C8917738143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05 310 E207504B0304140006080800CC70623B16AB87BA640500003C100000340000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F6F626A656374732E786D6CAD575B6FA33818FD2B887DE6924B3BED8A326A92B68A663B534DD4D13E548A0C38942D60649B369D5FBFC7 310 600890A493BDE42160637FD7F31D7FF63E6FB3D478A55C242CBF3247B66B1A340F5994E4F19559CA8D75611A9F7D8F33263BCB4C232719BD32D5B4E97B316765A1A722BA21652A07B3B7B33F0D11D29C9A46981221AE4C113ED38CD8A4942CA2E2C58E882476BCD9DA23BB5ED8171B73523C0F841684D35CC252CCE79062D4 310 468DFA43D7747CCF51DF7D4FFDEB5593E3AB9CCA9FBEFE241792E4E19EB28198C968BAB8199F5D5A67D3E9C49A9E8F47D6EC76B6B0469F26EEFC7C3EBFBCBEB98462213924694B38DD98FE1D62C393D073EA4FADC5DAF04326852CCF6958F90F0F2B9BB5C48816348F90C7840A68EB78EDF68723159BCEE7891A6B95DDE9D3 310 BCEAEEE8086A6C6F9E5D4B59F0175C10A7A0820BAA5055C7473B5AE3CFDD452D602CD5DF12616444529E90D448938013FE6EFA58AA96F85E4F8C42275708571E98FE6827AF6B2B4AE3D7D83D64E5A64C53054DD3AF90BD06FEA9149565C94FCA0F6B834DC85599E4F2423B24DF0B6AFA979E534DFA9E7A4CC6FA631D486393 310 921829879BF5D781A373557BCB85E97FB90DB62B558F8795179C15944B051F40AB495CF35451D26A4727654E6D8033BD98EF82F21D91FF8AF2DD9982BCF1643BDD4EB516C9492E368C67C88DED563FC36D5EACF66DFF057C3658BDBFA69DF9578B3DA735B64F18C7F20770A9D45CFCF7FCF563D6456A277DBEF78A02637CA2 310 43B90A490AEAB94F72244481D24819A6C0E59B606BFA4B3025981DBB48EAB701D97BF19C577CC77F2D1B6C55A9EF3C732474C0B727303F625995056C3B02963D9EAC146BE78EC5FCEC7FA999EBC5EACBAAE41B12D27B4D2C0BBA49F244E2ECDC81B76B502F113D8F5EE8FB1BE3111CDD4FC2AA9B844CAB1288B68AB90A7CDC 310 1C166AB0D3DC5310625FCC14E779BFD0709F8890A629C9292B1B2DED31A4B0DA928CEE135085754027E3018A397D4D5427D15BD1330B677DC8934285AC3DF45A9EB68FF8F2B8FC0A509AFEECFD0FF2DE25CC6047F7214B195F07EFEB9A094D800F7BFAE8FED187B78EA8A3A400F115961BCAD1215E47C966530AF0EE8128FE 310 58CEBB996A8964FFA529A046635D9353B0336A8F700DDF46271A024E70B0B37C9DE01847591E54DED53D54202AB947E4076556AC49C6CA5C9E1226B7F1A7B1BE15DEED62C41B91E1B3E9AFAAA735036547343A925075041DF0A9979E893B391F8FCFA6967B3EFB644DCF6E5CEBFAE272625DCC6FAF3FB93793C5F90CE1EF57 310 407342756B10D1C489E8953CD1617E5CEECAD6F4EF8914CE5D5D504E5C3F1F9736DA62CFC11E00BCDDB8CC8A9466349744C1F75EBDA4DF09BA8A9E8C7A7E9991989E20E5DBDD6A6003664ED8F7A04A8DBE0DF6EAD9B9AA858342E47399053949D2C146EDB85DE4B176BB0965FBAC19BD19AA918E27FA50C1D22402E144464C 310 59462568E704B6E71915404CB72B8FF4EDE184DDAF753F284990D2C6926782963815403548A70C657FDEF80D2D9CEAA2AE4C1C76F60BFE74219A06527D6582DF6412526107381E55E353090704D085B52408D0933C4ED159D79BDA71BB4BC506F4831350EB6F979CD22D69BF7AC49B91A2C0A9DDA3D5CA36AD20FC478E37E6 310 1844E2352865EBCB6EA275A652E3836BE04EFB400BF1A2556F515F1FBB35B2AB35BD889C744FFA1004B5544B121E57F70215746DD2F5E2C1412B602CBF19455AC6C8E5E9922C4E01E65215385004546899059180EAFCF7A707CE7017CD8CDB0410789AB32C63B91E5CEBBBACB17AC6CD347A022D5075FD106377347AAABA7E 310 7D11590744509B44E205134DC1290F06580320F78E537D3D73540E06CB970B431F185308AD40BBD794D6D77003C5A36E8EAA54BA64597CD8F83BD552A080A365F7FF06504B0304140006080000CC70623B000000000000000000000000350000006662782F39464131463745442D413632322D343644302D413938332D3331 310 353338454246344243312F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F747269616E676C65732E62696E636660600000504B0304140006080000CC70623B 310 000000000000000000000000370000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F39464131463745442D413632322D343644302D413938 310 332D3331353338454246344243312F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE607 310 FB144396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623B0D6EF93BFE000000A00100003B0000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F7265736F75726365732F63 310 6F72652E786D6C8D50596E833010BD0A9ADFCA60B334011947A8694ED00B586642AC041B79A97AFC9A40A5F6AF3F33A3B7689E1E3F7DCD8FEC139DD7D6F4C0720A191A65476DA61E62B892236427C19DB5E1970C322367EC618541F0C9D9B8EC90B226A009093576C41D94DE63804C3DD2D18357379C652E63480A7FCF17A9 310 EE72C29CE5894E3AC17D702940B63D59270887DE46A7D0F36263058F518FBB468FE9A7BE6A7420864373B8D4873369AA8691FA421B3294352543C5CAF65C0F6FEF43CB8BD52C78D0F34F46E550061C419494B6843142CB0F5677F4B52BEB177AEC28E5C52AFF638ACBF84F53D42654E51E77B379102C05791282176B5F693D 310 CB4C7BED567C03504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B 310 436F6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623B1EC5D7A3EB0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000094020000636E782E786D6C504B 310 01021400140006080800CC70623B8C9102E971010000D40300000C00000000000000000000000000180300006662782F636F72652E786D6C504B01021400140006080800CC70623BFFEA85907E0000009D0000000B00000000000000000000000000B30400006662782F636E782E786D6C504B01021400140006080800CC70 310 623B4FEEA4082C0100001202000031000000000000000000000000005A0500006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D5060000 310 6662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636E782E786D6C504B01021400140006080800CC70623B16AB87BA640500003C1000003400000000000000000000000000710800006662782F39464131463745442D413632322D343644302D413938332D3331353338 310 454246344243312F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000270E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F76657274696365732E62696E504B01021400140006 310 080800CC70623BF270F133060000000400000036000000000000000000000000007A0E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F747269616E676C65732E62696E504B01021400140006080000CC70623B0000000000000000000000003700000000000000 310 000000000000D40E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD190000000410100003600000000000000000000000000290F00006662782F39464131463745442D413632 310 322D343644302D413938332D3331353338454246344243312F6469726563746F72792E786D6C504B01021400140006080800CC70623B0D6EF93BFE000000A00100003B000000000000000000000000000D1000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F7265 310 736F75726365732F636F72652E786D6C504B0506000000000E000E0080040000641100000000 0 XRECORD 5 175 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 174 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1FB 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 70 0 90 1673772943 1 ECE7A1D2-D628-4531-984C-D00F80459256 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623BD9DDAED0EC0000007C01000008000000636F72652E786D6C8D90416EC3201045AF82665B61836D9CD8C2444DD39CA01740405C94182C03558F5F9C3852BBEB6A467FFE9B197D7EF89E6EE8CB2CC17A37002D0820E394D7D68D03A478C17B4007C117EFE32F1B20272733C0 310 2A83E0E3E2D3BC49CABB685CCCAAF3DA6CA20CC14440EA969B0182FA34932C648AD911AEC52CD5558EA6A0CF2EC329598D1E47ACCEFBECC59A050463A7EA5833865FEBDD0E37353BE3EE8DBDE3F6786A48D375FBF6CC78B9C282473B3DEFABC5C86834888A900E538A49F5419B9EB47DD5BC907D4F082F57FB1F28CDFA9F50 310 B22ED6D5F6EE030B20687EE43E10BC5CB3C8E51E54AE6B6EE207504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF326038 310 472BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623BA24EB22D72010000D40300000C0000006662782F636F72652E786D6CC5535B6E833010BC8AE5DF0A6C5E49888CA3A6694ED00B38E05014B091B1518EDFE511A5A9D228FD2A1F60CDEC7A67C6986DCE4D8D7A 310 69BA4AAB0C073EC548AA5C17952A33ECECD15B61B4E1CC686DBF9561A44423333CC098B3D268D7CE50AE9595CA02AA74216750749DB418E5352C32DCE59FB211BE70162ABA93DF8AFC244AE9073ED050C759670D0840D390E18DF9F1706664C23973AE2A66B62A605A75ACA4C13C4976E1364A12EF355A2EBD384AF65EFA96 310 BC7B8BED2EA6719AAE16FB8491A199335B351775B991C2CA02F390D2D40B028F861F41BCA68B7518BFD0D59A524686F29B26D7164F36B94AD9289CE54E6D1DE6010819891F6E21228B3AD1831EC219194284CF98F06DD01008846CC5A1BEF83801D4CBDC6A1303536877A57A513B0953A94FC707FDBE6064EA84A9E3E6E0FA 310 EE8CF0E9198F7784A316AA0413C2C2F2E0ECA0934D1AE6D05A69BCDE9E91D2A611F573361E38FC1375157F5752AE6B6DFE4B11990F88CCBF0719EE23FF02504B0304140006080800CC70623B408A7D3B7C0000009D0000000B0000006662782F636E782E786D6C4DCCD10A83201886E15B91FFDC552A92A0064DBC8F581632 310 D3703A76F9ABD1C18E3E78F878E5F0D9027ABBFCF2292AE86E2D20171F69F6715550CB827B40839639A5F2770314A7CD293819B45C73AAFB45B35BA61ACAA1C1C7E7855C58C15BC331339661262CC762340413D68D77DA5B42298546CBE6573AF60CEB2F504B0304140006080800CC70623B449FB9BD290100001202000031 310 0000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636F72652E786D6C8D515B6EC32010BC0AE22B55850D98B871848994463E412FE002495162B07854397EA176A4F62F3F2C9A9D991D587EB84F37F0AD7D30CEF6905418026DA553C65E7A98E219ED203808EE9D 310 8B7F6810D871D23D2C3014FCE25D9A57483A1BB58D19B54EE9151C43D0110279CB971E06F9A5A7B11A53CC8C70ADE6515EC78BAE4895DB992778883E0700CB907242D17643D7E2538BD869608875438BBAE38922CAC8F1BDD90DB4691A5E2F42C153326A951B95E398B3D1FE599322163C9AE9115F7A3D46ADA0A018778810 310 84E907617BDCEE297BC5BB3DC6BC2EF47FA234AB2745C9D8D8D035EE220B50105E2F0DC1954B9FB747187D9F9D8FA0CCDB042D5FA0C015C65B42DF78BD10F3F3B363CB56C7109DCFDFBBB97E662ED92EB62D13BC2E1BCAE5777DB9966D8A1F504B0304140006080800CC70623BAD7543B64E01000033030000300000006662 310 782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C789FEE 310 6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5C89177 310 38143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05E20750 310 4B0304140006080800CC70623B8D05915C650500003B100000340000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F6F626A656374732E786D6CAD575B6FA33814FE2B887D06429276DA1565D4266D158D3A339A6846FB502932E050B66023DB74D2FDF5FB190C01 310 9276B2973C046C8ECFF53B17071F77456EBD502133CEAE6CDF9DD81665314F32965ED995DA3A17B6F5310C04E7AA47665B8C14F4CAD6DB7618A48257A5D94AE89654B91AEDDEDDFC61C998326A5B714EA4BCB265FC440BE2924AF184CA6737218AB8E976E7FA6E4338649B0A523E8D98964450A6A029F619B8588D52FE7039 310 B1BD30F0F4F730D0FF866AF6369557DB33949F31A9088B0F848DD8CCFCF9F2767A76E99CCDE733677E3EF59D9BBB9BA5E37F984D16E78BC5E5F5ED25044B25C0C96822E8D60EEFE11B91C581D77CEA34368A1F5329E68CD1B8B61F16D63A1B8E092D294B10C78C4A48EB593D192E7DED9BDEE7995E1B91FDEDD3ACEA9FE831 310 6A756F9F7D4D79F4274C90A7A04248AA51D5F8C718DAE06FB2F75AC4796EBE65D22A88A22223B995679120E2D50E41AA49C260C046A35368846B0BECD0DFF3EBEB8AD4F835768F69B9ADF25C43D30E6B646F807FAA64AD59F61715C7A54127C4AACA98BA3006A9D792DAE165E0D59B61A01FB3A9F9D838D2DAE62445C86166 310 F37564E842E7DE6A69879FEEA2DD5AE7E371E1A5E025154AC307D06A03D73EB5978C58FFA4C8E9033066E0F3BD53BEC1F39F91BE7B55103791EDE6BBB991A2046172CB4581D8B893FA674DDA17A77B3B7C413D1B511FD2743BFF8A38F03A658705E3ADF8015C3A3417FF3D7E439FF591DA0B5F18BC20C1B8981957AE6392A3 310 F43C640C01D1A0B4728E2DD4F26DB4B3C3152A252A3B4E913CEC1C72F012782FF88EFF8637AA552DBEF76408E8A8DE9E50F9E1CB3A2DA0DB1B6039A893B56063DC5B3E3FFB5F72E67AB9FEB4AEC496C4F4C1149625DD662C53E89D7BF0F6151A046260D1337DFDC94502430F83B0EE07A130A224BCAD7DAE1D9FB6CD422FF6 310 920702629C4BB9AE79C12F243C6432A6794E18E5552BA56B431AAB5D91317302B2B071E86C3A42B1A02F999E24061403B5D0EB639195DA655DD3EBEAB4FB862DDF579F014AD0E73C22F99E28DA57FB98E75C6CA2D74D53086D600F4786E0FE3144B771A8A7B900F03594DB8A633CBC49B2EDB69228BB479CF863B5E807AAAB 310 23872F6DFEB4129B949CA33823F58830E86D65621E10047D9DB34D862E8EAC3C2ABC2F7B2C40D67CDFE01F5545B92105AF983AC54D93D69E56FB8E797F88913F898A9FEC705D3F9D1B54EC8426FB500D40A03BD0119B06E1B95DDC7EB8F6975367793EBD70E66733DFB9BC982F9CE564727731999F5D4ECFCE3B8D6A4DC2A0 310 6D50FD148437D110834A64C6CDDF57FBACB5C307A2A477DFE4939736CFEF2B175371E0E10CF0DD1D5C15654E0BCA14D1E87DD02FF93782A162C0A3D95F1524A52770F972BF1EE9809D13CE7DD599467F8ECE9ADD85CE85A34CD45355448C64F9E8A031DC2D596ACC6E5DD93D9B82DE2EF5CAF81363A8E47996A0DE24564A79 310 4115AACE09C55E14540231FDA13C319787134EBF34E3A022514E5B4D9E0826E25C02D5805B15ABE1BEF51B26383D445DD9E875EE33FE4C22DA16427D65A3BCA92CA6D28DD01DF5DC53330704308475351050232CCD31583787BA75774AFB06E5070DD0C8EF484E19968C5D83BA5B90B244D31E54D55A372320FE4786B7EA58 310 44E135AA5467CB7EA333A61683CC6A8C3257034C10CF46F40EF9F5BE59BE5BD30C3C72D235E95D10345C1D45445A5F0BB47E46A5EBE5570F9380B5FA629579952296A773720405982B9DE04011506178964401AA8BDF1FBF0A8EAB6861DD6580C0E38217056766716DAEB2D6FA0917D3E4116581EADB879C4E7CFFB11EFACD 310 3D641311495D92C8676CB409A72D18610D803CE8A626049E8EC1887CB5B44CC39883690DDA8399B4B9855B481E7D71D4A9D22F96E5BB73BF5793020C02137BF837504B0304140006080000CC70623B000000000000000000000000350000006662782F36394639363044362D344446342D343946362D394244322D32343142 310 43333846323333332F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F747269616E676C65732E62696E636660600000504B0304140006080000CC70623B0000 310 00000000000000000000370000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F36394639363044362D344446342D343946362D394244322D 310 3234314243333846323333332F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE607FB14 310 4396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623BCA768048FE000000A00100003B0000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F7265736F75726365732F636F72 310 652E786D6C8D50596E833010BD0A9ADFCA60D600328E9AA639412F609909B1126CE4A5EAF16B0295DABFFECC8CDEA2797AECF8353F924FB44E193D409E5248504B332A3D0D10FC95B4901C39B3C6F85F3248B49871801506CE266BC2B243D2688FDA47549B11775038871E12F988C7004EDE7016A9083E2ADC3D5D84BC8B09 310 D33C8D74D471E6BC8D0192EDC93A815B742658898E651BCB59086ADC356A8C3FD555A1055ED7E7E254D615792D0F075295F585746FF53B694EE78A565DD736979A65AB9933AFE69F8CD2A2F038022F28ED489E135A7CE4554F9BBEA85E68DB53CAB255FEC71496F19FA6A0B42F8B3DEE6673C0F318E4497096AD7DC5F52C33 310 EEB55BFE0D504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B436F 310 6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623BD9DDAED0EC0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000095020000636E782E786D6C504B0102 310 1400140006080800CC70623BA24EB22D72010000D40300000C00000000000000000000000000190300006662782F636F72652E786D6C504B01021400140006080800CC70623B408A7D3B7C0000009D0000000B00000000000000000000000000B50400006662782F636E782E786D6C504B01021400140006080800CC70623B 310 449FB9BD290100001202000031000000000000000000000000005A0500006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D20600006662 310 782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636E782E786D6C504B01021400140006080800CC70623B8D05915C650500003B10000034000000000000000000000000006E0800006662782F36394639363044362D344446342D343946362D394244322D32343142433338 310 46323333332F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000250E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F76657274696365732E62696E504B010214001400060808 310 00CC70623BF270F13306000000040000003600000000000000000000000000780E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F747269616E676C65732E62696E504B01021400140006080000CC70623B00000000000000000000000037000000000000000000 310 00000000D20E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD190000000410100003600000000000000000000000000270F00006662782F36394639363044362D344446342D 310 343946362D394244322D3234314243333846323333332F6469726563746F72792E786D6C504B01021400140006080800CC70623BCA768048FE000000A00100003B000000000000000000000000000B1000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F7265736F 310 75726365732F636F72652E786D6C504B0506000000000E000E0080040000621100000000 0 XRECORD 5 176 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 177 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 CELLSTYLEMAP 5 2BA 102 {ACAD_REACTORS 330 162 102 } 330 162 100 AcDbCellStyleMap 90 3 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 32768 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 11 144 6.0 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 1 91 1 300 _TITLE 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 11 144 4.5 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 2 91 1 300 _HEADER 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 2 62 0 340 11 144 4.5 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 3 91 2 300 _DATA 309 CELLSTYLE_END 0 ENDSEC 0 SECTION 2 ACDSDATA 70 2 71 8 0 ACDSSCHEMA 90 0 1 AcDb_Thumbnail_Schema 2 AcDbDs::ID 280 10 91 8 2 Thumbnail_Data 280 15 91 0 101 ACDSRECORD 95 0 90 1 2 AcDbDs::TreatedAsObjectData 280 1 291 1 101 ACDSRECORD 95 0 90 2 2 AcDbDs::Legacy 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 3 2 AcDs:Indexable 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 4 2 AcDbDs::HandleAttribute 280 7 282 1 0 ACDSSCHEMA 90 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 ACDSSCHEMA 90 2 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 ACDSSCHEMA 90 3 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 ACDSSCHEMA 90 4 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 22 2 Thumbnail_Data 280 15 94 1192 310 89504E470D0A1A0A0000000D4948445200000130000001000803000000035FDA6C00000300504C5445212830FFFFFF2128300000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF0000000000000000000000000000000000000000000000000000000000002E4550F1000001634944415478DAEDDCC10DC4200C0041FAEF977F2AE061C90EB6982DC09C265C1E28C95A922449922449922449924ADB59E54D8A2DFB3B58DA9C1DBA4CCD7E3E3060C0800103060C18 310 3060C080010336006C03AB5C15183060C0800103060C183060C080010306AC7845C73BE139C0800103060C183060C0800103060C18B0D32943D6AB337658DD243B2CB8C31A5EEFDEF73060C0800103060C183060C080010306CC01223060C0800103060CD835300F0597AE0A0C183060C05E027BFE3BAE9756B5C3EC30F730 310 60C0800103F63C98E39DF01C60C0800103060C183060C0800103060C183060C0800103060C5829984FC900F39704060C183060C0800103060C183060C08079C6754AC0800103060C183060C0800103060C183060A7398E77A273800103060C183060C0800103060C183060C05256CC7BD7E84A4B9224499224499224499224 310 499224499224499224499224499224499224499224499224499286F7013C57CBB289ED2ED80000000049454E44AE426082 0 ENDSEC 0 EOF ================================================ FILE: testdata/simple_axial_lines.ntf ================================================ 01depthmapX test\0% 02Land-Line\0% 050001 Axial set 1\0% 050002 Axial s1% et 2\0% 07depthmap 21000062000000001000006200000000100000531000000018400000000000000% 23000000 0001 0000000 0000000% 2100000000000033993014668 033294036321 0% 23000000 0001 0000000 0000000% 2100000000000048311025494 018859026891 0188591% 000000 0% 23000000 0001 0000000 0000000% 2100000000000044237011525 020838008614 0% 23000000 0001 0000000 0000000% 2100000000000004423021536 007101006286 0% 23000000 0001 0000000 0000000% 2100000000000003958000349 016880000931 0% 23000000 0001 0000000 0000000% 2100000000000014551004889 015366001280 0% 23000000 0001 0000000 0000000% 2100000000000034807011059 023748011.757 0% 23000000 0001 0000000 0000000% 2100000000000025494004889 024447013387 0% 23000000 0001 0000000 0000000% 2100000000000026658005122 014318005937 0% 23000000 0002 0000000 0000000% 2100000000000015599003026 015366013853 0% 23000000 0002 0000000 0000000% 2100000000000025844013154 010128012107 0% 23000000 0002 0000000 0000000% 2100000000000004423010360 004772017345 0% 23000000 0002 0000000 0000000% 2100000000000005005040745 003725035389 0% 23000000 0002 0000000 0000000% 2100000000000004540034807 000582039580 0% 23000000 0002 0000000 0000000% 2100000000000020605036670 002211030616 0% 23000000 0002 0000000 0000000% 2100000000000015133038882 013620022817 0% 23000000 0002 0000000 0000000% 2100000000000016996037252 000465035972 0% ================================================ FILE: testdata/simple_axlines.mid ================================================ 0,2,67.185654 1,3,50.994308 2,2,65.140717 3,2,27.951588 4,2,12.985298 5,1,6.2235465 6,2,11.059984 7,3,8.5625963 8,2,12.366808 9,2,10.829045 10,3,35.987316 11,1,6.9935918 12,1,10.242486 13,2,6.2006397 14,1,19.364029 15,3,16.136318 16,2,16.580376 ================================================ FILE: testdata/simple_axlines.mif ================================================ Version 300 Charset "WindowsLatin1" Delimiter "," Index 1 CoordSys NonEarth Units "m" Bounds (-50.000000, -50.000000) ( 50.000000, 50.000000) Columns 3 Depthmap_Ref Integer Connectivity Float Line_Length Float Data LINE -48.31199068684517 25.49476135040745 18.85913853317811 26.89173457508731 PEN (1,2,0) LINE -33.9930151338766 -14.66821885913853 -33.29452852153667 36.32130384167637 PEN (1,2,0) LINE -44.23748544819558 -11.52502910360885 20.83818393480792 -8.614668218859139 PEN (1,2,0) LINE 4.423748544819557 -21.53667054714785 7.10128055878929 6.286379511059371 PEN (1,2,0) LINE 3.958090803259604 0.3492433061699651 16.88009313154831 -0.9313154831199069 PEN (1,2,0) LINE 14.55180442374854 4.889406286379511 15.36670547147846 -1.280558789289872 PEN (1,2,0) LINE -34.80791618160652 11.05937136204889 -23.74854481955763 11.17578579743888 PEN (1,2,0) LINE -25.49476135040745 4.889406286379511 -24.44703143189756 13.38766006984866 PEN (1,2,0) LINE -26.65890570430733 5.122235157159488 -14.31897555296857 5.937136204889407 PEN (1,2,0) LINE -15.59953434225844 3.026775320139697 -15.36670547147846 13.85331781140861 PEN (1,2,0) LINE -25.84400465657741 13.15483119906868 10.12805587892899 12.10710128055879 PEN (1,2,0) LINE 4.423748544819557 10.36088474970896 4.772991850989523 17.34575087310827 PEN (1,2,0) LINE -5.005820721769499 40.74505238649593 3.725261932479627 35.38998835855646 PEN (1,2,0) LINE -4.540162980209546 34.80791618160652 -0.5820721769499417 39.58090803259604 PEN (1,2,0) LINE -20.60535506402794 36.67054714784634 -2.211874272409779 30.61699650756694 PEN (1,2,0) LINE -15.13387660069849 38.88242142025611 -13.62048894062864 22.81722933643772 PEN (1,2,0) LINE -16.9965075669383 37.25261932479627 -0.4656577415599534 35.9720605355064 PEN (1,2,0) ================================================ FILE: testdata/simple_axlines_pline.mid ================================================ 0,2,67.185654 1,3,50.994308 2,2,65.140717 3,2,27.951588 4,2,12.985298 5,1,6.2235465 6,2,11.059984 7,3,8.5625963 8,2,12.366808 9,2,10.829045 10,3,35.987316 11,1,6.9935918 12,1,10.242486 13,2,6.2006397 14,1,19.364029 15,3,16.136318 16,2,16.580376 ================================================ FILE: testdata/simple_axlines_pline.mif ================================================ Version 300 Charset "WindowsLatin1" Delimiter "," Index 1 CoordSys NonEarth Units "m" Bounds (-50.000000, -50.000000) ( 50.000000, 50.000000) Columns 3 Depthmap_Ref Integer Connectivity Float Line_Length Float Data PLINE 3 -48.31199068684517 25.49476135040745 18.85913853317811 26.89173457508731 18.85913853317811 0 PEN (1,2,0) LINE -33.9930151338766 -14.66821885913853 -33.29452852153667 36.32130384167637 PEN (1,2,0) LINE -44.23748544819558 -11.52502910360885 20.83818393480792 -8.614668218859139 PEN (1,2,0) LINE 4.423748544819557 -21.53667054714785 7.10128055878929 6.286379511059371 PEN (1,2,0) LINE 3.958090803259604 0.3492433061699651 16.88009313154831 -0.9313154831199069 PEN (1,2,0) LINE 14.55180442374854 4.889406286379511 15.36670547147846 -1.280558789289872 PEN (1,2,0) LINE -34.80791618160652 11.05937136204889 -23.74854481955763 11.17578579743888 PEN (1,2,0) LINE -25.49476135040745 4.889406286379511 -24.44703143189756 13.38766006984866 PEN (1,2,0) LINE -26.65890570430733 5.122235157159488 -14.31897555296857 5.937136204889407 PEN (1,2,0) LINE -15.59953434225844 3.026775320139697 -15.36670547147846 13.85331781140861 PEN (1,2,0) LINE -25.84400465657741 13.15483119906868 10.12805587892899 12.10710128055879 PEN (1,2,0) LINE 4.423748544819557 10.36088474970896 4.772991850989523 17.34575087310827 PEN (1,2,0) LINE -5.005820721769499 40.74505238649593 3.725261932479627 35.38998835855646 PEN (1,2,0) LINE -4.540162980209546 34.80791618160652 -0.5820721769499417 39.58090803259604 PEN (1,2,0) LINE -20.60535506402794 36.67054714784634 -2.211874272409779 30.61699650756694 PEN (1,2,0) LINE -15.13387660069849 38.88242142025611 -13.62048894062864 22.81722933643772 PEN (1,2,0) LINE -16.9965075669383 37.25261932479627 -0.4656577415599534 35.9720605355064 PEN (1,2,0) ================================================ FILE: testdata/turns.dxf ================================================ 0 SECTION 2 HEADER 9 $ACADVER 1 AC1027 9 $ACADMAINTVER 70 125 9 $DWGCODEPAGE 3 ANSI_1252 9 $LASTSAVEDBY 1 petros 9 $REQUIREDVERSIONS 160 0 9 $INSBASE 10 0.0 20 0.0 30 0.0 9 $EXTMIN 10 0.0 20 0.0 30 0.0 9 $EXTMAX 10 2.5 20 1.5 30 0.0 9 $LIMMIN 10 0.0 20 0.0 9 $LIMMAX 10 420.0 20 297.0 9 $ORTHOMODE 70 0 9 $REGENMODE 70 1 9 $FILLMODE 70 1 9 $QTEXTMODE 70 0 9 $MIRRTEXT 70 0 9 $LTSCALE 40 1.0 9 $ATTMODE 70 1 9 $TEXTSIZE 40 2.5 9 $TRACEWID 40 1.0 9 $TEXTSTYLE 7 Standard 9 $CLAYER 8 0 9 $CELTYPE 6 ByLayer 9 $CECOLOR 62 256 9 $CELTSCALE 40 1.0 9 $DISPSILH 70 0 9 $DIMSCALE 40 1.0 9 $DIMASZ 40 2.5 9 $DIMEXO 40 0.625 9 $DIMDLI 40 3.75 9 $DIMRND 40 0.0 9 $DIMDLE 40 0.0 9 $DIMEXE 40 1.25 9 $DIMTP 40 0.0 9 $DIMTM 40 0.0 9 $DIMTXT 40 2.5 9 $DIMCEN 40 2.5 9 $DIMTSZ 40 0.0 9 $DIMTOL 70 0 9 $DIMLIM 70 0 9 $DIMTIH 70 0 9 $DIMTOH 70 0 9 $DIMSE1 70 0 9 $DIMSE2 70 0 9 $DIMTAD 70 1 9 $DIMZIN 70 8 9 $DIMBLK 1 9 $DIMASO 70 1 9 $DIMSHO 70 1 9 $DIMPOST 1 9 $DIMAPOST 1 9 $DIMALT 70 0 9 $DIMALTD 70 3 9 $DIMALTF 40 0.03937007874016 9 $DIMLFAC 40 1.0 9 $DIMTOFL 70 1 9 $DIMTVP 40 0.0 9 $DIMTIX 70 0 9 $DIMSOXD 70 0 9 $DIMSAH 70 0 9 $DIMBLK1 1 9 $DIMBLK2 1 9 $DIMSTYLE 2 ISO-25 9 $DIMCLRD 70 0 9 $DIMCLRE 70 0 9 $DIMCLRT 70 0 9 $DIMTFAC 40 1.0 9 $DIMGAP 40 0.625 9 $DIMJUST 70 0 9 $DIMSD1 70 0 9 $DIMSD2 70 0 9 $DIMTOLJ 70 0 9 $DIMTZIN 70 8 9 $DIMALTZ 70 0 9 $DIMALTTZ 70 0 9 $DIMUPT 70 0 9 $DIMDEC 70 2 9 $DIMTDEC 70 2 9 $DIMALTU 70 2 9 $DIMALTTD 70 3 9 $DIMTXSTY 7 Standard 9 $DIMAUNIT 70 0 9 $DIMADEC 70 0 9 $DIMALTRND 40 0.0 9 $DIMAZIN 70 0 9 $DIMDSEP 70 44 9 $DIMATFIT 70 3 9 $DIMFRAC 70 0 9 $DIMLDRBLK 1 9 $DIMLUNIT 70 2 9 $DIMLWD 70 -2 9 $DIMLWE 70 -2 9 $DIMTMOVE 70 0 9 $DIMFXL 40 1.0 9 $DIMFXLON 70 0 9 $DIMJOGANG 40 0.7853981633974483 9 $DIMTFILL 70 0 9 $DIMTFILLCLR 70 0 9 $DIMARCSYM 70 0 9 $DIMLTYPE 6 9 $DIMLTEX1 6 9 $DIMLTEX2 6 9 $DIMTXTDIRECTION 70 0 9 $LUNITS 70 2 9 $LUPREC 70 4 9 $SKETCHINC 40 1.0 9 $FILLETRAD 40 0.0 9 $AUNITS 70 0 9 $AUPREC 70 0 9 $MENU 1 . 9 $ELEVATION 40 0.0 9 $PELEVATION 40 0.0 9 $THICKNESS 40 0.0 9 $LIMCHECK 70 0 9 $CHAMFERA 40 0.0 9 $CHAMFERB 40 0.0 9 $CHAMFERC 40 0.0 9 $CHAMFERD 40 0.0 9 $SKPOLY 70 0 9 $TDCREATE 40 2458063.099826389 9 $TDUCREATE 40 2458063.099826389 9 $TDUPDATE 40 2458063.103020833 9 $TDUUPDATE 40 2458063.103020833 9 $TDINDWG 40 0.0032060185 9 $TDUSRTIMER 40 0.0032060185 9 $USRTIMER 70 1 9 $ANGBASE 50 0.0 9 $ANGDIR 70 0 9 $PDMODE 70 0 9 $PDSIZE 40 0.0 9 $PLINEWID 40 0.0 9 $SPLFRAME 70 0 9 $SPLINETYPE 70 6 9 $SPLINESEGS 70 8 9 $HANDSEED 5 27E 9 $SURFTAB1 70 6 9 $SURFTAB2 70 6 9 $SURFTYPE 70 6 9 $SURFU 70 6 9 $SURFV 70 6 9 $UCSBASE 2 9 $UCSNAME 2 9 $UCSORG 10 0.0 20 0.0 30 0.0 9 $UCSXDIR 10 1.0 20 0.0 30 0.0 9 $UCSYDIR 10 0.0 20 1.0 30 0.0 9 $UCSORTHOREF 2 9 $UCSORTHOVIEW 70 0 9 $UCSORGTOP 10 0.0 20 0.0 30 0.0 9 $UCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $UCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $UCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $UCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $UCSORGBACK 10 0.0 20 0.0 30 0.0 9 $PUCSBASE 2 9 $PUCSNAME 2 9 $PUCSORG 10 0.0 20 0.0 30 0.0 9 $PUCSXDIR 10 1.0 20 0.0 30 0.0 9 $PUCSYDIR 10 0.0 20 1.0 30 0.0 9 $PUCSORTHOREF 2 9 $PUCSORTHOVIEW 70 0 9 $PUCSORGTOP 10 0.0 20 0.0 30 0.0 9 $PUCSORGBOTTOM 10 0.0 20 0.0 30 0.0 9 $PUCSORGLEFT 10 0.0 20 0.0 30 0.0 9 $PUCSORGRIGHT 10 0.0 20 0.0 30 0.0 9 $PUCSORGFRONT 10 0.0 20 0.0 30 0.0 9 $PUCSORGBACK 10 0.0 20 0.0 30 0.0 9 $USERI1 70 0 9 $USERI2 70 0 9 $USERI3 70 0 9 $USERI4 70 0 9 $USERI5 70 0 9 $USERR1 40 0.0 9 $USERR2 40 0.0 9 $USERR3 40 0.0 9 $USERR4 40 0.0 9 $USERR5 40 0.0 9 $WORLDVIEW 70 1 9 $SHADEDGE 70 3 9 $SHADEDIF 70 70 9 $TILEMODE 70 1 9 $MAXACTVP 70 64 9 $PINSBASE 10 0.0 20 0.0 30 0.0 9 $PLIMCHECK 70 0 9 $PEXTMIN 10 0.0 20 0.0 30 0.0 9 $PEXTMAX 10 0.0 20 0.0 30 0.0 9 $PLIMMIN 10 0.0 20 0.0 9 $PLIMMAX 10 12.0 20 9.0 9 $UNITMODE 70 0 9 $VISRETAIN 70 1 9 $PLINEGEN 70 0 9 $PSLTSCALE 70 1 9 $TREEDEPTH 70 3020 9 $CMLSTYLE 2 Standard 9 $CMLJUST 70 0 9 $CMLSCALE 40 20.0 9 $PROXYGRAPHICS 70 1 9 $MEASUREMENT 70 1 9 $CELWEIGHT 370 -1 9 $ENDCAPS 280 0 9 $JOINSTYLE 280 0 9 $LWDISPLAY 290 0 9 $INSUNITS 70 4 9 $HYPERLINKBASE 1 9 $STYLESHEET 1 9 $XEDIT 290 1 9 $CEPSNTYPE 380 0 9 $PSTYLEMODE 290 1 9 $FINGERPRINTGUID 2 {AFD1DA9D-7DA5-454D-AE1C-440A3E196D4F} 9 $VERSIONGUID 2 {9AECDF69-EDC8-E448-993E-6650646B9926} 9 $EXTNAMES 290 1 9 $PSVPSCALE 40 0.0 9 $OLESTARTUP 290 0 9 $SORTENTS 280 127 9 $INDEXCTL 280 0 9 $HIDETEXT 280 1 9 $XCLIPFRAME 280 2 9 $HALOGAP 280 0 9 $OBSCOLOR 70 257 9 $OBSLTYPE 280 0 9 $INTERSECTIONDISPLAY 280 0 9 $INTERSECTIONCOLOR 70 257 9 $DIMASSOC 280 2 9 $PROJECTNAME 1 9 $CAMERADISPLAY 290 0 9 $LENSLENGTH 40 50.0 9 $CAMERAHEIGHT 40 0.0 9 $STEPSPERSEC 40 2.0 9 $STEPSIZE 40 6.0 9 $3DDWFPREC 40 2.0 9 $PSOLWIDTH 40 5.0 9 $PSOLHEIGHT 40 80.0 9 $LOFTANG1 40 1.570796326794896 9 $LOFTANG2 40 1.570796326794896 9 $LOFTMAG1 40 0.0 9 $LOFTMAG2 40 0.0 9 $LOFTPARAM 70 7 9 $LOFTNORMALS 280 1 9 $LATITUDE 40 37.795 9 $LONGITUDE 40 -122.394 9 $NORTHDIRECTION 40 0.0 9 $TIMEZONE 70 -8000 9 $LIGHTGLYPHDISPLAY 280 1 9 $TILEMODELIGHTSYNCH 280 1 9 $CMATERIAL 347 EC 9 $SOLIDHIST 280 0 9 $SHOWHIST 280 1 9 $DWFFRAME 280 2 9 $DGNFRAME 280 0 9 $REALWORLDSCALE 290 1 9 $INTERFERECOLOR 62 1 9 $INTERFEREOBJVS 345 F9 9 $INTERFEREVPVS 346 F6 9 $CSHADOW 280 0 9 $SHADOWPLANELOCATION 40 0.0 0 ENDSEC 0 SECTION 2 CLASSES 0 CLASS 1 ACDBDICTIONARYWDFLT 2 AcDbDictionaryWithDefault 3 ObjectDBX Classes 90 0 91 1 280 0 281 0 0 CLASS 1 DICTIONARYVAR 2 AcDbDictionaryVar 3 ObjectDBX Classes 90 0 91 11 280 0 281 0 0 CLASS 1 TABLESTYLE 2 AcDbTableStyle 3 ObjectDBX Classes 90 4095 91 1 280 0 281 0 0 CLASS 1 MATERIAL 2 AcDbMaterial 3 ObjectDBX Classes 90 1153 91 3 280 0 281 0 0 CLASS 1 VISUALSTYLE 2 AcDbVisualStyle 3 ObjectDBX Classes 90 4095 91 24 280 0 281 0 0 CLASS 1 SCALE 2 AcDbScale 3 ObjectDBX Classes 90 1153 91 17 280 0 281 0 0 CLASS 1 MLEADERSTYLE 2 AcDbMLeaderStyle 3 ACDB_MLEADERSTYLE_CLASS 90 4095 91 2 280 0 281 0 0 CLASS 1 CELLSTYLEMAP 2 AcDbCellStyleMap 3 ObjectDBX Classes 90 1152 91 1 280 0 281 0 0 CLASS 1 EXACXREFPANELOBJECT 2 ExAcXREFPanelObject 3 EXAC_ESW 90 1025 91 0 280 0 281 0 0 CLASS 1 NPOCOLLECTION 2 AcDbImpNonPersistentObjectsCollection 3 ObjectDBX Classes 90 1153 91 0 280 0 281 0 0 CLASS 1 LAYER_INDEX 2 AcDbLayerIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 SPATIAL_INDEX 2 AcDbSpatialIndex 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 IDBUFFER 2 AcDbIdBuffer 3 ObjectDBX Classes 90 0 91 0 280 0 281 0 0 CLASS 1 ACDBSECTIONVIEWSTYLE 2 AcDbSectionViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 CLASS 1 ACDBDETAILVIEWSTYLE 2 AcDbDetailViewStyle 3 ObjectDBX Classes 90 1025 91 1 280 0 281 0 0 ENDSEC 0 SECTION 2 TABLES 0 TABLE 2 VPORT 5 8 330 0 100 AcDbSymbolTable 70 1 1001 ACAD 1000 DbSaveVer 1071 30 0 VPORT 5 EA 330 8 100 AcDbSymbolTableRecord 100 AcDbViewportTableRecord 2 *Active 70 0 10 0.0 20 0.0 11 1.0 21 1.0 12 1.001627717390972 22 0.5962582929476006 13 0.0 23 0.0 14 10.0 24 10.0 15 10.0 25 10.0 16 0.0 26 0.0 36 1.0 17 0.0 27 0.0 37 0.0 40 3.854413096348022 41 1.394052044609665 42 50.0 43 0.0 44 0.0 50 0.0 51 0.0 71 0 72 1000 73 1 74 3 75 0 76 1 77 0 78 0 281 0 65 1 110 0.0 120 0.0 130 0.0 111 1.0 121 0.0 131 0.0 112 0.0 122 1.0 132 0.0 79 0 146 0.0 348 F5 60 3 61 5 292 1 282 1 141 0.0 142 0.0 63 250 421 3355443 1001 ACAD_NAV_VCDISPLAY 1070 3 0 ENDTAB 0 TABLE 2 LTYPE 5 5 330 0 100 AcDbSymbolTable 70 2 0 LTYPE 5 14 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByBlock 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 15 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 ByLayer 70 0 3 72 65 73 0 40 0.0 0 LTYPE 5 16 330 5 100 AcDbSymbolTableRecord 100 AcDbLinetypeTableRecord 2 Continuous 70 0 3 Solid line 72 65 73 0 40 0.0 0 ENDTAB 0 TABLE 2 LAYER 5 2 102 {ACAD_XDICTIONARY 360 1FF 102 } 330 0 100 AcDbSymbolTable 70 1 0 LAYER 5 10 102 {ACAD_XDICTIONARY 360 13C 102 } 330 2 100 AcDbSymbolTableRecord 100 AcDbLayerTableRecord 2 0 70 0 62 7 6 Continuous 370 -3 390 F 347 EE 348 0 0 ENDTAB 0 TABLE 2 STYLE 5 3 330 0 100 AcDbSymbolTable 70 2 0 STYLE 5 11 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Standard 70 0 40 0.0 41 1.0 50 0.0 71 0 42 2.5 3 arial.ttf 4 1001 ACAD 1000 Arial 1071 34 0 STYLE 5 132 330 3 100 AcDbSymbolTableRecord 100 AcDbTextStyleTableRecord 2 Annotative 70 0 40 0.0 41 1.0 50 0.0 71 0 42 2.5 3 arial.ttf 4 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 1001 ACAD 1000 Arial 1071 34 0 ENDTAB 0 TABLE 2 VIEW 5 6 330 0 100 AcDbSymbolTable 70 1 0 ENDTAB 0 TABLE 2 UCS 5 7 330 0 100 AcDbSymbolTable 70 0 0 ENDTAB 0 TABLE 2 APPID 5 9 330 0 100 AcDbSymbolTable 70 9 0 APPID 5 12 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD 70 0 0 APPID 5 9E 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_PSEXT 70 0 0 APPID 5 133 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnoPO 70 0 0 APPID 5 134 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 AcadAnnotative 70 0 0 APPID 5 135 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_DSTYLE_DIMJAG 70 0 0 APPID 5 136 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_DSTYLE_DIMTALN 70 0 0 APPID 5 165 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_MLEADERVER 70 0 0 APPID 5 217 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_NAV_VCDISPLAY 70 0 0 APPID 5 26C 330 9 100 AcDbSymbolTableRecord 100 AcDbRegAppTableRecord 2 ACAD_EXEMPT_FROM_CAD_STANDARDS 70 0 0 ENDTAB 0 TABLE 2 DIMSTYLE 5 A 330 0 100 AcDbSymbolTable 70 4 100 AcDbDimStyleTable 71 2 340 27 340 137 0 DIMSTYLE 105 1B0 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Standard 70 0 340 11 0 DIMSTYLE 105 137 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 Annotative 70 0 40 0.0 41 2.5 42 0.625 43 3.75 44 1.25 73 0 74 0 77 1 78 8 140 2.5 141 2.5 143 0.03937007874016 147 0.625 171 3 172 1 271 2 272 2 274 3 278 44 283 0 284 8 340 11 1001 AcadAnnotative 1000 AnnotativeData 1002 { 1070 1 1070 1 1002 } 1001 ACAD_DSTYLE_DIMJAG 1070 388 1040 1.5 1001 ACAD_DSTYLE_DIMTALN 1070 392 1070 0 0 DIMSTYLE 105 27 330 A 100 AcDbSymbolTableRecord 100 AcDbDimStyleTableRecord 2 ISO-25 70 0 41 2.5 42 0.625 43 3.75 44 1.25 73 0 74 0 77 1 78 8 140 2.5 141 2.5 143 0.03937007874016 147 0.625 171 3 172 1 271 2 272 2 274 3 278 44 283 0 284 8 340 11 0 ENDTAB 0 TABLE 2 BLOCK_RECORD 5 1 330 0 100 AcDbSymbolTable 70 2 0 BLOCK_RECORD 5 1F 102 {ACAD_XDICTIONARY 360 1CE 102 } 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Model_Space 340 22 70 0 280 1 281 0 0 BLOCK_RECORD 5 D2 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space 340 D3 70 0 280 1 281 0 0 BLOCK_RECORD 5 D6 330 1 100 AcDbSymbolTableRecord 100 AcDbBlockTableRecord 2 *Paper_Space0 340 D7 70 0 280 1 281 0 0 ENDTAB 0 ENDSEC 0 SECTION 2 BLOCKS 0 BLOCK 5 20 330 1F 100 AcDbEntity 8 0 100 AcDbBlockBegin 2 *Model_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Model_Space 1 0 ENDBLK 5 21 330 1F 100 AcDbEntity 8 0 100 AcDbBlockEnd 0 BLOCK 5 D4 330 D2 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space 1 0 ENDBLK 5 D5 330 D2 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 BLOCK 5 D8 330 D6 100 AcDbEntity 67 1 8 0 100 AcDbBlockBegin 2 *Paper_Space0 70 0 10 0.0 20 0.0 30 0.0 3 *Paper_Space0 1 0 ENDBLK 5 D9 330 D6 100 AcDbEntity 67 1 8 0 100 AcDbBlockEnd 0 ENDSEC 0 SECTION 2 ENTITIES 0 LWPOLYLINE 5 26B 330 1F 100 AcDbEntity 8 0 100 AcDbPolyline 90 12 70 1 43 0.0 10 1.0 20 1.0 10 1.0 20 0.5 10 0.5 20 0.5 10 0.5000000000000001 20 1.0 10 0.0000000000000001 20 1.0 10 0.0 20 0.0 10 1.499999999999999 20 0.0 10 1.5 20 0.75 10 2.0 20 0.75 10 2.0 20 0.0 10 2.5 20 0.0 10 2.5 20 1.0 0 ENDSEC 0 SECTION 2 OBJECTS 0 DICTIONARY 5 C 330 0 100 AcDbDictionary 281 1 3 ACAD_CIP_PREVIOUS_PRODUCT_INFO 350 216 3 ACAD_COLOR 350 6B 3 ACAD_DETAILVIEWSTYLE 350 21B 3 ACAD_GROUP 350 D 3 ACAD_LAYOUT 350 1A 3 ACAD_MATERIAL 350 6A 3 ACAD_MLEADERSTYLE 350 12D 3 ACAD_MLINESTYLE 350 17 3 ACAD_PLOTSETTINGS 350 19 3 ACAD_PLOTSTYLENAME 350 E 3 ACAD_SCALELIST 350 10C 3 ACAD_SECTIONVIEWSTYLE 350 219 3 ACAD_TABLESTYLE 350 7E 3 ACAD_VISUALSTYLE 350 EF 3 ACDB_RECOMPOSE_DATA 350 27D 3 AcDbVariableDictionary 350 5E 0 DICTIONARY 5 1FF 330 2 100 AcDbDictionary 280 1 281 1 3 ACAD_LAYERSTATES 360 200 0 DICTIONARY 5 13C 330 10 100 AcDbDictionary 280 1 281 1 0 DICTIONARY 5 1CE 330 1F 100 AcDbDictionary 280 1 281 1 0 XRECORD 5 216 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 300 ACDMAC 300 2017 300 ACDMAC_F_S 0 DICTIONARY 5 6B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 21B 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Metric50 350 21C 0 DICTIONARY 5 D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 DICTIONARY 5 1A 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Layout1 350 D3 3 Layout2 350 D7 3 Model 350 22 0 DICTIONARY 5 6A 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 ByBlock 350 ED 3 ByLayer 350 EC 3 Global 350 EE 0 DICTIONARY 5 12D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Annotative 350 13B 3 Standard 350 12E 0 DICTIONARY 5 17 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 18 0 DICTIONARY 5 19 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 0 ACDBDICTIONARYWDFLT 5 E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Normal 350 F 100 AcDbDictionaryWithDefault 340 F 0 DICTIONARY 5 10C 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 A0 350 10D 3 A1 350 1BE 3 A2 350 1BF 3 A3 350 1C0 3 A4 350 1C1 3 A5 350 1C2 3 A6 350 1C3 3 A7 350 1C4 3 A8 350 1C5 3 A9 350 1C6 3 B0 350 1C7 3 B1 350 1C8 3 B2 350 1C9 3 B3 350 1CA 3 B4 350 1CB 3 B5 350 1CC 3 B6 350 1CD 0 DICTIONARY 5 219 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Metric50 350 21A 0 DICTIONARY 5 7E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 Standard 350 7F 0 DICTIONARY 5 EF 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 2dWireframe 350 F5 3 Basic 350 F4 3 Brighten 350 FB 3 ColorChange 350 FF 3 Conceptual 350 F8 3 Dim 350 FA 3 EdgeColorOff 350 1E6 3 Facepattern 350 FE 3 Flat 350 F0 3 FlatWithEdges 350 F1 3 Gouraud 350 F2 3 GouraudWithEdges 350 F3 3 Hidden 350 F7 3 JitterOff 350 1E4 3 Linepattern 350 FD 3 OverhangOff 350 1E5 3 Realistic 350 F9 3 Shaded 350 1F3 3 Shaded with edges 350 1F2 3 Shades of Gray 350 1EF 3 Sketchy 350 1F0 3 Thicken 350 FC 3 Wireframe 350 F6 3 X-Ray 350 1F1 0 XRECORD 5 27D 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbXrecord 280 1 90 1 330 7F 330 21A 330 21C 0 DICTIONARY 5 5E 102 {ACAD_REACTORS 330 C 102 } 330 C 100 AcDbDictionary 281 1 3 CANNOSCALE 350 146 3 CENTEREXE 350 259 3 CENTERLTYPEFILE 350 25A 3 CMLEADERSTYLE 350 145 3 CTABLESTYLE 350 84 3 CVIEWDETAILSTYLE 350 227 3 CVIEWSECTIONSTYLE 350 228 3 DIMASSOC 350 5F 3 HIDETEXT 350 63 3 LAYEREVAL 350 1AE 3 LAYERNOTIFY 350 1AF 0 DICTIONARY 5 200 102 {ACAD_REACTORS 330 1FF 102 } 330 1FF 100 AcDbDictionary 281 1 0 ACDBDETAILVIEWSTYLE 5 21C 102 {ACAD_XDICTIONARY 360 236 102 } 102 {ACAD_REACTORS 330 21B 102 } 330 21B 100 AcDbModelDocViewStyle 70 0 3 Metric50 290 0 100 AcDbDetailViewStyle 70 0 71 0 90 3 71 1 340 11 62 256 40 5.0 340 0 62 256 40 5.0 300 40 0.0 280 1 71 2 340 16 90 25 62 256 71 3 340 11 62 256 40 5.0 90 0 40 15.0 90 1 300 %<\AcVar ViewDetailId>% (%<\AcVar ViewScale \f "%sn">%) 71 4 340 16 90 25 62 256 340 16 90 25 62 256 280 0 0 LAYOUT 5 D3 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 C:\Documents and Settings\basas\Application Data\Autodesk\AutoCAD 2005\R16.1\enu\plotters\Default Windows System Printer.pc3 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout1 70 1 71 1 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 D2 0 LAYOUT 5 D7 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 C:\Documents and Settings\basas\Application Data\Autodesk\AutoCAD 2005\R16.1\enu\plotters\Default Windows System Printer.pc3 4 6 40 0.0 41 0.0 42 0.0 43 0.0 44 0.0 45 0.0 46 0.0 47 0.0 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 1.0 70 688 72 0 73 0 74 5 7 75 16 147 1.0 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Layout2 70 1 71 2 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 D6 0 LAYOUT 5 22 102 {ACAD_XDICTIONARY 360 205 102 } 102 {ACAD_REACTORS 330 1A 102 } 330 1A 100 AcDbPlotSettings 1 2 none_device 4 ISO_A4_(210.00_x_297.00_MM) 6 40 7.5 41 20.0 42 7.5 43 20.0 44 210.0 45 297.0 46 11.54999923706054 47 -13.65000009536743 48 0.0 49 0.0 140 0.0 141 0.0 142 1.0 143 8.704084754739808 70 11952 72 1 73 0 74 0 7 75 0 147 0.1148885871608098 76 0 77 2 78 300 148 0.0 149 0.0 100 AcDbLayout 1 Model 70 1 71 0 10 0.0 20 0.0 11 12.0 21 9.0 12 0.0 22 0.0 32 0.0 14 0.0 24 0.0 34 0.0 15 0.0 25 0.0 35 0.0 146 0.0 13 0.0 23 0.0 33 0.0 16 1.0 26 0.0 36 0.0 17 0.0 27 1.0 37 0.0 76 0 330 1F 331 EA 1001 ACAD_PSEXT 1000 None 1000 None 1000 Not applicable 1000 The layout will not be plotted unless a new plotter configuration name is selected. 1070 0 0 MATERIAL 5 ED 102 {ACAD_XDICTIONARY 360 1F9 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 ByBlock 94 63 0 MATERIAL 5 EC 102 {ACAD_XDICTIONARY 360 1F7 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 ByLayer 94 63 0 MATERIAL 5 EE 102 {ACAD_XDICTIONARY 360 173 102 } 102 {ACAD_REACTORS 330 6A 102 } 330 6A 100 AcDbMaterial 1 Global 43 0.0007999999797903 43 0.0 43 0.0 43 0.0 43 0.0 43 0.0007999999797903 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 43 0.0 43 0.0 43 0.0 43 0.0 43 1.0 49 0.0007999999797903 49 0.0 49 0.0 49 0.0 49 0.0 49 0.0007999999797903 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 49 0.0 49 0.0 49 0.0 49 0.0 49 1.0 142 0.0007999999797903 142 0.0 142 0.0 142 0.0 142 0.0 142 0.0007999999797903 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 142 0.0 142 0.0 142 0.0 142 0.0 142 1.0 144 0.0007999999797903 144 0.0 144 0.0 144 0.0 144 0.0 144 0.0007999999797903 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 144 0.0 144 0.0 144 0.0 144 0.0 144 1.0 94 63 1001 ACAD 1070 -1 1070 3 1070 0 1000 1071 0 1070 0 0 MLEADERSTYLE 5 13B 102 {ACAD_REACTORS 330 12D 102 } 330 12D 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 14 92 -2 290 1 42 2.0 291 1 43 8.0 3 Standard 44 4.0 300 342 11 174 1 178 1 175 1 176 0 93 -1056964608 45 4.0 292 0 297 0 46 4.0 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 1 143 3.75 271 0 272 9 273 9 298 0 0 MLEADERSTYLE 5 12E 102 {ACAD_REACTORS 330 12D 102 } 330 12D 100 AcDbMLeaderStyle 179 2 170 2 171 1 172 0 90 2 40 0.0 41 0.0 173 1 91 -1056964608 340 14 92 -2 290 1 42 2.0 291 1 43 8.0 3 Standard 44 4.0 300 342 11 174 1 178 1 175 1 176 0 93 -1056964608 45 4.0 292 0 297 0 46 4.0 94 -1056964608 47 1.0 49 1.0 140 1.0 293 1 141 0.0 294 1 177 0 142 1.0 295 0 296 0 143 3.75 271 0 272 9 273 9 298 0 0 MLINESTYLE 5 18 102 {ACAD_REACTORS 330 17 102 } 330 17 100 AcDbMlineStyle 2 STANDARD 70 0 3 62 256 51 90.0 52 90.0 71 2 49 0.5 62 256 6 BYLAYER 49 -0.5 62 256 6 BYLAYER 0 ACDBPLACEHOLDER 5 F 102 {ACAD_REACTORS 330 E 102 } 330 E 0 SCALE 5 10D 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:1 140 1.0 141 1.0 290 1 0 SCALE 5 1BE 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:2 140 1.0 141 2.0 290 0 0 SCALE 5 1BF 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:4 140 1.0 141 4.0 290 0 0 SCALE 5 1C0 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:5 140 1.0 141 5.0 290 0 0 SCALE 5 1C1 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:8 140 1.0 141 8.0 290 0 0 SCALE 5 1C2 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:10 140 1.0 141 10.0 290 0 0 SCALE 5 1C3 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:16 140 1.0 141 16.0 290 0 0 SCALE 5 1C4 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:20 140 1.0 141 20.0 290 0 0 SCALE 5 1C5 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:30 140 1.0 141 30.0 290 0 0 SCALE 5 1C6 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:40 140 1.0 141 40.0 290 0 0 SCALE 5 1C7 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:50 140 1.0 141 50.0 290 0 0 SCALE 5 1C8 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 1:100 140 1.0 141 100.0 290 0 0 SCALE 5 1C9 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 2:1 140 2.0 141 1.0 290 0 0 SCALE 5 1CA 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 4:1 140 4.0 141 1.0 290 0 0 SCALE 5 1CB 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 8:1 140 8.0 141 1.0 290 0 0 SCALE 5 1CC 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 10:1 140 10.0 141 1.0 290 0 0 SCALE 5 1CD 102 {ACAD_REACTORS 330 10C 102 } 330 10C 100 AcDbScale 70 0 300 100:1 140 100.0 141 1.0 290 0 0 ACDBSECTIONVIEWSTYLE 5 21A 102 {ACAD_XDICTIONARY 360 234 102 } 102 {ACAD_REACTORS 330 219 102 } 330 219 100 AcDbModelDocViewStyle 70 0 3 Metric50 290 0 100 AcDbSectionViewStyle 70 0 71 0 90 102 71 1 340 11 62 256 40 5.0 340 0 340 0 62 256 40 5.0 300 I, O, Q, S, X, Z 40 10.0 90 0 40 2.5 90 0 71 2 340 16 90 25 62 256 340 16 90 50 62 256 40 5.0 40 2.5 40 5.0 71 3 340 11 62 256 40 5.0 90 0 40 15.0 90 1 300 %<\AcVar ViewSectionStartId>%-%<\AcVar ViewSectionEndId>% (%<\AcVar ViewScale \f "%sn">%) 71 4 62 256 62 257 300 ANSI31 40 1.0 90 0 290 0 290 0 90 6 40 0.0 40 1.570796326794896 40 0.2617993877991494 40 1.308996938995747 40 -0.2617993877991494 40 1.832595714594046 0 TABLESTYLE 5 7F 102 {ACAD_XDICTIONARY 360 162 102 } 102 {ACAD_REACTORS 330 7E 102 } 330 7E 100 AcDbTableStyle 280 0 3 Standard 70 0 71 0 40 1.5 41 1.5 280 0 281 0 7 Standard 140 4.5 170 2 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 6.0 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 7 Standard 140 4.5 170 5 62 0 63 7 283 0 90 512 91 0 1 274 -2 284 1 64 0 275 -2 285 1 65 0 276 -2 286 1 66 0 277 -2 287 1 67 0 278 -2 288 1 68 0 279 -2 289 1 69 0 0 VISUALSTYLE 5 F5 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 2dWireframe 70 4 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F4 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Basic 70 7 177 3 291 1 70 58 90 1 176 1 90 0 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FB 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Brighten 70 12 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FF 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 ColorChange 70 16 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 8 420 8421504 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 8 420 8421504 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F8 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Conceptual 70 9 177 3 291 0 70 58 90 3 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FA 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Dim 70 11 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 -50.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E6 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 EdgeColorOff 70 22 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 8 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FE 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Facepattern 70 15 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F0 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Flat 70 0 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F1 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 FlatWithEdges 70 1 177 3 291 1 70 58 90 2 176 1 90 1 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F2 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Gouraud 70 2 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F3 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 GouraudWithEdges 70 3 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F7 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Hidden 70 6 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 40.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E4 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 JitterOff 70 20 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 10 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FD 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Linepattern 70 14 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 7 176 1 90 7 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1E5 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 OverhangOff 70 21 177 3 291 1 70 58 90 2 176 0 90 2 176 0 90 0 176 0 90 0 176 0 40 0.6 176 0 40 30.0 176 0 62 7 420 16777215 176 0 90 1 176 0 90 4 176 0 62 7 176 0 62 257 176 0 90 1 176 0 90 1 176 0 40 1.0 176 0 90 9 176 2 62 7 176 0 40 1.0 176 0 90 1 176 0 90 6 176 0 90 2 176 0 62 7 176 0 90 5 176 0 90 0 176 0 90 0 176 0 290 0 176 0 90 1 176 0 40 0.0 176 0 90 0 176 0 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F9 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Realistic 70 8 177 3 291 0 70 58 90 2 176 1 90 3 176 1 90 0 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F3 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shaded 70 27 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 0 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 8 420 7895160 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F2 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shaded with edges 70 26 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 2 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 2 176 1 62 7 176 1 62 257 176 1 90 2 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 5 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1EF 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Shades of Gray 70 23 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 3 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F0 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Sketchy 70 24 177 3 291 0 70 58 90 1 176 1 90 2 176 1 90 2 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 2 176 1 90 2 176 1 62 7 176 1 62 7 176 1 90 1 176 1 90 1 176 1 40 40.0 176 1 90 11 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 6 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 FC 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Thicken 70 13 177 3 291 1 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 12 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 5 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 F6 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 Wireframe 70 5 177 3 291 0 70 58 90 0 176 1 90 2 176 1 90 0 176 1 90 0 176 1 40 0.6 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 4 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 0 176 1 62 257 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 1 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 VISUALSTYLE 5 1F1 102 {ACAD_REACTORS 330 EF 102 } 330 EF 100 AcDbVisualStyle 2 X-Ray 70 25 177 3 291 0 70 58 90 2 176 1 90 2 176 1 90 1 176 1 90 1 176 1 40 0.5 176 1 40 30.0 176 1 62 7 420 16777215 176 1 90 1 176 1 90 0 176 1 62 7 176 1 62 257 176 1 90 1 176 1 90 1 176 1 40 1.0 176 1 90 8 176 1 62 7 176 1 40 1.0 176 1 90 1 176 1 90 6 176 1 90 2 176 1 62 7 176 1 90 3 176 1 90 0 176 1 90 0 176 1 290 0 176 1 90 13 176 1 40 0.0 176 1 90 0 176 1 290 0 176 1 290 1 176 1 290 1 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 290 0 176 1 90 50 176 1 40 0.0 176 1 40 1.0 176 1 90 0 176 1 62 18 420 0 176 1 90 50 176 1 90 3 176 1 62 5 420 255 176 1 290 0 176 1 90 50 176 1 90 50 176 1 90 50 176 1 290 0 176 1 90 50 176 1 62 256 176 0 40 1.0 176 0 90 2 176 1 1 strokes_ogs.tif 176 1 290 0 176 1 40 1.0 176 1 40 1.0 176 1 0 DICTIONARYVAR 5 146 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 1:1 0 DICTIONARYVAR 5 259 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 3.500000 0 DICTIONARYVAR 5 25A 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 acadiso.lin 0 DICTIONARYVAR 5 145 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 84 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 STANDARD 0 DICTIONARYVAR 5 227 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 Metric50 0 DICTIONARYVAR 5 228 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 Metric50 0 DICTIONARYVAR 5 5F 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 2 0 DICTIONARYVAR 5 63 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 1 0 DICTIONARYVAR 5 1AE 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 0 0 DICTIONARYVAR 5 1AF 102 {ACAD_REACTORS 330 5E 102 } 330 5E 100 DictionaryVariables 280 0 1 0 0 DICTIONARY 5 236 330 21C 100 AcDbDictionary 280 1 281 1 3 ACAD_XREC_ROUNDTRIP 360 27C 0 DICTIONARY 5 205 330 22 100 AcDbDictionary 280 1 281 1 0 DICTIONARY 5 1F9 330 ED 100 AcDbDictionary 280 1 281 1 3 FBXASSET 360 1FA 0 DICTIONARY 5 1F7 330 EC 100 AcDbDictionary 280 1 281 1 3 FBXASSET 360 1F8 0 DICTIONARY 5 173 330 EE 100 AcDbDictionary 280 1 281 1 3 BUMPTILE 360 175 3 DIFFUSETILE 360 174 3 FBXASSET 360 1FB 3 OPACITYTILE 360 176 3 REFLECTIONTILE 360 177 0 DICTIONARY 5 234 330 21A 100 AcDbDictionary 280 1 281 1 3 ACAD_XREC_ROUNDTRIP 360 27B 0 DICTIONARY 5 162 330 7F 100 AcDbDictionary 280 1 281 1 3 ACAD_ROUNDTRIP_2008_TABLESTYLE_CELLSTYLEMAP 360 27A 0 XRECORD 5 27C 102 {ACAD_REACTORS 330 236 102 } 330 236 100 AcDbXrecord 280 1 102 DISPLAYNAME 1 Metric50 102 FLAGS 90 0 0 XRECORD 5 1FA 102 {ACAD_REACTORS 330 1F9 102 } 330 1F9 100 AcDbXrecord 280 1 70 1 90 429727718 1 D62C5603-E3A1-4AEA-B7FB-FE5D8D0755AF 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623B853B8169EB0000007C01000008000000636F72652E786D6C8D90416EC3201045AF62CDB6C206821CC7C244919D9CA01740401C94182C03558F5F9C3852BBEB6A467FFE9B197D7EFC9E1EC5975982F5AE035262288C535E5B377690E21535501C055FBC8FBF6C503839990E 310 5619041F179FE64D52DE45E362569DD7661365082642A11EB9E920A89B99642953CC8E702F67A9EE7234257977194EC9EAE275C4EABCCF5EAD5940D4AC6F0E35A568B8F43562CD7046CD199FD07E60174276A7BE677B5EADB0E0D14EEFFB6A31321A0D82627C4084204C3F096B71DD52F6819B16635EADF63F509AF53FA164 310 5DDCD1EDDD17164090FCC8732078B56691CB33A85CD7DCC40F504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF32603847 310 2BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623BDBABAAF470010000D40300000C0000006662782F636F72652E786D6CC553D16E823014FD95A6AF4B694182CC941A83FA05FB810A9511A125A5257EFE2E82712ECEB8A7F100CD39F7F69E734AF9FADC366850B6 310 AF8DCE7018308C942E4C59EB2AC3DE1D498AD15A706B8CFB56869196ADCAF00863C12B6B7C374385D14E6907A836A59A41D9F7CA615434B0C8705F7CAA5606D23BA8E84F41278B93AC54100640439DE0BDB320004D43C63716C7C399D30917DCFBBA9CD9BA8469F5B156168B24CED3F7248AC8769F27244EB73B92EED8862C 310 B7F13E0C179B3C8F979C8ECD82BBBABDAA2BAC924E9558448CBD9330242CFA08E3154B5651FCC6D215639C8EE5774DBE2B5F6CF2B5768B68963BB5F5588420E442FC700B1139D4CB01F450C1E918227C2E09DF070D8140C84E1E9AAB8F1340832A9CB13130A5F1376A908D57309505ECF2A0DF179C4E9D30F5B239B87E3823 310 7A79C6F31DE1A8A5AEC08474B03C7837EAE4938639B44E5932B833D2C6B6B279CDC613877FA26EE21F4A2A4C63EC7F29A2F301D1F9F7A0E37D145F504B0304140006080800CC70623B9C113CC27E0000009D0000000B0000006662782F636E782E786D6C4DCCDF0A83201C86E15B91DFB94BFB330DD428C8FB886521330DA7 310 6397BF1A1DECE883878F57749FCDA1B7892F1BBC047A23808C7F84D9FA55424E0BE6803A256208E9EF06C84F9B91703228B1C690F78B66B34CD9A5439DF5CF0BFBF65E35BCA1B8D6A5C6F540381E886698B5741C695F9503EBA150A2F8958E3DC3EA0B504B0304140006080800CC70623B7DF2F77C2A010000120200003100 310 00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636F72652E786D6C8D51DB8EC22014FC15C2939B0D2DB4B45643319AE817EC0F6041255A68B86CFCFC856D4D76DF7CE190393373060EDB3DC707F856CE6B6B7A480A0C81328395DA5C7B18C3057510EC3873D686 310 3F34088C18550F330C39BB3A1BA7051AAC09CA84841A2BD5020AEF55806078A44B0FFD7053A328440C89E1EFC52486BBB8AA8214A99D789CF9E05200300FC927E4FB4D5B375D43103D5527440FB843077C5AA3F5861C8F645F5787F59E95B390B318B55CE45AA638FAA2957BD7248B390B7A7CC51F9C124149C82B8C378810 310 84AB2F42B7B8DD56F413775B8C5999E9FF4471926F8AA236A1AE96B8B3CC434E5839373893369E1FAF30EA395917409EB7F26AF8801C171837A4A6AC9C89E9F9C9B1A58BA30FD6A5EF5DDDCF894B9AD9B6A59C957943A9FCAE2FD5BC4DFE03504B0304140006080800CC70623BAD7543B64E01000033030000300000006662 310 782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C789FEE 310 6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5C89177 310 38143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05E20750 310 4B0304140006080800CC70623BE75B7789680500003C100000340000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F6F626A656374732E786D6CAD575B8F9B3818FD2B887D06C22499CB8AA1CA655245D5B455A356FB305264C061D8018C6C3393D95FBFC7600890 310 A4CD5EF210B0B1BFEBF98E3F7B1FF6596ABC522E1296DF9BAE3D320D9A872C4AF2F8DE2CE5CEBA358D0FBEC719939D65A691938CDE9B6ADAF4BD98B3B2D05311DD91329583D9D5FC0F438434A7A611A644887B5384CF34233629258BA878B12322891DEFF6B66BD70BFB62634E8AE781D082709A4B588AF91C528CDA28B73F 310 1C998EEF39EABBEFA97FBD6A7C7E9553F9D3D79FE442923C3C523610337627CB87ABE99D359D4CC6D6E4FACAB5E6ABF9D2726FC6A3C5F56271377BB88362213924694B38DD99FE47C48627A1E7D49F5A8BB5E1A74C0A599ED3B0F21F1E56366B89112D681E218F0915D0D6F17AD41FBA2A369DCF6335D62ABBD39779D5DDD1 310 11D4D8DE3CBB96B2E04FB8202E41051754A1AA8E8F76B4C6DFE810B580B1547F4B84911149794252234D024EF8BBE963A95AE27B3D310A9D5C215C7960FAEE415ED75694C6AFB17BCACA5D99A60A9AA65F217B0BFC53292ACB92BF283FAD0D3621576592CB5BED907C2FA8E9DF794E35E97BEA31BED21FEB401ABB94C44839 310 DCACBF0E1C5DA8DA5B2F4DFFD32AD86F543D9E565E7056502E157C00AD2671CD534549AB752FCA9CDA00677A313F04E51B22FF19E57B300579E3C97EB29F682D92935CEC18CF901B7B54FD8C51F362B56FC72FE0B3C1EAE335EDCCBF5AEC39ADB17DC238973F804BA5E6F6BFE7AF1FB32E523BE9F3BD571418E3631DCA4D48 310 5250CF639223210A9446CA30052EDF057BD35F8329C1ECD84552BF0DC8D18BE7BCE23BFE6BD960AB4A7DE79923A103BEBD80F911CBAA2C60DB19B01CF164A5583B772EE6D3FFA56666CBCDA74DC97724A48F9A58967497E489C4D979006FD7A05E227A1EBDD0F737C623387A9C844D3709995625106D157315F8B8392CD4E0 310 A0B9A720C4BE9829CEF37EA1E13111214D53925356365ADA634861B52519DD27A00AEB808EAF0628E6F435519D446F45CF2C9CF5214F0A15B2F6D06B79DA3EE3CBF7F56780D2F4E7EF73A0F5E5B02A38D07DC852C6B7C1FBB6664213E0C39E3EBA7FF4E1AD23EA2829407C85E586727488B751B2DB9502BC7B228A3FD68B6E 310 A65A22397E690AA8D158D7E404EC8CDA235CC3B7D1898680131CEC2CDF2638C65196279577750F15884AEE19F94199155B92B13297978469D4F8D358DF0AEF7631E28DC8F0D9F437D5D39A83B2231A1D52D543813A824EF8D44BCFF2FA6A31BD1E8DAD87F1CCB526B3879935BF59CDADD5C37479BB1CDD4CA7B3556B516589 310 EF352754B706114D9C885EC9131DE6EFEB43D99AFE2391C2F958179413D7CFEF6B1B6DB1E7600F00DE6E5C67454A339A4BA2E0FBA85ED26F045D454F463DBFCE484C2F90F2E5E3666003662ED8F755951A7D1BECD5B30B550B2785C8E7320B7292A4838DDA71BBC863ED7613CAF659337A3354231D4FF4A182A54904C2898C 310 98B28C4AD0CE056CCF332A80986E571EE9DBC305BB5FEB7E509220A58D25CF042D712A806AC0AD0C657FDEF80D2D9CEAA2EE4D1C76F60BFE74219A06527D6F82DF6412526107381E55E353090704D085B52408A8913C4ED159D79BDA71BB4BC506F4831350EB6F975CD22D69BF7AC49B91A2C0A9DDA3D5CA36AD20FC478E37 310 E61844E2352865EBCB61A275A65283CAAA9DD27703B4102F5AF51EF5F573B75CBB5AD38BC845F7A49F82A0966A49C2E3EA5EA0ECD326CD965F1DB402C6FA8B51A4658C5C5E2EC9E214602E55810345408596591009A82E7E7FFACA19EEA299B14A0081A705CB3296EBC14CDF658DCD336EA6D1136881AAEB87B81AB9EE53D5 310 F5EB8BC8362082DA24122F98680A4E7930C01A0079749CEA14382A0783E5EBA5A10F8C098456A03D6A4AEB6BB881E2513747552A5DB22C7EDAF83BD5528081A365F7FF06504B0304140006080000CC70623B000000000000000000000000350000006662782F41393633353835312D344632462D344230382D423046372D37 310 39314545314133324237412F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F747269616E676C65732E62696E636660600000504B0304140006080000CC7062 310 3B000000000000000000000000370000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F41393633353835312D344632462D344230382D4230 310 46372D3739314545314133324237412F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE6 310 07FB144396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623BEDD1DC58FD000000A00100003B0000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F7265736F75726365732F 310 636F72652E786D6C8D504B6E833010BD0A9A6D65B00922041947112427E8052C33A156828DFCA97AFC9A40A576D7CDCCE87D344F8F9FBFE667F689CE6B6B3A6039850C8DB2A336530731DC4903D95970676DF82583CCC8193B5861107C72362E3BA4AC096842428D1D7107A5F7182053CF7474E0D507CE32973124857FE48B 310 540F3961CEF244279DE03EB81420DB9EAC1384436FA353E879B1B182C7A8C75DA3C7F453DF353A1075D537A7BA6464B8F535A99AE14A9A2BBD90E350DD183B5CFABE3AF262350B1EF4FC9351399401471025A527C218A1E53BAB5A5AB765F5469B96525EACF23FA6B88CFF34456DC2A1DCE36E360F82A5202F42F062ED2BAD 310 579969AFDD8A6F504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B 310 436F6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623B853B8169EB0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000094020000636E782E786D6C504B 310 01021400140006080800CC70623BDBABAAF470010000D40300000C00000000000000000000000000180300006662782F636F72652E786D6C504B01021400140006080800CC70623B9C113CC27E0000009D0000000B00000000000000000000000000B20400006662782F636E782E786D6C504B01021400140006080800CC70 310 623B7DF2F77C2A010000120200003100000000000000000000000000590500006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D2060000 310 6662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F636E782E786D6C504B01021400140006080800CC70623BE75B7789680500003C10000034000000000000000000000000006E0800006662782F41393633353835312D344632462D344230382D423046372D3739314545 310 314133324237412F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000280E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F76657274696365732E62696E504B01021400140006 310 080800CC70623BF270F133060000000400000036000000000000000000000000007B0E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F747269616E676C65732E62696E504B01021400140006080000CC70623B0000000000000000000000003700000000000000 310 000000000000D50E00006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD1900000004101000036000000000000000000000000002A0F00006662782F41393633353835312D344632 310 462D344230382D423046372D3739314545314133324237412F6469726563746F72792E786D6C504B01021400140006080800CC70623BEDD1DC58FD000000A00100003B000000000000000000000000000E1000006662782F41393633353835312D344632462D344230382D423046372D3739314545314133324237412F7265 310 736F75726365732F636F72652E786D6C504B0506000000000E000E0080040000641100000000 0 XRECORD 5 1F8 102 {ACAD_REACTORS 330 1F7 102 } 330 1F7 100 AcDbXrecord 280 1 70 1 90 429727718 1 30362254-06B7-45E0-A893-8CFA70E3D6BC 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623B1EC5D7A3EB0000007C01000008000000636F72652E786D6C8D90416EC3201045AF82665B6103C6756C6122AB4D4ED00B204C5C94182C03558F5F9C3852BBEB6A467FFE9B197D71FC9E6FE8CBACC17AD7032D0820E3B41FAD9B7A48F1820F808E52ACDEC75F36404ECDA687 310 4D0629A6D5A76597B477D1B89855E747B38B2A041301E95B6E7A08FAD3CCAA50296647B8168BD2573599823EBB0CA76447F43862C7BCCF5EAC59410E4DDD9C7973C2755553CCCFA4C603E3040F1565ED3B1FDE4E432BCA0D9622DAF9795FAF464533826484B498524CD807E51D79ED187F21878E10516EF63F505AC67F42C9 310 BA58B1FDDD071640D2FCC87D2045B96591CB3DA85CB7DCE40F504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF32603847 310 2BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623B8C9102E971010000D40300000C0000006662782F636F72652E786D6CC5535B6E833010BC8AE5DF0A6C08340F1947A84D4ED00B38C6A128602363A31CBFCB234A53A551FA553EC09AD9F5CE8C31DB9E9B1AF5CA 310 7695D1198E428A91D2D214952E33ECDD315861B4E5CC1AE3BE9561A445A3323CC098B3D21ADFCE9034DA29ED00D5A6503328BA4E398C640D8B0C77F253352214DE4145770A5B214FA2546114020D759C75CE8200340D19DE981F0F6746269C33EFAB6266AB02A655C74A59CCF365BADC27CB5D902ED22848F6340DF238A141 310 BE88E2F57B92BFEDF23523433367AE6A2EEAA455C2A902F398D2751045018D3FA264435F3771F242571B4A1919CA6F9A7C5B3CD9E42BED16F12C776AEB308F40C848FC700B1139D4891EF410CEC810227CC6846F8386402064270EF5C5C709A05E49676C024C61FC95EA45ED154CA5211D1FF4FB8291A913A68E9B83EBBB33 310 E2A7673CDE118E5AE8124C0807CB8377834E366998436B950D7A7746DAD846D4CFD978E0F04FD455FC5D49D2D4C6FE9722321F10997F0F32DC47FE05504B0304140006080800CC70623BFFEA85907E0000009D0000000B0000006662782F636E782E786D6C4DCCD10A83201886E15B91FFDC95D95A811AB6F23E625948A6C3 310 E9D8E5AF46073BFAE0E1E365ED67B3E8ADC3CB78C7815C7240DA3DFC64DCC221C519D7805AC182F7F1EF06C88D9BE6703008B6049F9E274D7A1E938DBB5AE3D6131B2589BA0D3D965551E0B2EA732C9B9A624AAEB41E3A557677029960D9AFB4EF11165F504B0304140006080800CC70623B4FEEA4082C0100001202000031 310 0000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636F72652E786D6C8D515B6EC32010BC0AE2AB55850DD871ED0813254D72825EC00192A2C460F1A872FC42ED48ED5F7E00CDCECCCEB26C731F6FE05B39AFADE921293004CA082BB5B9F43086336A21D870E6AC 310 0D7F68109861543DCC30E4ECE26C9C164858139409093556AA051CBC570102714B8F1E7AF1A5C6A11862480C7F2DA6415C878B2A4891CA89C7990F2E050073937C42DE1DB7E4F87ED8A36D4329AA9B3D46DBAEAD504556557BD81DEBDD0761E52CE42C462D17B996298E3E6BE59E35C962CE821E1FF18553435012728A7187 310 0841987E927A8D9B35ADDF70BBC6989599FE4F1427F9A4286A132ABAC49D651EF234CD5CE04CDA78BA3DC2A8FB645D00B9DF8B57E215725C60BCA2A463E54C4CE327C7A65E1C7DB02E7DEFCBF594B864C5CA6CDBD49C957943E9FA5D5FBAF336F90F504B0304140006080800CC70623BAD7543B64E01000033030000300000 310 006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C 310 789FEE6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5 310 C8917738143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05 310 E207504B0304140006080800CC70623B16AB87BA640500003C100000340000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F6F626A656374732E786D6CAD575B6FA33818FD2B887DE6924B3BED8A326A92B68A663B534DD4D13E548A0C38942D60649B369D5FBFC7 310 600890A493BDE42160637FD7F31D7FF63E6FB3D478A55C242CBF3247B66B1A340F5994E4F19559CA8D75611A9F7D8F33263BCB4C232719BD32D5B4E97B316765A1A722BA21652A07B3B7B33F0D11D29C9A46981221AE4C113ED38CD8A4942CA2E2C58E882476BCD9DA23BB5ED8171B73523C0F841684D35CC252CCE79062D4 310 468DFA43D7747CCF51DF7D4FFDEB5593E3AB9CCA9FBEFE241792E4E19EB28198C968BAB8199F5D5A67D3E9C49A9E8F47D6EC76B6B0469F26EEFC7C3EBFBCBEB98462213924694B38DD98FE1D62C393D073EA4FADC5DAF04326852CCF6958F90F0F2B9BB5C48816348F90C7840A68EB78EDF68723159BCEE7891A6B95DDE9D3 310 BCEAEEE8086A6C6F9E5D4B59F0175C10A7A0820BAA5055C7473B5AE3CFDD452D602CD5DF12616444529E90D448938013FE6EFA58AA96F85E4F8C42275708571E98FE6827AF6B2B4AE3D7D83D64E5A64C53054DD3AF90BD06FEA9149565C94FCA0F6B834DC85599E4F2423B24DF0B6AFA979E534DFA9E7A4CC6FA631D486393 310 921829879BF5D781A373557BCB85E97FB90DB62B558F8795179C15944B051F40AB495CF35451D26A4727654E6D8033BD98EF82F21D91FF8AF2DD9982BCF1643BDD4EB516C9492E368C67C88DED563FC36D5EACF66DFF057C3658BDBFA69DF9578B3DA735B64F18C7F20770A9D45CFCF7FCF563D6456A277DBEF78A02637CA2 310 43B90A490AEAB94F72244481D24819A6C0E59B606BFA4B3025981DBB48EAB701D97BF19C577CC77F2D1B6C55A9EF3C732474C0B727303F625995056C3B02963D9EAC146BE78EC5FCEC7FA999EBC5EACBAAE41B12D27B4D2C0BBA49F244E2ECDC81B76B502F113D8F5EE8FB1BE3111CDD4FC2AA9B844CAB1288B68AB90A7CDC 310 1C166AB0D3DC5310625FCC14E779BFD0709F8890A629C9292B1B2DED31A4B0DA928CEE135085754027E3018A397D4D5427D15BD1330B677DC8934285AC3DF45A9EB68FF8F2B8FC0A509AFEECFD0FF2DE25CC6047F7214B195F07EFEB9A094D800F7BFAE8FED187B78EA8A3A400F115961BCAD1215E47C966530AF0EE8128FE 310 58CEBB996A8964FFA529A046635D9353B0336A8F700DDF46271A024E70B0B37C9DE01847591E54DED53D54202AB947E4076556AC49C6CA5C9E1226B7F1A7B1BE15DEED62C41B91E1B3E9AFAAA735036547343A925075041DF0A9979E893B391F8FCFA6967B3EFB644DCF6E5CEBFAE272625DCC6FAF3FB93793C5F90CE1EF57 310 407342756B10D1C489E8953CD1617E5CEECAD6F4EF8914CE5D5D504E5C3F1F9736DA62CFC11E00BCDDB8CC8A9466349744C1F75EBDA4DF09BA8A9E8C7A7E9991989E20E5DBDD6A6003664ED8F7A04A8DBE0DF6EAD9B9AA858342E47399053949D2C146EDB85DE4B176BB0965FBAC19BD19AA918E27FA50C1D22402E144464C 310 59462568E704B6E71915404CB72B8FF4EDE184DDAF753F284990D2C6926782963815403548A70C657FDEF80D2D9CEAA2AE4C1C76F60BFE74219A06527D6582DF6412526107381E55E353090704D085B52408D0933C4ED159D79BDA71BB4BC506F4831350EB6F979CD22D69BF7AC49B91A2C0A9DDA3D5CA36AD20FC478E37E6 310 1844E2352865EBCB6EA275A652E3836BE04EFB400BF1A2556F515F1FBB35B2AB35BD889C744FFA1004B5544B121E57F70215746DD2F5E2C1412B602CBF19455AC6C8E5E9922C4E01E65215385004546899059180EAFCF7A707CE7017CD8CDB0410789AB32C63B91E5CEBBBACB17AC6CD347A022D5075FD106377347AAABA7E 310 7D11590744509B44E205134DC1290F06580320F78E537D3D73540E06CB970B431F185308AD40BBD794D6D77003C5A36E8EAA54BA64597CD8F83BD552A080A365F7FF06504B0304140006080000CC70623B000000000000000000000000350000006662782F39464131463745442D413632322D343644302D413938332D3331 310 353338454246344243312F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F747269616E676C65732E62696E636660600000504B0304140006080000CC70623B 310 000000000000000000000000370000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F39464131463745442D413632322D343644302D413938 310 332D3331353338454246344243312F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE607 310 FB144396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623B0D6EF93BFE000000A00100003B0000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F7265736F75726365732F63 310 6F72652E786D6C8D50596E833010BD0A9ADFCA60B334011947A8694ED00B586642AC041B79A97AFC9A40A5F6AF3F33A3B7689E1E3F7DCD8FEC139DD7D6F4C0720A191A65476DA61E62B892236427C19DB5E1970C322367EC618541F0C9D9B8EC90B226A009093576C41D94DE63804C3DD2D18357379C652E63480A7FCF17A9 310 EE72C29CE5894E3AC17D702940B63D59270887DE46A7D0F36263058F518FBB468FE9A7BE6A7420864373B8D4873369AA8691FA421B3294352543C5CAF65C0F6FEF43CB8BD52C78D0F34F46E550061C419494B6843142CB0F5677F4B52BEB177AEC28E5C52AFF638ACBF84F53D42654E51E77B379102C05791282176B5F693D 310 CB4C7BED567C03504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B 310 436F6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623B1EC5D7A3EB0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000094020000636E782E786D6C504B 310 01021400140006080800CC70623B8C9102E971010000D40300000C00000000000000000000000000180300006662782F636F72652E786D6C504B01021400140006080800CC70623BFFEA85907E0000009D0000000B00000000000000000000000000B30400006662782F636E782E786D6C504B01021400140006080800CC70 310 623B4FEEA4082C0100001202000031000000000000000000000000005A0500006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D5060000 310 6662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F636E782E786D6C504B01021400140006080800CC70623B16AB87BA640500003C1000003400000000000000000000000000710800006662782F39464131463745442D413632322D343644302D413938332D3331353338 310 454246344243312F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000270E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F76657274696365732E62696E504B01021400140006 310 080800CC70623BF270F133060000000400000036000000000000000000000000007A0E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F747269616E676C65732E62696E504B01021400140006080000CC70623B0000000000000000000000003700000000000000 310 000000000000D40E00006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD190000000410100003600000000000000000000000000290F00006662782F39464131463745442D413632 310 322D343644302D413938332D3331353338454246344243312F6469726563746F72792E786D6C504B01021400140006080800CC70623B0D6EF93BFE000000A00100003B000000000000000000000000000D1000006662782F39464131463745442D413632322D343644302D413938332D3331353338454246344243312F7265 310 736F75726365732F636F72652E786D6C504B0506000000000E000E0080040000641100000000 0 XRECORD 5 175 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 174 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 1FB 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 70 0 90 1673772943 1 ECE7A1D2-D628-4531-984C-D00F80459256 310 504B03040A0000080000CC70623B3DEE336E79000000790000001B0000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C666F726D6174733E3C666F726D61743E687474703A2F2F736368656D612E 310 6175746F6465736B2E636F6D2F64657369676E2D7061636B6167652F323030393C2F666F726D61743E3C2F666F726D6174733E504B0304140006080800CC70623BD486FD9CA0000000F4000000130000005B436F6E74656E745F54797065735D2E786D6C7D8EC10E82300C865F65E91D8A1E8C310C0EEA1BF002731658846E 310 D98AC1B77784ABF1D8FE5FBFBF75BBCE937A534CCEB38643598122B6FEE978D0B0485F9C41B54DDD7D022595594E1A469170414C76A4D9A4D207E29CF43ECE46F218070CC6BECC4078ACAA135ACF422C856C0E68EA1BF5669944DDD7BCDE7B1F8E415D77AECB980613C2E4AC91FC167A2B244592486606FC29C8FD7F045B9A 310 EF7053A7E60B504B0304140006080800CC70623BD9DDAED0EC0000007C01000008000000636F72652E786D6C8D90416EC3201045AF82665B61836D9CD8C2444DD39CA01740405C94182C03558F5F9C3852BBEB6A467FFE9B197D7EF89E6EE8CB2CC17A37002D0820E394D7D68D03A478C17B4007C117EFE32F1B20272733C0 310 2A83E0E3E2D3BC49CABB685CCCAAF3DA6CA20CC14440EA969B0182FA34932C648AD911AEC52CD5558EA6A0CF2EC329598D1E47ACCEFBECC59A050463A7EA5833865FEBDD0E37353BE3EE8DBDE3F6786A48D375FBF6CC78B9C282473B3DEFABC5C86834888A900E538A49F5419B9EB47DD5BC907D4F082F57FB1F28CDFA9F50 310 B22ED6D5F6EE030B20687EE43E10BC5CB3C8E51E54AE6B6EE207504B0304140006080800CC70623B55019EA25F0000007C00000007000000636E782E786D6C4DCB3B0E80201045D1AD90E915ED2CF8AC45050C11660C8261F98AB1B07AC9C97D42D718D865D3E909258CFD00CCE24AC6E326A164D74DC0B4128928FF326038 310 472BA13128B1252AC747C6BAB984FC68F0B87FE8960A5C09FE86CFB69FBA01504B0304140006080800CC70623BA24EB22D72010000D40300000C0000006662782F636F72652E786D6CC5535B6E833010BC8AE5DF0A6C5E49888CA3A6694ED00B38E05014B091B1518EDFE511A5A9D228FD2A1F60CDEC7A67C6986DCE4D8D7A 310 69BA4AAB0C073EC548AA5C17952A33ECECD15B61B4E1CC686DBF9561A44423333CC098B3D268D7CE50AE9595CA02AA74216750749DB418E5352C32DCE59FB211BE70162ABA93DF8AFC244AE9073ED050C759670D0840D390E18DF9F1706664C23973AE2A66B62A605A75ACA4C13C4976E1364A12EF355A2EBD384AF65EFA96 310 BC7B8BED2EA6719AAE16FB8491A199335B351775B991C2CA02F390D2D40B028F861F41BCA68B7518BFD0D59A524686F29B26D7164F36B94AD9289CE54E6D1DE6010819891F6E21228B3AD1831EC219194284CF98F06DD01008846CC5A1BEF83801D4CBDC6A1303536877A57A513B0953A94FC707FDBE6064EA84A9E3E6E0FA 310 EE8CF0E9198F7784A316AA0413C2C2F2E0ECA0934D1AE6D05A69BCDE9E91D2A611F573361E38FC1375157F5752AE6B6DFE4B11990F88CCBF0719EE23FF02504B0304140006080800CC70623B408A7D3B7C0000009D0000000B0000006662782F636E782E786D6C4DCCD10A83201886E15B91FFDC552A92A0064DBC8F581632 310 D3703A76F9ABD1C18E3E78F878E5F0D9027ABBFCF2292AE86E2D20171F69F6715550CB827B40839639A5F2770314A7CD293819B45C73AAFB45B35BA61ACAA1C1C7E7855C58C15BC331339661262CC762340413D68D77DA5B42298546CBE6573AF60CEB2F504B0304140006080800CC70623B449FB9BD290100001202000031 310 0000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636F72652E786D6C8D515B6EC32010BC0AE22B55850D98B871848994463E412FE002495162B07854397EA176A4F62F3F2C9A9D991D587EB84F37F0AD7D30CEF6905418026DA553C65E7A98E219ED203808EE9D 310 8B7F6810D871D23D2C3014FCE25D9A57483A1BB58D19B54EE9151C43D0110279CB971E06F9A5A7B11A53CC8C70ADE6515EC78BAE4895DB992778883E0700CB907242D17643D7E2538BD869608875438BBAE38922CAC8F1BDD90DB4691A5E2F42C153326A951B95E398B3D1FE599322163C9AE9115F7A3D46ADA0A018778810 310 84E907617BDCEE297BC5BB3DC6BC2EF47FA234AB2745C9D8D8D035EE220B50105E2F0DC1954B9FB747187D9F9D8FA0CCDB042D5FA0C015C65B42DF78BD10F3F3B363CB56C7109DCFDFBBB97E662ED92EB62D13BC2E1BCAE5777DB9966D8A1F504B0304140006080800CC70623BAD7543B64E01000033030000300000006662 310 782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636E782E786D6CD593CD6EC32010845F0571AD6CE3D48AD20813A9873E410FBD12D82434182C7EAAE6EDBB2424CD25871E7B41D6EC30B3FA84F9E67BB2E40B4234DE8DB46F1925E094D7C6ED479AD3AE5951B2113C789FEE 310 6C943839C1488B4C05DF079FE72A69D8C96C13AAD6B8631503449F83828872B949AC57D26200B826A308D316B4064D6E46FCDA41C05550DC9E483A00797BFD207EFB092A45DE9514C1BBD22178396BD39D891265658C238DEA00936C654E5E433CB65A26D9F6EDB5EBC14EBF49A45CB856E66048291F6939A9A81BB5C89177 310 38143CA680F4AA299D66A042CEB3354A2684DC9D8D178FE0D9B8B41CAAD720F880EE7EF93C0C18769E099ECC04D5A102C8049A8A05632F4DDF376CF1DE0F6BB65C2F8627B65A33C6BB62177CEBBDAD973006829F89F22E814B54F4BC2BE347F8AA8F681390B50FA73F804400B5F542E796F19FF974E7F78DB802FE05E20750 310 4B0304140006080800CC70623B8D05915C650500003B100000340000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F6F626A656374732E786D6CAD575B6FA33814FE2B887D06429276DA1565D4266D158D3A339A6846FB502932E050B66023DB74D2FDF5FB190C01 310 9276B2973C046C8ECFF53B17071F77456EBD502133CEAE6CDF9DD81665314F32965ED995DA3A17B6F5310C04E7AA47665B8C14F4CAD6DB7618A48257A5D94AE89654B91AEDDEDDFC61C998326A5B714EA4BCB265FC440BE2924AF184CA6737218AB8E976E7FA6E4338649B0A523E8D98964450A6A029F619B8588D52FE7039 310 B1BD30F0F4F730D0FF866AF6369557DB33949F31A9088B0F848DD8CCFCF9F2767A76E99CCDE733677E3EF59D9BBB9BA5E37F984D16E78BC5E5F5ED25044B25C0C96822E8D60EEFE11B91C581D77CEA34368A1F5329E68CD1B8B61F16D63A1B8E092D294B10C78C4A48EB593D192E7DED9BDEE7995E1B91FDEDD3ACEA9FE831 310 6A756F9F7D4D79F4274C90A7A04248AA51D5F8C718DAE06FB2F75AC4796EBE65D22A88A22223B995679120E2D50E41AA49C260C046A35368846B0BECD0DFF3EBEB8AD4F835768F69B9ADF25C43D30E6B646F807FAA64AD59F61715C7A54127C4AACA98BA3006A9D792DAE165E0D59B61A01FB3A9F9D838D2DAE62445C86166 310 F37564E842E7DE6A69879FEEA2DD5AE7E371E1A5E025154AC307D06A03D73EB5978C58FFA4C8E9033066E0F3BD53BEC1F39F91BE7B55103791EDE6BBB991A2046172CB4581D8B893FA674DDA17A77B3B7C413D1B511FD2743BFF8A38F03A658705E3ADF8015C3A3417FF3D7E439FF591DA0B5F18BC20C1B8981957AE6392A3 310 F43C640C01D1A0B4728E2DD4F26DB4B3C3152A252A3B4E913CEC1C72F012782FF88EFF8637AA552DBEF76408E8A8DE9E50F9E1CB3A2DA0DB1B6039A893B56063DC5B3E3FFB5F72E67AB9FEB4AEC496C4F4C1149625DD662C53E89D7BF0F6151A046260D1337DFDC94502430F83B0EE07A130A224BCAD7DAE1D9FB6CD422FF6 310 920702629C4BB9AE79C12F243C6432A6794E18E5552BA56B431AAB5D91317302B2B071E86C3A42B1A02F999E24061403B5D0EB639195DA655DD3EBEAB4FB862DDF579F014AD0E73C22F99E28DA57FB98E75C6CA2D74D53086D600F4786E0FE3144B771A8A7B900F03594DB8A633CBC49B2EDB69228BB479CF863B5E807AAAB 310 23872F6DFEB4129B949CA33823F58830E86D65621E10047D9DB34D862E8EAC3C2ABC2F7B2C40D67CDFE01F5545B92105AF983AC54D93D69E56FB8E797F88913F898A9FEC705D3F9D1B54EC8426FB500D40A03BD0119B06E1B95DDC7EB8F6975367793EBD70E66733DFB9BC982F9CE564727731999F5D4ECFCE3B8D6A4DC2A0 310 6D50FD148437D110834A64C6CDDF57FBACB5C307A2A477DFE4939736CFEF2B175371E0E10CF0DD1D5C15654E0BCA14D1E87DD02FF93782A162C0A3D95F1524A52770F972BF1EE9809D13CE7DD599467F8ECE9ADD85CE85A34CD45355448C64F9E8A031DC2D596ACC6E5DD93D9B82DE2EF5CAF81363A8E47996A0DE24564A79 310 4115AACE09C55E14540231FDA13C319787134EBF34E3A022514E5B4D9E0826E25C02D5805B15ABE1BEF51B26383D445DD9E875EE33FE4C22DA16427D65A3BCA92CA6D28DD01DF5DC53330704308475351050232CCD31583787BA75774AFB06E5070DD0C8EF484E19968C5D83BA5B90B244D31E54D55A372320FE4786B7EA58 310 44E135AA5467CB7EA333A61683CC6A8C3257034C10CF46F40EF9F5BE59BE5BD30C3C72D235E95D10345C1D45445A5F0BB47E46A5EBE5570F9380B5FA629579952296A773720405982B9DE04011506178964401AA8BDF1FBF0A8EAB6861DD6580C0E38217056766716DAEB2D6FA0917D3E4116581EADB879C4E7CFFB11EFACD 310 3D641311495D92C8676CB409A72D18610D803CE8A626049E8EC1887CB5B44CC39883690DDA8399B4B9855B481E7D71D4A9D22F96E5BB73BF5793020C02137BF837504B0304140006080000CC70623B000000000000000000000000350000006662782F36394639363044362D344446342D343946362D394244322D32343142 310 43333846323333332F76657274696365732E62696E504B0304140006080800CC70623BF270F1330600000004000000360000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F747269616E676C65732E62696E636660600000504B0304140006080000CC70623B0000 310 00000000000000000000370000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F617474726962757465732E62696E504B0304140006080800CC70623B08DA0BD19000000041010000360000006662782F36394639363044362D344446342D343946362D394244322D 310 3234314243333846323333332F6469726563746F72792E786D6C858F410AC3201045AF22B36F53E9A60B35CBEEBAE80D244E44489C6234F4F835464A48035D0DF398FF9F8AF63D0E6CC63039F212F8F9020C7D47C6792B21C5FE7403D62A1188E2E60C98D7234A5830286103A55745067B9D86B8A3CF9C7F90C11DE607FB14 310 4396D7B6A82D282E9A152AD114D5EF2CB866EEE831B8EEA07A7BB5A8D7D61A2BAAEB7FD5F70921FF497D00504B0304140006080800CC70623BCA768048FE000000A00100003B0000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F7265736F75726365732F636F72 310 652E786D6C8D50596E833010BD0A9ADFCA60D600328E9AA639412F609909B1126CE4A5EAF16B0295DABFFECC8CDEA2797AECF8353F924FB44E193D409E5248504B332A3D0D10FC95B4901C39B3C6F85F3248B49871801506CE266BC2B243D2688FDA47549B11775038871E12F988C7004EDE7016A9083E2ADC3D5D84BC8B09 310 D33C8D74D471E6BC8D0192EDC93A815B742658898E651BCB59086ADC356A8C3FD555A1055ED7E7E254D615792D0F075295F585746FF53B694EE78A565DD736979A65AB9933AFE69F8CD2A2F038022F28ED489E135A7CE4554F9BBEA85E68DB53CAB255FEC71496F19FA6A0B42F8B3DEE6673C0F318E4497096AD7DC5F52C33 310 EEB55BFE0D504B010214000A0000080000CC70623B3DEE336E79000000790000001B00000000000000000000000000000000006175746F6465736B2D64657369676E2D7061636B6167652E786D6C504B01021400140006080800CC70623BD486FD9CA0000000F40000001300000000000000000000000000B20000005B436F 310 6E74656E745F54797065735D2E786D6C504B01021400140006080800CC70623BD9DDAED0EC0000007C010000080000000000000000000000000083010000636F72652E786D6C504B01021400140006080800CC70623B55019EA25F0000007C000000070000000000000000000000000095020000636E782E786D6C504B0102 310 1400140006080800CC70623BA24EB22D72010000D40300000C00000000000000000000000000190300006662782F636F72652E786D6C504B01021400140006080800CC70623B408A7D3B7C0000009D0000000B00000000000000000000000000B50400006662782F636E782E786D6C504B01021400140006080800CC70623B 310 449FB9BD290100001202000031000000000000000000000000005A0500006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636F72652E786D6C504B01021400140006080800CC70623BAD7543B64E010000330300003000000000000000000000000000D20600006662 310 782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F636E782E786D6C504B01021400140006080800CC70623B8D05915C650500003B10000034000000000000000000000000006E0800006662782F36394639363044362D344446342D343946362D394244322D32343142433338 310 46323333332F6F626A656374732E786D6C504B01021400140006080000CC70623B0000000000000000000000003500000000000000000000000000250E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F76657274696365732E62696E504B010214001400060808 310 00CC70623BF270F13306000000040000003600000000000000000000000000780E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F747269616E676C65732E62696E504B01021400140006080000CC70623B00000000000000000000000037000000000000000000 310 00000000D20E00006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F617474726962757465732E62696E504B01021400140006080800CC70623B08DA0BD190000000410100003600000000000000000000000000270F00006662782F36394639363044362D344446342D 310 343946362D394244322D3234314243333846323333332F6469726563746F72792E786D6C504B01021400140006080800CC70623BCA768048FE000000A00100003B000000000000000000000000000B1000006662782F36394639363044362D344446342D343946362D394244322D3234314243333846323333332F7265736F 310 75726365732F636F72652E786D6C504B0506000000000E000E0080040000621100000000 0 XRECORD 5 176 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 177 102 {ACAD_REACTORS 330 173 102 } 330 173 100 AcDbXrecord 280 1 270 1 271 1 0 XRECORD 5 27B 102 {ACAD_REACTORS 330 234 102 } 330 234 100 AcDbXrecord 280 1 102 DISPLAYNAME 1 Metric50 102 FLAGS 90 0 0 CELLSTYLEMAP 5 27A 102 {ACAD_REACTORS 330 162 102 } 330 162 100 AcDbCellStyleMap 90 3 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 32768 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 11 144 6.0 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 1 91 1 300 _TITLE 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 5 62 0 340 11 144 4.5 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 2 91 1 300 _HEADER 309 CELLSTYLE_END 300 CELLSTYLE 1 TABLEFORMAT_BEGIN 90 5 170 1 91 0 92 0 62 257 93 1 300 CONTENTFORMAT 1 CONTENTFORMAT_BEGIN 90 0 91 0 92 512 93 0 300 40 0.0 140 1.0 94 2 62 0 340 11 144 4.5 309 CONTENTFORMAT_END 171 1 301 MARGIN 1 CELLMARGIN_BEGIN 40 1.5 40 1.5 40 1.5 40 1.5 40 4.5 40 4.5 309 CELLMARGIN_END 94 6 95 1 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 2 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 4 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 8 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 16 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 95 32 302 GRIDFORMAT 1 GRIDFORMAT_BEGIN 90 0 91 1 62 0 92 -2 340 14 93 0 40 1.125 309 GRIDFORMAT_END 309 TABLEFORMAT_END 1 CELLSTYLE_BEGIN 90 3 91 2 300 _DATA 309 CELLSTYLE_END 0 ENDSEC 0 SECTION 2 ACDSDATA 70 2 71 8 0 ACDSSCHEMA 90 0 1 AcDb_Thumbnail_Schema 2 AcDbDs::ID 280 10 91 8 2 Thumbnail_Data 280 15 91 0 101 ACDSRECORD 95 0 90 1 2 AcDbDs::TreatedAsObjectData 280 1 291 1 101 ACDSRECORD 95 0 90 2 2 AcDbDs::Legacy 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 3 2 AcDs:Indexable 280 1 291 1 101 ACDSRECORD 1 AcDbDs::ID 90 4 2 AcDbDs::HandleAttribute 280 7 282 1 0 ACDSSCHEMA 90 1 1 AcDbDs::TreatedAsObjectDataSchema 2 AcDbDs::TreatedAsObjectData 280 1 91 0 0 ACDSSCHEMA 90 2 1 AcDbDs::LegacySchema 2 AcDbDs::Legacy 280 1 91 0 0 ACDSSCHEMA 90 3 1 AcDbDs::IndexedPropertySchema 2 AcDs:Indexable 280 1 91 0 0 ACDSSCHEMA 90 4 1 AcDbDs::HandleAttributeSchema 2 AcDbDs::HandleAttribute 280 7 91 1 284 1 0 ACDSRECORD 90 0 2 AcDbDs::ID 280 10 320 22 2 Thumbnail_Data 280 15 94 997 310 89504E470D0A1A0A0000000D4948445200000100000000B70803000000CA14702D00000300504C54452128300000000000000000000000000000000000000000000000000000000000000000330000660000990000CC0000FF0033000033330033660033990033CC0033FF0066000066330066660066990066CC0066FF0099 310 000099330099660099990099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF0000FF3300FF6600FF9900FFCC00FFFF3300003300333300663300993300CC3300FF3333003333333333663333993333CC3333FF3366003366333366663366993366CC3366FF3399003399333399663399993399CC3399FF33CC00 310 33CC3333CC6633CC9933CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF6600006600336600666600996600CC6600FF6633006633336633666633996633CC6633FF6666006666336666666666996666CC6666FF6699006699336699666699996699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066 310 FF3366FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF9933009933339933669933999933CC9933FF9966009966339966669966999966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC3399CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFFCC0000CC00 310 33CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFFCCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0000FF0033FF0066FF0099FF00CCFF00FFFF3300FF3333 310 FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33FFCC66FFCC99FFCCCCFFCCFFFFFF00FFFF33FFFF66FFFF99FFFFCCFFFFFF0000000D0D0D1A1A1A2828283535354343435050505D5D5D6B6B6B787878868686939393A1A1A1AEAEAEBB 310 BBBBC9C9C9D6D6D6E4E4E4F1F1F1FFFFFF000000000000000000000000000000000000000000000000000000000000544354A8000000A04944415478DAEDDAA10A00200C4041FFFF7FED16AB61E09CCA5D1C82F03018D61A0000000000000000000000000000000000C0D45782C7A3EE09109BF7E46B051040000104104000 310 010410E0B100D13FFF7F0136CD051040000104104000010410A03CC09EBFFDBB01721F920002082080000208208000020820800002082080000208208000450172D7DFEF5F9707000000000000000000000000000080F3060A83AEBAB9C3D29D0000000049454E44AE426082 0 ENDSEC 0 EOF ================================================ FILE: tools/build_and_upload.sh ================================================ #!/bin/sh timestamp=$(date +%Y.%m.%d.%H.%M.%S) if [ $# -ne 3 ]; then echo "Three arguments are required, runner, sync git path and location of server upload php file" exit 1 fi runner=$1 gitpath=$2 uploadpath=$3 cd "$(dirname "$0")" rm -rf depthmapX/ git clone $gitpath currentcommit=$(git rev-parse HEAD) cd depthmapX mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release .. make -j cd ../RegressionTest python3 RegressionTestRunner.py performance_regression.json cd ../../ mkdir -p runs cd runs rundir=run-$timestamp mkdir $rundir cp -r ../depthmapX/RegressionTest/rundir/* $rundir/ cd $rundir params="{\"time\":\"$timestamp\",\"runner\":\"$runner\",\"commit\":\"$currentcommit\",\"tests\":[" counter="0" for i in $(find . | grep 'timings_[0-9]\+_[0-9]\+\.csv') do newparams=$(csvtool drop 1 $i | csvtool format ',"%(1)":"%(2)"' - | cut -c2-); #newparams="${newparams// /_}" if [ "$counter" -eq "1" ]; then params="${params},"; fi params="${params}{\"file\":\"$i\",\"times\":{$newparams}}" counter="1" done params="${params}]}" curl --data "$params" $uploadpath ================================================ FILE: tools/graph.grammar ================================================ Grammar for depthmap GRAPH files ================================================ FILE: tools/storePerformanceTest.php ================================================ getTimeStamp() . '.json'; file_put_contents($fileName, $data, FILE_APPEND | LOCK_EX); } ?> ================================================ FILE: version.h ================================================ // depthmapX - spatial network analysis platform // Copyright (C) 2017 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef VERSION_H #define VERSION_H #include "version_defs.h" // use these to define the depthmap versions #define DEPTHMAPX_MAJOR_VERSION 0 #define DEPTHMAPX_MINOR_VERSION 8 #define DEPTHMAPX_REVISION_VERSION 0 #define DEPTHMAP_MODULE_VERSION 10.04 // leave these alone - C Preprocessor magic to get stuff to the right format #define STRINGIFY(v) #v #define TITLE_BASE_FORMAT(version, minor, revision) "depthmapX " STRINGIFY(version) "." STRINGIFY(minor) "." STRINGIFY(revision) #define TITLE_BASE TITLE_BASE_FORMAT(DEPTHMAPX_MAJOR_VERSION, DEPTHMAPX_MINOR_VERSION, DEPTHMAPX_REVISION_VERSION) #endif // VERSION_H ================================================ FILE: version_defs.h.in ================================================ // Copyright (C) 2018 Christian Sailer // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // This file is autogenerated - do not modify it directly! #pragma once #ifndef APP_DATE #define APP_DATE "@APP_DATE@" #endif #ifndef APP_GIT_BRANCH #define APP_GIT_BRANCH "@APP_BRANCH@" #endif #ifndef APP_GIT_COMMIT #define APP_GIT_COMMIT "@APP_COMMIT@" #endif