📄 svg_interactive_map.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// User Interface //
// //
// Program: SAGA //
// //
//-------------------------------------------------------//
// //
// SVG_Interactive_map.cpp //
// //
// Copyright (C) 2005 by Victor Olaya //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. SAGA is free software; you //
// can redistribute it and/or modify it under the terms //
// of the GNU General Public License as published by the //
// Free Software Foundation; version 2 of the License. //
// //
// SAGA is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A //
// PARTICULAR PURPOSE. See the GNU General Public //
// License for more details. //
// //
// You should have received a copy of the GNU General //
// Public License along with this program; if not, //
// write to the Free Software Foundation, Inc., //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, //
// USA. //
// //
//-------------------------------------------------------//
// //
// contact: Olaf Conrad //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
// e-mail: oconrad@saga-gis.org //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include "wksp_map_layer.h"
#include "wksp_layer_classify.h"
#include "svg_interactive_map.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define MAP_WINDOW_WIDTH 550.
#define MAP_WINDOW_HEIGHT 700.
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CSVG_Interactive_Map::CSVG_Interactive_Map(void)
{
}
//---------------------------------------------------------
CSVG_Interactive_Map::~CSVG_Interactive_Map(void)
{
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CSVG_Interactive_Map::Create_From_Map(CWKSP_Map *pMap, CSG_Shapes *pIndexLayer, const wxChar *Filename)
{
//-----------------------------------------------------
m_Directory = SG_File_Get_Path(Filename);
_Add_Opening(pMap->Get_Extent());
//-----------------------------------------------------
m_sSVGCode.Append(wxT("<g id=\"mainMapGroup\" transform=\"translate(0,0)\">\n"));
for(int i=pMap->Get_Count()-1; i>-1; i--)
{
switch( pMap->Get_Layer(i)->Get_Layer()->Get_Type() )
{
default: break;
case WKSP_ITEM_Grid: _Add_Grid ((CWKSP_Grid *)pMap->Get_Layer(i)->Get_Layer()); break;
case WKSP_ITEM_Shapes: _Add_Shapes ((CWKSP_Shapes *)pMap->Get_Layer(i)->Get_Layer()); break;
}
}
m_sSVGCode.Append(wxT("</g>\n</svg>\n"));
//-----------------------------------------------------
_Add_CheckBoxes(pMap);
_Add_ReferenceMap(pIndexLayer, pMap->Get_Extent());
m_sSVGCode.Append(_Get_Code_Closing_1());
Save(Filename);
//-----------------------------------------------------
_Write_Code(SG_File_Make_Path(m_Directory, wxT("checkbox") , wxT("js")), _Get_Code_CheckBox());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("mapApp") , wxT("js")), _Get_Code_MapApp ());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("timer") , wxT("js")), _Get_Code_Timer ());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("slider") , wxT("js")), _Get_Code_Slider ());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("helper_functions") , wxT("js")), _Get_Code_Helper ());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("button") , wxT("js")), _Get_Code_Buttons ());
_Write_Code(SG_File_Make_Path(m_Directory, wxT("navigation") , wxT("js")), CSG_String::Format(wxT("%s%s"), _Get_Code_Navigation_1(), _Get_Code_Navigation_2()));
}
//---------------------------------------------------------
void CSVG_Interactive_Map::_Write_Code(const wxChar *FileName, const wxChar *Code)
{
CSG_File Stream;
if( Stream.Open(FileName, SG_FILE_W, false) )
{
Stream.Write((void *)Code, SG_STR_LEN(Code));
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CSVG_Interactive_Map::_Add_Opening(CSG_Rect r)
{
CSG_String sViewBox;
double Width, Height;
double OffsetX, OffsetY;
m_sSVGCode.Append(_Get_Opening_Code_1());
m_sSVGCode.Append(SG_Get_String(r.Get_XRange(),2));
m_sSVGCode.Append(wxT("),"));
m_sSVGCode.Append(SG_Get_String(r.Get_XRange() / 400.,2));
m_sSVGCode.Append(_Get_Opening_Code_2());
if (r.Get_XRange() / r.Get_YRange() > MAP_WINDOW_WIDTH / MAP_WINDOW_HEIGHT)
{
Width = r.Get_XRange();
Height = r.Get_XRange() * MAP_WINDOW_HEIGHT / MAP_WINDOW_WIDTH;
}
else
{
Height = r.Get_YRange();
Width = r.Get_YRange() / MAP_WINDOW_HEIGHT * MAP_WINDOW_WIDTH;
}
OffsetX = (Width - r.Get_XRange()) / 2.;
OffsetY = (Height - r.Get_YRange()) / 2.;
sViewBox.Append(SG_Get_String(r.Get_XMin() - OffsetX,2));
sViewBox.Append(wxT(" "));
sViewBox.Append(SG_Get_String(-r.Get_YMax() - OffsetY,2));
sViewBox.Append(wxT(" "));
sViewBox.Append(SG_Get_String(Width,2));
sViewBox.Append(wxT(" "));
sViewBox.Append(SG_Get_String(Height,2));
_AddAttribute(wxT("viewBox"), sViewBox);
m_sSVGCode.Append(wxT(">\n"));
m_dWidth = Width;
}
//---------------------------------------------------------
const wxChar * CSVG_Interactive_Map::_Get_Opening_Code_1(void)
{
return( SG_STR_MBTOSG(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" [\n"
"<!ATTLIST svg\n"
" xmlns:attrib CDATA #IMPLIED\n"
" xmlns:batik CDATA #IMPLIED\n"
">\n"
"<!ATTLIST g\n"
" batik:static CDATA #IMPLIED\n"
">\n"
"<!ATTLIST image\n"
" batik:static CDATA #IMPLIED\n"
">\n"
"<!ATTLIST path\n"
" batik:static CDATA #IMPLIED\n"
">\n"
"]>\n"
"<?AdobeSVGViewer save=\"snapshot\"?>\n"
"<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 1024 768\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:attrib=\"http://www.carto.net/attrib\" xmlns:batik=\"http://xml.apache.org/batik/ext\" onload=\"init(evt);\" zoomAndPan=\"disable\">\n"
" <script type=\"text/ecmascript\" xlink:href=\"helper_functions.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"mapApp.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"timer.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"slider.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"button.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"checkbox.js\"/>\n"
" <script type=\"text/ecmascript\" xlink:href=\"navigation.js\"/>\n"
" <script type=\"text/ecmascript\"><![CDATA[\n"
" //global variables for mapApp and map object\n"
" var myMapApp = new mapApp();\n"
" var myMainMap;\n"
" function init(evt) {\n"
" //dynamic layer array that allow loading from database\n"
" var dynamicLayers = new Array();\n"
" //initialize digiLayers (layers that allow digitizing)\n"
" var digiLayers = new Array();\n"
" //initialize myMainMap object\n"
" myMainMap = new map(\"mainMap\"),"
));
}
//---------------------------------------------------------
const wxChar * CSVG_Interactive_Map::_Get_Opening_Code_2(void)
{
return( SG_STR_MBTOSG(
"),0.6,0,0,\"\"),1,true,\"coordX\"),\"coordY\"),dynamicLayers,digiLayers,\"\"));\n"
" //initialize refMapDragger object\n"
" myMapApp.refMapDragger = new dragObj(\"dragRectForRefMap\"),\"referenceMap\"),\"myDragCross\"),0.1,true,\"coordX\"),\"coordY\"),myMainMap);\n"
" //create zoom slider \n"
" myMapApp.zoomSlider = new slider(715,75,myMainMap.minWidth,715,165,myMainMap.maxWidth,myMainMap.maxWidth,\"mapZoomSlider\"),\"dimgray\"),2,10,\"sliderSymbol\"),myMapApp.refMapDragger,true);\n"
" //now initialize buttons\n"
" myMapApp.buttons = new Array();\n"
" //groupId,functionToCall,buttonType,buttonText,buttonSymbolId,x,y,width,height,fontSize,fontFamily,textFill,buttonFill,shadeLightFill,shadeDarkFill,shadowOffset\n"
" myMapApp.buttons[\"zoomIn\"] = new button(\"zoomIn\"),zoomImageButtons,\"rect\"),undefined,\"magnifyerZoomIn\"),705,47,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"zoomOut\"] = new button(\"zoomOut\"),zoomImageButtons,\"rect\"),undefined,\"magnifyerZoomOut\"),705,173,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"infoButton\"] = new switchbutton(\"infoButton\"),zoomImageSwitchButtons,\"rect\"),undefined,\"infoBut\"),746,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"infoButton\"].setSwitchValue(true,false);\n"
" statusChange(\"Mode: Infomode\"));\n"
" myMapApp.buttons[\"zoomFull\"] = new button(\"zoomFull\"),zoomImageButtons,\"rect\"),undefined,\"magnifyerFull\"),771,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"zoomManual\"] = new switchbutton(\"zoomManual\"),zoomImageSwitchButtons,\"rect\"),undefined,\"magnifyerManual\"),796,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"panManual\"] = new switchbutton(\"panManual\"),zoomImageSwitchButtons,\"rect\"),undefined,\"symbPan\"),821,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"recenterMap\"] = new switchbutton(\"recenterMap\"),zoomImageSwitchButtons,\"rect\"),undefined,\"symbRecenter\"),846,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"backwardExtent\"] = new button(\"backwardExtent\"),zoomImageButtons,\"rect\"),undefined,\"symbArrowLeft\"),871,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" myMapApp.buttons[\"forwardExtent\"] = new button(\"forwardExtent\"),zoomImageButtons,\"rect\"),undefined,\"symbArrowRight\"),896,74,20,20,10,\"\"),\"\"),\"white\"),\"rgb(235,235,235)\"),\"dimgray\"),1);\n"
" //see if we need to disable buttons\n"
" myMainMap.checkButtons();\n"
" //load function specific to the current map project\n"
" loadProjectSpecific();\n"
" }\n"
" function loadProjectSpecific() {\n"
" //adopt width and height of map extent\n"
" document.getElementById(\"myScaleTextW\")).firstChild.nodeValue = formatNumberString(myMainMap.curWidth.toFixed(myMainMap.nrDecimals)) + myMainMap.units;\n"
" document.getElementById(\"myScaleTextH\")).firstChild.nodeValue = formatNumberString(myMainMap.curHeight.toFixed(myMainMap.nrDecimals)) + myMainMap.units;\n"
" }\n"
"]]></script>\n"
" <defs>\n"
" <!-- Symbols for checkboxes -->\n"
" <symbol id=\"checkBoxRect\" overflow=\"visible\">\n"
" <rect x=\"-6\" y=\"-6\" width=\"12\" height=\"12\" fill=\"white\" stroke=\"dimgray\" stroke-width=\"1.5\"/>\n"
" </symbol>\n"
" <symbol id=\"checkBoxCross\" overflow=\"visible\" fill=\"none\" stroke=\"dimgray\" stroke-width=\"1\" pointer-events=\"none\">\n"
" <line x1=\"-5\" y1=\"-5\" x2=\"5\" y2=\"5\"/>\n"
" <line x1=\"-5\" y1=\"5\" x2=\"5\" y2=\"-5\"/>\n"
" </symbol>\n"
" <!-- Symbols for Zoom Magnifyer glasses -->\n"
" <symbol id=\"magnifyerFull\" overflow=\"visible\">\n"
" <text y=\"7.5\" font-family=\"sans-serif\" fill=\"dimgray\" font-size=\"18px\" font-weight=\"bold\" text-anchor=\"middle\" pointer-events=\"none\">F</text>\n"
" </symbol>\n"
" <symbol id=\"infoBut\" overflow=\"visible\">\n"
" <circle fill=\"none\" stroke=\"dimgray\" stroke-width=\"1.5\" r=\"7.5\" />\n"
" <text y=\"5\" font-family=\"sans-serif\" font-size=\"13px\" font-weight=\"bold\" fill=\"dimgray\" text-anchor=\"middle\" pointer-events=\"none\">i</text>\n"
" </symbol>\n"
" <symbol id=\"magnifyerManual\" overflow=\"visible\" fill=\"none\" stroke=\"dimgray\" stroke-width=\"1.5\">\n"
" <rect x=\"-6\" y=\"-6\" width=\"12\" height=\"12\" stroke-dasharray=\"1.5,1.5\"/>\n"
" <line x1=\"-3\" y1=\"0\" x2=\"3\" y2=\"0\" />\n"
" <line x1=\"0\" y1=\"-3\" x2=\"0\" y2=\"3\" />\n"
" </symbol>\n"
" <symbol id=\"magnifyerZoomIn\" overflow=\"visible\" fill=\"none\" stroke=\"dimgray\" stroke-width=\"2\">\n"
" <line x1=\"-4\" y1=\"0\" x2=\"4\" y2=\"0\"/>\n"
" <line x1=\"0\" y1=\"-4\" x2=\"0\" y2=\"4\"/>\n"
" </symbol>\n"
" <symbol id=\"magnifyerZoomOut\" overflow=\"visible\">\n"
" <line x1=\"-4\" y1=\"0\" x2=\"4\" y2=\"0\" fill=\"none\" stroke=\"dimgray\" stroke-width=\"2\" />\n"
" </symbol>\n"
" <!-- hand symbol for panning -->\n"
" <symbol id=\"symbPan\" overflow=\"visible\">\n"
" <path transform=\"scale(1.2)\" fill=\"none\" stroke=\"dimgray\" stroke-width=\"1\" d=\"M-2 6 C -2.2 2.5 -8.0 -0 -5.7 -1.9 C -4.3 -2.5 -3.3 -0.5 -2.5 0.7 C -3.2 -2.1 -5.5 -5.2 -3.6 -5.8 C -2.1 -6.3 -1.6 -3.6 -1.1 -1.9 C -0.9 -4.2 -1.6 -6.4 -0.2 -6.6 C 1.4 -6.8 0.9 -3 1.1 -1.9 C 1.5 -3.5 1.2 -6.1 2.5 -6.1 C 3.9 -6.1 3.5 -3.2 3.6 -1.6 C 4 -2.9 4.1 -4.3 5.3 -4.4 C 7.3 -3.5 4 2.2 3 6z\"/>\n"
" </symbol>\n"
" <!-- Symbol for Arrows -->\n"
" <symbol id=\"symbArrow\" overflow=\"visible\">\n"
" <polyline fill=\"none\" stroke=\"dimgray\" stroke-width=\"1\" points=\"-3,-6 3,-6 3,1 5,1 0,7 -5,1 -3,1 -3,-5\"/>\n"
" </symbol>\n"
" <symbol id=\"symbArrowLeft\" overflow=\"visible\">\n"
" <use xlink:href=\"#symbArrow\" transform=\"rotate(90)\" />\n"
" </symbol>\n"
" <symbol id=\"symbArrowRight\" overflow=\"visible\">\n"
" <use xlink:href=\"#symbArrow\" transform=\"rotate(-90)\" />\n"
" </symbol>\n"
" <!-- Symbol for Recentering Map -->\n"
" <symbol id=\"symbRecenter\" overflow=\"visible\">\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -