diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d13d39e..12be570ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,422 +1,433 @@ project(marble) #################################################### # CMake Settings SET(CMAKE_COLOR_MAKEFILE ON) # SET(CMAKE_SKIP_RPATH ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) #################################################### # Where to look first for cmake modules, # before ${CMAKE_ROOT}/Modules/ is checked set ( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/cmake_find_rules ${CMAKE_CURRENT_SOURCE_DIR}/cmake_scripts ${CMAKE_MODULE_PATH} ) # add cmake macros include( MarbleMacros ) #################################################### # Generate the tiles with the tilecreator at compile time # if this option is set, srtm.jpg will not be installed but the generated tiles instead option(QTONLY "Create Marble version without KDE dependencies" OFF) option(MOBILE "Create a Marble version optimized for handheld devices") #################################################### # Specific options for if building with Qt or kde4 libs if(NOT QT5BUILD) find_package(Qt4) endif() if(QT4_FOUND) set( QT5BUILD FALSE ) set( QT_USE_QTXML ON ) set( QT_USE_QTNETWORK ON ) set( QT_USE_QTTEST ON ) set( QT_USE_QTSCRIPT ON ) set( QT_USE_QTWEBKIT ON ) set( QT_USE_QTSVG ON ) set( QT_USE_QTDECLARATIVE ON ) set( QT_USE_QTSQL ON ) set( QT_USE_QTDBUS ON ) include( ${QT_USE_FILE} ) marble_set_package_properties( Qt4 PROPERTIES DESCRIPTION "cross-platform application framework" ) marble_set_package_properties( Qt4 PROPERTIES URL "http://qt.digia.com/" ) marble_set_package_properties( Qt4 PROPERTIES TYPE REQUIRED PURPOSE "core framework" ) IF ( NOT QT_QTDECLARATIVE_FOUND ) # older cmake versions have a FindQt4.cmake without support for declarative, # but the library may still be available FIND_PACKAGE(QtDeclarative) include_directories(${QT_QTDECLARATIVE_INCLUDE_DIR}) ENDIF() else() set( QT5BUILD TRUE ) - IF( NOT QTONLY ) - # TODO: Port to KDE frameworks 5 - set( QTONLY TRUE ) - MESSAGE(WARNING "Qt 5 build detected. Disabling KDE support which has not been ported yet. Please compile Marble with Qt 4 if you want to build the Marble KDE desktop application.") - ENDIF() +# IF( NOT QTONLY ) +# TODO: Port to KDE frameworks 5 +# set( QTONLY TRUE ) +# MESSAGE(WARNING "Qt 5 build detected. Disabling KDE support which has not been ported yet. Please compile Marble with Qt 4 if you want to build the Marble KDE desktop application.") +# ENDIF() find_package(Qt5Core REQUIRED) find_package(Qt5Xml REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5Test REQUIRED) find_package(Qt5Script REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5WebKitWidgets REQUIRED) find_package(Qt5Svg REQUIRED) find_package(Qt5Sql REQUIRED) find_package(Qt5Concurrent REQUIRED) find_package(Qt5PrintSupport REQUIRED) include_directories( ${Qt5Svg_INCLUDE_DIRS} ) include_directories( ${Qt5PrintSupport_INCLUDE_DIRS} ) include_directories( ${Qt5Network_INCLUDE_DIRS} ) include_directories( ${Qt5Script_INCLUDE_DIRS} ) include_directories( ${Qt5Test_INCLUDE_DIRS} ) SET(CMAKE_AUTOMOC TRUE) SET(CMAKE_AUTOMOC_RELAXED_MODE TRUE) endif() if( NOT ${CMAKE_VERSION} STRLESS "2.8" AND NOT QT4_FOUND) SET(CMAKE_AUTOMOC TRUE) SET(CMAKE_AUTOMOC_RELAXED_MODE TRUE) endif() if(QTONLY) # add a flag to be able to distinguish between qt # and kde mode in the sources add_definitions(-DQTONLY) # Use M_PI under Windows if( WIN32 ) add_definitions( -D_USE_MATH_DEFINES ) endif( WIN32 ) endif (QTONLY) #################################################### # Build a D-Bus interface for marble # This is disabled by default for all win32, apple and Qt-Only builds if( QTONLY OR WIN32 OR APPLE) option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" OFF) else( QTONLY OR WIN32 OR APPLE ) option(BUILD_WITH_DBUS "Build the D-Bus interface for the Marble widget" ON) endif( QTONLY OR WIN32 OR APPLE ) ################################################### # Check if KDE4 is available if( NOT QTONLY AND NOT KDE4_FOUND ) - find_package(KDE4 REQUIRED) + find_package(ECM REQUIRED) + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) + include(KDEInstallDirs) + find_package(KF5 REQUIRED COMPONENTS KDE4Support KI18n) marble_set_package_properties( KDE4 PROPERTIES DESCRIPTION "technological foundation for KDE applications" ) marble_set_package_properties( KDE4 PROPERTIES URL "http://kde.org/" ) marble_set_package_properties( KDE4 PROPERTIES TYPE REQUIRED PURPOSE "KDE version of Marble" ) include (KDE4Defaults) include (MacroLibrary) endif( NOT QTONLY AND NOT KDE4_FOUND) #### Python support #### set(PythonSupport_FOUND FALSE) if( NOT QTONLY ) -macro_log_feature(EXPERIMENTAL_PYTHON_BINDINGS "Experimental Python binding support for the Marble library" "Experimental Python binding support for the Marble library" - "http://techbase.kde.org/Development/Languages/Python" FALSE "" - "Experimental Python binding support for the Marble library. To activate it pass -DEXPERIMENTAL_PYTHON_BINDINGS=TRUE to cmake.") +set_package_properties(EXPERIMENTAL_PYTHON_BINDINGS PROPERTIES + URL "http://techbase.kde.org/Development/Languages/Python" + TYPE OPTIONAL + PURPOSE "Experimental Python binding support for the Marble library. To activate it pass -DEXPERIMENTAL_PYTHON_BINDINGS=TRUE to cmake." + ) endif() if(EXPERIMENTAL_PYTHON_BINDINGS) macro_optional_find_package(PythonLibrary) macro_optional_find_package(SIP) if(SIP_FOUND AND SIP_VERSION STRLESS "040c02") message(STATUS "The version of SIP found is too old. 4.12.2 or later is needed.") set(SIP_FOUND) endif(SIP_FOUND AND SIP_VERSION STRLESS "040c02") include(SIPMacros) macro_optional_find_package(PyQt4) if(PYQT4_FOUND AND PYQT4_VERSION STRLESS "040804") message(STATUS "The version of PyQt found is too old. 4.8.4 or later is required.") set(PYQT4_FOUND) endif(PYQT4_FOUND AND PYQT4_VERSION STRLESS "040804") if( NOT QTONLY ) - macro_log_feature(PYQT4_FOUND "PyQt4" "PyQt4 was not found. It is needed by marble python plugins to run. " "http://www.riverbankcomputing.co.uk/software/pyqt/intro" FALSE) + set_package_properties(PYTHONQT4_FOUND PROPERTIES + URL "http://www.riverbankcomputing.co.uk/software/pyqt/intro" + TYPE OPTIONAL + PURPOSE "PyQt4" + ) endif() if (PYTHONLIBRARY_FOUND AND SIP_FOUND AND PYQT4_FOUND) set(PythonSupport_FOUND TRUE) endif (PYTHONLIBRARY_FOUND AND SIP_FOUND AND PYQT4_FOUND) if( NOT QTONLY ) - macro_log_feature(PythonSupport_FOUND "Python" "KDE Python support" - "http://techbase.kde.org/Development/Languages/Python" FALSE "" - "Needed for Python bindings to the marble widget.") + set_package_properties(PythonSupport_FOUND PROPERTIES + URL "http://techbase.kde.org/Development/Languages/Python" + TYPE OPTIONAL + PURPOSE "Needed for Python bindings to the marble widget." + ) endif() endif(EXPERIMENTAL_PYTHON_BINDINGS) #### End Python support #### #################################################### # build unit tests INCLUDE (CTest) ENABLE_TESTING() if( QTONLY AND NOT WIN32 ) option( BUILD_MARBLE_TESTS "Build unit tests" ON ) else() option( BUILD_MARBLE_TESTS "Build unit tests" ${KDE4_BUILD_TESTS} ) endif() add_feature_info("Unit tests" BUILD_MARBLE_TESTS "Build unit tests. Toggle with BUILD_MARBLE_TESTS=YES/NO. 'make test' will run all.") if( BUILD_MARBLE_TESTS ) # SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/tests/test_data") #where unit test binaries should be installed to and run from # SET (MARBLE_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/tests) endif( BUILD_MARBLE_TESTS ) #################################################### # minimum required cmake version if( QTONLY ) # all previous releases lack QT_QTSCRIPT_LIBRARY needed for panoramio # this might be replaced by a workaround cmake_minimum_required( VERSION 2.4.8 ) #suppress the policy warnings while keeping the same behaviour if( COMMAND cmake_policy ) cmake_policy( SET CMP0005 OLD ) cmake_policy( SET CMP0003 OLD ) endif( COMMAND cmake_policy ) endif( QTONLY ) #################################################### # User configurable options if(KDE4_FOUND) set (QTONLY FALSE CACHE BOOL "Determines if we should compile for Qt only.") else(KDE4_FOUND) set (QTONLY TRUE CACHE BOOL "Determines if we should compile for Qt only.") endif(KDE4_FOUND) set (PEDANTIC FALSE CACHE BOOL "Determines if we should compile with -Wall -Werror.") set (ENABLE_TESTS FALSE CACHE BOOL "Build unit tests?") set (WITH_DESIGNER_PLUGIN TRUE CACHE BOOL "Build plugins for Qt Designer") add_feature_info("Qt Designer plugins" WITH_DESIGNER_PLUGIN "Marble widget support in Qt Designer. Toggle with WITH_DESIGNER_PLUGIN=YES/NO") if (QTONLY) set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Base directory for executables and libraries" FORCE) endif (QTONLY) #################################################### # Detect default for the user configurable MARBLE_DATA_PATH option if(WIN32) if(QTONLY) set(data_dir data) set(plugin_dir plugins) set(CMAKE_MODULES_INSTALL_PATH ${CMAKE_ROOT}/Modules) else(QTONLY) set(data_dir ${DATA_INSTALL_DIR}/marble/data) set(plugin_dir ${PLUGIN_INSTALL_DIR}/plugins/marble) set(CMAKE_MODULES_INSTALL_PATH ${DATA_INSTALL_DIR}/cmake/modules) set(APPS_INSTALL_DIR ${XDG_APPS_INSTALL_DIR}) endif(QTONLY) else(WIN32) if(APPLE) # needed for finding bundle path in e.g. katlasdir.h FIND_LIBRARY(APP_SERVICES_LIBRARY ApplicationServices ) MARK_AS_ADVANCED (APP_SERVICES_LIBRARY) SET(MAC_EXTRA_LIBS ${APP_SERVICES_LIBRARY}) if (QTONLY) # for Mac OS X, everything is put inside an application bundle SET (CMAKE_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/) # path for library references SET (CMAKE_INSTALL_NAME_DIR @executable_path/lib) #set info.plist properties on mac SET( PROGNAME ${PROJECT_NAME}) SET( MACOSX_BUNDLE_ICON_FILE Marble.icns) SET( MACOSX_BUNDLE_SHORT_VERSION_STRING 0.3.0 ) SET( MACOSX_BUNDLE_VERSION 0.3.0 ) SET( MACOSX_BUNDLE_LONG_VERSION_STRING Version 0.3.0 ) SET( MACOSX_BUNDLE_BUNDLE_NAME Marble) #SET( CMAKE_OSX_ARCHITECTURES ppc;i386 ) #Comment out if not universal binary SET( CMAKE_OSX_ARCHITECTURES x86_64 ) #Comment out if universal binary #SET (lib_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/lib) SET (data_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/data) SET (plugin_dir ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/resources/plugins) else (QTONLY) # KDE4 on Mac... set(data_dir ${DATA_INSTALL_DIR}/marble/data) set(plugin_dir ${PLUGIN_INSTALL_DIR}/plugins/marble) set(APPS_INSTALL_DIR ${XDG_APPS_INSTALL_DIR}) endif (QTONLY) else(APPLE) # Linux / bsd etc... if (QTONLY) set(data_dir ${CMAKE_INSTALL_PREFIX}/share/marble/data) set(plugin_dir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/marble/plugins) set(CMAKE_MODULES_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/share/marble/cmake) if(NOT ICON_INSTALL_DIR) set(ICON_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/icons) endif(NOT ICON_INSTALL_DIR) if(NOT APPS_INSTALL_DIR) set(APPS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications) endif(NOT APPS_INSTALL_DIR) else (QTONLY) set(data_dir ${DATA_INSTALL_DIR}/marble/data) set(plugin_dir ${PLUGIN_INSTALL_DIR}/plugins/marble) set(CMAKE_MODULES_INSTALL_PATH ${DATA_INSTALL_DIR}/cmake/modules) set(APPS_INSTALL_DIR ${XDG_APPS_INSTALL_DIR}) endif (QTONLY) endif(APPLE) endif(WIN32) if (NOT MARBLE_DATA_PATH) set (MARBLE_DATA_PATH ${data_dir}) endif (NOT MARBLE_DATA_PATH) if (NOT MARBLE_PLUGIN_PATH) set (MARBLE_PLUGIN_PATH ${plugin_dir}) endif (NOT MARBLE_PLUGIN_PATH) if (NOT MARBLE_DATA_INSTALL_PATH) set (MARBLE_DATA_INSTALL_PATH ${MARBLE_DATA_PATH}) endif (NOT MARBLE_DATA_INSTALL_PATH) if (NOT MARBLE_PLUGIN_INSTALL_PATH) set (MARBLE_PLUGIN_INSTALL_PATH ${MARBLE_PLUGIN_PATH}) endif (NOT MARBLE_PLUGIN_INSTALL_PATH) #MESSAGE( STATUS, "MARBLE_PLUGIN_INSTALL_PATH: ${MARBLE_PLUGIN_INSTALL_PATH}" ) if(WIN32) set (STATIC_BUILD FALSE CACHE BOOL "Link to static Qt libs (win32 only)?") endif(WIN32) # Variables to test new kml implementation # Will removed in feature after success #add_definitions(-DKML_DEBUG) #add_definitions(-DKML_GSOC) add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS) #################################################### # Options for static build if(STATIC_BUILD) add_definitions(-DSTATIC_BUILD=1) endif(STATIC_BUILD) #################################################### # Workaround FindQt4.cmake bug not finding # QtDesigner includes if(APPLE) if (NOT DEFINED ${QT_QTDESIGNER_INCLUDE_DIR}) set ( QT_QTDESIGNER_INCLUDE_DIR ${QT_LIBRARY_DIR}/QtDesigner.framework/Headers ) endif(NOT DEFINED ${QT_QTDESIGNER_INCLUDE_DIR}) endif(APPLE) ############################################################# if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") # Its good programming practice to build with no warnings... add_definitions( -Wall -Wextra -Wundef -Wnon-virtual-dtor -Woverloaded-virtual -Wno-long-long -Wchar-subscripts -Wcast-align -Wpointer-arith -Wformat-security ) # In pedantic mode, treat warnings as errors if (PEDANTIC) add_definitions( -Werror ) endif (PEDANTIC) endif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER MATCHES "icc") ############################################################# # Add a compiler def so that we can conditionally compile # code in debug mode only (e.g. extra console messages) IF (CMAKE_BUILD_TYPE MATCHES Debug) IF(NOT MINGW) ADD_DEFINITIONS(-DDEBUG) ELSE(NOT MINGW) REMOVE_DEFINITIONS( -DQT_NO_DEBUG ) ENDIF(NOT MINGW) ENDIF (CMAKE_BUILD_TYPE MATCHES Debug) #################################################### # on Win32 set the debug postfix if(WIN32) # distinguish between debug and release plugin SET(CMAKE_DEBUG_POSTFIX "d") endif(WIN32) #################################################### #################################################### # Add the include directories include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/projections ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/data ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/graphicsitem ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/handlers/dgml ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/parser ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/writer ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/geodata/scene ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/marble/graphicsview ${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src/lib/marble ) #################################################### # Descend into subdirectories IF( NOT QTONLY ) add_subdirectory(doc) ENDIF() add_subdirectory(src) add_subdirectory(data) include(DistTarget) add_subdirectory(tests) option(BUILD_MARBLE_TOOLS "Build various tools related to Marble" OFF) add_feature_info("Marble tools" BUILD_MARBLE_TOOLS "Build various Marble tools for e.g. file format conversion. Toggle with BUILD_MARBLE_TOOLS=YES/NO.") if(BUILD_MARBLE_TOOLS) add_subdirectory(tools) endif() option(BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library" OFF) add_feature_info("Marble library C++ examples" BUILD_MARBLE_EXAMPLES "Build C++ examples showing how to use the Marble library. Toggle with BUILD_MARBLE_EXAMPLES=YES/NO.") if(BUILD_MARBLE_EXAMPLES) add_subdirectory(examples/cpp) endif() #################################################### # Install extra files install(FILES LICENSE.txt DESTINATION ${MARBLE_DATA_INSTALL_PATH}) #################################################### # Install CMake module if( CMAKE_MODULES_INSTALL_PATH ) install( FILES FindMarble.cmake DESTINATION ${CMAKE_MODULES_INSTALL_PATH} ) endif( CMAKE_MODULES_INSTALL_PATH ) ############################################################ # Uninstall stuff if(QTONLY) # only add the uninstall target for qt-only builds CONFIGURE_FILE( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") endif(QTONLY) include(MarbleCPackOptions) marble_feature_summary(WHAT ALL) diff --git a/MarbleMacros.cmake b/MarbleMacros.cmake index b86481f91..6f5675e7d 100644 --- a/MarbleMacros.cmake +++ b/MarbleMacros.cmake @@ -1,259 +1,260 @@ include(FeatureSummary) if( COMMAND set_package_properties ) macro( marble_set_package_properties ) set_package_properties( ${ARGN} ) endmacro() else() macro( marble_set_package_properties ) # Just ignore it endmacro() endif() if ( COMMAND feature_summary ) macro( marble_feature_summary ) feature_summary( ${ARGN} ) endmacro() else() macro( marble_feature_summary ) # Just ignore it endmacro() endif() macro( marble_qt4_automoc ) if( ${CMAKE_VERSION} STRLESS "2.8" OR QT4_FOUND) qt4_automoc( ${ARGN} ) else() # Just ignore it endif() endmacro() macro(qt_add_resources) if( QT4_FOUND ) qt4_add_resources(${ARGN}) else() qt5_add_resources(${ARGN}) endif() endmacro() macro(qt_wrap_ui) if( QT4_FOUND ) qt4_wrap_ui(${ARGN}) else() qt5_wrap_ui(${ARGN}) endif() endmacro() macro(qt_generate_moc) if( QT4_FOUND ) qt4_generate_moc(${ARGN}) else() qt5_generate_moc(${ARGN}) endif() endmacro() # the place to put in common cmake macros # this is needed to minimize the amount of errors to do macro( marble_add_plugin _target_name ) set( _src ${ARGN} ) if( QTONLY ) marble_qt4_automoc( ${_src} ) add_library( ${_target_name} MODULE ${_src} ) target_link_libraries( ${_target_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTMAIN_LIBRARY} ${${_target_name}_LIBS} marblewidget ) install( TARGETS ${_target_name} DESTINATION ${MARBLE_PLUGIN_INSTALL_PATH} ) else( QTONLY ) kde4_add_plugin( ${_target_name} ${_src} ) target_link_libraries( ${_target_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KDE4_KDEUI_LIBRARY} ${KDE4_KIO_LIBRARY} ${QT_QTMAIN_LIBRARY} ${${_target_name}_LIBS} marblewidget ) install( TARGETS ${_target_name} DESTINATION ${MARBLE_PLUGIN_INSTALL_PATH} ) endif( QTONLY ) set_target_properties( ${_target_name} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE SKIP_BUILD_RPATH TRUE BUILD_WITH_INSTALL_RPATH TRUE ) endmacro( marble_add_plugin _target_name ) # these plugins are slightly different macro( marble_add_designer_plugin _target_name ) set( _src ${ARGN} ) qt_add_resources( _src ../../../apps/marble-ui/marble.qrc ) if( QTONLY ) marble_qt4_automoc( ${_src} ) add_library( ${_target_name} MODULE ${_src} ) target_link_libraries( ${_target_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTMAIN_LIBRARY} ${${_target_name}_LIBS} marblewidget ) install( TARGETS ${_target_name} DESTINATION ${QT_PLUGINS_DIR}/designer ) else( QTONLY ) kde4_add_plugin( ${_target_name} ${_src} ) target_link_libraries( ${_target_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KDE4_KDEUI_LIBRARY} ${KDE4_KIO_LIBRARY} ${QT_QTMAIN_LIBRARY} ${${_target_name}_LIBS} marblewidget ) install( TARGETS ${_target_name} DESTINATION ${PLUGIN_INSTALL_DIR}/plugins/designer ) endif( QTONLY ) set_target_properties( ${_target_name} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE SKIP_BUILD_RPATH TRUE BUILD_WITH_INSTALL_RPATH TRUE ) endmacro( marble_add_designer_plugin _target_name ) macro( marble_add_declarative_plugin _target_name _install_path ) set( _src ${ARGN} ) marble_qt4_automoc( ${_src} ) add_library( ${_target_name} MODULE ${_src} ) target_link_libraries( ${_target_name} ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTMAIN_LIBRARY} ${${_target_name}_LIBS} marblewidget ) install( TARGETS ${_target_name} DESTINATION ${MARBLE_QT_IMPORTS_DIR}/org/kde/edu/marble/${_install_path} ) set_target_properties( ${_target_name} PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE SKIP_BUILD_RPATH TRUE BUILD_WITH_INSTALL_RPATH TRUE ) endmacro( marble_add_declarative_plugin _target_name ) if( WIN32 ) set( DATA_PATH ${CMAKE_INSTALL_PREFIX}/${MARBLE_DATA_PATH} ) set( PLUGIN_PATH ${CMAKE_INSTALL_PREFIX}/${MARBLE_PLUGIN_PATH} ) else( WIN32 ) set( DATA_PATH ${MARBLE_DATA_PATH} ) set( PLUGIN_PATH ${MARBLE_PLUGIN_PATH} ) endif( WIN32 ) macro( marble_add_test TEST_NAME ) if( BUILD_MARBLE_TESTS ) set( ${TEST_NAME}_SRCS ${TEST_NAME}.cpp ${ARGN} ) if( QTONLY ) qt_generate_moc( ${TEST_NAME}.cpp ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.moc ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) set( ${TEST_NAME}_SRCS ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.moc ${${TEST_NAME}_SRCS} ) add_executable( ${TEST_NAME} ${${TEST_NAME}_SRCS} ) else( QTONLY ) kde4_add_executable( ${TEST_NAME} ${${TEST_NAME}_SRCS} ) endif( QTONLY ) target_link_libraries( ${TEST_NAME} ${QT_QTMAIN_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTTEST_LIBRARY} ${Qt5Test_LIBRARIES} + ${Qt5DBus_LIBRARIES} marblewidget ) set_target_properties( ${TEST_NAME} PROPERTIES COMPILE_FLAGS "-DDATA_PATH=\"\\\"${DATA_PATH}\\\"\" -DPLUGIN_PATH=\"\\\"${PLUGIN_PATH}\\\"\"" ) add_test( ${TEST_NAME} ${TEST_NAME} ) endif( BUILD_MARBLE_TESTS ) endmacro( marble_add_test TEST_NAME ) macro( marble_add_project_resources resources ) add_custom_target( ${PROJECT_NAME}_Resources ALL SOURCES ${ARGN} ) endmacro() # - MACRO_OPTIONAL_FIND_PACKAGE() combines FIND_PACKAGE() with an OPTION() # MACRO_OPTIONAL_FIND_PACKAGE( [QUIT] ) # This macro is a combination of OPTION() and FIND_PACKAGE(), it # works like FIND_PACKAGE(), but additionally it automatically creates # an option name WITH_, which can be disabled via the cmake GUI. # or via -DWITH_=OFF # The standard _FOUND variables can be used in the same way # as when using the normal FIND_PACKAGE() # Copyright (c) 2006-2010 Alexander Neundorf, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. # This is just a helper macro to set a bunch of variables empty. # We don't know whether the package uses UPPERCASENAME or CamelCaseName, so we try both: if(NOT COMMAND _MOFP_SET_EMPTY_IF_DEFINED) macro(_MOFP_SET_EMPTY_IF_DEFINED _name _var) if(DEFINED ${_name}_${_var}) set(${_name}_${_var} "") endif(DEFINED ${_name}_${_var}) string(TOUPPER ${_name} _nameUpper) if(DEFINED ${_nameUpper}_${_var}) set(${_nameUpper}_${_var} "") endif(DEFINED ${_nameUpper}_${_var}) endmacro(_MOFP_SET_EMPTY_IF_DEFINED _package _var) endif() if(NOT COMMAND MACRO_OPTIONAL_FIND_PACKAGE) macro (MACRO_OPTIONAL_FIND_PACKAGE _name ) option(WITH_${_name} "Search for ${_name} package" ON) if (WITH_${_name}) find_package(${_name} ${ARGN}) else (WITH_${_name}) string(TOUPPER ${_name} _nameUpper) set(${_name}_FOUND FALSE) set(${_nameUpper}_FOUND FALSE) _mofp_set_empty_if_defined(${_name} INCLUDE_DIRS) _mofp_set_empty_if_defined(${_name} INCLUDE_DIR) _mofp_set_empty_if_defined(${_name} INCLUDES) _mofp_set_empty_if_defined(${_name} LIBRARY) _mofp_set_empty_if_defined(${_name} LIBRARIES) _mofp_set_empty_if_defined(${_name} LIBS) _mofp_set_empty_if_defined(${_name} FLAGS) _mofp_set_empty_if_defined(${_name} DEFINITIONS) endif (WITH_${_name}) endmacro (MACRO_OPTIONAL_FIND_PACKAGE) endif() # older cmake version don't have the add_feature_info macro. # It's just informative, so we add our own that does # nothing in that case if(NOT COMMAND ADD_FEATURE_INFO) macro(ADD_FEATURE_INFO) # just ignore it endmacro() endif() diff --git a/src/apps/marble-kde/kdemain.cpp b/src/apps/marble-kde/kdemain.cpp index 1b4733dc9..3c735dc4f 100644 --- a/src/apps/marble-kde/kdemain.cpp +++ b/src/apps/marble-kde/kdemain.cpp @@ -1,400 +1,400 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // #include #include -#include +#include #include #include #include #include #include #include "ControlView.h" #include "KdeMainWindow.h" #include "MarbleDebug.h" #include "MarbleTest.h" #ifdef STATIC_BUILD #include Q_IMPORT_PLUGIN(qjpeg) Q_IMPORT_PLUGIN(qsvg) #endif using namespace Marble; // The GraphicsSystem needs to be set before the instantiation of the // QApplication. Therefore we need to parse the current setting // in this unusual place :-/ -QString readGraphicsSystem( int argc, char *argv[], const KAboutData& aboutData ) +QString readGraphicsSystem( int argc, char *argv[], const K4AboutData& aboutData ) { QCoreApplication app( argc, argv ); KComponentData componentData( aboutData, KComponentData::SkipMainComponentRegistration ); KConfigGroup viewGroup( componentData.config(), "View" ); QString graphicsSystem = viewGroup.readEntry( "graphicsSystem", "RasterGraphics" ); QString graphicsString( "native" ); if ( graphicsSystem == QString( "RasterGraphics" ) ) { graphicsString = QString( "raster" ); } if ( graphicsSystem == QString( "OpenGLGraphics" ) ) { graphicsString = QString( "opengl" ); } return graphicsString; } int main ( int argc, char *argv[] ) { - KAboutData aboutData( "marble", 0, + K4AboutData aboutData( "marble", 0, ki18n( "Marble Virtual Globe" ), ControlView::applicationVersion().toLatin1(), ki18n( "A World Atlas." ), - KAboutData::License_LGPL, + K4AboutData::License_LGPL, ki18n( "(c) 2007-2012" ), // FIXME: use subs() here and replace 2012 by %1 KLocalizedString(), "http://edu.kde.org/marble" ); // Active Development Team of Marble aboutData.addAuthor( ki18n( "Torsten Rahn" ), ki18n( "Developer and Original Author" ), "rahn@kde.org" ); aboutData.addAuthor( ki18n( "Bernhard Beschow" ), ki18n( "WMS Support, Mobile, Performance" ), "bbeschow@cs.tu-berlin.de" ); aboutData.addAuthor( ki18n( "Thibaut Gridel" ), ki18n( "Geodata" ), "tgridel@free.fr" ); aboutData.addAuthor( ki18n( "Jens-Michael Hoffmann" ), ki18n( "OpenStreetMap Integration, OSM Namefinder, Download Management" ), "jmho@c-xx.com", "http://www.c-xx.com" ); aboutData.addAuthor( ki18n( "Florian Eßer" ), ki18n( "Elevation Profile" ), "f.esser@rwth-aachen.de" ); aboutData.addAuthor( ki18n( "Wes Hardaker" ), ki18n( "APRS Plugin" ), "marble@hardakers.net" ); aboutData.addAuthor( ki18n( "Bastian Holst" ), ki18n( "Online Services support" ), "bastianholst@gmx.de" ); aboutData.addAuthor( ki18n( "Guillaume Martres" ), ki18n( "Satellites" ), "smarter@ubuntu.com" ); aboutData.addAuthor( ki18n( "Rene Kuettner" ), ki18n( "Satellites, Eclipses" ), "rene@bitkanal.net" ); aboutData.addAuthor( ki18n( "Friedrich W. H. Kossebau" ), ki18n( "Plasma Integration, Bugfixes" ), "kossebau@kde.org" ); aboutData.addAuthor( ki18n( "Dennis Nienhüser" ), ki18n( "Routing, Navigation, Mobile" ), "earthwings@gentoo.org" ); aboutData.addAuthor( ki18n( "Niko Sams" ), ki18n( "Routing, Elevation Profile" ), "niko.sams@gmail.com" ); aboutData.addAuthor( ki18n( "Patrick Spendrin" ), ki18n( "Core Developer: KML and Windows support" ), "pspendrin@gmail.com" ); aboutData.addAuthor( ki18n( "Eckhart Wörner" ), ki18n( "Bugfixes" ), "kde@ewsoftware.de" ); // Developers: aboutData.addAuthor( ki18n( "Inge Wallin" ), ki18n( "Core Developer and Co-Maintainer" ), "inge@lysator.liu.se" ); aboutData.addAuthor( ki18n( "Henry de Valence" ), ki18n( "Core Developer: Marble Runners, World-Clock Plasmoid" ), "hdevalence@gmail.com" ); aboutData.addAuthor( ki18n( "Pino Toscano" ), ki18n( "Network plugins" ), "pino@kde.org" ); aboutData.addAuthor( ki18n( "Harshit Jain" ), ki18n( "Planet filter" ), "sonu.itbhu@googlemail.com" ); aboutData.addAuthor( ki18n( "Simon Edwards" ), ki18n( "Marble Python Bindings" ), "simon@simonzone.com" ); aboutData.addAuthor( ki18n( "Magnus Valle" ), ki18n( "Historical Maps" ), "" ); aboutData.addAuthor( ki18n( "Médéric Boquien" ), ki18n( "Astronomical Observatories" ), "mboquien@free.fr" ); // ESA Summer of Code in Space aboutData.addAuthor( ki18n( "Rene Kuettner" ), ki18n( "ESA Summer of Code in Space 2012 Project:" " Visualization of planetary satellites" ), "rene@bitkanal.net" ); aboutData.addAuthor( ki18n( "Guillaume Martres" ), ki18n( "ESA Summer of Code in Space 2011 Project:" " Visualisation of Satellite Orbits" ), "smarter@ubuntu.com" ); // Google Summer of Code aboutData.addAuthor( ki18n( "Konstantin Oblaukhov" ), ki18n( "Google Summer of Code 2011 Project:" " OpenStreetMap Vector Rendering" ), "oblaukhov.konstantin@gmail.com" ); aboutData.addAuthor( ki18n( "Daniel Marth" ), ki18n( "Google Summer of Code 2011 Project:" " Marble Touch on MeeGo" ), "danielmarth@gmx.at" ); aboutData.addAuthor( ki18n( "Gaurav Gupta" ), ki18n( "Google Summer of Code 2010 Project:" " Bookmarks" ), "1989.gaurav@gmail.com" ); aboutData.addAuthor( ki18n( "Harshit Jain " ), ki18n( "Google Summer of Code 2010 Project:" " Time Support" ), "hjain.itbhu@gmail.com" ); aboutData.addAuthor( ki18n( "Siddharth Srivastava" ), ki18n( "Google Summer of Code 2010 Project:" " Turn-by-turn Navigation" ), "akssps011@gmail.com" ); aboutData.addAuthor( ki18n( "Andrew Manson" ), ki18n( "Google Summer of Code 2009 Project:" " OSM Annotation" ), "g.real.ate@gmail.com" ); aboutData.addAuthor( ki18n( "Bastian Holst" ), ki18n( "Google Summer of Code 2009 Project:" " Online Services" ), "bastianholst@gmx.de" ); aboutData.addAuthor( ki18n( "Patrick Spendrin" ), ki18n( "Google Summer of Code 2008 Project:" " Vector Tiles for Marble" ), "pspendrin@gmail.com" ); aboutData.addAuthor( ki18n( "Shashank Singh" ), ki18n( "Google Summer of Code 2008 Project:" " Panoramio / Wikipedia -photo support for Marble" ), "shashank.personal@gmail.com" ); aboutData.addAuthor( ki18n( "Carlos Licea" ), ki18n( "Google Summer of Code 2007 Project:" " Equirectangular Projection (\"Flat Map\")" ), "carlos.licea@kdemail.net" ); aboutData.addAuthor( ki18n( "Andrew Manson" ), ki18n( "Google Summer of Code 2007 Project:" " GPS Support for Marble" ), "g.real.ate@gmail.com" ); aboutData.addAuthor( ki18n( "Murad Tagirov" ), ki18n( "Google Summer of Code 2007 Project:" " KML Support for Marble" ), "tmurad@gmail.com" ); // Developers aboutData.addAuthor( ki18n( "Simon Schmeisser" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Claudiu Covaci" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "David Roberts" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Nikolas Zimmermann" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Jan Becker" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Stefan Asserhäll" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Laurent Montel" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Mayank Madan" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Prashanth Udupa" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Anne-Marie Mahfouf" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Josef Spillner" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Frerich Raabe" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Frederik Gladhorn" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Fredrik Höglund" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Albert Astals Cid" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Thomas Zander" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Joseph Wenninger" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Kris Thomsen" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Daniel Molkentin" ), ki18n( "Development & Patches" )); aboutData.addAuthor( ki18n( "Christophe Leske" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Sebastian Wiedenroth" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Tim Sutton" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Christian Ehrlicher" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Ralf Habacker" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Steffen Joeris" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Marcus Czeslinski" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Marcus D. Hanwell" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Chitlesh Goorah" ), ki18n( "Platforms & Distributions" )); aboutData.addAuthor( ki18n( "Nuno Pinheiro" ), ki18n( "Artwork" )); aboutData.addAuthor( ki18n( "Torsten Rahn" ), ki18n( "Artwork" )); // Credits aboutData.addCredit( ki18n( "Luis Silva" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Stefan Jordan" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Robert Scott" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Lubos Petrovic" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Benoit Sigoure" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Martin Konold" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Matthias Welwarsky" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Rainer Endres" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Ralf Gesellensetter" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "Tim Alder" ), ki18n( "Various Suggestions & Testing" )); aboutData.addCredit( ki18n( "John Layt" ), ki18n( "Special thanks for providing an" " important source of inspiration by creating" " Marble's predecessor \"Kartographer\"." )); QApplication::setGraphicsSystem( readGraphicsSystem( argc, argv, aboutData ) ); KCmdLineArgs::init( argc, argv, &aboutData ); // Autodetect profiles MarbleGlobal::Profiles profiles = MarbleGlobal::detectProfiles(); KCmdLineOptions options; options.add( "debug-info", ki18n( "Enable debug output" ) ); options.add( "timedemo", ki18n( "Make a time measurement to check performance" ) ); options.add( "fps", ki18n( "Show frame rate" ) ); options.add( "tile-id", ki18n( "Show tile IDs" ) ); options.add( "runtimeTrace", ki18n( "Show time spent in each layer" ) ); options.add( "marbledatapath ", ki18n( "Use a different directory which contains map data" ) ); if( profiles & MarbleGlobal::SmallScreen ) { options.add( "nosmallscreen", ki18n( "Do not use the interface optimized for small screens" ) ); } else { options.add( "smallscreen", ki18n( "Use the interface optimized for small screens" ) ); } if( profiles & MarbleGlobal::HighResolution ) { options.add( "nohighresolution", ki18n( "Do not use the interface optimized for high resolutions" ) ); } else { options.add( "highresolution", ki18n( "Use the interface optimized for high resolutions" ) ); } options.add( "latlon ", ki18n( "Show map at given lat lon coordinates" ) ); options.add( "distance ", ki18n( "Set the distance of the observer to the globe (in km)" ) ); options.add( "map ", ki18n( "Use map id (e.g. \"earth/openstreetmap/openstreetmap.dgml\")" ) ); options.add( "+[file]", ki18n( "One or more placemark files to be opened" ) ); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); KApplication app; KGlobal::locale()->insertCatalog( "marble_qt" ); MarbleDebug::setEnabled( args->isSet( "debug-info" ) ); if ( args->isSet( "smallscreen" ) ) { profiles |= MarbleGlobal::SmallScreen; } else { profiles &= ~MarbleGlobal::SmallScreen; } if ( args->isSet( "highresolution" ) ) { profiles |= MarbleGlobal::HighResolution; } else { profiles &= ~MarbleGlobal::HighResolution; } MarbleGlobal::getInstance()->setProfiles( profiles ); QString marbleDataPath = args->getOption( "marbledatapath" ); if( marbleDataPath.isEmpty() ) { marbleDataPath.clear(); /** @todo: why is this done? */ } MainWindow *window = new MainWindow( marbleDataPath ); window->setAttribute( Qt::WA_DeleteOnClose, true ); window->show(); if ( args->isSet( "timedemo" ) ) { window->resize(900, 640); MarbleTest test( window->marbleWidget() ); test.timeDemo(); return 0; } if ( args->isSet( "fps" ) ) { window->marbleControl()->marbleWidget()->setShowFrameRate( true ); } if ( args->isSet( "tile-id" ) ) { window->marbleControl()->marbleWidget()->setShowTileId( true ); } const QString map = args->getOption( "map" ); if ( !map.isEmpty() ) { window->marbleWidget()->setMapThemeId(map); } const QString coordinatesString = args->getOption( "latlon" ); if ( !coordinatesString.isEmpty() ) { bool success = false; const GeoDataCoordinates coordinates = GeoDataCoordinates::fromString(coordinatesString, success); if ( success ) { const qreal longitude = coordinates.longitude(GeoDataCoordinates::Degree); const qreal latitude = coordinates.latitude(GeoDataCoordinates::Degree); window->marbleWidget()->centerOn(longitude, latitude); } } const QString distance = args->getOption( "distance" ); if ( !distance.isEmpty() ) { bool success = false; const qreal distanceValue = distance.toDouble(&success); if ( success ) window->marbleWidget()->setDistance(distanceValue); } // Read the files that are given on the command line. for ( int i = 0; i < args->count(); ++i ) { // FIXME: Use openUrl( args->url(i) ) instead? if ( QFile::exists( args->arg( i ) ) ) window->marbleControl()->addGeoDataFile( args->arg( i ) ); } return app.exec(); } diff --git a/src/apps/marble-kde/marble_part.cpp b/src/apps/marble-kde/marble_part.cpp index 72a1ae04e..86d4b4192 100644 --- a/src/apps/marble-kde/marble_part.cpp +++ b/src/apps/marble-kde/marble_part.cpp @@ -1,1761 +1,1766 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Tobias Koenig // Copyright 2008 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // Copyright 2010 Harshit Jain // // Own #include "marble_part.h" // Qt #include #include #include #include #include #include #include #include #include #include #include #include #include +#include +#include // KDE -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Marble library classes #include "AbstractFloatItem.h" #include "AbstractDataPlugin.h" #include "EditBookmarkDialog.h" #include "BookmarkManager.h" #include "BookmarkManagerDialog.h" #include "DialogConfigurationInterface.h" #include "DownloadRegionDialog.h" #include "GeoDataCoordinates.h" #include "GeoDataFolder.h" #include "GeoDataLatLonAltBox.h" #include "GeoDataLookAt.h" #include "GeoDataPlacemark.h" #include "HttpDownloadManager.h" #include "MarbleDirs.h" #include "MarbleDebug.h" #include "MarbleLocale.h" #include "MarbleModel.h" #include "MarblePluginSettingsWidget.h" #include "MapWizard.h" #include "NewBookmarkFolderDialog.h" #include "RenderPluginModel.h" #include "routing/RoutingManager.h" #include "routing/RoutingProfilesModel.h" #include "routing/RoutingProfilesWidget.h" #include "routing/RouteRequest.h" #include "SunControlWidget.h" #include "TimeControlWidget.h" #include "TileCoordsPyramid.h" #include "ViewportParams.h" #include "MarbleClock.h" #include "ParseRunnerPlugin.h" #include "PositionTracking.h" #include "PositionProviderPlugin.h" #include "PluginManager.h" #include "SearchInputWidget.h" #include "MarbleWidgetInputHandler.h" #include "Planet.h" #include "MapThemeDownloadDialog.h" #include "cloudsync/BookmarkSyncManager.h" // Marble non-library classes #include "ControlView.h" #include "settings.h" using namespace Marble; #include "ui_MarbleCacheSettingsWidget.h" #include "ui_MarbleViewSettingsWidget.h" #include "ui_MarbleNavigationSettingsWidget.h" #include "ui_MarbleTimeSettingsWidget.h" #include "ui_MarbleCloudSyncSettingsWidget.h" namespace Marble { namespace { const char* POSITION_STRING = I18N_NOOP( "Position: %1" ); const char* DISTANCE_STRING = I18N_NOOP( "Altitude: %1" ); const char* TILEZOOMLEVEL_STRING = I18N_NOOP( "Tile Zoom Level: %1" ); const char* DATETIME_STRING = I18N_NOOP( "Time: %1" ); } K_PLUGIN_FACTORY(MarblePartFactory, registerPlugin();) K_EXPORT_PLUGIN(MarblePartFactory("marble")) MarblePart::MarblePart( QWidget *parentWidget, QObject *parent, const QVariantList &arguments ) : KParts::ReadOnlyPart( parent ), m_sunControlDialog( 0 ), m_timeControlDialog( 0 ), m_downloadRegionDialog( 0 ), m_externalMapEditorAction( 0 ), m_recentFilesAction( 0 ), m_configDialog( 0 ), m_position( i18n( NOT_AVAILABLE ) ), m_tileZoomLevel( i18n( NOT_AVAILABLE ) ), m_positionLabel( 0 ), m_distanceLabel( 0 ) { // only set marble data path when a path was given if ( arguments.count() != 0 && !arguments.first().toString().isEmpty() ) MarbleDirs::setMarbleDataPath( arguments.first().toString() ); // Setting measure system to provide nice standards for all unit questions. // This has to happen before any initialization so plugins (for example) can // use it during initialization. MarbleLocale *marbleLocale = MarbleGlobal::getInstance()->locale(); - KLocale *kLocale = KGlobal::locale(); - if ( kLocale->measureSystem() == KLocale::Metric ) { - marbleLocale->setMeasurementSystem( QLocale::MetricSystem ); - } - else { - marbleLocale->setMeasurementSystem( QLocale::ImperialSystem ); - } - + // KF5 TODO: Read Connecting Calls to Catalogs" in ki18n programmer's guide + // and enable translations + // KLocale *kLocale = KGlobal::locale(); +// if ( kLocale->measureSystem() == KLocale::Metric ) { +// marbleLocale->setMeasurementSystem( QLocale::MetricSystem ); +// } +// else { +// marbleLocale->setMeasurementSystem( QLocale::ImperialSystem ); +// } + + marbleLocale->setMeasurementSystem( QLocale::ImperialSystem ); migrateNewstuffConfigFiles(); m_externalEditorMapping[0] = ""; m_externalEditorMapping[1] = "potlatch"; m_externalEditorMapping[2] = "josm"; m_externalEditorMapping[3] = "merkaartor"; m_controlView = new ControlView( parentWidget ); setWidget( m_controlView ); setupActions(); setXMLFile( "marble_part.rc" ); m_statusBarExtension = new KParts::StatusBarExtension( this ); m_statusBarExtension->statusBar()->setUpdatesEnabled( false ); // Load bookmark file. If it does not exist, a default one will be used. m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" ); initializeCustomTimezone(); setupStatusBar(); readSettings(); m_statusBarExtension->statusBar()->setUpdatesEnabled( true ); // Show startup location switch ( MarbleSettings::onStartup() ) { case LastLocationVisited: { GeoDataLookAt target; target.setLongitude( MarbleSettings::quitLongitude() ); target.setLatitude( MarbleSettings::quitLatitude() ); target.setRange( MarbleSettings::quitRange() ); m_controlView->marbleWidget()->flyTo( target, Instant ); } break; case ShowHomeLocation: m_controlView->marbleWidget()->goHome( Instant ); break; } connect( m_controlView, SIGNAL(showUploadDialog()), this, SLOT(showUploadNewStuffDialog()) ); connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) ); connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) ); } MarblePart::~MarblePart() { writeSettings(); // Check whether this delete is really needed. delete m_configDialog; } ControlView* MarblePart::controlView() const { return m_controlView; } -KAboutData *MarblePart::createAboutData() +K4AboutData *MarblePart::createAboutData() { - return new KAboutData( I18N_NOOP( "marble_part" ), 0, + return new K4AboutData( I18N_NOOP( "marble_part" ), 0, ki18n( "A Virtual Globe" ), ControlView::applicationVersion().toLatin1() ); } bool MarblePart::openUrl( const KUrl &url ) { QFileInfo fileInfo( url.toLocalFile() ); if ( fileInfo.isReadable() ) { m_controlView->marbleModel()->addGeoDataFile( url.toLocalFile() ); m_recentFilesAction->addUrl( url ); return true; } KMessageBox::error( widget(), tr( "Sorry, unable to open '%1'. The file is not accessible." ).arg( fileInfo.fileName() ), tr( "File not accessible" ) ); return false; } bool MarblePart::openFile() { const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager(); QStringList allFileExtensions; QStringList filters; foreach ( const ParseRunnerPlugin *plugin, pluginManager->parsingRunnerPlugins() ) { if ( plugin->nameId() == "Cache" ) continue; const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." ); const QString filter = QString( "%1|%2" ).arg( fileExtensions.join( " " ) ).arg( plugin->fileFormatDescription() ); filters << filter; allFileExtensions << fileExtensions; } allFileExtensions.sort(); const QString allFileTypes = QString( "%1|%2" ).arg( allFileExtensions.join( " " ) ).arg( i18n( "All Supported Files" ) ); filters.sort(); filters.prepend( allFileTypes ); const QString filter = filters.join( "\n" ); QStringList fileNames = KFileDialog::getOpenFileNames( m_lastFileOpenPath, filter, widget(), i18n("Open File") ); if ( !fileNames.isEmpty() ) { const QString firstFile = fileNames.first(); m_lastFileOpenPath = KUrl::fromLocalFile( QFileInfo( firstFile ).absolutePath() ); } foreach( const QString &fileName, fileNames ) { openUrl( fileName ); } return true; } void MarblePart::exportMapScreenShot() { QString fileName = KFileDialog::getSaveFileName( QDir::homePath(), i18n( "Images *.jpg *.png" ), widget(), i18n("Export Map") ); if ( !fileName.isEmpty() ) { // Take the case into account where no file format is indicated const char * format = 0; if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive) && !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) ) { format = "JPG"; } QPixmap mapPixmap = m_controlView->mapScreenShot(); bool success = mapPixmap.save( fileName, format ); if ( !success ) { KMessageBox::error( widget(), i18nc( "Application name", "Marble" ), i18n( "An error occurred while trying to save the file.\n" ), KMessageBox::Notify ); } } } void MarblePart::setShowBookmarks( bool show ) { m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show ); m_toggleBookmarkDisplayAction->setChecked( show ); // Sync state with the GUI } void MarblePart::setShowClouds( bool isChecked ) { m_controlView->marbleWidget()->setShowClouds( isChecked ); m_showCloudsAction->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::showPositionLabel( bool isChecked ) { m_positionLabel->setVisible( isChecked ); } void MarblePart::showAltitudeLabel( bool isChecked ) { m_distanceLabel->setVisible( isChecked ); } void MarblePart::showTileZoomLevelLabel( bool isChecked ) { m_tileZoomLevelLabel->setVisible( isChecked ); } void MarblePart::showDateTimeLabel( bool isChecked ) { m_clockLabel->setVisible( isChecked ); } void MarblePart::showDownloadProgressBar( bool isChecked ) { MarbleSettings::setShowDownloadProgressBar( isChecked ); // Change visibility only if there is a download happening m_downloadProgressBar->setVisible( isChecked && m_downloadProgressBar->value() >= 0 ); } void MarblePart::showFullScreen( bool isChecked ) { if ( KApplication::activeWindow() ) KToggleFullScreenAction::setFullScreen( KApplication::activeWindow(), isChecked ); m_fullScreenAct->setChecked( isChecked ); // Sync state with the GUI } void MarblePart::showStatusBar( bool isChecked ) { if ( !m_statusBarExtension->statusBar() ) return; m_statusBarExtension->statusBar()->setVisible( isChecked ); } void MarblePart::controlSun() { if ( !m_sunControlDialog ) { m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), m_controlView ); connect( m_sunControlDialog, SIGNAL(showSun(bool)), this, SLOT (showSun(bool)) ); connect( m_sunControlDialog, SIGNAL(showSun(bool)), m_showShadow, SLOT (setChecked(bool)) ); connect( m_sunControlDialog, SIGNAL(isLockedToSubSolarPoint(bool)), m_lockToSubSolarPoint, SLOT (setChecked(bool)) ); connect( m_sunControlDialog, SIGNAL(isSubSolarPointIconVisible(bool)), m_setSubSolarPointIconVisible, SLOT (setChecked(bool)) ); } m_sunControlDialog->show(); m_sunControlDialog->raise(); m_sunControlDialog->activateWindow(); } void MarblePart::controlTime() { if ( !m_timeControlDialog ) { m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() ); } m_timeControlDialog->show(); m_timeControlDialog->raise(); m_timeControlDialog->activateWindow(); } void MarblePart::showSun( bool active ) { m_controlView->marbleWidget()->setShowSunShading( active ); m_sunControlDialog->setSunShading( active ); } void MarblePart::lockToSubSolarPoint( bool lock ) { m_controlView->marbleWidget()->setLockToSubSolarPoint( lock ); } void MarblePart::setSubSolarPointIconVisible( bool show ) { m_controlView->marbleWidget()->setSubSolarPointIconVisible( show ); } void MarblePart::workOffline( bool offline ) { m_controlView->setWorkOffline( offline ); m_newStuffAction->setEnabled( !offline ); m_downloadRegionAction->setEnabled( !offline ); } void MarblePart::copyMap() { QPixmap mapPixmap = m_controlView->mapScreenShot(); QClipboard *clipboard = KApplication::clipboard(); clipboard->setPixmap( mapPixmap ); } void MarblePart::copyCoordinates() { qreal lon = m_controlView->marbleWidget()->centerLongitude(); qreal lat = m_controlView->marbleWidget()->centerLatitude(); QString positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText( positionString ); } void MarblePart::readSettings() { kDebug() << "Start: MarblePart::readSettings()"; // Set home position m_controlView->marbleModel()->setHome( MarbleSettings::homeLongitude(), MarbleSettings::homeLatitude(), MarbleSettings::homeZoom() ); // Map theme and projection QString mapTheme = MarbleSettings::mapTheme(); if ( mapTheme.isEmpty() ) { mapTheme = m_controlView->defaultMapThemeId(); } m_controlView->marbleWidget()->setMapThemeId( mapTheme ); m_controlView->marbleWidget()->setProjection( (Projection) MarbleSettings::projection() ); m_controlView->marbleWidget()->setShowClouds( MarbleSettings::showClouds() ); m_showCloudsAction->setChecked( MarbleSettings::showClouds() ); workOffline( MarbleSettings::workOffline() ); m_workOfflineAction->setChecked( MarbleSettings::workOffline() ); m_lockFloatItemsAct->setChecked(MarbleSettings::lockFloatItemPositions()); lockFloatItemPosition(MarbleSettings::lockFloatItemPositions()); setShowBookmarks( MarbleSettings::showBookmarks() ); // Sun m_controlView->marbleWidget()->setShowSunShading( MarbleSettings::showSun() ); m_showShadow->setChecked( MarbleSettings::showSun() ); m_controlView->marbleWidget()->setShowCityLights( MarbleSettings::showCitylights() ); m_controlView->marbleWidget()->setSubSolarPointIconVisible( MarbleSettings::subSolarPointIconVisible() ); m_controlView->marbleWidget()->setLockToSubSolarPoint( MarbleSettings::lockToSubSolarPoint() ); m_setSubSolarPointIconVisible->setChecked( MarbleSettings::subSolarPointIconVisible() ); m_lockToSubSolarPoint->setChecked( MarbleSettings::lockToSubSolarPoint() ); // View m_initialGraphicsSystem = (GraphicsSystem) MarbleSettings::graphicsSystem(); m_previousGraphicsSystem = m_initialGraphicsSystem; m_lastFileOpenPath = KUrl::fromLocalFile( MarbleSettings::lastFileOpenDir() ); // Load previous route settings m_controlView->marbleModel()->routingManager()->readSettings(); bool const startupWarning = MarbleSettings::showGuidanceModeStartupWarning(); m_controlView->marbleModel()->routingManager()->setShowGuidanceModeStartupWarning( startupWarning ); KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); if ( sharedConfig->hasGroup( "Routing Profiles" ) ) { QList profiles; KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" ); int numProfiles = profilesGroup.readEntry( "Num", 0 ); for ( int i = 0; i < numProfiles; ++i ) { KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) ); QString name = profileGroup.readEntry( "Name", tr( "Unnamed" ) ); RoutingProfile profile( name ); foreach ( const QString& pluginName, profileGroup.groupList() ) { KConfigGroup pluginGroup = profileGroup.group( pluginName ); profile.pluginSettings().insert( pluginName, QHash() ); foreach ( const QString& key, pluginGroup.keyList() ) { if ( key != "Enabled" ) { profile.pluginSettings()[ pluginName ].insert( key, pluginGroup.readEntry( key ) ); } } } profiles << profile; } m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles ); } else { m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles(); } int const profileIndex = MarbleSettings::currentRoutingProfile(); if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) { RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex ); m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile ); } QString positionProvider = MarbleSettings::activePositionTrackingPlugin(); if ( !positionProvider.isEmpty() ) { PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager(); foreach( const PositionProviderPlugin* plugin, pluginManager->positionProviderPlugins() ) { if ( plugin->nameId() == positionProvider ) { PositionProviderPlugin* instance = plugin->newInstance(); instance->setMarbleModel( m_controlView->marbleModel() ); tracking->setPositionProviderPlugin( instance ); break; } } } readStatusBarSettings(); updateSettings(); // Time if( MarbleSettings::systemTime() == true ) { /* nothing to do */ } else if( MarbleSettings::lastSessionTime() == true ) { m_controlView->marbleModel()->setClockDateTime( MarbleSettings::dateTime() ); m_controlView->marbleModel()->setClockSpeed( MarbleSettings::speedSlider() ); } readPluginSettings(); m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] ); CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); cloudSyncManager->setOwncloudServer( MarbleSettings::owncloudServer() ); cloudSyncManager->setOwncloudUsername( MarbleSettings::owncloudUsername() ); cloudSyncManager->setOwncloudPassword( MarbleSettings::owncloudPassword() ); cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() ); cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() ); cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() ); } void MarblePart::readStatusBarSettings() { const bool showPos = MarbleSettings::showPositionLabel(); m_showPositionAction->setChecked( showPos ); showPositionLabel( showPos ); const bool showAlt = MarbleSettings::showAltitudeLabel(); m_showAltitudeAction->setChecked( showAlt ); showAltitudeLabel( showAlt ); const bool showTileZoom = MarbleSettings::showTileZoomLevelLabel(); m_showTileZoomLevelAction->setChecked( showTileZoom ); showTileZoomLevelLabel( showTileZoom ); const bool showDateTime = MarbleSettings::showDateTimeLabel(); m_showDateTimeAction->setChecked( showDateTime ); showDateTimeLabel( showDateTime ); const bool showProgress = MarbleSettings::showDownloadProgressBar(); m_showDownloadProgressAction->setChecked( showProgress ); showDownloadProgressBar( showProgress ); } void MarblePart::writeSettings() { // Get the 'quit' values from the widget and store them in the settings. qreal quitLon = m_controlView->marbleWidget()->lookAt().longitude(); qreal quitLat = m_controlView->marbleWidget()->lookAt().latitude(); qreal quitRange = m_controlView->marbleWidget()->lookAt().range(); MarbleSettings::setQuitLongitude( quitLon ); MarbleSettings::setQuitLatitude( quitLat ); MarbleSettings::setQuitRange( quitRange ); // Get the 'home' values from the widget and store them in the settings. qreal homeLon = 0; qreal homeLat = 0; int homeZoom = 0; m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom ); MarbleSettings::setHomeLongitude( homeLon ); MarbleSettings::setHomeLatitude( homeLat ); MarbleSettings::setHomeZoom( homeZoom ); // Set default font MarbleSettings::setMapFont( m_controlView->marbleWidget()->defaultFont() ); // Get whether animations to the target are enabled MarbleSettings::setAnimateTargetVoyage( m_controlView->marbleWidget()->animationsEnabled() ); // Map theme and projection MarbleSettings::setMapTheme( m_controlView->marbleWidget()->mapThemeId() ); MarbleSettings::setProjection( m_controlView->marbleWidget()->projection() ); MarbleSettings::setShowClouds( m_controlView->marbleWidget()->showClouds() ); MarbleSettings::setWorkOffline( m_workOfflineAction->isChecked() ); MarbleSettings::setStillQuality( m_controlView->marbleWidget()->mapQuality( Still ) ); MarbleSettings::setAnimationQuality( m_controlView->marbleWidget()-> mapQuality( Animation ) ); MarbleSettings::setShowBookmarks( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() ); // FIXME: Hopefully Qt will have a getter for this one in the future ... GraphicsSystem graphicsSystem = (GraphicsSystem) MarbleSettings::graphicsSystem(); MarbleSettings::setGraphicsSystem( graphicsSystem ); MarbleSettings::setLastFileOpenDir( m_lastFileOpenPath.toLocalFile() ); MarbleSettings::setDistanceUnit( MarbleGlobal::getInstance()->locale()->measurementSystem() ); MarbleSettings::setAngleUnit( m_controlView->marbleWidget()->defaultAngleUnit() ); // Sun MarbleSettings::setShowSun( m_controlView->marbleWidget()->showSunShading() ); MarbleSettings::setShowCitylights( m_controlView->marbleWidget()->showCityLights() ); MarbleSettings::setLockToSubSolarPoint( m_controlView->marbleWidget()->isLockedToSubSolarPoint() ); MarbleSettings::setSubSolarPointIconVisible( m_controlView->marbleWidget()->isSubSolarPointIconVisible() ); // Caches MarbleSettings::setVolatileTileCacheLimit( m_controlView->marbleWidget()-> volatileTileCacheLimit() / 1024 ); MarbleSettings::setPersistentTileCacheLimit( m_controlView->marbleModel()-> persistentTileCacheLimit() / 1024 ); // Time MarbleSettings::setDateTime( m_controlView->marbleModel()->clockDateTime() ); MarbleSettings::setSpeedSlider( m_controlView->marbleModel()->clockSpeed() ); // Plugins writePluginSettings(); QString positionProvider; PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); if ( tracking && tracking->positionProviderPlugin() ) { positionProvider = tracking->positionProviderPlugin()->nameId(); } MarbleSettings::setActivePositionTrackingPlugin( positionProvider ); MarbleSettings::setLockFloatItemPositions( m_lockFloatItemsAct->isChecked() ); writeStatusBarSettings(); // Store recent files KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); m_recentFilesAction->saveEntries( sharedConfig->group( "RecentFiles" ) ); // Store current route settings RoutingManager *routingManager = m_controlView->marbleWidget()->model()->routingManager(); routingManager->writeSettings(); bool const startupWarning = routingManager->showGuidanceModeStartupWarning(); MarbleSettings::setShowGuidanceModeStartupWarning( startupWarning ); QList profiles = routingManager->profilesModel()->profiles(); RoutingProfile const profile = routingManager->routeRequest()->routingProfile(); MarbleSettings::setCurrentRoutingProfile( profiles.indexOf( profile ) ); QList const editors = m_externalEditorMapping.values(); MarbleSettings::setExternalMapEditor( editors.indexOf( m_controlView->externalMapEditor() ) ); applyPluginState(); MarbleSettings::self()->writeConfig(); } void MarblePart::writeStatusBarSettings() { MarbleSettings::setShowPositionLabel( m_showPositionAction->isChecked() ); MarbleSettings::setShowAltitudeLabel( m_showAltitudeAction->isChecked() ); MarbleSettings::setShowTileZoomLevelLabel( m_showTileZoomLevelAction->isChecked() ); MarbleSettings::setShowDateTimeLabel( m_showDateTimeAction->isChecked() ); MarbleSettings::setShowDownloadProgressBar( m_showDownloadProgressAction->isChecked() ); } void MarblePart::setupActions() { // Action: Recent Files m_recentFilesAction = KStandardAction::openRecent( this, SLOT(openUrl(KUrl)), actionCollection() ); KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); m_recentFilesAction->loadEntries( sharedConfig->group( "RecentFiles" ) ); // Action: Download Region m_downloadRegionAction = new KAction( this ); m_downloadRegionAction->setText( i18nc( "Action for downloading an entire region of a map", "Download Region..." )); actionCollection()->addAction( "file_download_region", m_downloadRegionAction ); connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog())); // Action: Print Map m_printMapAction = KStandardAction::print( this, SLOT(printMapScreenShot()), actionCollection() ); m_printPreviewAction = KStandardAction::printPreview( m_controlView, SLOT(printPreview()), actionCollection() ); // Action: Export Map m_exportMapAction = new KAction( this ); actionCollection()->addAction( "exportMap", m_exportMapAction ); m_exportMapAction->setText( i18nc( "Action for saving the map to a file", "&Export Map..." ) ); m_exportMapAction->setIcon( KIcon( "document-save-as" ) ); m_exportMapAction->setShortcut( Qt::CTRL + Qt::Key_S ); connect( m_exportMapAction, SIGNAL(triggered(bool)), this, SLOT(exportMapScreenShot()) ); // Action: Work Offline m_workOfflineAction = new KAction( this ); actionCollection()->addAction( "workOffline", m_workOfflineAction ); m_workOfflineAction->setText( i18nc( "Action for toggling offline mode", "&Work Offline" ) ); m_workOfflineAction->setIcon( KIcon( "user-offline" ) ); m_workOfflineAction->setCheckable( true ); m_workOfflineAction->setChecked( false ); connect( m_workOfflineAction, SIGNAL(triggered(bool)), this, SLOT(workOffline(bool)) ); // Action: Copy Map to the Clipboard m_copyMapAction = KStandardAction::copy( this, SLOT(copyMap()), actionCollection() ); m_copyMapAction->setText( i18nc( "Action for copying the map to the clipboard", "&Copy Map" ) ); // Action: Copy Coordinates string m_copyCoordinatesAction = new KAction( this ); actionCollection()->addAction( "edit_copy_coordinates", m_copyCoordinatesAction ); m_copyCoordinatesAction->setText( i18nc( "Action for copying the coordinates to the clipboard", "C&opy Coordinates" ) ); m_copyCoordinatesAction->setIcon( KIcon( ":/icons/copy-coordinates.png" ) ); connect( m_copyCoordinatesAction, SIGNAL(triggered(bool)), this, SLOT(copyCoordinates()) ); // Action: Open a Gpx or a Kml File m_openAct = KStandardAction::open( this, SLOT(openFile()), actionCollection() ); m_openAct->setText( i18nc( "Action for opening a file", "&Open..." ) ); // Standard actions. So far only Quit. KStandardAction::quit( kapp, SLOT(closeAllWindows()), actionCollection() ); // Action: Get hot new stuff m_newStuffAction = KNS3::standardAction( i18nc( "Action for downloading maps (GHNS)", "Download Maps..."), this, SLOT(showNewStuffDialog()), actionCollection(), "new_stuff" ); m_newStuffAction->setStatusTip( i18nc( "Status tip", "Download new maps")); m_newStuffAction->setShortcut( Qt::CTRL + Qt::Key_N ); // Action: Create a New Map m_mapWizardAct = new KAction( i18nc( "Action for creating new maps", "&Create a New Map..." ), this ); m_mapWizardAct->setIcon( KIcon( ":/icons/create-new-map.png" ) ); actionCollection()->addAction( "createMap", m_mapWizardAct ); m_mapWizardAct->setStatusTip( i18nc( "Status tip", "A wizard guides you through the creation of your own map theme." ) ); connect( m_mapWizardAct, SIGNAL(triggered()), SLOT(showMapWizard()) ); KStandardAction::showStatusbar( this, SLOT(showStatusBar(bool)), actionCollection() ); m_fullScreenAct = KStandardAction::fullScreen( 0, 0, widget(), actionCollection() ); connect( m_fullScreenAct, SIGNAL(triggered(bool)), this, SLOT(showFullScreen(bool)) ); // Action: Show Crosshairs option QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = pluginList.constBegin(); QList::const_iterator const end = pluginList.constEnd(); for (; i != end; ++i ) { if ( (*i)->nameId() == "crosshairs" ) { actionCollection()->addAction( "show_crosshairs", (*i)->action() ); } } // Action: Show Clouds option m_showCloudsAction = new KAction( this ); actionCollection()->addAction( "show_clouds", m_showCloudsAction ); m_showCloudsAction->setCheckable( true ); m_showCloudsAction->setChecked( true ); m_showCloudsAction->setIcon( KIcon( ":/icons/clouds.png" ) ); m_showCloudsAction->setText( i18nc( "Action for toggling clouds", "&Clouds" ) ); connect( m_showCloudsAction, SIGNAL(triggered(bool)), this, SLOT(setShowClouds(bool)) ); // Action: Show Sunshade options m_controlSunAction = new KAction( this ); actionCollection()->addAction( "control_sun", m_controlSunAction ); m_controlSunAction->setText( i18nc( "Action for sun control dialog", "S&un Control..." ) ); connect( m_controlSunAction, SIGNAL(triggered(bool)), this, SLOT(controlSun()) ); KStandardAction::redisplay( m_controlView->marbleWidget(), SLOT(reloadMap()), actionCollection() ); // Action: Show Time options m_controlTimeAction = new KAction( this ); actionCollection()->addAction( "control_time", m_controlTimeAction ); m_controlTimeAction->setIcon( KIcon( ":/icons/clock.png" ) ); m_controlTimeAction->setText( i18nc( "Action for time control dialog", "&Time Control..." ) ); connect( m_controlTimeAction, SIGNAL(triggered(bool)), this, SLOT(controlTime()) ); // Action: Lock float items m_lockFloatItemsAct = new KAction ( this ); actionCollection()->addAction( "options_lock_floatitems", m_lockFloatItemsAct ); m_lockFloatItemsAct->setText( i18nc( "Action for locking float items on the map", "Lock Position" ) ); m_lockFloatItemsAct->setIcon( KIcon( ":/icons/unlock.png" ) ); m_lockFloatItemsAct->setCheckable( true ); m_lockFloatItemsAct->setChecked( false ); connect( m_lockFloatItemsAct, SIGNAL(triggered(bool)), this, SLOT(lockFloatItemPosition(bool)) ); KStandardAction::preferences( this, SLOT(editSettings()), actionCollection() ); //Toggle Action: Show sun shadow m_showShadow = new KToggleAction( i18n( "Show Shadow" ), this ); m_showShadow->setIcon( KIcon( "" ) ); // Fixme: Add Icon actionCollection()->addAction( "sun_shadow", m_showShadow ); m_showShadow->setCheckedState( KGuiItem( i18n( "Hide Shadow" ) ) ); m_showShadow->setToolTip(i18n("Shows and hides the shadow of the sun")); connect( m_showShadow, SIGNAL(triggered(bool)), this, SLOT(showSun(bool))); //Toggle Action: Show Sun icon on the Sub-Solar Point m_setSubSolarPointIconVisible = new KToggleAction( i18n( "Show sun icon on the Sub-Solar Point" ), this ); actionCollection()->addAction( "show_icon_on_subsolarpoint", m_setSubSolarPointIconVisible ); m_setSubSolarPointIconVisible->setCheckedState( KGuiItem( i18n( "Hide sun icon on the Sub-Solar Point" ) ) ); m_setSubSolarPointIconVisible->setToolTip( i18n( "Show sun icon on the sub-solar point" ) ); connect( m_setSubSolarPointIconVisible, SIGNAL(triggered(bool)), this, SLOT(setSubSolarPointIconVisible(bool))); //Toggle Action: Lock globe to the Sub-Solar Point m_lockToSubSolarPoint = new KToggleAction( i18n( "Lock Globe to the Sub-Solar Point" ), this ); actionCollection()->addAction( "lock_to_subsolarpoint", m_lockToSubSolarPoint ); m_lockToSubSolarPoint->setCheckedState( KGuiItem( i18n( "Unlock Globe to the Sub-Solar Point" ) ) ); m_lockToSubSolarPoint->setToolTip( i18n( "Lock globe to the sub-solar point" ) ); connect( m_lockToSubSolarPoint, SIGNAL(triggered(bool)), this, SLOT(lockToSubSolarPoint(bool))); // FIXME: Discuss if this is the best place to put this QList::const_iterator it = pluginList.constBegin(); QList::const_iterator const itEnd = pluginList.constEnd(); for (; it != itEnd; ++it ) { connect( (*it), SIGNAL(actionGroupsChanged()), this, SLOT(createPluginMenus()) ); } m_addBookmarkAction = new KAction( this ); actionCollection()->addAction( "add_bookmark", m_addBookmarkAction ); m_addBookmarkAction->setText( i18nc( "Add Bookmark", "&Add Bookmark" ) ); m_addBookmarkAction->setIcon( KIcon( ":/icons/bookmark-new.png" ) ); m_addBookmarkAction->setShortcut( Qt::CTRL + Qt::Key_B ); connect( m_addBookmarkAction, SIGNAL(triggered()), this, SLOT(openEditBookmarkDialog()) ); m_toggleBookmarkDisplayAction = new KAction( this ); actionCollection()->addAction( "show_bookmarks", m_toggleBookmarkDisplayAction ); m_toggleBookmarkDisplayAction->setText( i18nc( "Show Bookmarks", "Show &Bookmarks" ) ); m_toggleBookmarkDisplayAction->setStatusTip( tr( "Show or hide bookmarks in the map" ) ); m_toggleBookmarkDisplayAction->setCheckable( true ); m_toggleBookmarkDisplayAction->setChecked( m_controlView->marbleModel()->bookmarkManager()->showBookmarks() ); connect( m_toggleBookmarkDisplayAction, SIGNAL(toggled(bool)), m_controlView->marbleModel()->bookmarkManager(), SLOT(setShowBookmarks(bool)) ); m_setHomeAction = new KAction( this ); actionCollection()->addAction( "set_home", m_setHomeAction ); m_setHomeAction->setText( tr( "&Set Home Location" ) ); m_setHomeAction->setIcon( KIcon( "go-home" ) ); connect( m_setHomeAction, SIGNAL(triggered()), this, SLOT(setHome()) ); m_manageBookmarksAction = new KAction( this ); actionCollection()->addAction( "manage_bookmarks", m_manageBookmarksAction ); m_manageBookmarksAction->setText( i18nc( "Manage Bookmarks", "&Manage Bookmarks" ) ); m_manageBookmarksAction->setIcon( KIcon( ":/icons/bookmarks-organize.png" ) ); connect( m_manageBookmarksAction, SIGNAL(triggered()), this, SLOT(openManageBookmarksDialog()) ); createFolderList(); connect( m_controlView->marbleModel()->bookmarkManager(), SIGNAL(bookmarksChanged()), this, SLOT(createFolderList()) ); m_externalMapEditorAction = new KAction( this ); actionCollection()->addAction( "external_editor", m_externalMapEditorAction ); m_externalMapEditorAction->setText( i18nc( "Edit the map in an external application", "&Edit Map" ) ); m_externalMapEditorAction->setIcon( KIcon( ":/icons/edit-map.png" ) ); m_externalMapEditorAction->setShortcut( Qt::CTRL + Qt::Key_E ); connect( m_externalMapEditorAction, SIGNAL(triggered()), m_controlView, SLOT(launchExternalMapEditor()) ); connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)), this, SLOT(updateMapEditButtonVisibility(QString)) ); } void MarblePart::createFolderList() { QList actionList; QVector folders = m_controlView->marbleModel()->bookmarkManager()->folders(); QVector::const_iterator i = folders.constBegin(); QVector::const_iterator end = folders.constEnd(); for (; i != end; ++i ) { QMenu *m_bookmarksListMenu = new QMenu( (*i)->name() ); createBookmarksListMenu( m_bookmarksListMenu, *(*i) ); connect( m_bookmarksListMenu, SIGNAL(triggered(QAction*)), this, SLOT(lookAtBookmark(QAction*)) ); actionList.append( m_bookmarksListMenu->menuAction() ); } unplugActionList("folders"); plugActionList( "folders", actionList ); } void MarblePart::createBookmarksListMenu( QMenu *m_bookmarksListMenu, const GeoDataFolder &folder ) { m_bookmarksListMenu->clear(); QVector bookmarks = folder.placemarkList(); QVector::const_iterator i = bookmarks.constBegin(); QVector::const_iterator end = bookmarks.constEnd(); for (; i != end; ++i ) { QAction *bookmarkAct = new QAction( (*i)->name(), this ); QVariant var; GeoDataLookAt* lookAt = (*i)->lookAt(); if ( !lookAt ) { GeoDataLookAt coordinateToLookAt; coordinateToLookAt.setCoordinates( (*i)->coordinate() ); coordinateToLookAt.setRange( (*i)->coordinate().altitude() ); } else { var.setValue( *lookAt ); } bookmarkAct->setData( var ); m_bookmarksListMenu->addAction( bookmarkAct ); } } void MarblePart::createInfoBoxesMenu() { QList floatItemList = m_controlView->marbleWidget()->floatItems(); QList actionList; QList::const_iterator i = floatItemList.constBegin(); QList::const_iterator const end = floatItemList.constEnd(); for (; i != end; ++i ) { actionList.append( (*i)->action() ); } unplugActionList( "infobox_actionlist" ); plugActionList( "infobox_actionlist", actionList ); } void MarblePart::createOnlineServicesMenu() { QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList actionList; QList::const_iterator i = renderPluginList.constBegin(); QList::const_iterator const end = renderPluginList.constEnd(); for (; i != end; ++i ) { // FIXME: This will go into the layer manager when AbstractDataPlugin is an interface if( (*i)->renderType() == RenderPlugin::OnlineRenderType ) { actionList.append( (*i)->action() ); } } unplugActionList( "onlineservices_actionlist" ); plugActionList( "onlineservices_actionlist", actionList ); } void MarblePart::createRenderPluginActions() { QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList actionList; QList::const_iterator i = renderPluginList.constBegin(); QList::const_iterator const end = renderPluginList.constEnd(); for (; i != end; ++i ) { if( (*i)->renderType() == RenderPlugin::ThemeRenderType ) { actionList.append( (*i)->action() ); } } unplugActionList( "themerender_actionlist" ); plugActionList( "themerender_actionlist", actionList ); } void MarblePart::showDateTime() { m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat ); updateStatusBar(); } void MarblePart::showPosition( const QString& position ) { m_position = position; updateStatusBar(); } void MarblePart::showZoomLevel( const int tileLevel ) { if ( tileLevel == -1 ) m_tileZoomLevel = i18n( NOT_AVAILABLE ); else { m_tileZoomLevel.setNum( tileLevel ); } updateStatusBar(); } void MarblePart::mapThemeChanged( const QString& newMapTheme ) { Q_UNUSED( newMapTheme ); updateTileZoomLevel(); updateStatusBar(); } void MarblePart::createPluginMenus() { unplugActionList("plugins_actionlist"); QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = renderPluginList.constBegin(); QList::const_iterator const end = renderPluginList.constEnd(); //Load the toolbars for (; i != end; ++i ) { const QList *tmp_toolbarActionGroups = (*i)->toolbarActionGroups(); if ( tmp_toolbarActionGroups ) { foreach( QActionGroup* ag, *tmp_toolbarActionGroups ) { plugActionList( "plugins_actionlist", ag->actions() ); } } } } void MarblePart::updateTileZoomLevel() { const int tileZoomLevel = m_controlView->marbleWidget()->tileZoomLevel(); if ( tileZoomLevel == -1 ) m_tileZoomLevel = i18n( NOT_AVAILABLE ); else { m_tileZoomLevel.setNum( tileZoomLevel ); } } void MarblePart::migrateNewstuffConfigFiles() const { // Newstuff config files used to be in the KDE data directory of the user, but are now // shared between Marble KDE and Marble Qt in Marble's data path of the user. // This method moves an old KDE newstuff config file to the new location if the former // exists and the latter not. QFileInfo const target( MarbleDirs::localPath() + "/newstuff/marble-map-themes.knsregistry" ); if ( !target.exists() ) { QString const source = KStandardDirs::locate( "data", "knewstuff3/marble.knsregistry" ); if ( !source.isEmpty() ) { if ( !target.absoluteDir().exists() ) { if ( !QDir::root().mkpath( target.absolutePath() ) ) { mDebug() << "Failed to create target directory " << target.absolutePath() << " needed for newstuff migration"; return; } } QFile registryFile( source ); if ( !registryFile.open( QFile::ReadOnly ) ) { mDebug() << "Cannot parse newstuff xml file"; return; } QDomDocument xml; if ( !xml.setContent( registryFile.readAll() ) ) { mDebug() << "Cannot parse newstuff xml data"; return; } QDomNodeList items = xml.elementsByTagName( "stuff" ); for ( unsigned int i = 0; i < items.length(); ++i ) { repairNode( items.item(i), "summary" ); repairNode( items.item(i), "author" ); } QFile output( target.absoluteFilePath() ); if ( !output.open( QFile::WriteOnly ) ) { mDebug() << "Cannot open " << target.absoluteFilePath() << " for writing"; } else { QTextStream outStream( &output ); outStream << xml.toString( 2 ); outStream.flush(); output.close(); } } } } void MarblePart::repairNode( QDomNode node, const QString &child ) const { int const size = node.namedItem( child ).toElement().text().size(); if ( size > 1024 ) { QString const theme = node.namedItem( "name" ).toElement().text(); mDebug() << "Removing GHNS field " << child << " of map theme " << theme << ": Size " << size << " exceeds maximum size (see bug 319542)."; node.removeChild( node.namedItem( child ) ); } } void MarblePart::updateStatusBar() { if ( m_positionLabel ) m_positionLabel->setText( i18n( POSITION_STRING, m_position ) ); if ( m_distanceLabel ) m_distanceLabel->setText( i18n( DISTANCE_STRING, m_controlView->marbleWidget()->distanceString() ) ); if ( m_tileZoomLevelLabel ) m_tileZoomLevelLabel->setText( i18n( TILEZOOMLEVEL_STRING, m_tileZoomLevel ) ); if ( m_clockLabel ) m_clockLabel->setText( i18n( DATETIME_STRING, m_clock ) ); } void MarblePart::setupStatusBar() { QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() ); QString templatePositionString = QString( "%1 000\xb0 00\' 00\"_, 000\xb0 00\' 00\"_" ).arg(POSITION_STRING); m_positionLabel = setupStatusBarLabel( templatePositionString ); QString templateDistanceString = QString( "%1 00.000,0 mu" ).arg(DISTANCE_STRING); m_distanceLabel = setupStatusBarLabel( templateDistanceString ); QString templateDateTimeString = QString( "%1 %2" ).arg( DATETIME_STRING , QLocale().toString( QDateTime::fromString ( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat ) ); m_clockLabel = setupStatusBarLabel( templateDateTimeString ); const QString templateTileZoomLevelString = i18n( TILEZOOMLEVEL_STRING ); m_tileZoomLevelLabel = setupStatusBarLabel( templateTileZoomLevelString ); connect( m_controlView->marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)), this, SLOT(showPosition(QString)) ); connect( m_controlView->marbleWidget(), SIGNAL(distanceChanged(QString)), this, SLOT(updateStatusBar()) ); connect( m_controlView->marbleWidget(), SIGNAL(tileLevelChanged(int)), SLOT(showZoomLevel(int))); connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)), this, SLOT(mapThemeChanged(QString)), Qt::QueuedConnection ); connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()), this, SLOT(showDateTime()) ); setupDownloadProgressBar(); setupStatusBarActions(); updateStatusBar(); } QLabel * MarblePart::setupStatusBarLabel( const QString& templateString ) { QFontMetrics statusBarFontMetrics( m_statusBarExtension->statusBar()->fontMetrics() ); QLabel * const label = new QLabel( m_statusBarExtension->statusBar() ); label->setIndent( 5 ); int maxWidth = statusBarFontMetrics.boundingRect( templateString ).width() + 2 * label->margin() + 2 * label->indent(); label->setFixedWidth( maxWidth ); m_statusBarExtension->addStatusBarItem( label, -1, false ); return label; } void MarblePart::setupDownloadProgressBar() { // get status bar and add progress widget KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); m_downloadProgressBar = new QProgressBar; m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() ); statusBar->addPermanentWidget( m_downloadProgressBar ); HttpDownloadManager * const downloadManager = m_controlView->marbleModel()->downloadManager(); Q_ASSERT( downloadManager ); connect( downloadManager, SIGNAL(jobAdded()), SLOT(downloadJobAdded()) ); connect( downloadManager, SIGNAL(jobRemoved()), SLOT(downloadJobRemoved()) ); } void MarblePart::setupStatusBarActions() { KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); statusBar->setContextMenuPolicy( Qt::CustomContextMenu ); connect( statusBar, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showStatusBarContextMenu(QPoint))); m_showPositionAction = new KToggleAction( i18nc( "Action for toggling", "Show Position" ), this ); m_showDateTimeAction = new KToggleAction( i18nc( "Action for toggling", "Show Date and Time" ), this ); m_showAltitudeAction = new KToggleAction( i18nc( "Action for toggling", "Show Altitude" ), this ); m_showTileZoomLevelAction = new KToggleAction( i18nc( "Action for toggling", "Show Tile Zoom Level" ), this ); m_showDownloadProgressAction = new KToggleAction( i18nc( "Action for toggling", "Show Download Progress Bar" ), this ); connect( m_showPositionAction, SIGNAL(triggered(bool)), this, SLOT(showPositionLabel(bool)) ); connect( m_showAltitudeAction, SIGNAL(triggered(bool)), this, SLOT(showAltitudeLabel(bool)) ); connect( m_showTileZoomLevelAction, SIGNAL(triggered(bool)), this, SLOT(showTileZoomLevelLabel(bool)) ); connect( m_showDateTimeAction, SIGNAL(triggered(bool)), this, SLOT(showDateTimeLabel(bool)) ); connect( m_showDownloadProgressAction, SIGNAL(triggered(bool)), this, SLOT(showDownloadProgressBar(bool)) ); } void MarblePart::showNewStuffDialog() { QPointer dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) ); dialog->exec(); delete dialog; } void MarblePart::showUploadNewStuffDialog() { QString newStuffConfig = KStandardDirs::locate ( "data", "marble/marble.knsrc" ); - kDebug() << "KNS config file:" << newStuffConfig; + qDebug() << "KNS config file:" << newStuffConfig; QPointer dialog( new KNS3::UploadDialog( newStuffConfig, m_controlView ) ); - kDebug() << "Creating the archive"; + qDebug() << "Creating the archive"; dialog->setUploadFile( KUrl( MapWizard::createArchive( m_controlView, m_controlView->marbleWidget()->mapThemeId() ) ) ); dialog->exec(); MapWizard::deleteArchive( m_controlView->marbleWidget()->mapThemeId() ); delete dialog; } void MarblePart::showDownloadRegionDialog() { MarbleWidget * const marbleWidget = m_controlView->marbleWidget(); if ( !m_downloadRegionDialog ) { m_downloadRegionDialog = new DownloadRegionDialog( marbleWidget, widget() ); // it might be tempting to move the connects to DownloadRegionDialog's "accepted" and // "applied" signals, be aware that the "hidden" signal might be come before the "accepted" // signal, leading to a too early disconnect. connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion())); connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion())); } // FIXME: get allowed range from current map theme m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 ); m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod ); ViewportParams const * const viewport = marbleWidget->viewport(); m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() ); m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() ); m_downloadRegionDialog->setVisibleTileLevel( marbleWidget->tileZoomLevel() ); m_downloadRegionDialog->show(); m_downloadRegionDialog->raise(); m_downloadRegionDialog->activateWindow(); } void MarblePart::downloadRegion() { Q_ASSERT( m_downloadRegionDialog ); QVector const pyramid = m_downloadRegionDialog->region(); if ( !pyramid.isEmpty() ) { m_controlView->marbleWidget()->downloadRegion( pyramid ); } } void MarblePart::showStatusBarContextMenu( const QPoint& pos ) { KStatusBar * const statusBar = m_statusBarExtension->statusBar(); Q_ASSERT( statusBar ); KMenu statusBarContextMenu( m_controlView->marbleWidget() ); statusBarContextMenu.addAction( m_showPositionAction ); statusBarContextMenu.addAction( m_showDateTimeAction ); statusBarContextMenu.addAction( m_showAltitudeAction ); statusBarContextMenu.addAction( m_showTileZoomLevelAction ); statusBarContextMenu.addAction( m_showDownloadProgressAction ); statusBarContextMenu.exec( statusBar->mapToGlobal( pos )); } void MarblePart::showMapWizard() { // Map Wizard QPointer mapWizard = new MapWizard( m_controlView ); mapWizard->setWmsServers( MarbleSettings::wmsServers() ); mapWizard->setStaticUrlServers( MarbleSettings::staticUrlServers() ); mapWizard->exec(); MarbleSettings::setWmsServers( mapWizard->wmsServers() ); MarbleSettings::setStaticUrlServers( mapWizard->staticUrlServers() ); mapWizard->deleteLater(); } void MarblePart::editSettings() { if ( KConfigDialog::showDialog( "settings" ) ) return; m_configDialog = new KConfigDialog( m_controlView, "settings", MarbleSettings::self() ); // view page Ui_MarbleViewSettingsWidget ui_viewSettings; QWidget *w_viewSettings = new QWidget( 0 ); w_viewSettings->setObjectName( "view_page" ); ui_viewSettings.setupUi( w_viewSettings ); m_configDialog->addPage( w_viewSettings, i18n( "View" ), "configure" ); // It's experimental -- so we remove it for now. // FIXME: Delete the following line once OpenGL support is officially supported. ui_viewSettings.kcfg_graphicsSystem->removeItem( OpenGLGraphics ); QString nativeString ( i18n("Native") ); #ifdef Q_WS_X11 nativeString = i18n( "Native (X11)" ); #endif #ifdef Q_WS_MAC nativeString = i18n( "Native (Mac OS X Core Graphics)" ); #endif ui_viewSettings.kcfg_graphicsSystem->setItemText( NativeGraphics, nativeString ); // navigation page Ui_MarbleNavigationSettingsWidget ui_navigationSettings; QWidget *w_navigationSettings = new QWidget( 0 ); w_navigationSettings->setObjectName( "navigation_page" ); ui_navigationSettings.setupUi( w_navigationSettings ); m_configDialog->addPage( w_navigationSettings, i18n( "Navigation" ), "transform-move" ); // cache page Ui_MarbleCacheSettingsWidget ui_cacheSettings; QWidget *w_cacheSettings = new QWidget( 0 ); w_cacheSettings->setObjectName( "cache_page" ); ui_cacheSettings.setupUi( w_cacheSettings ); m_configDialog->addPage( w_cacheSettings, i18n( "Cache & Proxy" ), "preferences-web-browser-cache" ); connect( ui_cacheSettings.button_clearVolatileCache, SIGNAL(clicked()), m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) ); connect( ui_cacheSettings.button_clearPersistentCache, SIGNAL(clicked()), m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) ); // time page Ui_MarbleTimeSettingsWidget ui_timeSettings; QWidget *w_timeSettings = new QWidget( 0 ); w_timeSettings->setObjectName( "time_page" ); ui_timeSettings.setupUi( w_timeSettings ); m_configDialog->addPage( w_timeSettings, i18n( "Date & Time" ), "clock" ); if ( MarbleSettings::showCloudSyncSettings() ) { // Sync page Ui_MarbleCloudSyncSettingsWidget ui_cloudSyncSettings; QWidget *w_cloudSyncSettings = new QWidget( 0 ); w_cloudSyncSettings->setObjectName( "sync_page" ); ui_cloudSyncSettings.setupUi( w_cloudSyncSettings ); ui_cloudSyncSettings.button_syncNow->setEnabled( MarbleSettings::syncBookmarks() ); m_configDialog->addPage( w_cloudSyncSettings, i18n( "Synchronization" ), "folder-sync" ); connect( ui_cloudSyncSettings.button_syncNow, SIGNAL(clicked()), m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) ); } // routing page RoutingProfilesWidget *w_routingSettings = new RoutingProfilesWidget( m_controlView->marbleModel() ); w_routingSettings->setObjectName( "routing_page" ); m_configDialog->addPage( w_routingSettings, i18n( "Routing" ), "flag"); // plugin page MarblePluginSettingsWidget *w_pluginSettings = new MarblePluginSettingsWidget(); RenderPluginModel *const pluginModel = new RenderPluginModel( w_pluginSettings ); pluginModel->setRenderPlugins( m_controlView->marbleWidget()->renderPlugins() ); w_pluginSettings->setModel( pluginModel ); w_pluginSettings->setObjectName( "plugin_page" ); m_configDialog->addPage( w_pluginSettings, i18n( "Plugins" ), "preferences-plugin" ); // Setting the icons of the pluginSettings page. w_pluginSettings->setConfigIcon( KIcon( "configure" ) ); w_pluginSettings->setAboutIcon( KIcon( "help-about" ) ); connect( w_pluginSettings, SIGNAL(pluginListViewClicked()), SLOT(enableApplyButton()) ); connect( m_configDialog, SIGNAL(settingsChanged(QString)), SLOT(updateSettings()) ); connect( m_configDialog, SIGNAL(applyClicked()), SLOT(applyPluginState()) ); connect( m_configDialog, SIGNAL(okClicked()), SLOT(applyPluginState()) ); connect( m_configDialog, SIGNAL(applyClicked()), pluginModel, SLOT(applyPluginState()) ); connect( m_configDialog, SIGNAL(okClicked()), pluginModel, SLOT(applyPluginState()) ); connect( m_configDialog, SIGNAL(cancelClicked()), pluginModel, SLOT(retrievePluginState()) ); m_configDialog->show(); } void MarblePart::enableApplyButton() { m_configDialog->enableButtonApply( true ); } void MarblePart::applyPluginState() { QList profiles = m_controlView->marbleWidget() ->model()->routingManager()->profilesModel()->profiles(); KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); KConfigGroup profilesGroup = sharedConfig->group( "Routing Profiles" ); profilesGroup.writeEntry( "Num", profiles.count() ); for ( int i = 0; i < profiles.count(); ++i ) { KConfigGroup profileGroup = profilesGroup.group( QString( "Profile %0" ).arg(i) ); RoutingProfile profile = profiles.at( i ); profileGroup.writeEntry( "Name", profile.name() ); foreach ( const QString &pluginName, profileGroup.groupList() ) { profileGroup.group( pluginName ).deleteGroup(); } foreach ( const QString &key, profile.pluginSettings().keys() ) { KConfigGroup pluginGroup = profileGroup.group( key ); pluginGroup.writeEntry( "Enabled", true ); foreach ( const QString& settingKey, profile.pluginSettings()[ key ].keys() ) { Q_ASSERT( settingKey != "Enabled" ); pluginGroup.writeEntry( settingKey, profile.pluginSettings()[ key ][ settingKey ] ); } } } } void MarblePart::updateSettings() { kDebug() << "Updating Settings ..."; // FIXME: Font doesn't get updated instantly. m_controlView->marbleWidget()->setDefaultFont( MarbleSettings::mapFont() ); m_controlView->marbleWidget()-> setMapQualityForViewContext( (MapQuality) MarbleSettings::stillQuality(), Still ); m_controlView->marbleWidget()-> setMapQualityForViewContext( (MapQuality) MarbleSettings::animationQuality(), Animation ); GraphicsSystem graphicsSystem = (GraphicsSystem) MarbleSettings::graphicsSystem(); m_controlView->marbleWidget()-> setDefaultAngleUnit( (AngleUnit) MarbleSettings::angleUnit() ); MarbleGlobal::getInstance()->locale()-> setMeasurementSystem( (QLocale::MeasurementSystem) MarbleSettings::distanceUnit() ); updateStatusBar(); m_controlView->marbleWidget()->setAnimationsEnabled( MarbleSettings::animateTargetVoyage() ); // Cache m_controlView->marbleModel()-> setPersistentTileCacheLimit( MarbleSettings::persistentTileCacheLimit() * 1024 ); m_controlView->marbleWidget()-> setVolatileTileCacheLimit( MarbleSettings::volatileTileCacheLimit() * 1024 ); //Create and export the proxy QNetworkProxy proxy; // Make sure that no proxy is used for an empty string or the default value: if ( MarbleSettings::proxyUrl().isEmpty() || MarbleSettings::proxyUrl() == "http://" ) { proxy.setType( QNetworkProxy::NoProxy ); } else { if ( MarbleSettings::proxyType() == Marble::Socks5Proxy ) { proxy.setType( QNetworkProxy::Socks5Proxy ); } else if ( MarbleSettings::proxyType() == Marble::HttpProxy ) { proxy.setType( QNetworkProxy::HttpProxy ); } else { kDebug() << "Unknown proxy type! Using Http Proxy instead."; proxy.setType( QNetworkProxy::HttpProxy ); } } proxy.setHostName( MarbleSettings::proxyUrl() ); proxy.setPort( MarbleSettings::proxyPort() ); if ( MarbleSettings::proxyAuth() ) { proxy.setUser( MarbleSettings::proxyUser() ); proxy.setPassword( MarbleSettings::proxyPass() ); } QNetworkProxy::setApplicationProxy(proxy); m_controlView->marbleWidget()->update(); // Show message box if ( m_initialGraphicsSystem != graphicsSystem && m_previousGraphicsSystem != graphicsSystem ) { KMessageBox::information (m_controlView->marbleWidget(), i18n("You have decided to run Marble with a different graphics system.\n" "For this change to become effective, Marble has to be restarted.\n" "Please close the application and start Marble again."), i18n("Graphics System Change") ); } m_previousGraphicsSystem = graphicsSystem; // Time if( MarbleSettings::systemTimezone() == true ) { QDateTime localTime = QDateTime::currentDateTime().toLocalTime(); localTime.setTimeSpec( Qt::UTC ); m_controlView->marbleModel()->setClockTimezone( QDateTime::currentDateTime().toUTC().secsTo( localTime ) ); } else if( MarbleSettings::utc() == true ) { m_controlView->marbleModel()->setClockTimezone( 0 ); } else if( MarbleSettings::customTimezone() == true ) { m_controlView->marbleModel()->setClockTimezone( m_timezone.value( MarbleSettings::chosenTimezone() ) ); } // Route rendering colors and alpha values QColor tempColor; tempColor = MarbleSettings::routeColorStandard(); tempColor.setAlpha( MarbleSettings::routeAlphaStandard() ); m_controlView->marbleModel()->routingManager()->setRouteColorStandard( tempColor ); tempColor = MarbleSettings::routeColorHighlighted(); tempColor.setAlpha( MarbleSettings::routeAlphaHighlighted() ); m_controlView->marbleModel()->routingManager()->setRouteColorHighlighted( tempColor ); tempColor = MarbleSettings::routeColorAlternative(); tempColor.setAlpha( MarbleSettings::routeAlphaAlternative() ); m_controlView->marbleModel()->routingManager()->setRouteColorAlternative( tempColor ); // External map editor m_controlView->setExternalMapEditor( m_externalEditorMapping[MarbleSettings::externalMapEditor()] ); m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( MarbleSettings::inertialEarthRotation() ); CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); cloudSyncManager->setOwncloudServer( MarbleSettings::owncloudServer() ); cloudSyncManager->setOwncloudUsername( MarbleSettings::owncloudUsername() ); cloudSyncManager->setOwncloudPassword( MarbleSettings::owncloudPassword() ); cloudSyncManager->setSyncEnabled( MarbleSettings::enableSync() ); cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( MarbleSettings::syncRoutes() ); cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( MarbleSettings::syncBookmarks() ); } void MarblePart::writePluginSettings() { KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); foreach( RenderPlugin *plugin, m_controlView->marbleWidget()->renderPlugins() ) { KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() ); const QHash hash = plugin->settings(); QHash::const_iterator it = hash.begin(); while( it != hash.end() ) { group.writeEntry( it.key(), it.value() ); ++it; } group.sync(); } } void MarblePart::readPluginSettings() { disconnect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()), this, SLOT(writePluginSettings()) ); KSharedConfig::Ptr sharedConfig = KSharedConfig::openConfig( KGlobal::mainComponent() ); foreach( RenderPlugin *plugin, m_controlView->marbleWidget()->renderPlugins() ) { KConfigGroup group = sharedConfig->group( QString( "plugin_" ) + plugin->nameId() ); QHash hash; foreach ( const QString& key, group.keyList() ) { hash.insert( key, group.readEntry( key ) ); } plugin->setSettings( hash ); } connect( m_controlView->marbleWidget(), SIGNAL(pluginSettingsChanged()), this, SLOT(writePluginSettings()) ); } void MarblePart::lockFloatItemPosition( bool enabled ) { QList floatItemList = m_controlView->marbleWidget()->floatItems(); QList::const_iterator i = floatItemList.constBegin(); QList::const_iterator const end = floatItemList.constEnd(); for (; i != end; ++i ) { // Locking one would suffice as it affects all. // Nevertheless go through all. (*i)->setPositionLocked(enabled); } } void MarblePart::downloadJobAdded() { m_downloadProgressBar->setUpdatesEnabled( false ); if ( m_downloadProgressBar->value() < 0 ) { m_downloadProgressBar->setMaximum( 1 ); m_downloadProgressBar->setValue( 0 ); m_downloadProgressBar->setVisible( MarbleSettings::showDownloadProgressBar() ); } else { m_downloadProgressBar->setMaximum( m_downloadProgressBar->maximum() + 1 ); } // kDebug() << "downloadProgressJobAdded: value/maximum: " // << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum(); m_downloadProgressBar->setUpdatesEnabled( true ); } void MarblePart::downloadJobRemoved() { m_downloadProgressBar->setUpdatesEnabled( false ); m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 ); if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) { m_downloadProgressBar->reset(); m_downloadProgressBar->setVisible( false ); } // kDebug() << "downloadProgressJobCompleted: value/maximum: " // << m_downloadProgressBar->value() << '/' << m_downloadProgressBar->maximum(); m_downloadProgressBar->setUpdatesEnabled( true ); } void MarblePart::openEditBookmarkDialog() { MarbleWidget *widget = m_controlView->marbleWidget(); QPointer dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget ); dialog->setCoordinates( widget->lookAt().coordinates() ); dialog->setRange( widget->lookAt().range() ); dialog->setMarbleWidget( widget ); dialog->setReverseGeocodeName(); if ( dialog->exec() == QDialog::Accepted ) { widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() ); } delete dialog; } void MarblePart::setHome() { MarbleWidget *widget = m_controlView->marbleWidget(); widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() ); } void MarblePart::openManageBookmarksDialog() { MarbleModel * const model = m_controlView->marbleModel(); QPointer dialog = new BookmarkManagerDialog( model, m_controlView->marbleWidget() ); dialog->exec(); delete dialog; } void MarblePart::lookAtBookmark( QAction *action) { GeoDataLookAt temp = qvariant_cast( action->data() ) ; m_controlView->marbleWidget()->flyTo( temp ) ; mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree) << " latitude : "<< temp.latitude(GeoDataCoordinates::Degree) << " distance : " << temp.range(); } void MarblePart::initializeCustomTimezone() { if( m_timezone.count() == 0) { m_timezone.insert( 0, 0 ); m_timezone.insert( 1, 3600 ); m_timezone.insert( 2, 7200 ); m_timezone.insert( 3, 7200 ); m_timezone.insert( 4, 10800 ); m_timezone.insert( 5, 12600 ); m_timezone.insert( 6, 14400 ); m_timezone.insert( 7, 18000 ); m_timezone.insert( 8, 19800 ); m_timezone.insert( 9, 21600 ); m_timezone.insert( 10, 25200 ); m_timezone.insert( 11, 28800 ); m_timezone.insert( 12, 32400 ); m_timezone.insert( 13, 34200 ); m_timezone.insert( 14, 36000 ); m_timezone.insert( 15, 39600 ); m_timezone.insert( 16, 43200 ); m_timezone.insert( 17, -39600 ); m_timezone.insert( 18, -36000 ); m_timezone.insert( 19, -32400 ); m_timezone.insert( 20, -28800 ); m_timezone.insert( 21, -25200 ); m_timezone.insert( 22, -25200 ); m_timezone.insert( 23, -21600 ); m_timezone.insert( 24, -18000 ); m_timezone.insert( 25, -18000 ); m_timezone.insert( 26, -14400 ); m_timezone.insert( 27, -12600 ); m_timezone.insert( 28, -10800 ); m_timezone.insert( 29, -10800 ); m_timezone.insert( 30, -3600 ); } } void MarblePart::printMapScreenShot() { #ifndef QT_NO_PRINTER QPrinter printer( QPrinter::HighResolution ); QPointer printDialog = KdePrint::createPrintDialog(&printer, widget()); m_controlView->printMapScreenShot( printDialog ); delete printDialog; #endif } void MarblePart::updateMapEditButtonVisibility( const QString &mapTheme ) { Q_ASSERT( m_externalMapEditorAction ); m_externalMapEditorAction->setVisible( mapTheme == "earth/openstreetmap/openstreetmap.dgml" ); } void MarblePart::fallBackToDefaultTheme() { m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() ); } } #include "marble_part.moc" diff --git a/src/apps/marble-kde/marble_part.h b/src/apps/marble-kde/marble_part.h index a53602eb4..3ed2cb99c 100644 --- a/src/apps/marble-kde/marble_part.h +++ b/src/apps/marble-kde/marble_part.h @@ -1,261 +1,261 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Tobias Koenig // Copyright 2008 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // Copyright 2010 Harshit Jain // #ifndef MARBLE_MARBLEPART_H #define MARBLE_MARBLEPART_H #include #include #include #include #include #include "MarbleGlobal.h" #include "cloudsync/CloudSyncManager.h" #include -class KAboutData; +class K4AboutData; class KAction; class KToggleAction; class KConfigDialog; class KToolBar; class QLabel; class QPrinter; class QProgressBar; class QStandardItemModel; namespace KParts { class StatusBarExtension; } namespace Marble { class ControlView; class DownloadRegionDialog; class RoutingProfilesWidget; class SunControlWidget; class TimeControlWidget; class GeoDataFolder; class MarblePart: public KParts::ReadOnlyPart { Q_OBJECT public: MarblePart( QWidget *parentWidget, QObject *parent, const QVariantList& ); virtual ~MarblePart(); ControlView *controlView() const; - static KAboutData* createAboutData(); + static K4AboutData* createAboutData(); void createInfoBoxesMenu(); void createOnlineServicesMenu(); void createRenderPluginActions(); void initializeCustomTimezone(); public Q_SLOTS: bool openUrl( const KUrl &url ); bool openFile(); void showPosition( const QString& position); void showZoomLevel( const int ); void showDateTime(); void mapThemeChanged( const QString& newMapTheme ); void createPluginMenus(); void createFolderList(); void fallBackToDefaultTheme(); private Q_SLOTS: void exportMapScreenShot(); void printMapScreenShot(); void copyMap(); void copyCoordinates(); void setShowClouds( bool ); void setShowBookmarks( bool isChecked ); void showFullScreen( bool ); void showStatusBar( bool ); /** * @brief Show the dateTime label in the status bar. * This slot is connected with the "triggered" signal of * m_showDateTimeAction. */ void showDateTimeLabel( bool isChecked ); /** * @brief Show the position label in the status bar. * This slot is connected with the "triggered" signal of * m_showPositionAction. */ void showPositionLabel( bool isChecked ); /** * @brief Show the altitude label in the status bar. * This slot is connected with the "triggered" signal of * m_showAltitudeAction. */ void showAltitudeLabel( bool isChecked ); /** * @brief Show the tile zoom level label in the status bar. * This slot is connected with the "triggered" signal of * m_showTileZoomLevelAction. */ void showTileZoomLevelLabel( bool isChecked ); /** * @brief Show the download progress bar in the status bar. * This slot is connected with the "triggered" signal of * m_showDownloadProgressAction. */ void showDownloadProgressBar( bool isChecked ); void downloadJobAdded(); void downloadJobRemoved(); void lockFloatItemPosition( bool ); void controlSun(); void controlTime(); void showSun( bool ); void lockToSubSolarPoint( bool ); void setSubSolarPointIconVisible( bool ); void workOffline( bool ); void setupStatusBar(); void showNewStuffDialog(); void showUploadNewStuffDialog(); void showDownloadRegionDialog(); void downloadRegion(); void showStatusBarContextMenu( const QPoint& pos ); void showMapWizard(); void editSettings(); void enableApplyButton(); void applyPluginState(); void updateSettings(); void updateStatusBar(); /** * Saves the settings of all plugins. */ void writePluginSettings(); /** * Reads the settings of all plugins. */ void readPluginSettings(); //Bookmark Menu void openEditBookmarkDialog(); void setHome(); void openManageBookmarksDialog(); void createBookmarksListMenu( QMenu *, const GeoDataFolder& ); void lookAtBookmark( QAction * ); // void createBookmarkMenu(); void updateMapEditButtonVisibility( const QString &mapTheme ); private: void setupActions(); void setupDownloadProgressBar(); void setupStatusBarActions(); QLabel * setupStatusBarLabel( const QString& templateString ); void readSettings(); void readStatusBarSettings(); void writeSettings(); void writeStatusBarSettings(); /** Only updates member variable m_tileZoomLevel, does not trigger screen update. */ void updateTileZoomLevel(); void migrateNewstuffConfigFiles() const; void repairNode( QDomNode node, const QString &child ) const; private: // All the functionality is provided by this widget. ControlView *m_controlView; // MarbleControlBox and MarbleWidget SunControlWidget *m_sunControlDialog; TimeControlWidget *m_timeControlDialog; DownloadRegionDialog *m_downloadRegionDialog; // Actions for the GUI. KAction *m_exportMapAction; KAction *m_printMapAction; KAction *m_printPreviewAction; KAction *m_workOfflineAction; KAction *m_copyMapAction; KAction *m_copyCoordinatesAction; KAction *m_showCloudsAction; KAction *m_fullScreenAct; KAction *m_openAct; KAction *m_newStuffAction; KAction *m_downloadRegionAction; KAction *m_controlSunAction; KAction *m_controlTimeAction; KAction *m_lockFloatItemsAct; KAction *m_mapWizardAct; KAction *m_externalMapEditorAction; KRecentFilesAction *m_recentFilesAction; //Bookmark Menu KAction *m_addBookmarkAction; KAction *m_toggleBookmarkDisplayAction; KAction *m_setHomeAction; KAction *m_manageBookmarksAction; // Actions for the status bar KAction *m_showPositionAction; KAction *m_showDateTimeAction; KAction *m_showAltitudeAction; KAction *m_showTileZoomLevelAction; KAction *m_showDownloadProgressAction; // Action for the tool bar KToggleAction *m_showShadow; KToggleAction *m_lockToSubSolarPoint; KToggleAction *m_setSubSolarPointIconVisible; KConfigDialog *m_configDialog; QHash m_pluginEnabled; QString m_position; QString m_clock; QString m_tileZoomLevel; KUrl m_lastFileOpenPath; // Items for the statusbar. QLabel *m_positionLabel; QLabel *m_clockLabel; QLabel *m_distanceLabel; QLabel *m_tileZoomLevelLabel; QProgressBar *m_downloadProgressBar; KParts::StatusBarExtension *m_statusBarExtension; // Information about the graphics system GraphicsSystem m_initialGraphicsSystem; GraphicsSystem m_previousGraphicsSystem; QHash< int, int > m_timezone; QMap m_externalEditorMapping; }; } #endif diff --git a/src/apps/marble-qt/CMakeLists.txt b/src/apps/marble-qt/CMakeLists.txt index 7d16bd793..792c75d4f 100644 --- a/src/apps/marble-qt/CMakeLists.txt +++ b/src/apps/marble-qt/CMakeLists.txt @@ -1,81 +1,82 @@ set(marble_SRCS qtmain.cpp QtMainWindow.cpp) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../marble-ui) if(MSVC) set(marble_SRCS ${marble_SRCS} marble.rc) endif(MSVC) if(MINGW) QT4_ADD_RESOURCES2(marble_SRCS marble.rc) endif(MINGW) qt_wrap_ui(marble_SRCS ${marble_UI}) marble_qt4_automoc(${marble_SRCS}) if (WIN32) add_executable (marble-qt WIN32 ${marble_SRCS}) else (WIN32) if (APPLE) add_executable (marble-qt MACOSX_BUNDLE ${marble_SRCS}) # For Mac OS X, the executable must be at the root of the bundle's executable folder INSTALL(TARGETS marble-qt RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) else (APPLE) add_executable (marble-qt ${marble_SRCS}) endif (APPLE) endif (WIN32) if (QT4_FOUND) target_link_libraries ( marble-qt ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${QT_QTMAIN_LIBRARY} + ${QT_QTDBUS_LIBRARY} + Qt5::QDBus marbleui marblewidget) else() target_link_libraries ( marble-qt ${Qt5Core_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5PrintSupport_LIBRARIES} ${Qt5Network_LIBRARIES} ${Qt5WebKitWidgets_LIBRARIES} ${Qt5WebKit_LIBRARIES} marbleui marblewidget) endif() if(WIN32) target_link_libraries( marble-qt ws2_32 imm32 winmm ) endif(WIN32) ## this works for win32 only because FindQt4 does not handle this correct if(STATIC_BUILD) target_link_libraries(marble ${QT_PLUGINS_DIR}/imageformats/qjpeg.lib) target_link_libraries(marble ${QT_PLUGINS_DIR}/imageformats/qsvg.lib) endif(STATIC_BUILD) if(WIN32) install (TARGETS marble-qt RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) else(WIN32) if (APPLE) # No need for this when installing to a bundle else (APPLE) install (TARGETS marble-qt RUNTIME DESTINATION bin ) endif (APPLE) endif(WIN32) if(APPS_INSTALL_DIR) install(PROGRAMS marble-qt.desktop DESTINATION ${APPS_INSTALL_DIR}) endif(APPS_INSTALL_DIR) diff --git a/src/apps/marble-qt/QtMainWindow.cpp b/src/apps/marble-qt/QtMainWindow.cpp index 750650a88..81bdf4b9c 100644 --- a/src/apps/marble-qt/QtMainWindow.cpp +++ b/src/apps/marble-qt/QtMainWindow.cpp @@ -1,1425 +1,1425 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2010 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2011-2013 Bernhard Beschow // Copyright 2012 Illya Kovalevskyy // Copyright 2012 Mohammed Nafees // #include "QtMainWindow.h" #include "MarbleDebug.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "EditBookmarkDialog.h" #include "BookmarkManagerDialog.h" #include "CurrentLocationWidget.h" #include "MapViewWidget.h" #include "MarbleDirs.h" #include "MarbleAboutDialog.h" #include "QtMarbleConfigDialog.h" #include "SunControlWidget.h" #include "TimeControlWidget.h" #include "MarbleLocale.h" #include "DownloadRegionDialog.h" #include "ViewportParams.h" #include "AbstractDataPlugin.h" #include "AbstractFloatItem.h" #include "MarbleModel.h" #include "MarbleClock.h" #include "HttpDownloadManager.h" #include "BookmarkManager.h" #include "NewBookmarkFolderDialog.h" #include "GeoDataDocument.h" #include "GeoDataPlacemark.h" #include "routing/RoutingManager.h" #include "routing/RoutingProfilesModel.h" #include "routing/RoutingWidget.h" #include "routing/RouteRequest.h" #include "ParseRunnerPlugin.h" #include "PositionTracking.h" #include "PositionProviderPlugin.h" #include "PluginManager.h" #include "MapThemeDownloadDialog.h" #include "MapWizard.h" #include "GoToDialog.h" #include "MarbleWidgetInputHandler.h" #include "Planet.h" #include "cloudsync/CloudSyncManager.h" #include "cloudsync/BookmarkSyncManager.h" namespace { const char* POSITION_STRING = "Position:"; const char* DISTANCE_STRING = "Altitude:"; const char* ZOOM_STRING = "Zoom:"; const char* DATETIME_STRING = "Time:"; } using namespace Marble; /* TRANSLATOR Marble::MainWindow */ MainWindow::MainWindow(const QString& marbleDataPath, const QVariantMap& cmdLineSettings, QWidget *parent) : QMainWindow(parent), m_sunControlDialog( 0 ), m_timeControlDialog( 0 ), m_downloadRegionDialog( 0 ), m_panelMenu( 0 ), m_downloadRegionAction( 0 ), m_osmEditAction( 0 ), m_zoomLabel( 0 ) { setUpdatesEnabled( false ); QString selectedPath = marbleDataPath.isEmpty() ? readMarbleDataPath() : marbleDataPath; if ( !selectedPath.isEmpty() ) MarbleDirs::setMarbleDataPath( selectedPath ); m_controlView = new ControlView( this ); setWindowTitle( tr("Marble - Virtual Globe") ); setWindowIcon( QIcon(":/icons/marble.png") ); setCentralWidget( m_controlView ); // Initializing config dialog m_configDialog = new QtMarbleConfigDialog( m_controlView->marbleWidget(), this ); connect( m_configDialog, SIGNAL(settingsChanged()), this, SLOT(updateSettings()) ); connect( m_configDialog, SIGNAL(clearVolatileCacheClicked()), m_controlView->marbleWidget(), SLOT(clearVolatileTileCache()) ); connect( m_configDialog, SIGNAL(clearPersistentCacheClicked()), m_controlView->marbleModel(), SLOT(clearPersistentTileCache()) ); connect( m_configDialog, SIGNAL(syncNowClicked()), m_controlView->cloudSyncManager()->bookmarkSyncManager(), SLOT(startBookmarkSync()) ); // Load bookmark file. If it does not exist, a default one will be used. m_controlView->marbleModel()->bookmarkManager()->loadFile( "bookmarks/bookmarks.kml" ); createActions(); QList const panelActions = m_controlView->setupDockWidgets( this ); createMenus( panelActions ); createStatusBar(); connect( m_controlView->marbleWidget(), SIGNAL(themeChanged(QString)), this, SLOT(updateMapEditButtonVisibility(QString)) ); connect( m_controlView, SIGNAL(showMapWizard()), this, SLOT(showMapWizard()) ); connect( m_controlView, SIGNAL(mapThemeDeleted()), this, SLOT(fallBackToDefaultTheme()) ); setUpdatesEnabled( true ); m_position = tr( NOT_AVAILABLE ); m_distance = marbleWidget()->distanceString(); m_zoom = QString::number( marbleWidget()->tileZoomLevel() ); m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat ); QMetaObject::invokeMethod(this, "initObject", Qt::QueuedConnection, Q_ARG(QVariantMap, cmdLineSettings)); } void MainWindow::addGeoDataFile( const QString &fileName ) { QFileInfo file( fileName ); if ( !file.exists() ) return; // delay file loading to initObject(), such that restoring view from previous session in readSettings() // doesn't interfere with focusing on these files m_commandlineFilePaths << file.absoluteFilePath(); } void MainWindow::initObject(const QVariantMap& cmdLineSettings) { QCoreApplication::processEvents (); setupStatusBar(); readSettings(cmdLineSettings); foreach ( const QString &path, m_commandlineFilePaths ) { m_controlView->marbleModel()->addGeoDataFile( path ); } m_commandlineFilePaths.clear(); } void MainWindow::createActions() { m_openAct = new QAction( QIcon(":/icons/document-open.png"), tr( "&Open..."), this ); m_openAct->setShortcut( tr( "Ctrl+O" ) ); m_openAct->setStatusTip( tr( "Open a file for viewing on Marble")); connect( m_openAct, SIGNAL(triggered()), this, SLOT(openFile()) ); m_downloadAct = new QAction( QIcon(":/icons/get-hot-new-stuff.png"), tr("&Download Maps..."), this); connect(m_downloadAct, SIGNAL(triggered()), this, SLOT(openMapDialog())); m_exportMapAct = new QAction( QIcon(":/icons/document-save-as.png"), tr("&Export Map..."), this); m_exportMapAct->setShortcut(tr("Ctrl+S")); m_exportMapAct->setStatusTip(tr("Save a screenshot of the map")); connect(m_exportMapAct, SIGNAL(triggered()), this, SLOT(exportMapScreenShot())); // Action: Download Region m_downloadRegionAction = new QAction( tr( "Download &Region..." ), this ); m_downloadRegionAction->setStatusTip( tr( "Download a map region in different zoom levels for offline usage" ) ); connect( m_downloadRegionAction, SIGNAL(triggered()), SLOT(showDownloadRegionDialog()) ); m_printAct = new QAction( QIcon(":/icons/document-print.png"), tr("&Print..."), this); m_printAct->setShortcut(tr("Ctrl+P")); m_printAct->setStatusTip(tr("Print a screenshot of the map")); connect(m_printAct, SIGNAL(triggered()), this, SLOT(printMapScreenShot())); m_printPreviewAct = new QAction( QIcon(":/icons/document-print-preview.png"), tr("Print Previe&w ..."), this); m_printPreviewAct->setStatusTip(tr("Print a screenshot of the map")); connect(m_printPreviewAct, SIGNAL(triggered()), m_controlView, SLOT(printPreview())); m_quitAct = new QAction( QIcon(":/icons/application-exit.png"), tr("&Quit"), this); m_quitAct->setShortcut(tr("Ctrl+Q")); m_quitAct->setStatusTip(tr("Quit the Application")); connect(m_quitAct, SIGNAL(triggered()), this, SLOT(close())); m_copyMapAct = new QAction( QIcon(":/icons/edit-copy.png"), tr("&Copy Map"), this); m_copyMapAct->setShortcut(tr("Ctrl+C")); m_copyMapAct->setStatusTip(tr("Copy a screenshot of the map")); connect(m_copyMapAct, SIGNAL(triggered()), this, SLOT(copyMap())); m_osmEditAction = new QAction( QIcon(":/icons/edit-map.png"), tr( "&Edit Map" ), this ); m_osmEditAction->setShortcut(tr( "Ctrl+E" ) ); m_osmEditAction->setStatusTip(tr( "Edit the current map region in an external editor" ) ); updateMapEditButtonVisibility( m_controlView->marbleWidget()->mapThemeId() ); connect( m_osmEditAction, SIGNAL(triggered()), m_controlView, SLOT(launchExternalMapEditor()) ); m_configDialogAct = new QAction( QIcon(":/icons/settings-configure.png"),tr("&Configure Marble"), this); m_configDialogAct->setStatusTip(tr("Show the configuration dialog")); connect(m_configDialogAct, SIGNAL(triggered()), this, SLOT(editSettings())); m_copyCoordinatesAct = new QAction( QIcon(":/icons/copy-coordinates.png"), tr("C&opy Coordinates"), this); m_copyCoordinatesAct->setStatusTip(tr("Copy the center coordinates as text")); connect(m_copyCoordinatesAct, SIGNAL(triggered()), this, SLOT(copyCoordinates())); m_fullScreenAct = new QAction( QIcon(":/icons/view-fullscreen.png"), tr("&Full Screen Mode"), this); m_fullScreenAct->setShortcut(tr("Ctrl+Shift+F")); m_fullScreenAct->setCheckable( true ); m_fullScreenAct->setStatusTip(tr("Full Screen Mode")); connect(m_fullScreenAct, SIGNAL(triggered(bool)), this, SLOT(showFullScreen(bool))); m_statusBarAct = new QAction( tr("&Show Status Bar"), this); m_statusBarAct->setCheckable( true ); m_statusBarAct->setStatusTip(tr("Show Status Bar")); connect(m_statusBarAct, SIGNAL(triggered(bool)), this, SLOT(showStatusBar(bool))); m_lockFloatItemsAct = new QAction( QIcon(":/icons/unlock.png"), tr("Lock Position"),this); m_lockFloatItemsAct->setCheckable( true ); m_lockFloatItemsAct->setStatusTip(tr("Lock Position of Floating Items")); connect(m_lockFloatItemsAct, SIGNAL(triggered(bool)), this, SLOT(lockPosition(bool))); m_showCloudsAct = new QAction( QIcon(":/icons/clouds.png"), tr("&Clouds"), this); m_showCloudsAct->setCheckable( true ); m_showCloudsAct->setStatusTip(tr("Show Real Time Cloud Cover")); connect(m_showCloudsAct, SIGNAL(triggered(bool)), this, SLOT(showClouds(bool))); m_workOfflineAct = new QAction( QIcon(":/icons/user-offline.png"), tr("Work Off&line"), this); m_workOfflineAct->setCheckable( true ); connect(m_workOfflineAct, SIGNAL(triggered(bool)), this, SLOT(workOffline(bool))); m_controlTimeAct = new QAction( QIcon(":/icons/clock.png"), tr( "&Time Control..." ), this ); m_controlTimeAct->setStatusTip( tr( "Configure Time Control " ) ); connect( m_controlTimeAct, SIGNAL(triggered()), this, SLOT(controlTime()) ); m_controlSunAct = new QAction( tr( "S&un Control..." ), this ); m_controlSunAct->setStatusTip( tr( "Configure Sun Control" ) ); connect( m_controlSunAct, SIGNAL(triggered()), this, SLOT(controlSun()) ); m_reloadAct = new QAction( QIcon(":/icons/view-refresh.png"), tr("&Redisplay"), this); m_reloadAct->setShortcut(tr("F5")); m_reloadAct->setStatusTip(tr("Reload Current Map")); connect(m_reloadAct, SIGNAL(triggered()), this, SLOT(reload())); m_handbookAct = new QAction( QIcon(":/icons/help-contents.png"), tr("Marble Virtual Globe &Handbook"), this); m_handbookAct->setShortcut(tr("F1")); m_handbookAct->setStatusTip(tr("Show the Handbook for Marble Virtual Globe")); connect(m_handbookAct, SIGNAL(triggered()), this, SLOT(handbook())); m_whatsThisAct = new QAction( QIcon(":/icons/help-whatsthis.png"), tr("What's &This"), this); m_whatsThisAct->setShortcut(tr("Shift+F1")); m_whatsThisAct->setStatusTip(tr("Show a detailed explanation of the action.")); connect(m_whatsThisAct, SIGNAL(triggered()), this, SLOT(enterWhatsThis())); m_aboutMarbleAct = new QAction( QIcon(":/icons/marble.png"), tr("&About Marble Virtual Globe"), this); m_aboutMarbleAct->setStatusTip(tr("Show the application's About Box")); connect(m_aboutMarbleAct, SIGNAL(triggered()), this, SLOT(aboutMarble())); m_aboutQtAct = new QAction(tr("About &Qt"), this); m_aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); connect(m_aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); //Bookmark Actions m_addBookmarkAct = new QAction( QIcon(":/icons/bookmark-new.png"), tr("&Add Bookmark"),this); m_addBookmarkAct->setShortcut(tr("Ctrl+B")); m_addBookmarkAct->setStatusTip(tr("Add Bookmark")); connect( m_addBookmarkAct, SIGNAL(triggered()), this, SLOT(openEditBookmarkDialog()) ); m_setHomeAct = new QAction( QIcon(":/icons/go-home.png"), tr( "&Set Home Location" ),this); m_setHomeAct->setStatusTip( tr( "&Set Home Location" ) ); connect( m_setHomeAct, SIGNAL(triggered()), this, SLOT(setHome()) ); m_toggleBookmarkDisplayAct = new QAction(tr( "Show &Bookmarks" ), this); m_toggleBookmarkDisplayAct->setStatusTip( tr( "Toggle display of Bookmarks" ) ); m_toggleBookmarkDisplayAct->setCheckable( true ); connect( m_toggleBookmarkDisplayAct, SIGNAL(triggered(bool)), this, SLOT(showBookmarks(bool)) ); m_manageBookmarksAct = new QAction( QIcon( ":/icons/bookmarks-organize.png" ), tr( "&Manage Bookmarks" ), this); m_manageBookmarksAct->setStatusTip( tr( "Manage Bookmarks" ) ); connect( m_manageBookmarksAct, SIGNAL(triggered()), this, SLOT(manageBookmarks()) ); // Map Wizard action m_mapWizardAct = new QAction( QIcon( ":/icons/create-new-map.png" ), tr("&Create a New Map..."), this ); m_mapWizardAct->setStatusTip( tr( "A wizard guides you through the creation of your own map theme." ) ); connect( m_mapWizardAct, SIGNAL(triggered()), SLOT(showMapWizard()) ); } void MainWindow::createMenus( const QList &panelActions ) { m_fileMenu = menuBar()->addMenu(tr("&File")); m_fileMenu->addAction(m_openAct); m_fileMenu->addAction(m_downloadAct); m_fileMenu->addAction( m_downloadRegionAction ); m_fileMenu->addAction( m_mapWizardAct ); m_fileMenu->addAction(m_exportMapAct); m_fileMenu->addSeparator(); m_fileMenu->addAction(m_printAct); m_fileMenu->addAction(m_printPreviewAct); m_fileMenu->addSeparator(); m_fileMenu->addAction(m_workOfflineAct); m_fileMenu->addAction(m_quitAct); m_fileMenu = menuBar()->addMenu(tr("&Edit")); m_fileMenu->addAction(m_copyMapAct); m_fileMenu->addAction(m_copyCoordinatesAct); m_fileMenu->addAction( m_osmEditAction ); m_viewMenu = menuBar()->addMenu(tr("&View")); m_infoBoxesMenu = new QMenu( "&Info Boxes" ); m_onlineServicesMenu = new QMenu( "&Online Services" ); createPluginsMenus(); m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks")); createBookmarkMenu(); connect( m_bookmarkMenu, SIGNAL(aboutToShow()), this, SLOT(createBookmarkMenu()) ); m_panelMenu = new QMenu( "&Panels" ); foreach( QAction* action, panelActions ) { m_panelMenu->addAction( action ); } m_settingsMenu = menuBar()->addMenu(tr("&Settings")); m_settingsMenu->addMenu( m_panelMenu ); m_settingsMenu->addAction(m_statusBarAct); m_settingsMenu->addAction(m_fullScreenAct); m_settingsMenu->addSeparator(); m_settingsMenu->addAction(m_configDialogAct); m_helpMenu = menuBar()->addMenu(tr("&Help")); m_helpMenu->addAction(m_handbookAct); m_helpMenu->addSeparator(); m_helpMenu->addAction(m_whatsThisAct); m_helpMenu->addSeparator(); m_helpMenu->addAction(m_aboutMarbleAct); m_helpMenu->addAction(m_aboutQtAct); // FIXME: Discuss if this is the best place to put this QList pluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator it = pluginList.constBegin(); QList::const_iterator const listEnd = pluginList.constEnd(); for (; it != listEnd; ++it ) { connect( (*it), SIGNAL(actionGroupsChanged()), this, SLOT(createPluginMenus()) ); } } void MainWindow::createPluginsMenus() { m_onlineServicesMenu->clear(); m_infoBoxesMenu->clear(); m_viewMenu->clear(); m_viewMenu->addAction(m_reloadAct); m_viewMenu->addSeparator(); // Do not create too many menu entries on a MID // FIXME: Set up another way of switching the plugins on and off. if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { return; } m_infoBoxesMenu->addAction(m_lockFloatItemsAct); m_infoBoxesMenu->addSeparator(); QList themeActions; QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = renderPluginList.constBegin(); QList::const_iterator const end = renderPluginList.constEnd(); for (; i != end; ++i ) { switch( (*i)->renderType() ) { case RenderPlugin::TopLevelRenderType: m_viewMenu->addAction( (*i)->action() ); break; case RenderPlugin::PanelRenderType: m_infoBoxesMenu->addAction( (*i)->action() ); break; case RenderPlugin::OnlineRenderType: m_onlineServicesMenu->addAction( (*i)->action() ); break; case RenderPlugin::ThemeRenderType: themeActions.append( (*i)->action() ); break; default: break; } } m_viewMenu->addMenu( m_infoBoxesMenu ); m_viewMenu->addMenu( m_onlineServicesMenu ); m_viewMenu->addActions( themeActions ); m_viewMenu->addAction( m_showCloudsAct ); m_viewMenu->addSeparator(); m_viewMenu->addAction(m_controlSunAct); m_viewMenu->addAction(m_controlTimeAct); } void MainWindow::createBookmarksListMenu( QMenu *bookmarksListMenu, const GeoDataContainer *container ) { //m_bookmarksListMenu->clear(); QVector bookmarks = container->placemarkList(); foreach ( const GeoDataPlacemark *placemark, bookmarks ) { QAction *bookmarkAct = new QAction( placemark->name(), this ); QVariant var; const GeoDataLookAt* lookAt = placemark->lookAt(); if ( !lookAt ) { GeoDataCoordinates coordinates = placemark->coordinate( m_controlView->marbleModel()->clockDateTime() ); GeoDataLookAt coordinateToLookAt; coordinateToLookAt.setCoordinates( coordinates ); coordinateToLookAt.setRange( marbleWidget()->lookAt().range() ); var.setValue( coordinateToLookAt ); } else { var.setValue( *lookAt ); } bookmarkAct->setData( var ); bookmarksListMenu->addAction( bookmarkAct ); } } void MainWindow::createBookmarkMenu() { m_bookmarkMenu->clear(); m_bookmarkMenu->addAction( m_addBookmarkAct ); m_bookmarkMenu->addAction( m_toggleBookmarkDisplayAct ); m_toggleBookmarkDisplayAct->setChecked( m_controlView->marbleModel()->bookmarkManager()->document()->isVisible() ); m_bookmarkMenu->addAction( m_setHomeAct ); m_bookmarkMenu->addAction( m_manageBookmarksAct ); m_bookmarkMenu->addSeparator(); m_bookmarkMenu->addAction( QIcon( ":/icons/go-home.png" ), "&Home", m_controlView->marbleWidget(), SLOT(goHome()) ); createFolderList( m_bookmarkMenu, m_controlView->marbleModel()->bookmarkManager()->document() ); } void MainWindow::createFolderList( QMenu *bookmarksListMenu, const GeoDataContainer *container ) { QVector folders = container->folderList(); if ( folders.size() == 1 ) { createBookmarksListMenu( bookmarksListMenu, folders.first() ); } else { foreach ( const GeoDataFolder *folder, folders ) { QMenu *subMenu = bookmarksListMenu->addMenu( QIcon( ":/icons/folder-bookmark.png" ), folder->name() ); createFolderList( subMenu, folder ); connect( subMenu, SIGNAL(triggered(QAction*)), this, SLOT(lookAtBookmark(QAction*)) ); } } createBookmarksListMenu( bookmarksListMenu, container ); connect( bookmarksListMenu, SIGNAL(triggered(QAction*)), this, SLOT(lookAtBookmark(QAction*)) ); } void MainWindow::lookAtBookmark( QAction *action) { if ( action->data().isNull() ) { return; } GeoDataLookAt temp = qvariant_cast( action->data() ) ; m_controlView->marbleWidget()->flyTo( temp ) ; mDebug() << " looking at bookmark having longitude : "<< temp.longitude(GeoDataCoordinates::Degree) << " latitude : "<< temp.latitude(GeoDataCoordinates::Degree) << " distance : " << temp.range(); } void MainWindow::manageBookmarks() { MarbleModel * const model = m_controlView->marbleModel(); QPointer dialog = new BookmarkManagerDialog( model, this ); #ifdef Q_WS_MAEMO_5 dialog->setButtonBoxVisible( false ); dialog->setAttribute( Qt::WA_Maemo5StackedWindow ); dialog->setWindowFlags( Qt::Window ); #endif // Q_WS_MAEMO_5 dialog->exec(); delete dialog; } void MainWindow::setHome() { MarbleWidget *widget = m_controlView->marbleWidget(); widget->model()->setHome( widget->centerLongitude(), widget->centerLatitude(), widget->zoom() ); } void MainWindow::openEditBookmarkDialog() { MarbleWidget *widget = m_controlView->marbleWidget(); QPointer dialog = new EditBookmarkDialog( widget->model()->bookmarkManager(), widget ); dialog->setMarbleWidget( widget ); dialog->setCoordinates( widget->lookAt().coordinates() ); dialog->setRange( widget->lookAt().range() ); dialog->setReverseGeocodeName(); if ( dialog->exec() == QDialog::Accepted ) { widget->model()->bookmarkManager()->addBookmark( dialog->folder(), dialog->bookmark() ); } delete dialog; } void MainWindow::createPluginMenus() { // Remove and delete toolbars if they exist while( !m_pluginToolbars.isEmpty() ) { QToolBar* tb = m_pluginToolbars.takeFirst(); this->removeToolBar(tb); delete tb; } // Do not create too many menu entries on a MID // FIXME: Set up another way of switching the plugins on and off. if( MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen ) { return; } //remove and delete old menus if they exist while( !m_pluginMenus.isEmpty() ) { m_pluginMenus.takeFirst(); // FIXME: this does not provide an easy way to remove a menu. // Make a workaround // this->menuBar()->removeAction(); } const QList *tmp_toolbarActionGroups; QList renderPluginList = m_controlView->marbleWidget()->renderPlugins(); QList::const_iterator i = renderPluginList.constBegin(); QList::const_iterator const end = renderPluginList.constEnd(); //Load the toolbars for (; i != end; ++i ) { tmp_toolbarActionGroups = (*i)->toolbarActionGroups(); if ( tmp_toolbarActionGroups ) { QToolBar* toolbar = new QToolBar(this); toolbar->setObjectName( QString( "plugin-toolbar-%1" ).arg( (*i)->nameId() ) ); foreach( QActionGroup* ag, *tmp_toolbarActionGroups ) { toolbar->addActions( ag->actions() ); } m_pluginToolbars.append( toolbar ); this->addToolBar( toolbar ); } } // FIXME: load the menus once the method has been settled on } void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); statusBar()->hide(); } void MainWindow::openMapDialog() { QPointer dialog( new MapThemeDownloadDialog( m_controlView->marbleWidget() ) ); dialog->exec(); delete dialog; } void MainWindow::exportMapScreenShot() { QString fileName = QFileDialog::getSaveFileName(this, tr("Export Map"), // krazy:exclude=qclasses QDir::homePath(), tr("Images (*.jpg *.png)")); if ( !fileName.isEmpty() ) { // Take the case into account where no file format is indicated const char * format = 0; if ( !fileName.endsWith(QLatin1String( "png" ), Qt::CaseInsensitive) | !fileName.endsWith(QLatin1String( "jpg" ), Qt::CaseInsensitive) ) { format = "JPG"; } QPixmap mapPixmap = m_controlView->mapScreenShot(); bool success = mapPixmap.save( fileName, format ); if ( !success ) { QMessageBox::warning(this, tr("Marble"), // krazy:exclude=qclasses tr( "An error occurred while trying to save the file.\n" ), QMessageBox::Ok); } } } void MainWindow::showFullScreen( bool isChecked ) { if ( isChecked ) { setWindowState( windowState() | Qt::WindowFullScreen ); // set } else { setWindowState( windowState() & ~Qt::WindowFullScreen ); // reset } m_fullScreenAct->setChecked( isChecked ); // Sync state with the GUI } void MainWindow::copyCoordinates() { qreal lon = m_controlView->marbleWidget()->centerLongitude(); qreal lat = m_controlView->marbleWidget()->centerLatitude(); QString positionString = GeoDataCoordinates( lon, lat, 0.0, GeoDataCoordinates::Degree ).toString(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText( positionString ); } void MainWindow::copyMap() { QPixmap mapPixmap = m_controlView->mapScreenShot(); QClipboard *clipboard = QApplication::clipboard(); clipboard->setPixmap( mapPixmap ); } void MainWindow::showStatusBar( bool isChecked ) { if ( isChecked ) { statusBar()->show(); } else { statusBar()->hide(); } m_statusBarAct->setChecked( isChecked ); // Sync state with the GUI } void MainWindow::showClouds( bool isChecked ) { m_controlView->marbleWidget()->setShowClouds( isChecked ); m_showCloudsAct->setChecked( isChecked ); // Sync state with the GUI } void MainWindow::showBookmarks( bool show ) { m_controlView->marbleModel()->bookmarkManager()->setShowBookmarks( show ); m_toggleBookmarkDisplayAct->setChecked( show ); // Sync state with the GUI } void MainWindow::workOffline( bool offline ) { m_controlView->setWorkOffline( offline ); m_workOfflineAct->setChecked( offline ); // Sync state with the GUI } void MainWindow::lockPosition( bool isChecked ) { QList floatItemList = m_controlView->marbleWidget()->floatItems(); QList::const_iterator i = floatItemList.constBegin(); QList::const_iterator const end = floatItemList.constEnd(); for (; i != end; ++i ) { // Locking one would suffice as it affects all. // Nevertheless go through all. (*i)->setPositionLocked(isChecked); } } void MainWindow::controlSun() { if (!m_sunControlDialog) { m_sunControlDialog = new SunControlWidget( m_controlView->marbleWidget(), this ); connect( m_sunControlDialog, SIGNAL(showSun(bool)), this, SLOT (showSun(bool)) ); } m_sunControlDialog->show(); m_sunControlDialog->raise(); m_sunControlDialog->activateWindow(); } void MainWindow::controlTime() { if ( !m_timeControlDialog ) { m_timeControlDialog = new TimeControlWidget( m_controlView->marbleModel()->clock() ); } /* m_timeControlDialog is a modeless dialog so that user may adjust time and interact with main application simultaneously.*/ m_timeControlDialog->show(); m_timeControlDialog->raise(); m_timeControlDialog->activateWindow(); } void MainWindow::showSun( bool active ) { m_controlView->marbleWidget()->setShowSunShading( active ); } void MainWindow::reload() { m_controlView->marbleWidget()->reloadMap(); } void MainWindow::enterWhatsThis() { QWhatsThis::enterWhatsThisMode(); } void MainWindow::aboutMarble() { MarbleAboutDialog dlg(this); dlg.setApplicationTitle( tr( "Marble Virtual Globe %1" ).arg( ControlView::applicationVersion() ) ); dlg.exec(); } void MainWindow::handbook() { const QString code = MarbleLocale::languageCode(); QUrl handbookLocation( "http://docs.kde.org/stable/" + code + "/kdeedu/marble/index.html" ); if ( handbookLocation.isEmpty() ) handbookLocation = QUrl("http://docs.kde.org/stable/en/kdeedu/marble/index.html"); if( !QDesktopServices::openUrl( handbookLocation ) ) qDebug() << "URL not opened"; } void MainWindow::showPosition( const QString& position ) { m_position = position; updateStatusBar(); } void MainWindow::showDistance( const QString& distance ) { m_distance = distance; updateStatusBar(); } void MainWindow::showZoom( int zoom ) { m_zoom = QString::number( zoom ); updateStatusBar(); } void MainWindow::showDateTime() { m_clock = QLocale().toString( m_controlView->marbleModel()->clockDateTime().addSecs( m_controlView->marbleModel()->clockTimezone() ), QLocale::ShortFormat ); updateStatusBar(); } void MainWindow::updateStatusBar() { if ( m_positionLabel ) m_positionLabel->setText( QString( "%1 %2" ). arg( tr( POSITION_STRING ) ).arg( m_position ) ); if ( m_distanceLabel ) m_distanceLabel->setText( QString( "%1 %2" ) .arg( tr( DISTANCE_STRING ) ).arg( m_distance ) ); if ( m_zoomLabel ) m_zoomLabel->setText( QString( "%1 %2" ) .arg( tr( ZOOM_STRING ) ).arg( m_zoom ) ); if ( m_clockLabel ) m_clockLabel->setText( QString( "%1 %2" ) .arg( tr( DATETIME_STRING ) ).arg( m_clock ) ); } void MainWindow::openFile() { const PluginManager *const pluginManager = m_controlView->marbleModel()->pluginManager(); QStringList allFileExtensions; QStringList filters; foreach ( const ParseRunnerPlugin *plugin, pluginManager->parsingRunnerPlugins() ) { if ( plugin->nameId() == "Cache" ) continue; const QStringList fileExtensions = plugin->fileExtensions().replaceInStrings( QRegExp( "^" ), "*." ); const QString filter = QString( "%1 (%2)" ).arg( plugin->fileFormatDescription() ).arg( fileExtensions.join( " " ) ); filters << filter; allFileExtensions << fileExtensions; } allFileExtensions.sort(); // sort since file extensions are visible under Windows const QString allFileTypes = QString( "%1 (%2)" ).arg( tr( "All Supported Files" ) ).arg( allFileExtensions.join( " " ) ); filters.sort(); filters.prepend( allFileTypes ); const QString filter = filters.join( ";;" ); QStringList fileNames = QFileDialog::getOpenFileNames( this, tr( "Open File" ), m_lastFileOpenPath, filter ); if ( !fileNames.isEmpty() ) { const QString firstFile = fileNames.first(); m_lastFileOpenPath = QFileInfo( firstFile ).absolutePath(); } foreach( const QString &fileName, fileNames ) { m_controlView->marbleModel()->addGeoDataFile( fileName ); } } void MainWindow::setupStatusBar() { statusBar()->setSizeGripEnabled( true ); statusBar()->setContextMenuPolicy( Qt::ActionsContextMenu ); QAction* toggleTileLevelAction = new QAction( "Show zoom level", statusBar() ); toggleTileLevelAction->setCheckable( true ); toggleTileLevelAction->setChecked( false ); connect( toggleTileLevelAction, SIGNAL(triggered(bool)), this, SLOT(showZoomLevel(bool)) ); statusBar()->addAction( toggleTileLevelAction ); setupDownloadProgressBar(); m_positionLabel = new QLabel( ); m_positionLabel->setIndent( 5 ); QString templatePositionString = QString( "%1 000\xb0 00\' 00\"_, 000\xb0 00\' 00\"_" ).arg(POSITION_STRING); int maxPositionWidth = fontMetrics().boundingRect(templatePositionString).width() + 2 * m_positionLabel->margin() + 2 * m_positionLabel->indent(); m_positionLabel->setFixedWidth( maxPositionWidth ); statusBar()->addPermanentWidget ( m_positionLabel ); m_distanceLabel = new QLabel( ); m_distanceLabel->setIndent( 5 ); QString templateDistanceString = QString( "%1 00.000,0 mu" ).arg(DISTANCE_STRING); int maxDistanceWidth = fontMetrics().boundingRect(templateDistanceString).width() + 2 * m_distanceLabel->margin() + 2 * m_distanceLabel->indent(); m_distanceLabel->setFixedWidth( maxDistanceWidth ); statusBar()->addPermanentWidget ( m_distanceLabel ); m_zoomLabel = new QLabel( ); m_zoomLabel->setIndent( 5 ); QString templateZoomString = QString( "%1 00" ).arg(ZOOM_STRING); int maxZoomWidth = fontMetrics().boundingRect(templateZoomString).width() + 2 * m_zoomLabel->margin() + 2 * m_zoomLabel->indent(); m_zoomLabel->setFixedWidth( maxZoomWidth ); // Not added here, but activated by the user with the context menu m_clockLabel = new QLabel( ); m_clockLabel->setIndent( 5 ); QString templateDateTimeString = QString( "%1 %2" ).arg( DATETIME_STRING , QLocale().toString( QDateTime::fromString ( "01:01:1000", "dd:mm:yyyy"), QLocale::ShortFormat ) ); int maxDateTimeWidth = fontMetrics().boundingRect( templateDateTimeString ).width() + 2 * m_clockLabel->margin() + 2 * m_clockLabel->indent(); m_clockLabel->setFixedWidth( maxDateTimeWidth ); statusBar()->addPermanentWidget ( m_clockLabel ); connect( marbleWidget(), SIGNAL(mouseMoveGeoPosition(QString)), this, SLOT(showPosition(QString)) ); connect( marbleWidget(), SIGNAL(distanceChanged(QString)), this, SLOT(showDistance(QString)) ); connect( marbleWidget(), SIGNAL(tileLevelChanged(int)), this, SLOT(showZoom(int)) ); connect( m_controlView->marbleModel()->clock(), SIGNAL(timeChanged()), this, SLOT(showDateTime()) ); updateStatusBar(); } void MainWindow::setupDownloadProgressBar() { m_downloadProgressBar = new QProgressBar; m_downloadProgressBar->setVisible( true ); statusBar()->addPermanentWidget( m_downloadProgressBar ); HttpDownloadManager * const downloadManager = m_controlView->marbleModel()->downloadManager(); Q_ASSERT( downloadManager ); connect( downloadManager, SIGNAL(jobAdded()), SLOT(downloadJobAdded()) ); connect( downloadManager, SIGNAL(jobRemoved()), SLOT(downloadJobRemoved()) ); } void MainWindow::downloadJobAdded(){ m_downloadProgressBar->setUpdatesEnabled( false ); if ( m_downloadProgressBar->value() < 0 ) { m_downloadProgressBar->setMaximum( 1 ); m_downloadProgressBar->setValue( 0 ); m_downloadProgressBar->setVisible( true ); } else { m_downloadProgressBar->setMaximum( m_downloadProgressBar->maximum() + 1 ); } m_downloadProgressBar->setUpdatesEnabled( true ); } void MainWindow::downloadJobRemoved(){ m_downloadProgressBar->setUpdatesEnabled( false ); m_downloadProgressBar->setValue( m_downloadProgressBar->value() + 1 ); if ( m_downloadProgressBar->value() == m_downloadProgressBar->maximum() ) { m_downloadProgressBar->reset(); m_downloadProgressBar->setVisible( false ); } m_downloadProgressBar->setUpdatesEnabled( true ); } void MainWindow::closeEvent(QCloseEvent *event) { writeSettings(); event->accept(); } QString MainWindow::readMarbleDataPath() { QSettings settings; settings.beginGroup("MarbleWidget"); QString marbleDataPath; marbleDataPath = settings.value("marbleDataPath", "").toString(), settings.endGroup(); return marbleDataPath; } void MainWindow::readSettings(const QVariantMap& overrideSettings) { QSettings settings; settings.beginGroup("MainWindow"); resize(settings.value("size", QSize(640, 480)).toSize()); move(settings.value("pos", QPoint(200, 200)).toPoint()); showFullScreen(settings.value("fullScreen", false ).toBool()); showStatusBar(settings.value("statusBar", false ).toBool()); show(); showClouds(settings.value("showClouds", true ).toBool()); workOffline(settings.value("workOffline", false ).toBool()); m_controlView->marbleWidget()->setShowAtmosphere(settings.value("showAtmosphere", true ).toBool()); m_lastFileOpenPath = settings.value("lastFileOpenDir", QDir::homePath()).toString(); showBookmarks( settings.value( "showBookmarks", true ).toBool() ); restoreState( settings.value("windowState").toByteArray() ); settings.endGroup(); setUpdatesEnabled(false); settings.beginGroup("MarbleWidget"); QString mapThemeId; const QVariantMap::ConstIterator mapThemeIdIt = overrideSettings.find(QLatin1String("mapTheme")); if ( mapThemeIdIt != overrideSettings.constEnd() ) { mapThemeId = mapThemeIdIt.value().toString(); } else { mapThemeId = settings.value("mapTheme", m_controlView->defaultMapThemeId() ).toString(); } mDebug() << Q_FUNC_INFO << "mapThemeId:" << mapThemeId; m_controlView->marbleWidget()->setMapThemeId( mapThemeId ); m_controlView->marbleWidget()->setProjection( (Projection)(settings.value("projection", Spherical ).toInt()) ); // Set home position m_controlView->marbleModel()->setHome( settings.value("homeLongitude", 9.4).toDouble(), settings.value("homeLatitude", 54.8).toDouble(), settings.value("homeZoom", 1050 ).toInt() ); // Center on/Distance const QVariantMap::ConstIterator distanceIt = overrideSettings.find(QLatin1String("distance")); const bool isDistanceOverwritten = (distanceIt != overrideSettings.constEnd()); const QVariantMap::ConstIterator lonLatIt = overrideSettings.find(QLatin1String("lonlat")); if ( lonLatIt != overrideSettings.constEnd() ) { const QVariantList lonLat = lonLatIt.value().toList(); m_controlView->marbleWidget()->centerOn( lonLat.at(0).toDouble(), lonLat.at(1).toDouble() ); } else { switch ( m_configDialog->onStartup() ) { case Marble::LastLocationVisited: m_controlView->marbleWidget()->centerOn( settings.value("quitLongitude", 0.0).toDouble(), settings.value("quitLatitude", 0.0).toDouble() ); if (! isDistanceOverwritten) { // set default radius to 1350 (Atlas theme's "sharp" radius) m_controlView->marbleWidget()->setRadius( settings.value("quitRadius", 1350).toInt() ); } break; case Marble::ShowHomeLocation: m_controlView->marbleWidget()->goHome(); break; default: break; } } if (isDistanceOverwritten) { m_controlView->marbleWidget()->setDistance(distanceIt.value().toDouble()); } bool isLocked = settings.value( "lockFloatItemPositions", false ).toBool(); m_lockFloatItemsAct->setChecked( isLocked ); lockPosition(isLocked); settings.endGroup(); settings.beginGroup( "Sun" ); m_controlView->marbleWidget()->setShowSunShading( settings.value( "showSun", false ).toBool() ); m_controlView->marbleWidget()->setShowCityLights( settings.value( "showCitylights", false ).toBool() ); m_controlView->marbleWidget()->setLockToSubSolarPoint( settings.value( "lockToSubSolarPoint", false ).toBool() ); m_controlView->marbleWidget()->setSubSolarPointIconVisible( settings.value( "subSolarPointIconVisible", false ).toBool() ); settings.endGroup(); settings.beginGroup( "Time" ); if( settings.value( "systemTime", "true" ).toBool() == true ) { /* nothing to do */ } else if( settings.value( "lastSessionTime", "true" ).toBool() == true ) { m_controlView->marbleModel()->setClockDateTime( settings.value( "dateTime" ).toDateTime() ); m_controlView->marbleModel()->setClockSpeed( settings.value( "speedSlider", 1 ).toInt() ); } settings.endGroup(); setUpdatesEnabled(true); // Load previous route settings settings.beginGroup( "Routing" ); { RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager(); routingManager->readSettings(); bool const startupWarning = settings.value( "showGuidanceModeStartupWarning", QVariant( true ) ).toBool(); routingManager->setShowGuidanceModeStartupWarning( startupWarning ); routingManager->setLastOpenPath( settings.value( "lastRouteOpenPath", QDir::homePath() ).toString() ); routingManager->setLastSavePath( settings.value( "lastRouteSavePath", QDir::homePath() ).toString() ); QColor tempColor; tempColor = QColor( settings.value( "routeColorStandard", Oxygen::skyBlue4.name() ).toString() ); tempColor.setAlpha( settings.value( "routeAlphaStandard", 200 ).toInt() ); routingManager->setRouteColorStandard( tempColor ); tempColor = QColor( settings.value( "routeColorHighlighted", Oxygen::skyBlue1.name() ).toString() ); tempColor.setAlpha( settings.value( "routeAlphaHighlighted", 200 ).toInt() ); routingManager->setRouteColorHighlighted( tempColor ); tempColor = QColor( settings.value( "routeColorAlternative", Oxygen::aluminumGray4.name() ).toString() ); tempColor.setAlpha( settings.value( "routeAlphaAlternative", 200 ).toInt() ); routingManager->setRouteColorAlternative( tempColor ); } settings.endGroup(); settings.beginGroup( "Routing Profile" ); if ( settings.contains( "Num" ) ) { QList profiles; int numProfiles = settings.value( "Num", 0 ).toInt(); for ( int i = 0; i < numProfiles; ++i ) { settings.beginGroup( QString( "Profile %0" ).arg(i) ); QString name = settings.value( "Name", tr( "Unnamed" ) ).toString(); RoutingProfile profile( name ); foreach ( const QString& pluginName, settings.childGroups() ) { settings.beginGroup( pluginName ); profile.pluginSettings().insert( pluginName, QHash() ); foreach ( const QString& key, settings.childKeys() ) { if ( key != "Enabled" ) { profile.pluginSettings()[ pluginName ].insert( key, settings.value( key ) ); } } settings.endGroup(); } profiles << profile; settings.endGroup(); } m_controlView->marbleModel()->routingManager()->profilesModel()->setProfiles( profiles ); } else { m_controlView->marbleModel()->routingManager()->profilesModel()->loadDefaultProfiles(); } int const profileIndex = settings.value( "currentIndex", 0 ).toInt(); if ( profileIndex >= 0 && profileIndex < m_controlView->marbleModel()->routingManager()->profilesModel()->rowCount() ) { RoutingProfile profile = m_controlView->marbleModel()->routingManager()->profilesModel()->profiles().at( profileIndex ); m_controlView->marbleModel()->routingManager()->routeRequest()->setRoutingProfile( profile ); } settings.endGroup(); settings.beginGroup( "Plugins"); PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); tracking->readSettings(); QString positionProvider = settings.value( "activePositionTrackingPlugin", QString() ).toString(); if ( !positionProvider.isEmpty() ) { const PluginManager* pluginManager = m_controlView->marbleModel()->pluginManager(); foreach( const PositionProviderPlugin* plugin, pluginManager->positionProviderPlugins() ) { if ( plugin->nameId() == positionProvider ) { PositionProviderPlugin* instance = plugin->newInstance(); instance->setMarbleModel( m_controlView->marbleModel() ); tracking->setPositionProviderPlugin( instance ); break; } } } settings.endGroup(); settings.beginGroup( "Tracking" ); if ( settings.contains( "autoCenter" ) || settings.contains( "recenterMode" ) ) { CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget(); Q_ASSERT( trackingWidget ); trackingWidget->setRecenterMode( settings.value( "recenterMode", 0 ).toInt() ); trackingWidget->setAutoZoom( settings.value( "autoZoom", false ).toBool() ); trackingWidget->setTrackVisible( settings.value( "trackVisible", true ).toBool() ); trackingWidget->setLastOpenPath( settings.value( "lastTrackOpenPath", QDir::homePath() ).toString() ); trackingWidget->setLastSavePath( settings.value( "lastTrackSavePath", QDir::homePath() ).toString() ); } settings.endGroup(); // The config dialog has to read settings. m_configDialog->readSettings(); settings.beginGroup( "Navigation" ); m_controlView->setExternalMapEditor( settings.value( "externalMapEditor", "" ).toString() ); settings.endGroup(); settings.beginGroup( "CloudSync" ); m_configDialog->setShowCloudSync( settings.value( "showCloudSyncSettings", false ).toBool() ); CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); cloudSyncManager->setOwncloudServer( settings.value( "owncloudServer", "" ).toString() ); cloudSyncManager->setOwncloudUsername( settings.value( "owncloudUsername", "" ).toString() ); cloudSyncManager->setOwncloudPassword( settings.value( "owncloudPassword", "" ).toString() ); cloudSyncManager->setSyncEnabled( settings.value( "enableSync", false ).toBool() ); cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( settings.value( "syncRoutes", true ).toBool() ); cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( settings.value( "syncBookmarks", true ).toBool() ); settings.endGroup(); } void MainWindow::writeSettings() { QSettings settings; settings.beginGroup( "MainWindow" ); settings.setValue( "size", size() ); settings.setValue( "pos", pos() ); settings.setValue( "fullScreen", m_fullScreenAct->isChecked() ); settings.setValue( "statusBar", m_statusBarAct->isChecked() ); settings.setValue( "showClouds", m_showCloudsAct->isChecked() ); settings.setValue( "workOffline", m_workOfflineAct->isChecked() ); settings.setValue( "showAtmosphere", m_controlView->marbleWidget()->showAtmosphere() ); settings.setValue( "lastFileOpenDir", m_lastFileOpenPath ); settings.setValue( "showBookmarks", m_toggleBookmarkDisplayAct->isChecked() ); settings.setValue( "windowState", saveState() ); settings.endGroup(); settings.beginGroup( "MarbleWidget" ); // Get the 'home' values from the widget and store them in the settings. qreal homeLon = 0; qreal homeLat = 0; int homeZoom = 0; m_controlView->marbleModel()->home( homeLon, homeLat, homeZoom ); QString mapTheme = m_controlView->marbleWidget()->mapThemeId(); int projection = (int)( m_controlView->marbleWidget()->projection() ); settings.setValue( "homeLongitude", homeLon ); settings.setValue( "homeLatitude", homeLat ); settings.setValue( "homeZoom", homeZoom ); settings.setValue( "mapTheme", mapTheme ); settings.setValue( "projection", projection ); // Get the 'quit' values from the widget and store them in the settings. qreal quitLon = m_controlView->marbleWidget()->centerLongitude(); qreal quitLat = m_controlView->marbleWidget()->centerLatitude(); const int quitRadius = m_controlView->marbleWidget()->radius(); settings.setValue( "quitLongitude", quitLon ); settings.setValue( "quitLatitude", quitLat ); settings.setValue( "quitRadius", quitRadius ); settings.setValue( "lockFloatItemPositions", m_lockFloatItemsAct->isChecked() ); settings.endGroup(); settings.beginGroup( "Sun" ); settings.setValue( "showSun", m_controlView->marbleWidget()->showSunShading() ); settings.setValue( "showCitylights", m_controlView->marbleWidget()->showCityLights() ); settings.setValue( "lockToSubSolarPoint", m_controlView->marbleWidget()->isLockedToSubSolarPoint() ); settings.setValue( "subSolarPointIconVisible", m_controlView->marbleWidget()->isSubSolarPointIconVisible() ); settings.endGroup(); settings.beginGroup( "Time" ); settings.setValue( "dateTime", m_controlView->marbleModel()->clockDateTime() ); settings.setValue( "speedSlider", m_controlView->marbleModel()->clockSpeed() ); settings.endGroup(); settings.beginGroup( "Routing Profile" ); QList profiles = m_controlView->marbleWidget() ->model()->routingManager()->profilesModel()->profiles(); settings.setValue( "Num", profiles.count() ); for ( int i = 0; i < profiles.count(); ++i ) { settings.beginGroup( QString( "Profile %0" ).arg(i) ); const RoutingProfile& profile = profiles.at( i ); settings.setValue( "Name", profile.name() ); foreach ( const QString& pluginName, settings.childGroups() ) { settings.beginGroup( pluginName ); settings.remove( "" ); //remove all keys settings.endGroup(); } foreach ( const QString &key, profile.pluginSettings().keys() ) { settings.beginGroup( key ); settings.setValue( "Enabled", true ); foreach ( const QString& settingKey, profile.pluginSettings()[ key ].keys() ) { Q_ASSERT( settingKey != "Enabled" ); settings.setValue( settingKey, profile.pluginSettings()[ key ][ settingKey ] ); } settings.endGroup(); } settings.endGroup(); } RoutingProfile const profile = m_controlView->marbleWidget()->model()->routingManager()->routeRequest()->routingProfile(); settings.setValue( "currentIndex", profiles.indexOf( profile ) ); settings.endGroup(); settings.beginGroup( "Plugins"); QString positionProvider; PositionTracking* tracking = m_controlView->marbleModel()->positionTracking(); tracking->writeSettings(); if ( tracking && tracking->positionProviderPlugin() ) { positionProvider = tracking->positionProviderPlugin()->nameId(); } settings.setValue( "activePositionTrackingPlugin", positionProvider ); settings.endGroup(); settings.beginGroup( "Tracking" ); CurrentLocationWidget* trackingWidget = m_controlView->currentLocationWidget(); if ( trackingWidget ) { // Can be null due to lazy initialization settings.setValue( "recenterMode", trackingWidget->recenterMode() ); settings.setValue( "autoZoom", trackingWidget->autoZoom() ); settings.setValue( "trackVisible", trackingWidget->trackVisible() ); settings.setValue( "lastTrackOpenPath", trackingWidget->lastOpenPath() ); settings.setValue( "lastTrackSavePath", trackingWidget->lastSavePath() ); } settings.endGroup(); // The config dialog has to write settings. m_configDialog->writeSettings(); // Store current route settings settings.beginGroup( "Routing" ); { RoutingManager *const routingManager = m_controlView->marbleModel()->routingManager(); routingManager->writeSettings(); settings.setValue( "showGuidanceModeStartupWarning", routingManager->showGuidanceModeStartupWarning() ); settings.setValue( "lastRouteOpenPath", routingManager->lastOpenPath() ); settings.setValue( "lastRouteSavePath", routingManager->lastSavePath() ); settings.setValue( "routeColorStandard", routingManager->routeColorStandard().name() ); settings.setValue( "routeAlphaStandard", routingManager->routeColorStandard().alpha() ); settings.setValue( "routeColorHighlighted", routingManager->routeColorHighlighted().name() ); settings.setValue( "routeAlphaHighlighted", routingManager->routeColorHighlighted().alpha() ); settings.setValue( "routeColorAlternative", routingManager->routeColorAlternative().name() ); settings.setValue( "routeAlphaAlternative", routingManager->routeColorAlternative().alpha() ); } settings.endGroup(); settings.beginGroup( "Navigation"); settings.setValue( "externalMapEditor", m_controlView->externalMapEditor() ); settings.endGroup(); } void MainWindow::editSettings() { // Show the settings dialog. m_configDialog->show(); m_configDialog->raise(); m_configDialog->activateWindow(); } void MainWindow::updateSettings() { mDebug() << Q_FUNC_INFO << "Updating Settings ..."; // FIXME: Font doesn't get updated instantly. m_controlView->marbleWidget()->setDefaultFont( m_configDialog->mapFont() ); m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->stillQuality(), Marble::Still ); m_controlView->marbleWidget()->setMapQualityForViewContext( m_configDialog->animationQuality(), Marble::Animation ); m_controlView->marbleWidget()->setDefaultAngleUnit( m_configDialog->angleUnit() ); MarbleGlobal::getInstance()->locale()->setMeasurementSystem( m_configDialog->measurementSystem() ); m_distance = m_controlView->marbleWidget()->distanceString(); updateStatusBar(); m_controlView->marbleWidget()->setAnimationsEnabled( m_configDialog->animateTargetVoyage() ); m_controlView->marbleWidget()->inputHandler()->setInertialEarthRotationEnabled( m_configDialog->inertialEarthRotation() ); if ( !m_configDialog->externalMapEditor().isEmpty() ) { m_controlView->setExternalMapEditor( m_configDialog->externalMapEditor() ); } // Cache m_controlView->marbleModel()->setPersistentTileCacheLimit( m_configDialog->persistentTileCacheLimit() * 1024 ); m_controlView->marbleWidget()->setVolatileTileCacheLimit( m_configDialog->volatileTileCacheLimit() * 1024 ); /* m_controlView->marbleWidget()->setProxy( m_configDialog->proxyUrl(), m_configDialog->proxyPort(), m_configDialog->user(), m_configDialog->password() ); */ CloudSyncManager* cloudSyncManager = m_controlView->cloudSyncManager(); cloudSyncManager->setOwncloudServer( m_configDialog->owncloudServer() ); cloudSyncManager->setOwncloudUsername( m_configDialog->owncloudUsername() ); cloudSyncManager->setOwncloudPassword( m_configDialog->owncloudPassword() ); cloudSyncManager->setSyncEnabled( m_configDialog->syncEnabled() ); cloudSyncManager->routeSyncManager()->setRouteSyncEnabled( m_configDialog->syncRoutes() ); cloudSyncManager->bookmarkSyncManager()->setBookmarkSyncEnabled( m_configDialog->syncBookmarks() ); m_controlView->marbleWidget()->update(); } void MainWindow::showDownloadRegionDialog() { if ( !m_downloadRegionDialog ) { m_downloadRegionDialog = new DownloadRegionDialog( m_controlView->marbleWidget(), m_controlView ); // it might be tempting to move the connects to DownloadRegionDialog's "accepted" and // "applied" signals, be aware that the "hidden" signal might be come before the "accepted" // signal, leading to a too early disconnect. connect( m_downloadRegionDialog, SIGNAL(accepted()), SLOT(downloadRegion())); connect( m_downloadRegionDialog, SIGNAL(applied()), SLOT(downloadRegion())); } // FIXME: get allowed range from current map theme m_downloadRegionDialog->setAllowedTileLevelRange( 0, 16 ); m_downloadRegionDialog->setSelectionMethod( DownloadRegionDialog::VisibleRegionMethod ); ViewportParams const * const viewport = m_controlView->marbleWidget()->viewport(); m_downloadRegionDialog->setSpecifiedLatLonAltBox( viewport->viewLatLonAltBox() ); m_downloadRegionDialog->setVisibleLatLonAltBox( viewport->viewLatLonAltBox() ); m_downloadRegionDialog->show(); m_downloadRegionDialog->raise(); m_downloadRegionDialog->activateWindow(); } void MainWindow::downloadRegion() { Q_ASSERT( m_downloadRegionDialog ); QVector const pyramid = m_downloadRegionDialog->region(); if ( !pyramid.isEmpty() ) { m_controlView->marbleWidget()->downloadRegion( pyramid ); } } void MainWindow::printMapScreenShot() { #ifndef QT_NO_PRINTER QPrinter printer( QPrinter::HighResolution ); QPointer printDialog = new QPrintDialog( &printer, this ); m_controlView->printMapScreenShot( printDialog ); delete printDialog; #endif } void MainWindow::updateMapEditButtonVisibility( const QString &mapTheme ) { Q_ASSERT( m_osmEditAction ); m_osmEditAction->setVisible( mapTheme == "earth/openstreetmap/openstreetmap.dgml" ); } void MainWindow::showMapWizard() { QPointer mapWizard = new MapWizard(); QSettings settings; settings.beginGroup( "MapWizard" ); mapWizard->setWmsServers( settings.value( "wmsServers" ).toStringList() ); mapWizard->setStaticUrlServers( settings.value( "staticUrlServers" ).toStringList() ); settings.endGroup(); mapWizard->exec(); settings.beginGroup( "MapWizard" ); settings.setValue( "wmsServers", mapWizard->wmsServers() ); settings.setValue( "staticUrlServers", mapWizard->staticUrlServers() ); settings.endGroup(); mapWizard->deleteLater(); } void MainWindow::showZoomLevel(bool show) { if ( show ) { m_zoomLabel->show(); statusBar()->insertPermanentWidget( 2, m_zoomLabel ); } else { statusBar()->removeWidget( m_zoomLabel ); } } void MainWindow::fallBackToDefaultTheme() { m_controlView->marbleWidget()->setMapThemeId( m_controlView->defaultMapThemeId() ); } -#include "QtMainWindow.moc" +//#include "QtMainWindow.moc" diff --git a/src/lib/marble/CMakeLists.txt b/src/lib/marble/CMakeLists.txt index bda9d4a3b..876705503 100644 --- a/src/lib/marble/CMakeLists.txt +++ b/src/lib/marble/CMakeLists.txt @@ -1,509 +1,510 @@ PROJECT(marblewidget) if (QTONLY) cmake_minimum_required(VERSION 2.4.0) endif (QTONLY) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/projections ${CMAKE_CURRENT_SOURCE_DIR}/routing ${CMAKE_CURRENT_SOURCE_DIR}/geodata ${CMAKE_CURRENT_SOURCE_DIR}/geodata/data ${CMAKE_CURRENT_SOURCE_DIR}/geodata/graphicsitem ${CMAKE_CURRENT_SOURCE_DIR}/geodata/scene ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers/kml ${CMAKE_CURRENT_SOURCE_DIR}/geodata/handlers/dgml ${CMAKE_CURRENT_SOURCE_DIR}/geodata/parser ${CMAKE_CURRENT_SOURCE_DIR}/graphicsview ${CMAKE_CURRENT_SOURCE_DIR}/layers ${CMAKE_CURRENT_SOURCE_DIR}/cloudsync ${QT_INCLUDE_DIR} ) if( QT4_FOUND ) INCLUDE(${QT_USE_FILE}) else() INCLUDE_DIRECTORIES( ${Qt5WebKitWidgets_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Concurrent_INCLUDE_DIRS} ) endif() INCLUDE(geodata/CMakeLists.txt) INCLUDE(graphicsview/CMakeLists.txt) INCLUDE(layers/CMakeLists.txt) set(GENERIC_LIB_VERSION "0.17.0") set(GENERIC_LIB_SOVERSION "17") if (QTONLY) # ce: don't know why this is needed here - on win32 'O2' is activated by default in release mode if(NOT WIN32) add_definitions (${QT_DEFINITIONS} -O3) endif(NOT WIN32) include_directories( ${QT_INCLUDE_DIR} ) else (QTONLY) if(NOT WIN32) add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -O3) endif(NOT WIN32) include_directories( ${KDE4_INCLUDES} ) endif (QTONLY) # link_directories (${QT_LIBRARY_DIR}) ########### next target ############### set(marblewidget_SRCS ${geodata_SRCS} ${graphicsview_SRCS} ${layers_SRCS} blendings/Blending.cpp blendings/BlendingAlgorithms.cpp blendings/BlendingFactory.cpp blendings/SunLightBlending.cpp DownloadRegion.cpp DownloadRegionDialog.cpp LatLonBoxWidget.cpp MarbleWidget.cpp MarbleWebView.cpp MarbleModel.cpp MarbleMap.cpp MarbleControlBox.cpp NavigationWidget.cpp MapViewWidget.cpp FileViewWidget.cpp LegendWidget.cpp CurrentLocationWidget.cpp MarbleNavigator.cpp MarbleLegendBrowser.cpp MarbleAboutDialog.cpp MarbleWidgetInputHandler.cpp MarbleWidgetPopupMenu.cpp MarblePlacemarkModel.cpp GeoDataTreeModel.cpp kdescendantsproxymodel.cpp BranchFilterProxyModel.cpp MarbleDebug.cpp Tile.cpp TextureTile.cpp TileCoordsPyramid.cpp TileLevelRangeWidget.cpp TileLoader.cpp QtMarbleConfigDialog.cpp ClipPainter.cpp DownloadPolicy.cpp DownloadQueueSet.cpp GeoPainter.cpp GeoPolygon.cpp HttpDownloadManager.cpp HttpJob.cpp LayerManager.cpp PluginManager.cpp TimeControlWidget.cpp AbstractFloatItem.cpp PopupItem.cpp MarbleGlobal.cpp MarbleDirs.cpp MarbleLocale.cpp MarblePhysics.cpp DeferredFlag.cpp TileCreatorDialog.cpp MapThemeManager.cpp ViewportParams.cpp ViewParams.cpp projections/AbstractProjection.cpp projections/CylindricalProjection.cpp projections/SphericalProjection.cpp projections/EquirectProjection.cpp projections/MercatorProjection.cpp VisiblePlacemark.cpp PlacemarkLayout.cpp Planet.cpp Quaternion.cpp TextureColorizer.cpp TextureMapperInterface.cpp ScanlineTextureMapperContext.cpp SphericalScanlineTextureMapper.cpp EquirectScanlineTextureMapper.cpp MercatorScanlineTextureMapper.cpp TileScalingTextureMapper.cpp VectorTileModel.cpp DiscCache.cpp ServerLayout.cpp StoragePolicy.cpp CacheStoragePolicy.cpp FileStoragePolicy.cpp FileStorageWatcher.cpp StackedTile.cpp TileId.cpp StackedTileLoader.cpp TileLoaderHelper.cpp TileCreator.cpp TinyWebBrowser.cpp #jsonparser.cpp VectorComposer.cpp VectorMap.cpp FileLoader.cpp FileManager.cpp PositionTracking.cpp DataMigration.cpp ImageF.cpp AbstractDataPlugin.cpp AbstractDataPluginModel.cpp AbstractDataPluginItem.cpp AbstractWorkerThread.cpp PluginInterface.cpp DialogConfigurationInterface.cpp LayerInterface.cpp RenderPlugin.cpp RenderPluginInterface.cpp PositionProviderPlugin.cpp PositionProviderPluginInterface.cpp MarblePluginSettingsWidget.cpp RenderPluginModel.cpp PluginAboutDialog.cpp PluginItemDelegate.cpp SunLocator.cpp MarbleClock.cpp SunControlWidget.cpp MergedLayerDecorator.cpp MathHelper.cpp LatLonEdit.cpp MapThemeSortFilterProxyModel.cpp TemplateDocument.cpp routing/AlternativeRoutesModel.cpp routing/Maneuver.cpp routing/Route.cpp routing/RouteRequest.cpp routing/RouteSegment.cpp routing/RoutingModel.cpp routing/RoutingProfile.cpp routing/RoutingManager.cpp routing/RoutingLayer.cpp routing/RoutingInputWidget.cpp routing/RoutingWidget.cpp routing/RoutingProfilesWidget.cpp routing/RoutingProfilesModel.cpp routing/RoutingProfileSettingsDialog.cpp routing/SpeakersModel.cpp routing/VoiceNavigationModel.cpp routing/instructions/InstructionTransformation.cpp routing/instructions/RoutingInstruction.cpp routing/instructions/RoutingPoint.cpp routing/instructions/RoutingWaypoint.cpp routing/instructions/WaypointParser.cpp ParsingRunnerManager.cpp ReverseGeocodingRunnerManager.cpp RoutingRunnerManager.cpp SearchRunnerManager.cpp AutoNavigation.cpp SearchRunnerPlugin.cpp ReverseGeocodingRunnerPlugin.cpp RoutingRunnerPlugin.cpp ParseRunnerPlugin.cpp SearchRunner.cpp ReverseGeocodingRunner.cpp RoutingRunner.cpp ParsingRunner.cpp RunnerTask.cpp BookmarkManager.cpp EditBookmarkDialog.cpp BookmarkManagerDialog.cpp NewBookmarkFolderDialog.cpp PrintOptionsWidget.cpp ExternalEditorDialog.cpp GoToDialog.cpp MapWizard.cpp MapThemeDownloadDialog.cpp GeoGraphicsScene.cpp ElevationModel.cpp MarbleLineEdit.cpp SearchInputWidget.cpp SearchWidget.cpp kineticmodel.cpp NewstuffModel.cpp cloudsync/CloudSyncManager.cpp cloudsync/RouteSyncManager.cpp cloudsync/OwncloudSyncBackend.cpp cloudsync/CloudRouteModel.cpp cloudsync/CloudRoutesDialog.cpp cloudsync/RouteItem.cpp cloudsync/RouteItemDelegate.cpp cloudsync/BookmarkSyncManager.cpp cloudsync/MergeItem.cpp cloudsync/ConflictDialog.cpp ) set (marblewidget_UI LatLonBoxWidget.ui NavigationWidget.ui LegendWidget.ui MapViewWidget.ui CurrentLocationWidget.ui FileViewWidget.ui MarbleNavigator.ui MarbleCacheSettingsWidget.ui MarbleViewSettingsWidget.ui MarbleNavigationSettingsWidget.ui TimeControlWidget.ui MarbleTimeSettingsWidget.ui MarblePluginSettingsWidget.ui TileCreatorDialog.ui TileLevelRangeWidget.ui MarbleAboutDialog.ui SunControlWidget.ui LatLonEdit.ui routing/RoutingWidget.ui DataMigrationWidget.ui EditBookmarkDialog.ui BookmarkManagerDialog.ui NewBookmarkFolderDialog.ui PrintOptions.ui ExternalEditor.ui GoToDialog.ui routing/RoutingSettingsWidget.ui routing/RoutingProfileSettingsDialog.ui MapWizard.ui MapThemeDownloadDialog.ui WebPopupWidget.ui cloudsync/CloudRoutesDialog.ui MarbleCloudSyncSettingsWidget.ui ) # FIXME: cleaner approach of src/lib/marblwidget/MarbleControlBox.* vs. marble.qrc qt_add_resources(marblewidget_SRCS libmarble.qrc ../../apps/marble-ui/marble.qrc) qt_wrap_ui(marblewidget_SRCS ${marblewidget_UI}) marble_qt4_automoc(${marblewidget_SRCS}) # link with release version of Qt libs ADD_LIBRARY(marblewidget SHARED ${marblewidget_SRCS} ${SOURCES_UI_HDRS}) if( QT4_FOUND ) TARGET_LINK_LIBRARIES (marblewidget ${QT_QTCORE_LIBRARY} ${QT_QTDBUS_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTSVG_LIBRARY} ${QT_QTNETWORK_LIBRARY} ${QT_QTSCRIPT_LIBRARY} ${QT_QTMAIN_LIBRARY} ${QT_QTWEBKIT_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY} ) else() TARGET_LINK_LIBRARIES (marblewidget ${Qt5Core_LIBRARIES} ${Qt5Xml_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5WebKitWidgets_LIBRARIES} ${Qt5Svg_LIBRARIES} ${Qt5Script_LIBRARIES} + Qt5::DBus ) endif() if (APPLE) #defined in top level makefile TARGET_LINK_LIBRARIES(marblewidget ${MAC_EXTRA_LIBS} ) endif (APPLE) if (CMAKE_SYSTEM_NAME MATCHES "SunOS") TARGET_LINK_LIBRARIES(marblewidget m) endif (CMAKE_SYSTEM_NAME MATCHES "SunOS") if(WIN32) TARGET_LINK_LIBRARIES(marblewidget ws2_32 imm32 winmm) endif(WIN32) set_target_properties(marblewidget PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} COMPILE_FLAGS "-DKML_LAZY_IMP") # needed for marble_export.h set_target_properties(marblewidget PROPERTIES DEFINE_SYMBOL MAKE_MARBLE_LIB ) # choose the correct target install library path if(WIN32 AND QTONLY) install(TARGETS marblewidget RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) else(WIN32 AND QTONLY) if(APPLE AND QTONLY) install (TARGETS marblewidget LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/Marble.app/Contents/MacOS/lib) else(APPLE AND QTONLY) if(QTONLY) install(TARGETS marblewidget LIBRARY DESTINATION ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}) else(QTONLY) install(TARGETS marblewidget ${INSTALL_TARGETS_DEFAULT_ARGS}) endif(QTONLY) endif(APPLE AND QTONLY) endif(WIN32 AND QTONLY) ########### install files ############### if (APPLE AND QTONLY) # do nothing because we don't put .h files in the bundle else (APPLE AND QTONLY) install( FILES ${graphicsview_HDRS} AutoNavigation.h BookmarkManager.h DownloadRegion.h DownloadRegionDialog.h LatLonBoxWidget.h MarbleWidget.h MarbleWebView.h MarbleMap.h MarbleModel.h MarbleControlBox.h NavigationWidget.h MapViewWidget.h LegendWidget.h FileViewWidget.h CurrentLocationWidget.h MarbleNavigator.h AbstractFloatItem.h MapThemeManager.h MarbleAboutDialog.h MarbleWidgetInputHandler.h MarbleWidgetPopupMenu.h TileId.h TileCoordsPyramid.h TileLevelRangeWidget.h TinyWebBrowser.h QtMarbleConfigDialog.h global.h MarbleColors.h MarbleGlobal.h MarbleDebug.h MarbleDirs.h GeoPainter.h TileCreatorDialog.h ViewportParams.h projections/AbstractProjection.h PositionTracking.h Quaternion.h SunLocator.h ClipPainter.h GeoGraphicsScene.h GeoDataTreeModel.h geodata/data/GeoDataAbstractView.h geodata/data/GeoDataAccuracy.h geodata/data/GeoDataBalloonStyle.h geodata/data/GeoDataColorStyle.h geodata/data/GeoDataContainer.h geodata/data/GeoDataCoordinates.h geodata/data/GeoDataDocument.h geodata/data/GeoDataFeature.h geodata/data/GeoDataFolder.h geodata/data/GeoDataGeometry.h geodata/data/GeoDataGroundOverlay.h geodata/data/GeoDataHotSpot.h geodata/data/GeoDataIconStyle.h geodata/data/GeoDataItemIcon.h geodata/data/GeoDataLabelStyle.h geodata/data/GeoDataLatLonAltBox.h geodata/data/GeoDataLatLonBox.h geodata/data/GeoDataLinearRing.h geodata/data/GeoDataLineString.h geodata/data/GeoDataLineStyle.h geodata/data/GeoDataListStyle.h geodata/data/GeoDataLod.h geodata/data/GeoDataLookAt.h geodata/data/GeoDataOverlay.h geodata/data/GeoDataMultiGeometry.h geodata/data/GeoDataObject.h geodata/data/GeoDataPlacemark.h geodata/data/GeoDataPoint.h geodata/data/GeoDataPolygon.h geodata/data/GeoDataPolyStyle.h geodata/data/GeoDataRegion.h geodata/data/GeoDataStyle.h geodata/data/GeoDataStyleMap.h geodata/data/GeoDataStyleSelector.h geodata/data/GeoDataTrack.h geodata/data/GeoDataTimeSpan.h geodata/data/GeoDataTimeStamp.h geodata/data/GeoDataTimePrimitive.h geodata/data/Serializable.h geodata/geodata_export.h geodata/parser/GeoDocument.h geodata/writer/GeoWriter.h routing/RoutingWidget.h routing/RoutingManager.h TileCreator.h PluginManager.h PluginInterface.h DialogConfigurationInterface.h PositionProviderPlugin.h PositionProviderPluginInterface.h RenderPlugin.h RenderPluginInterface.h ParsingRunnerManager.h ReverseGeocodingRunnerManager.h RoutingRunnerManager.h SearchRunnerManager.h ParsingRunner.h SearchRunner.h ReverseGeocodingRunner.h RoutingRunner.h SearchRunnerPlugin.h ReverseGeocodingRunnerPlugin.h RoutingRunnerPlugin.h ParseRunnerPlugin.h LayerInterface.h PluginAboutDialog.h marble_export.h Planet.h AbstractDataPlugin.h AbstractDataPluginModel.h AbstractDataPluginItem.h AbstractWorkerThread.h LatLonEdit.h MapWizard.h MapThemeDownloadDialog.h ElevationModel.h routing/AlternativeRoutesModel.h routing/Route.h routing/Maneuver.h routing/RouteRequest.h routing/RouteSegment.h routing/RoutingManager.h routing/RoutingModel.h routing/RoutingProfile.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/marble ) endif (APPLE AND QTONLY) diff --git a/src/plugins/render/satellites/sgp4/sgp4ext.cpp b/src/plugins/render/satellites/sgp4/sgp4ext.cpp index 6eb1ac236..25e440761 100644 --- a/src/plugins/render/satellites/sgp4/sgp4ext.cpp +++ b/src/plugins/render/satellites/sgp4/sgp4ext.cpp @@ -1,724 +1,724 @@ /* ---------------------------------------------------------------- * * sgp4ext.cpp * * this file contains extra routines needed for the main test program for sgp4. * these routines are derived from the astro libraries. * * companion code for * fundamentals of astrodynamics and applications * 2007 * by david vallado * * (w) 719-573-2600, email dvallado@agi.com * * current : * 7 may 08 david vallado * fix sgn * changes : * 2 apr 07 david vallado * fix jday floor and str lengths * updates for constants * 14 aug 06 david vallado * original baseline * ---------------------------------------------------------------- */ #include "sgp4ext.h" double sgn ( double x ) { if (x < 0.0) { return -1.0; } else { return 1.0; } } // end sgn /* ----------------------------------------------------------------------------- * * function mag * * this procedure finds the magnitude of a vector. the tolerance is set to * 0.000001, thus the 1.0e-12 for the squared test of underflows. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * vec - vector * * outputs : * vec - answer stored in fourth component * * locals : * none. * * coupling : * none. * --------------------------------------------------------------------------- */ double mag ( double x[3] ) { return sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]); } // end mag /* ----------------------------------------------------------------------------- * * procedure cross * * this procedure crosses two vectors. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * vec1 - vector number 1 * vec2 - vector number 2 * * outputs : * outvec - vector result of a x b * * locals : * none. * * coupling : * mag magnitude of a vector ---------------------------------------------------------------------------- */ void cross ( double vec1[3], double vec2[3], double outvec[3] ) { outvec[0]= vec1[1]*vec2[2] - vec1[2]*vec2[1]; outvec[1]= vec1[2]*vec2[0] - vec1[0]*vec2[2]; outvec[2]= vec1[0]*vec2[1] - vec1[1]*vec2[0]; } // end cross /* ----------------------------------------------------------------------------- * * function dot * * this function finds the dot product of two vectors. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * vec1 - vector number 1 * vec2 - vector number 2 * * outputs : * dot - result * * locals : * none. * * coupling : * none. * * --------------------------------------------------------------------------- */ double dot ( double x[3], double y[3] ) { return (x[0]*y[0] + x[1]*y[1] + x[2]*y[2]); } // end dot /* ----------------------------------------------------------------------------- * * procedure angle * * this procedure calculates the angle between two vectors. the output is * set to 999999.1 to indicate an undefined value. be sure to check for * this at the output phase. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * vec1 - vector number 1 * vec2 - vector number 2 * * outputs : * theta - angle between the two vectors -pi to pi * * locals : * temp - temporary real variable * * coupling : * dot dot product of two vectors * --------------------------------------------------------------------------- */ double angle ( double vec1[3], double vec2[3] ) { double small, undefined, magv1, magv2, temp; small = 0.00000001; undefined = 999999.1; magv1 = mag(vec1); magv2 = mag(vec2); if (magv1*magv2 > small*small) { temp= dot(vec1,vec2) / (magv1*magv2); if (fabs( temp ) > 1.0) temp= sgn(temp) * 1.0; return acos( temp ); } else return undefined; } // end angle /* ----------------------------------------------------------------------------- * * function asinh * * this function evaluates the inverse hyperbolic sine function. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * xval - angle value any real * * outputs : * arcsinh - result any real * * locals : * none. * * coupling : * none. * * --------------------------------------------------------------------------- */ double asinh ( double xval ) { return log( xval + sqrt( xval*xval + 1.0 ) ); } // end asinh /* ----------------------------------------------------------------------------- * * function newtonnu * * this function solves keplers equation when the true anomaly is known. * the mean and eccentric, parabolic, or hyperbolic anomaly is also found. * the parabolic limit at 168ø is arbitrary. the hyperbolic anomaly is also * limited. the hyperbolic sine is used because it's not double valued. * * author : david vallado 719-573-2600 27 may 2002 * * revisions * vallado - fix small 24 sep 2002 * * inputs description range / units * ecc - eccentricity 0.0 to * nu - true anomaly -2pi to 2pi rad * * outputs : * e0 - eccentric anomaly 0.0 to 2pi rad 153.02 ø * m - mean anomaly 0.0 to 2pi rad 151.7425 ø * * locals : * e1 - eccentric anomaly, next value rad * sine - sine of e * cose - cosine of e * ktr - index * * coupling : * asinh - arc hyperbolic sine * * references : * vallado 2007, 85, alg 5 * --------------------------------------------------------------------------- */ void newtonnu ( double ecc, double nu, double& e0, double& m ) { double small, sine, cose; // --------------------- implementation --------------------- e0= 999999.9; m = 999999.9; small = 0.00000001; // --------------------------- circular ------------------------ if ( fabs( ecc ) < small ) { m = nu; e0= nu; } else // ---------------------- elliptical ----------------------- if ( ecc < 1.0-small ) { sine= ( sqrt( 1.0 -ecc*ecc ) * sin(nu) ) / ( 1.0 +ecc*cos(nu) ); cose= ( ecc + cos(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = atan2( sine,cose ); m = e0 - ecc*sin(e0); } else // -------------------- hyperbolic -------------------- if ( ecc > 1.0 + small ) { - if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < pi-acos(1.0 /ecc))) + if ((ecc > 1.0 ) && (fabs(nu)+0.00001 < marble_pi-acos(1.0 /ecc))) { sine= ( sqrt( ecc*ecc-1.0 ) * sin(nu) ) / ( 1.0 + ecc*cos(nu) ); e0 = asinh( sine ); m = ecc*sinh(e0) - e0; } } else // ----------------- parabolic --------------------- - if ( fabs(nu) < 168.0*pi/180.0 ) + if ( fabs(nu) < 168.0*marble_pi/180.0 ) { e0= tan( nu*0.5 ); m = e0 + (e0*e0*e0)/3.0; } if ( ecc < 1.0 ) { - m = fmod( m,2.0 *pi ); + m = fmod( m,2.0 *marble_pi ); if ( m < 0.0 ) - m = m + 2.0 *pi; - e0 = fmod( e0,2.0 *pi ); + m = m + 2.0 *marble_pi; + e0 = fmod( e0,2.0 *marble_pi ); } } // end newtonnu /* ----------------------------------------------------------------------------- * * function rv2coe * * this function finds the classical orbital elements given the geocentric * equatorial position and velocity vectors. * * author : david vallado 719-573-2600 21 jun 2002 * * revisions * vallado - fix special cases 5 sep 2002 * vallado - delete extra check in inclination code 16 oct 2002 * vallado - add constant file use 29 jun 2003 * vallado - add mu 2 apr 2007 * * inputs description range / units * r - ijk position vector km * v - ijk velocity vector km / s * mu - gravitational parameter km3 / s2 * * outputs : * p - semilatus rectum km * a - semimajor axis km * ecc - eccentricity * incl - inclination 0.0 to pi rad * omega - longitude of ascending node 0.0 to 2pi rad * argp - argument of perigee 0.0 to 2pi rad * nu - true anomaly 0.0 to 2pi rad * m - mean anomaly 0.0 to 2pi rad * arglat - argument of latitude (ci) 0.0 to 2pi rad * truelon - true longitude (ce) 0.0 to 2pi rad * lonper - longitude of periapsis (ee) 0.0 to 2pi rad * * locals : * hbar - angular momentum h vector km2 / s * ebar - eccentricity e vector * nbar - line of nodes n vector * c1 - v**2 - u/r * rdotv - r dot v * hk - hk unit vector * sme - specific mechanical energy km2 / s2 * i - index * e - eccentric, parabolic, * hyperbolic anomaly rad * temp - temporary variable * typeorbit - type of orbit ee, ei, ce, ci * * coupling : * mag - magnitude of a vector * cross - cross product of two vectors * angle - find the angle between two vectors * newtonnu - find the mean anomaly * * references : * vallado 2007, 126, alg 9, ex 2-5 * --------------------------------------------------------------------------- */ void rv2coe ( double r[3], double v[3], double mu, double& p, double& a, double& ecc, double& incl, double& omega, double& argp, double& nu, double& m, double& arglat, double& truelon, double& lonper ) { double undefined, small, hbar[3], nbar[3], magr, magv, magn, ebar[3], sme, rdotv, infinite, temp, c1, hk, twopi, magh, halfpi, e; int i; char typeorbit[3]; - twopi = 2.0 * pi; - halfpi = 0.5 * pi; + twopi = 2.0 * marble_pi; + halfpi = 0.5 * marble_pi; small = 0.00000001; undefined = 999999.1; infinite = 999999.9; // ------------------------- implementation ----------------- magr = mag( r ); magv = mag( v ); // ------------------ find h n and e vectors ---------------- cross( r,v, hbar ); magh = mag( hbar ); if ( magh > small ) { nbar[0]= -hbar[1]; nbar[1]= hbar[0]; nbar[2]= 0.0; magn = mag( nbar ); c1 = magv*magv - mu /magr; rdotv = dot( r,v ); for (i= 0; i <= 2; i++) ebar[i]= (c1*r[i] - rdotv*v[i])/mu; ecc = mag( ebar ); // ------------ find a e and semi-latus rectum ---------- sme= ( magv*magv*0.5 ) - ( mu /magr ); if ( fabs( sme ) > small ) a= -mu / (2.0 *sme); else a= infinite; p = magh*magh/mu; // ----------------- find inclination ------------------- hk= hbar[2]/magh; incl= acos( hk ); // -------- determine type of orbit for later use -------- // ------ elliptical, parabolic, hyperbolic inclined ------- strcpy(typeorbit,"ei"); if ( ecc < small ) { // ---------------- circular equatorial --------------- - if ((incl small ) { temp= nbar[0] / magn; if ( fabs(temp) > 1.0 ) temp= sgn(temp); omega= acos( temp ); if ( nbar[1] < 0.0 ) omega= twopi - omega; } else omega= undefined; // ---------------- find argument of perigee --------------- if ( strcmp(typeorbit,"ei") == 0 ) { argp = angle( nbar,ebar); if ( ebar[2] < 0.0 ) argp= twopi - argp; } else argp= undefined; // ------------ find true anomaly at epoch ------------- if ( typeorbit[0] == 'e' ) { nu = angle( ebar,r); if ( rdotv < 0.0 ) nu= twopi - nu; } else nu= undefined; // ---- find argument of latitude - circular inclined ----- if ( strcmp(typeorbit,"ci") == 0 ) { arglat = angle( nbar,r ); if ( r[2] < 0.0 ) arglat= twopi - arglat; m = arglat; } else arglat= undefined; // -- find longitude of perigee - elliptical equatorial ---- if (( ecc>small ) && (strcmp(typeorbit,"ee") == 0)) { temp= ebar[0]/ecc; if ( fabs(temp) > 1.0 ) temp= sgn(temp); lonper= acos( temp ); if ( ebar[1] < 0.0 ) lonper= twopi - lonper; if ( incl > halfpi ) lonper= twopi - lonper; } else lonper= undefined; // -------- find true longitude - circular equatorial ------ if (( magr>small ) && ( strcmp(typeorbit,"ce") == 0 )) { temp= r[0]/magr; if ( fabs(temp) > 1.0 ) temp= sgn(temp); truelon= acos( temp ); if ( r[1] < 0.0 ) truelon= twopi - truelon; if ( incl > halfpi ) truelon= twopi - truelon; m = truelon; } else truelon= undefined; // ------------ find mean anomaly for all orbits ----------- if ( typeorbit[0] == 'e' ) newtonnu(ecc,nu, e, m); } else { p = undefined; a = undefined; ecc = undefined; incl = undefined; omega= undefined; argp = undefined; nu = undefined; m = undefined; arglat = undefined; truelon= undefined; lonper = undefined; } } // end rv2coe /* ----------------------------------------------------------------------------- * * procedure jday * * this procedure finds the julian date given the year, month, day, and time. * the julian date is defined by each elapsed day since noon, jan 1, 4713 bc. * * algorithm : calculate the answer in one step for efficiency * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - universal time hour 0 .. 23 * min - universal time min 0 .. 59 * sec - universal time sec 0.0 .. 59.999 * * outputs : * jd - julian date days from 4713 bc * * locals : * none. * * coupling : * none. * * references : * vallado 2007, 189, alg 14, ex 3-14 * * --------------------------------------------------------------------------- */ void jday ( int year, int mon, int day, int hr, int minute, double sec, double& jd ) { jd = 367.0 * year - floor((7 * (year + floor((mon + 9) / 12.0))) * 0.25) + floor( 275 * mon / 9.0 ) + day + 1721013.5 + ((sec / 60.0 + minute) / 60.0 + hr) / 24.0; // ut in days // - 0.5*sgn(100.0*year + mon - 190002.5) + 0.5; } // end jday /* ----------------------------------------------------------------------------- * * procedure days2mdhms * * this procedure converts the day of the year, days, to the equivalent month * day, hour, minute and second. * * algorithm : set up array for the number of days per month * find leap year - use 1900 because 2000 is a leap year * loop through a temp value while the value is < the days * perform int conversions to the correct day and month * convert remainder into h m s using type conversions * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * year - year 1900 .. 2100 * days - julian day of the year 0.0 .. 366.0 * * outputs : * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * dayofyr - day of year * temp - temporary extended values * inttemp - temporary int value * i - index * lmonth[12] - int array containing the number of days per month * * coupling : * none. * --------------------------------------------------------------------------- */ void days2mdhms ( int year, double days, int& mon, int& day, int& hr, int& minute, double& sec ) { int i, inttemp, dayofyr; double temp; int lmonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; dayofyr = (int)floor(days); /* ----------------- find month and day of month ---------------- */ if ( (year % 4) == 0 ) lmonth[1] = 29; i = 1; inttemp = 0; while ((dayofyr > inttemp + lmonth[i-1]) && (i < 12)) { inttemp = inttemp + lmonth[i-1]; i++; } mon = i; day = dayofyr - inttemp; /* ----------------- find hours minutes and seconds ------------- */ temp = (days - dayofyr) * 24.0; hr = (int)floor(temp); temp = (temp - hr) * 60.0; minute = (int)floor(temp); sec = (temp - minute) * 60.0; } // end days2mdhms /* ----------------------------------------------------------------------------- * * procedure invjday * * this procedure finds the year, month, day, hour, minute and second * given the julian date. tu can be ut1, tdt, tdb, etc. * * algorithm : set up starting values * find leap year - use 1900 because 2000 is a leap year * find the elapsed days through the year in a loop * call routine to find each individual value * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * jd - julian date days from 4713 bc * * outputs : * year - year 1900 .. 2100 * mon - month 1 .. 12 * day - day 1 .. 28,29,30,31 * hr - hour 0 .. 23 * min - minute 0 .. 59 * sec - second 0.0 .. 59.999 * * locals : * days - day of year plus fractional * portion of a day days * tu - julian centuries from 0 h * jan 0, 1900 * temp - temporary double values * leapyrs - number of leap years from 1900 * * coupling : * days2mdhms - finds month, day, hour, minute and second given days and year * * references : * vallado 2007, 208, alg 22, ex 3-13 * --------------------------------------------------------------------------- */ void invjday ( double jd, int& year, int& mon, int& day, int& hr, int& minute, double& sec ) { int leapyrs; double days, tu, temp; /* --------------- find year and days of the year --------------- */ temp = jd - 2415019.5; tu = temp / 365.25; year = 1900 + (int)floor(tu); leapyrs = (int)floor((year - 1901) * 0.25); // optional nudge by 8.64x10-7 sec to get even outputs days = temp - ((year - 1900) * 365.0 + leapyrs) + 0.00000000001; /* ------------ check for case of beginning of a year ----------- */ if (days < 1.0) { year = year - 1; leapyrs = (int)floor((year - 1901) * 0.25); days = temp - ((year - 1900) * 365.0 + leapyrs); } /* ----------------- find residual data ------------------------- */ days2mdhms(year, days, mon, day, hr, minute, sec); sec = sec - 0.00000086400; } // end invjday diff --git a/src/plugins/render/satellites/sgp4/sgp4io.cpp b/src/plugins/render/satellites/sgp4/sgp4io.cpp index 84f4aa2ab..698b3808f 100644 --- a/src/plugins/render/satellites/sgp4/sgp4io.cpp +++ b/src/plugins/render/satellites/sgp4/sgp4io.cpp @@ -1,261 +1,261 @@ /* ---------------------------------------------------------------- * * sgp4io.cpp * * this file contains a function to read two line element sets. while * not formerly part of the sgp4 mathematical theory, it is * required for practical implementation. * * companion code for * fundamentals of astrodynamics and applications * 2007 * by david vallado * * (w) 719-573-2600, email dvallado@agi.com * * current : * 3 sep 08 david vallado * add operationmode for afspc (a) or improved (i) * changes : * 9 may 07 david vallado * fix year correction to 57 * 27 mar 07 david vallado * misc fixes to manual inputs * 14 aug 06 david vallado * original baseline * ---------------------------------------------------------------- */ #include "sgp4io.h" /* ----------------------------------------------------------------------------- * * function twoline2rv * * this function converts the two line element set character string data to * variables and initializes the sgp4 variables. several intermediate varaibles * and quantities are determined. note that the result is a structure so multiple * satellites can be processed simultaneously without having to reinitialize. the * verification mode is an important option that permits quick checks of any * changes to the underlying technical theory. this option works using a * modified tle file in which the start, stop, and delta time values are * included at the end of the second line of data. this only works with the * verification mode. the catalog mode simply propagates from -1440 to 1440 min * from epoch and is useful when performing entire catalog runs. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs : * longstr1 - first line of the tle * longstr2 - second line of the tle * typerun - type of run verification 'v', catalog 'c', * manual 'm' * typeinput - type of manual input mfe 'm', epoch 'e', dayofyr 'd' * opsmode - mode of operation afspc or improved 'a', 'i' * whichconst - which set of constants to use 72, 84 * * outputs : * satrec - structure containing all the sgp4 satellite information * * coupling : * getgravconst- * days2mdhms - conversion of days to month, day, hour, minute, second * jday - convert day month year hour minute second into julian date * sgp4init - initialize the sgp4 variables * * references : * norad spacetrack report #3 * vallado, crawford, hujsak, kelso 2006 --------------------------------------------------------------------------- */ void twoline2rv ( char longstr1[130], char longstr2[130], char typerun, char typeinput, char opsmode, gravconsttype whichconst, double& startmfe, double& stopmfe, double& deltamin, elsetrec& satrec ) { - const double deg2rad = pi / 180.0; // 0.0174532925199433 - const double xpdotp = 1440.0 / (2.0 *pi); // 229.1831180523293 + const double deg2rad = marble_pi / 180.0; // 0.0174532925199433 + const double xpdotp = 1440.0 / (2.0 *marble_pi); // 229.1831180523293 double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2; double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop; int startyear, stopyear, startmon, stopmon, startday, stopday, starthr, stophr, startmin, stopmin; int cardnumb, numb, j; long revnum = 0, elnum = 0; char classification, intldesg[11]; int year = 0; int mon, day, hr, minute, nexp, ibexp; getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); satrec.error = 0; // set the implied decimal points since doing a formated read // fixes for bad input data values (missing, ...) for (j = 10; j <= 15; j++) if (longstr1[j] == ' ') longstr1[j] = '_'; if (longstr1[44] != ' ') longstr1[43] = longstr1[44]; longstr1[44] = '.'; if (longstr1[7] == ' ') longstr1[7] = 'U'; if (longstr1[9] == ' ') longstr1[9] = '.'; for (j = 45; j <= 49; j++) if (longstr1[j] == ' ') longstr1[j] = '0'; if (longstr1[51] == ' ') longstr1[51] = '0'; if (longstr1[53] != ' ') longstr1[52] = longstr1[53]; longstr1[53] = '.'; longstr2[25] = '.'; for (j = 26; j <= 32; j++) if (longstr2[j] == ' ') longstr2[j] = '0'; if (longstr1[62] == ' ') longstr1[62] = '0'; if (longstr1[68] == ' ') longstr1[68] = '0'; sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ", &cardnumb,&satrec.satnum,&classification, intldesg, &satrec.epochyr, &satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar, &ibexp, &numb, &elnum ); if (typerun == 'v') // run for specified times from the file { if (longstr2[52] == ' ') sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld %lf %lf %lf \n", &cardnumb,&satrec.satnum, &satrec.inclo, &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum, &startmfe, &stopmfe, &deltamin ); else sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld %lf %lf %lf \n", &cardnumb,&satrec.satnum, &satrec.inclo, &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum, &startmfe, &stopmfe, &deltamin ); } else // simply run -1 day to +1 day or user input times { if (longstr2[52] == ' ') sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %10lf %6ld \n", &cardnumb,&satrec.satnum, &satrec.inclo, &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum ); else sscanf(longstr2,"%2d %5ld %9lf %9lf %8lf %9lf %9lf %11lf %6ld \n", &cardnumb,&satrec.satnum, &satrec.inclo, &satrec.nodeo,&satrec.ecco, &satrec.argpo, &satrec.mo, &satrec.no, &revnum ); } // ---- find no, ndot, nddot ---- satrec.no = satrec.no / xpdotp; //* rad/min satrec.nddot= satrec.nddot * pow(10.0, nexp); satrec.bstar= satrec.bstar * pow(10.0, ibexp); // ---- convert to sgp4 units ---- satrec.a = pow( satrec.no*tumin , (-2.0/3.0) ); satrec.ndot = satrec.ndot / (xpdotp*1440.0); //* ? * minperday satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440); // ---- find standard orbital elements ---- satrec.inclo = satrec.inclo * deg2rad; satrec.nodeo = satrec.nodeo * deg2rad; satrec.argpo = satrec.argpo * deg2rad; satrec.mo = satrec.mo * deg2rad; satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0; satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0; // ---------------------------------------------------------------- // find sgp4epoch time of element set // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch) // and minutes from the epoch (time) // ---------------------------------------------------------------- // ---------------- temp fix for years from 1957-2056 ------------------- // --------- correct fix will occur when year is 4-digit in tle --------- if (satrec.epochyr < 57) year= satrec.epochyr + 2000; else year= satrec.epochyr + 1900; days2mdhms ( year,satrec.epochdays, mon,day,hr,minute,sec ); jday( year,mon,day,hr,minute,sec, satrec.jdsatepoch ); // ---- input start stop times manually if ((typerun != 'v') && (typerun != 'c')) { // ------------- enter start/stop ymd hms values -------------------- if (typeinput == 'e') { printf("input start prop year mon day hr min sec \n"); // make sure there is no space at the end of the format specifiers in scanf! scanf( "%i %i %i %i %i %lf",&startyear, &startmon, &startday, &starthr, &startmin, &startsec); fflush(stdin); jday( startyear,startmon,startday,starthr,startmin,startsec, jdstart ); printf("input stop prop year mon day hr min sec \n"); scanf( "%i %i %i %i %i %lf",&stopyear, &stopmon, &stopday, &stophr, &stopmin, &stopsec); fflush(stdin); jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec, jdstop ); startmfe = (jdstart - satrec.jdsatepoch) * 1440.0; stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0; printf("input time step in minutes \n"); scanf( "%lf",&deltamin ); } // -------- enter start/stop year and days of year values ----------- if (typeinput == 'd') { printf("input start year dayofyr \n"); scanf( "%i %lf",&startyear, &startdayofyr ); printf("input stop year dayofyr \n"); scanf( "%i %lf",&stopyear, &stopdayofyr ); days2mdhms ( startyear,startdayofyr, mon,day,hr,minute,sec ); jday( startyear,mon,day,hr,minute,sec, jdstart ); days2mdhms ( stopyear,stopdayofyr, mon,day,hr,minute,sec ); jday( stopyear,mon,day,hr,minute,sec, jdstop ); startmfe = (jdstart - satrec.jdsatepoch) * 1440.0; stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0; printf("input time step in minutes \n"); scanf( "%lf",&deltamin ); } // ------------------ enter start/stop mfe values ------------------- if (typeinput == 'm') { printf("input start min from epoch \n"); scanf( "%lf",&startmfe ); printf("input stop min from epoch \n"); scanf( "%lf",&stopmfe ); printf("input time step in minutes \n"); scanf( "%lf",&deltamin ); } } // ------------ perform complete catalog evaluation, -+ 1 day ----------- if (typerun == 'c') { startmfe = -1440.0; stopmfe = 1440.0; deltamin = 10.0; } // ---------------- initialize the orbit at sgp4epoch ------------------- sgp4init( whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar, satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no, satrec.nodeo, satrec); } // end twoline2rv diff --git a/src/plugins/render/satellites/sgp4/sgp4unit.cpp b/src/plugins/render/satellites/sgp4/sgp4unit.cpp index 1d34c0093..7a6873580 100644 --- a/src/plugins/render/satellites/sgp4/sgp4unit.cpp +++ b/src/plugins/render/satellites/sgp4/sgp4unit.cpp @@ -1,2117 +1,2117 @@ /* ---------------------------------------------------------------- * * sgp4unit.cpp * * this file contains the sgp4 procedures for analytical propagation * of a satellite. the code was originally released in the 1980 and 1986 * spacetrack papers. a detailed discussion of the theory and history * may be found in the 2006 aiaa paper by vallado, crawford, hujsak, * and kelso. * * companion code for * fundamentals of astrodynamics and applications * 2007 * by david vallado * * (w) 719-573-2600, email dvallado@agi.com * * current : * 3 Nov 08 david vallado * put returns in for error codes * changes : * 29 sep 08 david vallado * fix atime for faster operation in dspace * add operationmode for afspc (a) or improved (i) * performance mode * 16 jun 08 david vallado * update small eccentricity check * 16 nov 07 david vallado * misc fixes for better compliance * 20 apr 07 david vallado * misc fixes for constants * 11 aug 06 david vallado * chg lyddane choice back to strn3, constants, misc doc * 15 dec 05 david vallado * misc fixes * 26 jul 05 david vallado * fixes for paper * note that each fix is preceded by a * comment with "sgp4fix" and an explanation of * what was changed * 10 aug 04 david vallado * 2nd printing baseline working * 14 may 01 david vallado * 2nd edition baseline * 80 norad * original baseline * ---------------------------------------------------------------- */ #include "sgp4unit.h" const char help = 'n'; FILE *dbgfile; #define UNUSED(arg) (void)arg; /* ----------- local functions - only ever used internally by sgp4 ---------- */ static void dpper ( double e3, double ee2, double peo, double pgho, double pho, double pinco, double plo, double se2, double se3, double sgh2, double sgh3, double sgh4, double sh2, double sh3, double si2, double si3, double sl2, double sl3, double sl4, double t, double xgh2, double xgh3, double xgh4, double xh2, double xh3, double xi2, double xi3, double xl2, double xl3, double xl4, double zmol, double zmos, double inclo, char init, double& ep, double& inclp, double& nodep, double& argpp, double& mp, char opsmode ); static void dscom ( double epoch, double ep, double argpp, double tc, double inclp, double nodep, double np, double& snodm, double& cnodm, double& sinim, double& cosim, double& sinomm, double& cosomm,double& day, double& e3, double& ee2, double& em, double& emsq, double& gam, double& peo, double& pgho, double& pho, double& pinco, double& plo, double& rtemsq, double& se2, double& se3, double& sgh2, double& sgh3, double& sgh4, double& sh2, double& sh3, double& si2, double& si3, double& sl2, double& sl3, double& sl4, double& s1, double& s2, double& s3, double& s4, double& s5, double& s6, double& s7, double& ss1, double& ss2, double& ss3, double& ss4, double& ss5, double& ss6, double& ss7, double& sz1, double& sz2, double& sz3, double& sz11, double& sz12, double& sz13, double& sz21, double& sz22, double& sz23, double& sz31, double& sz32, double& sz33, double& xgh2, double& xgh3, double& xgh4, double& xh2, double& xh3, double& xi2, double& xi3, double& xl2, double& xl3, double& xl4, double& nm, double& z1, double& z2, double& z3, double& z11, double& z12, double& z13, double& z21, double& z22, double& z23, double& z31, double& z32, double& z33, double& zmol, double& zmos ); static void dsinit ( gravconsttype whichconst, double cosim, double emsq, double argpo, double s1, double s2, double s3, double s4, double s5, double sinim, double ss1, double ss2, double ss3, double ss4, double ss5, double sz1, double sz3, double sz11, double sz13, double sz21, double sz23, double sz31, double sz33, double t, double tc, double gsto, double mo, double mdot, double no, double nodeo, double nodedot, double xpidot, double z1, double z3, double z11, double z13, double z21, double z23, double z31, double z33, double ecco, double eccsq, double& em, double& argpm, double& inclm, double& mm, double& nm, double& nodem, int& irez, double& atime, double& d2201, double& d2211, double& d3210, double& d3222, double& d4410, double& d4422, double& d5220, double& d5232, double& d5421, double& d5433, double& dedt, double& didt, double& dmdt, double& dndt, double& dnodt, double& domdt, double& del1, double& del2, double& del3, double& xfact, double& xlamo, double& xli, double& xni ); static void dspace ( int irez, double d2201, double d2211, double d3210, double d3222, double d4410, double d4422, double d5220, double d5232, double d5421, double d5433, double dedt, double del1, double del2, double del3, double didt, double dmdt, double dnodt, double domdt, double argpo, double argpdot, double t, double tc, double gsto, double xfact, double xlamo, double no, double& atime, double& em, double& argpm, double& inclm, double& xli, double& mm, double& xni, double& nodem, double& dndt, double& nm ); static void initl ( int satn, gravconsttype whichconst, double ecco, double epoch, double inclo, double& no, char& method, double& ainv, double& ao, double& con41, double& con42, double& cosio, double& cosio2,double& eccsq, double& omeosq, double& posq, double& rp, double& rteosq,double& sinio , double& gsto, char opsmode ); /* ----------------------------------------------------------------------------- * * procedure dpper * * this procedure provides deep space long period periodic contributions * to the mean elements. by design, these periodics are zero at epoch. * this used to be dscom which included initialization, but it's really a * recurring function. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * e3 - * ee2 - * peo - * pgho - * pho - * pinco - * plo - * se2 , se3 , sgh2, sgh3, sgh4, sh2, sh3, si2, si3, sl2, sl3, sl4 - * t - * xh2, xh3, xi2, xi3, xl2, xl3, xl4 - * zmol - * zmos - * ep - eccentricity 0.0 - 1.0 * inclo - inclination - needed for lyddane modification * nodep - right ascension of ascending node * argpp - argument of perigee * mp - mean anomaly * * outputs : * ep - eccentricity 0.0 - 1.0 * inclp - inclination * nodep - right ascension of ascending node * argpp - argument of perigee * mp - mean anomaly * * locals : * alfdp - * betdp - * cosip , sinip , cosop , sinop , * dalf - * dbet - * dls - * f2, f3 - * pe - * pgh - * ph - * pinc - * pl - * sel , ses , sghl , sghs , shl , shs , sil , sinzf , sis , * sll , sls * xls - * xnoh - * zf - * zm - * * coupling : * none. * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ static void dpper ( double e3, double ee2, double peo, double pgho, double pho, double pinco, double plo, double se2, double se3, double sgh2, double sgh3, double sgh4, double sh2, double sh3, double si2, double si3, double sl2, double sl3, double sl4, double t, double xgh2, double xgh3, double xgh4, double xh2, double xh3, double xi2, double xi3, double xl2, double xl3, double xl4, double zmol, double zmos, double inclo, char init, double& ep, double& inclp, double& nodep, double& argpp, double& mp, char opsmode ) { UNUSED( inclo ); /* --------------------- local variables ------------------------ */ - const double twopi = 2.0 * pi; + const double twopi = 2.0 * marble_pi; double alfdp, betdp, cosip, cosop, dalf, dbet, dls, f2, f3, pe, pgh, ph, pinc, pl , sel, ses, sghl, sghs, shll, shs, sil, sinip, sinop, sinzf, sis, sll, sls, xls, xnoh, zf, zm, zel, zes, znl, zns; /* ---------------------- constants ----------------------------- */ zns = 1.19459e-5; zes = 0.01675; znl = 1.5835218e-4; zel = 0.05490; /* --------------- calculate time varying periodics ----------- */ zm = zmos + zns * t; // be sure that the initial call has time set to zero if (init == 'y') zm = zmos; zf = zm + 2.0 * zes * sin(zm); sinzf = sin(zf); f2 = 0.5 * sinzf * sinzf - 0.25; f3 = -0.5 * sinzf * cos(zf); ses = se2* f2 + se3 * f3; sis = si2 * f2 + si3 * f3; sls = sl2 * f2 + sl3 * f3 + sl4 * sinzf; sghs = sgh2 * f2 + sgh3 * f3 + sgh4 * sinzf; shs = sh2 * f2 + sh3 * f3; zm = zmol + znl * t; if (init == 'y') zm = zmol; zf = zm + 2.0 * zel * sin(zm); sinzf = sin(zf); f2 = 0.5 * sinzf * sinzf - 0.25; f3 = -0.5 * sinzf * cos(zf); sel = ee2 * f2 + e3 * f3; sil = xi2 * f2 + xi3 * f3; sll = xl2 * f2 + xl3 * f3 + xl4 * sinzf; sghl = xgh2 * f2 + xgh3 * f3 + xgh4 * sinzf; shll = xh2 * f2 + xh3 * f3; pe = ses + sel; pinc = sis + sil; pl = sls + sll; pgh = sghs + sghl; ph = shs + shll; if (init == 'n') { pe = pe - peo; pinc = pinc - pinco; pl = pl - plo; pgh = pgh - pgho; ph = ph - pho; inclp = inclp + pinc; ep = ep + pe; sinip = sin(inclp); cosip = cos(inclp); /* ----------------- apply periodics directly ------------ */ // sgp4fix for lyddane choice // strn3 used original inclination - this is technically feasible // gsfc used perturbed inclination - also technically feasible // probably best to readjust the 0.2 limit value and limit discontinuity // 0.2 rad = 11.45916 deg // use next line for original strn3 approach and original inclination // if (inclo >= 0.2) // use next line for gsfc version and perturbed inclination if (inclp >= 0.2) { ph = ph / sinip; pgh = pgh - cosip * ph; argpp = argpp + pgh; nodep = nodep + ph; mp = mp + pl; } else { /* ---- apply periodics with lyddane modification ---- */ sinop = sin(nodep); cosop = cos(nodep); alfdp = sinip * sinop; betdp = sinip * cosop; dalf = ph * cosop + pinc * cosip * sinop; dbet = -ph * sinop + pinc * cosip * cosop; alfdp = alfdp + dalf; betdp = betdp + dbet; nodep = fmod(nodep, twopi); // sgp4fix for afspc written intrinsic functions // nodep used without a trigonometric function ahead if ((nodep < 0.0) && (opsmode == 'a')) { nodep = nodep + twopi; } xls = mp + argpp + cosip * nodep; dls = pl + pgh - pinc * nodep * sinip; xls = xls + dls; xnoh = nodep; nodep = atan2(alfdp, betdp); // sgp4fix for afspc written intrinsic functions // nodep used without a trigonometric function ahead if ((nodep < 0.0) && (opsmode == 'a')) { nodep = nodep + twopi; } - if (fabs(xnoh - nodep) > pi) { + if (fabs(xnoh - nodep) > marble_pi) { if (nodep < xnoh) { nodep = nodep + twopi; } else { nodep = nodep - twopi; } } mp = mp + pl; argpp = xls - mp - cosip * nodep; } } // if init == 'n' //#include "debug1.cpp" } // end dpper /*----------------------------------------------------------------------------- * * procedure dscom * * this procedure provides deep space common items used by both the secular * and periodics subroutines. input is provided as shown. this routine * used to be called dpper, but the functions inside weren't well organized. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * epoch - * ep - eccentricity * argpp - argument of perigee * tc - * inclp - inclination * nodep - right ascension of ascending node * np - mean motion * * outputs : * sinim , cosim , sinomm , cosomm , snodm , cnodm * day - * e3 - * ee2 - * em - eccentricity * emsq - eccentricity squared * gam - * peo - * pgho - * pho - * pinco - * plo - * rtemsq - * se2, se3 - * sgh2, sgh3, sgh4 - * sh2, sh3, si2, si3, sl2, sl3, sl4 - * s1, s2, s3, s4, s5, s6, s7 - * ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3 - * sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33 - * xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4 - * nm - mean motion * z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33 - * zmol - * zmos - * * locals : * a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 - * betasq - * cc - * ctem, stem - * x1, x2, x3, x4, x5, x6, x7, x8 - * xnodce - * xnoi - * zcosg , zsing , zcosgl , zsingl , zcosh , zsinh , zcoshl , zsinhl , * zcosi , zsini , zcosil , zsinil , * zx - * zy - * * coupling : * none. * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ static void dscom ( double epoch, double ep, double argpp, double tc, double inclp, double nodep, double np, double& snodm, double& cnodm, double& sinim, double& cosim, double& sinomm, double& cosomm,double& day, double& e3, double& ee2, double& em, double& emsq, double& gam, double& peo, double& pgho, double& pho, double& pinco, double& plo, double& rtemsq, double& se2, double& se3, double& sgh2, double& sgh3, double& sgh4, double& sh2, double& sh3, double& si2, double& si3, double& sl2, double& sl3, double& sl4, double& s1, double& s2, double& s3, double& s4, double& s5, double& s6, double& s7, double& ss1, double& ss2, double& ss3, double& ss4, double& ss5, double& ss6, double& ss7, double& sz1, double& sz2, double& sz3, double& sz11, double& sz12, double& sz13, double& sz21, double& sz22, double& sz23, double& sz31, double& sz32, double& sz33, double& xgh2, double& xgh3, double& xgh4, double& xh2, double& xh3, double& xi2, double& xi3, double& xl2, double& xl3, double& xl4, double& nm, double& z1, double& z2, double& z3, double& z11, double& z12, double& z13, double& z21, double& z22, double& z23, double& z31, double& z32, double& z33, double& zmol, double& zmos ) { /* -------------------------- constants ------------------------- */ const double zes = 0.01675; const double zel = 0.05490; const double c1ss = 2.9864797e-6; const double c1l = 4.7968065e-7; const double zsinis = 0.39785416; const double zcosis = 0.91744867; const double zcosgs = 0.1945905; const double zsings = -0.98088458; - const double twopi = 2.0 * pi; + const double twopi = 2.0 * marble_pi; /* --------------------- local variables ------------------------ */ int lsflg; double a1 , a2 , a3 , a4 , a5 , a6 , a7 , a8 , a9 , a10 , betasq, cc , ctem , stem , x1 , x2 , x3 , x4 , x5 , x6 , x7 , x8 , xnodce, xnoi , zcosg , zcosgl, zcosh , zcoshl, zcosi , zcosil, zsing , zsingl, zsinh , zsinhl, zsini , zsinil, zx , zy; nm = np; em = ep; snodm = sin(nodep); cnodm = cos(nodep); sinomm = sin(argpp); cosomm = cos(argpp); sinim = sin(inclp); cosim = cos(inclp); emsq = em * em; betasq = 1.0 - emsq; rtemsq = sqrt(betasq); /* ----------------- initialize lunar solar terms --------------- */ peo = 0.0; pinco = 0.0; plo = 0.0; pgho = 0.0; pho = 0.0; day = epoch + 18261.5 + tc / 1440.0; xnodce = fmod(4.5236020 - 9.2422029e-4 * day, twopi); stem = sin(xnodce); ctem = cos(xnodce); zcosil = 0.91375164 - 0.03568096 * ctem; zsinil = sqrt(1.0 - zcosil * zcosil); zsinhl = 0.089683511 * stem / zsinil; zcoshl = sqrt(1.0 - zsinhl * zsinhl); gam = 5.8351514 + 0.0019443680 * day; zx = 0.39785416 * stem / zsinil; zy = zcoshl * ctem + 0.91744867 * zsinhl * stem; zx = atan2(zx, zy); zx = gam + zx - xnodce; zcosgl = cos(zx); zsingl = sin(zx); /* ------------------------- do solar terms --------------------- */ zcosg = zcosgs; zsing = zsings; zcosi = zcosis; zsini = zsinis; zcosh = cnodm; zsinh = snodm; cc = c1ss; xnoi = 1.0 / nm; for (lsflg = 1; lsflg <= 2; lsflg++) { a1 = zcosg * zcosh + zsing * zcosi * zsinh; a3 = -zsing * zcosh + zcosg * zcosi * zsinh; a7 = -zcosg * zsinh + zsing * zcosi * zcosh; a8 = zsing * zsini; a9 = zsing * zsinh + zcosg * zcosi * zcosh; a10 = zcosg * zsini; a2 = cosim * a7 + sinim * a8; a4 = cosim * a9 + sinim * a10; a5 = -sinim * a7 + cosim * a8; a6 = -sinim * a9 + cosim * a10; x1 = a1 * cosomm + a2 * sinomm; x2 = a3 * cosomm + a4 * sinomm; x3 = -a1 * sinomm + a2 * cosomm; x4 = -a3 * sinomm + a4 * cosomm; x5 = a5 * sinomm; x6 = a6 * sinomm; x7 = a5 * cosomm; x8 = a6 * cosomm; z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3; z32 = 24.0 * x1 * x2 - 6.0 * x3 * x4; z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4; z1 = 3.0 * (a1 * a1 + a2 * a2) + z31 * emsq; z2 = 6.0 * (a1 * a3 + a2 * a4) + z32 * emsq; z3 = 3.0 * (a3 * a3 + a4 * a4) + z33 * emsq; z11 = -6.0 * a1 * a5 + emsq * (-24.0 * x1 * x7-6.0 * x3 * x5); z12 = -6.0 * (a1 * a6 + a3 * a5) + emsq * (-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5)); z13 = -6.0 * a3 * a6 + emsq * (-24.0 * x2 * x8 - 6.0 * x4 * x6); z21 = 6.0 * a2 * a5 + emsq * (24.0 * x1 * x5 - 6.0 * x3 * x7); z22 = 6.0 * (a4 * a5 + a2 * a6) + emsq * (24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8)); z23 = 6.0 * a4 * a6 + emsq * (24.0 * x2 * x6 - 6.0 * x4 * x8); z1 = z1 + z1 + betasq * z31; z2 = z2 + z2 + betasq * z32; z3 = z3 + z3 + betasq * z33; s3 = cc * xnoi; s2 = -0.5 * s3 / rtemsq; s4 = s3 * rtemsq; s1 = -15.0 * em * s4; s5 = x1 * x3 + x2 * x4; s6 = x2 * x3 + x1 * x4; s7 = x2 * x4 - x1 * x3; /* ----------------------- do lunar terms ------------------- */ if (lsflg == 1) { ss1 = s1; ss2 = s2; ss3 = s3; ss4 = s4; ss5 = s5; ss6 = s6; ss7 = s7; sz1 = z1; sz2 = z2; sz3 = z3; sz11 = z11; sz12 = z12; sz13 = z13; sz21 = z21; sz22 = z22; sz23 = z23; sz31 = z31; sz32 = z32; sz33 = z33; zcosg = zcosgl; zsing = zsingl; zcosi = zcosil; zsini = zsinil; zcosh = zcoshl * cnodm + zsinhl * snodm; zsinh = snodm * zcoshl - cnodm * zsinhl; cc = c1l; } } zmol = fmod(4.7199672 + 0.22997150 * day - gam, twopi); zmos = fmod(6.2565837 + 0.017201977 * day, twopi); /* ------------------------ do solar terms ---------------------- */ se2 = 2.0 * ss1 * ss6; se3 = 2.0 * ss1 * ss7; si2 = 2.0 * ss2 * sz12; si3 = 2.0 * ss2 * (sz13 - sz11); sl2 = -2.0 * ss3 * sz2; sl3 = -2.0 * ss3 * (sz3 - sz1); sl4 = -2.0 * ss3 * (-21.0 - 9.0 * emsq) * zes; sgh2 = 2.0 * ss4 * sz32; sgh3 = 2.0 * ss4 * (sz33 - sz31); sgh4 = -18.0 * ss4 * zes; sh2 = -2.0 * ss2 * sz22; sh3 = -2.0 * ss2 * (sz23 - sz21); /* ------------------------ do lunar terms ---------------------- */ ee2 = 2.0 * s1 * s6; e3 = 2.0 * s1 * s7; xi2 = 2.0 * s2 * z12; xi3 = 2.0 * s2 * (z13 - z11); xl2 = -2.0 * s3 * z2; xl3 = -2.0 * s3 * (z3 - z1); xl4 = -2.0 * s3 * (-21.0 - 9.0 * emsq) * zel; xgh2 = 2.0 * s4 * z32; xgh3 = 2.0 * s4 * (z33 - z31); xgh4 = -18.0 * s4 * zel; xh2 = -2.0 * s2 * z22; xh3 = -2.0 * s2 * (z23 - z21); //#include "debug2.cpp" } // end dscom /*----------------------------------------------------------------------------- * * procedure dsinit * * this procedure provides deep space contributions to mean motion dot due * to geopotential resonance with half day and one day orbits. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * cosim, sinim- * emsq - eccentricity squared * argpo - argument of perigee * s1, s2, s3, s4, s5 - * ss1, ss2, ss3, ss4, ss5 - * sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33 - * t - time * tc - * gsto - greenwich sidereal time rad * mo - mean anomaly * mdot - mean anomaly dot (rate) * no - mean motion * nodeo - right ascension of ascending node * nodedot - right ascension of ascending node dot (rate) * xpidot - * z1, z3, z11, z13, z21, z23, z31, z33 - * eccm - eccentricity * argpm - argument of perigee * inclm - inclination * mm - mean anomaly * xn - mean motion * nodem - right ascension of ascending node * * outputs : * em - eccentricity * argpm - argument of perigee * inclm - inclination * mm - mean anomaly * nm - mean motion * nodem - right ascension of ascending node * irez - flag for resonance 0-none, 1-one day, 2-half day * atime - * d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433 - * dedt - * didt - * dmdt - * dndt - * dnodt - * domdt - * del1, del2, del3 - * ses , sghl , sghs , sgs , shl , shs , sis , sls * theta - * xfact - * xlamo - * xli - * xni * * locals : * ainv2 - * aonv - * cosisq - * eoc - * f220, f221, f311, f321, f322, f330, f441, f442, f522, f523, f542, f543 - * g200, g201, g211, g300, g310, g322, g410, g422, g520, g521, g532, g533 - * sini2 - * temp - * temp1 - * theta - * xno2 - * * coupling : * getgravconst * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ static void dsinit ( gravconsttype whichconst, double cosim, double emsq, double argpo, double s1, double s2, double s3, double s4, double s5, double sinim, double ss1, double ss2, double ss3, double ss4, double ss5, double sz1, double sz3, double sz11, double sz13, double sz21, double sz23, double sz31, double sz33, double t, double tc, double gsto, double mo, double mdot, double no, double nodeo, double nodedot, double xpidot, double z1, double z3, double z11, double z13, double z21, double z23, double z31, double z33, double ecco, double eccsq, double& em, double& argpm, double& inclm, double& mm, double& nm, double& nodem, int& irez, double& atime, double& d2201, double& d2211, double& d3210, double& d3222, double& d4410, double& d4422, double& d5220, double& d5232, double& d5421, double& d5433, double& dedt, double& didt, double& dmdt, double& dndt, double& dnodt, double& domdt, double& del1, double& del2, double& del3, double& xfact, double& xlamo, double& xli, double& xni ) { /* --------------------- local variables ------------------------ */ - const double twopi = 2.0 * pi; + const double twopi = 2.0 * marble_pi; double ainv2 , aonv=0.0, cosisq, eoc, f220 , f221 , f311 , f321 , f322 , f330 , f441 , f442 , f522 , f523 , f542 , f543 , g200 , g201 , g211 , g300 , g310 , g322 , g410 , g422 , g520 , g521 , g532 , g533 , ses , sgs , sghl , sghs , shs , shll , sis , sini2 , sls , temp , temp1 , theta , xno2 , q22 , q31 , q33 , root22, root44, root54, rptim , root32, root52, x2o3 , xke , znl , emo , zns , emsqo, tumin, mu, radiusearthkm, j2, j3, j4, j3oj2; q22 = 1.7891679e-6; q31 = 2.1460748e-6; q33 = 2.2123015e-7; root22 = 1.7891679e-6; root44 = 7.3636953e-9; root54 = 2.1765803e-9; rptim = 4.37526908801129966e-3; // this equates to 7.29211514668855e-5 rad/sec root32 = 3.7393792e-7; root52 = 1.1428639e-7; x2o3 = 2.0 / 3.0; znl = 1.5835218e-4; zns = 1.19459e-5; // sgp4fix identify constants and allow alternate values getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); /* -------------------- deep space initialization ------------ */ irez = 0; if ((nm < 0.0052359877) && (nm > 0.0034906585)) irez = 1; if ((nm >= 8.26e-3) && (nm <= 9.24e-3) && (em >= 0.5)) irez = 2; /* ------------------------ do solar terms ------------------- */ ses = ss1 * zns * ss5; sis = ss2 * zns * (sz11 + sz13); sls = -zns * ss3 * (sz1 + sz3 - 14.0 - 6.0 * emsq); sghs = ss4 * zns * (sz31 + sz33 - 6.0); shs = -zns * ss2 * (sz21 + sz23); // sgp4fix for 180 deg incl - if ((inclm < 5.2359877e-2) || (inclm > pi - 5.2359877e-2)) + if ((inclm < 5.2359877e-2) || (inclm > marble_pi - 5.2359877e-2)) shs = 0.0; if (sinim != 0.0) shs = shs / sinim; sgs = sghs - cosim * shs; /* ------------------------- do lunar terms ------------------ */ dedt = ses + s1 * znl * s5; didt = sis + s2 * znl * (z11 + z13); dmdt = sls - znl * s3 * (z1 + z3 - 14.0 - 6.0 * emsq); sghl = s4 * znl * (z31 + z33 - 6.0); shll = -znl * s2 * (z21 + z23); // sgp4fix for 180 deg incl - if ((inclm < 5.2359877e-2) || (inclm > pi - 5.2359877e-2)) + if ((inclm < 5.2359877e-2) || (inclm > marble_pi - 5.2359877e-2)) shll = 0.0; domdt = sgs + sghl; dnodt = shs; if (sinim != 0.0) { domdt = domdt - cosim / sinim * shll; dnodt = dnodt + shll / sinim; } /* ----------- calculate deep space resonance effects -------- */ dndt = 0.0; theta = fmod(gsto + tc * rptim, twopi); em = em + dedt * t; inclm = inclm + didt * t; argpm = argpm + domdt * t; nodem = nodem + dnodt * t; mm = mm + dmdt * t; // sgp4fix for negative inclinations // the following if statement should be commented out //if (inclm < 0.0) // { // inclm = -inclm; // argpm = argpm - pi; // nodem = nodem + pi; // } /* -------------- initialize the resonance terms ------------- */ if (irez != 0) { aonv = pow(nm / xke, x2o3); /* ---------- geopotential resonance for 12 hour orbits ------ */ if (irez == 2) { cosisq = cosim * cosim; emo = em; em = ecco; emsqo = emsq; emsq = eccsq; eoc = em * emsq; g201 = -0.306 - (em - 0.64) * 0.440; if (em <= 0.65) { g211 = 3.616 - 13.2470 * em + 16.2900 * emsq; g310 = -19.302 + 117.3900 * em - 228.4190 * emsq + 156.5910 * eoc; g322 = -18.9068 + 109.7927 * em - 214.6334 * emsq + 146.5816 * eoc; g410 = -41.122 + 242.6940 * em - 471.0940 * emsq + 313.9530 * eoc; g422 = -146.407 + 841.8800 * em - 1629.014 * emsq + 1083.4350 * eoc; g520 = -532.114 + 3017.977 * em - 5740.032 * emsq + 3708.2760 * eoc; } else { g211 = -72.099 + 331.819 * em - 508.738 * emsq + 266.724 * eoc; g310 = -346.844 + 1582.851 * em - 2415.925 * emsq + 1246.113 * eoc; g322 = -342.585 + 1554.908 * em - 2366.899 * emsq + 1215.972 * eoc; g410 = -1052.797 + 4758.686 * em - 7193.992 * emsq + 3651.957 * eoc; g422 = -3581.690 + 16178.110 * em - 24462.770 * emsq + 12422.520 * eoc; if (em > 0.715) g520 =-5149.66 + 29936.92 * em - 54087.36 * emsq + 31324.56 * eoc; else g520 = 1464.74 - 4664.75 * em + 3763.64 * emsq; } if (em < 0.7) { g533 = -919.22770 + 4988.6100 * em - 9064.7700 * emsq + 5542.21 * eoc; g521 = -822.71072 + 4568.6173 * em - 8491.4146 * emsq + 5337.524 * eoc; g532 = -853.66600 + 4690.2500 * em - 8624.7700 * emsq + 5341.4 * eoc; } else { g533 =-37995.780 + 161616.52 * em - 229838.20 * emsq + 109377.94 * eoc; g521 =-51752.104 + 218913.95 * em - 309468.16 * emsq + 146349.42 * eoc; g532 =-40023.880 + 170470.89 * em - 242699.48 * emsq + 115605.82 * eoc; } sini2= sinim * sinim; f220 = 0.75 * (1.0 + 2.0 * cosim+cosisq); f221 = 1.5 * sini2; f321 = 1.875 * sinim * (1.0 - 2.0 * cosim - 3.0 * cosisq); f322 = -1.875 * sinim * (1.0 + 2.0 * cosim - 3.0 * cosisq); f441 = 35.0 * sini2 * f220; f442 = 39.3750 * sini2 * sini2; f522 = 9.84375 * sinim * (sini2 * (1.0 - 2.0 * cosim- 5.0 * cosisq) + 0.33333333 * (-2.0 + 4.0 * cosim + 6.0 * cosisq) ); f523 = sinim * (4.92187512 * sini2 * (-2.0 - 4.0 * cosim + 10.0 * cosisq) + 6.56250012 * (1.0+2.0 * cosim - 3.0 * cosisq)); f542 = 29.53125 * sinim * (2.0 - 8.0 * cosim+cosisq * (-12.0 + 8.0 * cosim + 10.0 * cosisq)); f543 = 29.53125 * sinim * (-2.0 - 8.0 * cosim+cosisq * (12.0 + 8.0 * cosim - 10.0 * cosisq)); xno2 = nm * nm; ainv2 = aonv * aonv; temp1 = 3.0 * xno2 * ainv2; temp = temp1 * root22; d2201 = temp * f220 * g201; d2211 = temp * f221 * g211; temp1 = temp1 * aonv; temp = temp1 * root32; d3210 = temp * f321 * g310; d3222 = temp * f322 * g322; temp1 = temp1 * aonv; temp = 2.0 * temp1 * root44; d4410 = temp * f441 * g410; d4422 = temp * f442 * g422; temp1 = temp1 * aonv; temp = temp1 * root52; d5220 = temp * f522 * g520; d5232 = temp * f523 * g532; temp = 2.0 * temp1 * root54; d5421 = temp * f542 * g521; d5433 = temp * f543 * g533; xlamo = fmod(mo + nodeo + nodeo-theta - theta, twopi); xfact = mdot + dmdt + 2.0 * (nodedot + dnodt - rptim) - no; em = emo; emsq = emsqo; } /* ---------------- synchronous resonance terms -------------- */ if (irez == 1) { g200 = 1.0 + emsq * (-2.5 + 0.8125 * emsq); g310 = 1.0 + 2.0 * emsq; g300 = 1.0 + emsq * (-6.0 + 6.60937 * emsq); f220 = 0.75 * (1.0 + cosim) * (1.0 + cosim); f311 = 0.9375 * sinim * sinim * (1.0 + 3.0 * cosim) - 0.75 * (1.0 + cosim); f330 = 1.0 + cosim; f330 = 1.875 * f330 * f330 * f330; del1 = 3.0 * nm * nm * aonv * aonv; del2 = 2.0 * del1 * f220 * g200 * q22; del3 = 3.0 * del1 * f330 * g300 * q33 * aonv; del1 = del1 * f311 * g310 * q31 * aonv; xlamo = fmod(mo + nodeo + argpo - theta, twopi); xfact = mdot + xpidot - rptim + dmdt + domdt + dnodt - no; } /* ------------ for sgp4, initialize the integrator ---------- */ xli = xlamo; xni = no; atime = 0.0; nm = no + dndt; } //#include "debug3.cpp" } // end dsinit /*----------------------------------------------------------------------------- * * procedure dspace * * this procedure provides deep space contributions to mean elements for * perturbing third body. these effects have been averaged over one * revolution of the sun and moon. for earth resonance effects, the * effects have been averaged over no revolutions of the satellite. * (mean motion) * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * d2201, d2211, d3210, d3222, d4410, d4422, d5220, d5232, d5421, d5433 - * dedt - * del1, del2, del3 - * didt - * dmdt - * dnodt - * domdt - * irez - flag for resonance 0-none, 1-one day, 2-half day * argpo - argument of perigee * argpdot - argument of perigee dot (rate) * t - time * tc - * gsto - gst * xfact - * xlamo - * no - mean motion * atime - * em - eccentricity * ft - * argpm - argument of perigee * inclm - inclination * xli - * mm - mean anomaly * xni - mean motion * nodem - right ascension of ascending node * * outputs : * atime - * em - eccentricity * argpm - argument of perigee * inclm - inclination * xli - * mm - mean anomaly * xni - * nodem - right ascension of ascending node * dndt - * nm - mean motion * * locals : * delt - * ft - * theta - * x2li - * x2omi - * xl - * xldot - * xnddt - * xndt - * xomi - * * coupling : * none - * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ static void dspace ( int irez, double d2201, double d2211, double d3210, double d3222, double d4410, double d4422, double d5220, double d5232, double d5421, double d5433, double dedt, double del1, double del2, double del3, double didt, double dmdt, double dnodt, double domdt, double argpo, double argpdot, double t, double tc, double gsto, double xfact, double xlamo, double no, double& atime, double& em, double& argpm, double& inclm, double& xli, double& mm, double& xni, double& nodem, double& dndt, double& nm ) { - const double twopi = 2.0 * pi; + const double twopi = 2.0 * marble_pi; int iretn; double delt, ft, theta, x2li, x2omi, xl, xldot , xnddt, xndt, xomi, g22, g32, g44, g52, g54, fasx2, fasx4, fasx6, rptim , step2, stepn , stepp; fasx2 = 0.13130908; fasx4 = 2.8843198; fasx6 = 0.37448087; g22 = 5.7686396; g32 = 0.95240898; g44 = 1.8014998; g52 = 1.0508330; g54 = 4.4108898; rptim = 4.37526908801129966e-3; // this equates to 7.29211514668855e-5 rad/sec stepp = 720.0; stepn = -720.0; step2 = 259200.0; /* ----------- calculate deep space resonance effects ----------- */ dndt = 0.0; theta = fmod(gsto + tc * rptim, twopi); em = em + dedt * t; inclm = inclm + didt * t; argpm = argpm + domdt * t; nodem = nodem + dnodt * t; mm = mm + dmdt * t; // sgp4fix for negative inclinations // the following if statement should be commented out // if (inclm < 0.0) // { // inclm = -inclm; // argpm = argpm - pi; // nodem = nodem + pi; // } /* - update resonances : numerical (euler-maclaurin) integration - */ /* ------------------------- epoch restart ---------------------- */ // sgp4fix for propagator problems // the following integration works for negative time steps and periods // the specific changes are unknown because the original code was so convoluted // sgp4fix take out atime = 0.0 and fix for faster operation ft = 0.0; if (irez != 0) { // sgp4fix streamline check if ((atime == 0.0) || (t * atime <= 0.0) || (fabs(t) < fabs(atime)) ) { atime = 0.0; xni = no; xli = xlamo; } // sgp4fix move check outside loop if (t > 0.0) delt = stepp; else delt = stepn; iretn = 381; // added for do loop while (iretn == 381) { /* ------------------- dot terms calculated ------------- */ /* ----------- near - synchronous resonance terms ------- */ if (irez != 2) { xndt = del1 * sin(xli - fasx2) + del2 * sin(2.0 * (xli - fasx4)) + del3 * sin(3.0 * (xli - fasx6)); xldot = xni + xfact; xnddt = del1 * cos(xli - fasx2) + 2.0 * del2 * cos(2.0 * (xli - fasx4)) + 3.0 * del3 * cos(3.0 * (xli - fasx6)); xnddt = xnddt * xldot; } else { /* --------- near - half-day resonance terms -------- */ xomi = argpo + argpdot * atime; x2omi = xomi + xomi; x2li = xli + xli; xndt = d2201 * sin(x2omi + xli - g22) + d2211 * sin(xli - g22) + d3210 * sin(xomi + xli - g32) + d3222 * sin(-xomi + xli - g32)+ d4410 * sin(x2omi + x2li - g44)+ d4422 * sin(x2li - g44) + d5220 * sin(xomi + xli - g52) + d5232 * sin(-xomi + xli - g52)+ d5421 * sin(xomi + x2li - g54) + d5433 * sin(-xomi + x2li - g54); xldot = xni + xfact; xnddt = d2201 * cos(x2omi + xli - g22) + d2211 * cos(xli - g22) + d3210 * cos(xomi + xli - g32) + d3222 * cos(-xomi + xli - g32) + d5220 * cos(xomi + xli - g52) + d5232 * cos(-xomi + xli - g52) + 2.0 * (d4410 * cos(x2omi + x2li - g44) + d4422 * cos(x2li - g44) + d5421 * cos(xomi + x2li - g54) + d5433 * cos(-xomi + x2li - g54)); xnddt = xnddt * xldot; } /* ----------------------- integrator ------------------- */ // sgp4fix move end checks to end of routine if (fabs(t - atime) >= stepp) { iretn = 381; } else // exit here { ft = t - atime; iretn = 0; } if (iretn == 381) { xli = xli + xldot * delt + xndt * step2; xni = xni + xndt * delt + xnddt * step2; atime = atime + delt; } } // while iretn = 381 nm = xni + xndt * ft + xnddt * ft * ft * 0.5; xl = xli + xldot * ft + xndt * ft * ft * 0.5; if (irez != 1) { mm = xl - 2.0 * nodem + 2.0 * theta; dndt = nm - no; } else { mm = xl - nodem - argpm + theta; dndt = nm - no; } nm = no + dndt; } //#include "debug4.cpp" } // end dsspace /*----------------------------------------------------------------------------- * * procedure initl * * this procedure initializes the spg4 propagator. all the initialization is * consolidated here instead of having multiple loops inside other routines. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * ecco - eccentricity 0.0 - 1.0 * epoch - epoch time in days from jan 0, 1950. 0 hr * inclo - inclination of satellite * no - mean motion of satellite * satn - satellite number * * outputs : * ainv - 1.0 / a * ao - semi major axis * con41 - * con42 - 1.0 - 5.0 cos(i) * cosio - cosine of inclination * cosio2 - cosio squared * eccsq - eccentricity squared * method - flag for deep space 'd', 'n' * omeosq - 1.0 - ecco * ecco * posq - semi-parameter squared * rp - radius of perigee * rteosq - square root of (1.0 - ecco*ecco) * sinio - sine of inclination * gsto - gst at time of observation rad * no - mean motion of satellite * * locals : * ak - * d1 - * del - * adel - * po - * * coupling : * getgravconst * gstime - find greenwich sidereal time from the julian date * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ static void initl ( int satn, gravconsttype whichconst, double ecco, double epoch, double inclo, double& no, char& method, double& ainv, double& ao, double& con41, double& con42, double& cosio, double& cosio2,double& eccsq, double& omeosq, double& posq, double& rp, double& rteosq,double& sinio , double& gsto, char opsmode ) { UNUSED( satn ); /* --------------------- local variables ------------------------ */ double ak, d1, del, adel, po, x2o3, j2, xke, tumin, mu, radiusearthkm, j3, j4, j3oj2; // sgp4fix use old way of finding gst double ds70; double ts70, tfrac, c1, thgr70, fk5r, c1p2p; - const double twopi = 2.0 * pi; + const double twopi = 2.0 * marble_pi; /* ----------------------- earth constants ---------------------- */ // sgp4fix identify constants and allow alternate values getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); x2o3 = 2.0 / 3.0; /* ------------- calculate auxillary epoch quantities ---------- */ eccsq = ecco * ecco; omeosq = 1.0 - eccsq; rteosq = sqrt(omeosq); cosio = cos(inclo); cosio2 = cosio * cosio; /* ------------------ un-kozai the mean motion ----------------- */ ak = pow(xke / no, x2o3); d1 = 0.75 * j2 * (3.0 * cosio2 - 1.0) / (rteosq * omeosq); del = d1 / (ak * ak); adel = ak * (1.0 - del * del - del * (1.0 / 3.0 + 134.0 * del * del / 81.0)); del = d1/(adel * adel); no = no / (1.0 + del); ao = pow(xke / no, x2o3); sinio = sin(inclo); po = ao * omeosq; con42 = 1.0 - 5.0 * cosio2; con41 = -con42-cosio2-cosio2; ainv = 1.0 / ao; posq = po * po; rp = ao * (1.0 - ecco); method = 'n'; // sgp4fix modern approach to finding sidereal time if (opsmode == 'a') { // sgp4fix use old way of finding gst // count integer number of days from 0 jan 1970 ts70 = epoch - 7305.0; ds70 = floor(ts70 + 1.0e-8); tfrac = ts70 - ds70; // find greenwich location at epoch c1 = 1.72027916940703639e-2; thgr70= 1.7321343856509374; fk5r = 5.07551419432269442e-15; c1p2p = c1 + twopi; gsto = fmod( thgr70 + c1*ds70 + c1p2p*tfrac + ts70*ts70*fk5r, twopi); if ( gsto < 0.0 ) gsto = gsto + twopi; } else gsto = gstime(epoch + 2433281.5); //#include "debug5.cpp" } // end initl /*----------------------------------------------------------------------------- * * procedure sgp4init * * this procedure initializes variables for sgp4. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * opsmode - mode of operation afspc or improved 'a', 'i' * whichconst - which set of constants to use 72, 84 * satn - satellite number * bstar - sgp4 type drag coefficient kg/m2er * ecco - eccentricity * epoch - epoch time in days from jan 0, 1950. 0 hr * argpo - argument of perigee (output if ds) * inclo - inclination * mo - mean anomaly (output if ds) * no - mean motion * nodeo - right ascension of ascending node * * outputs : * satrec - common values for subsequent calls * return code - non-zero on error. * 1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er * 2 - mean motion less than 0.0 * 3 - pert elements, ecc < 0.0 or ecc > 1.0 * 4 - semi-latus rectum < 0.0 * 5 - epoch elements are sub-orbital * 6 - satellite has decayed * * locals : * cnodm , snodm , cosim , sinim , cosomm , sinomm * cc1sq , cc2 , cc3 * coef , coef1 * cosio4 - * day - * dndt - * em - eccentricity * emsq - eccentricity squared * eeta - * etasq - * gam - * argpm - argument of perigee * nodem - * inclm - inclination * mm - mean anomaly * nm - mean motion * perige - perigee * pinvsq - * psisq - * qzms24 - * rtemsq - * s1, s2, s3, s4, s5, s6, s7 - * sfour - * ss1, ss2, ss3, ss4, ss5, ss6, ss7 - * sz1, sz2, sz3 * sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33 - * tc - * temp - * temp1, temp2, temp3 - * tsi - * xpidot - * xhdot1 - * z1, z2, z3 - * z11, z12, z13, z21, z22, z23, z31, z32, z33 - * * coupling : * getgravconst- * initl - * dscom - * dpper - * dsinit - * sgp4 - * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ bool sgp4init ( gravconsttype whichconst, char opsmode, const int satn, const double epoch, const double xbstar, const double xecco, const double xargpo, const double xinclo, const double xmo, const double xno, const double xnodeo, elsetrec& satrec ) { /* --------------------- local variables ------------------------ */ double ao, ainv, con42, cosio, sinio, cosio2, eccsq, omeosq, posq, rp, rteosq, cnodm , snodm , cosim , sinim , cosomm, sinomm, cc1sq , cc2 , cc3 , coef , coef1 , cosio4, day , dndt , em , emsq , eeta , etasq , gam , argpm , nodem , inclm , mm , nm , perige, pinvsq, psisq , qzms24, rtemsq, s1 , s2 , s3 , s4 , s5 , s6 , s7 , sfour , ss1 , ss2 , ss3 , ss4 , ss5 , ss6 , ss7 , sz1 , sz2 , sz3 , sz11 , sz12 , sz13 , sz21 , sz22 , sz23 , sz31 , sz32 , sz33 , tc , temp , temp1 , temp2 , temp3 , tsi , xpidot, xhdot1, z1 , z2 , z3 , z11 , z12 , z13 , z21 , z22 , z23 , z31 , z32 , z33, qzms2t, ss, j2, j3oj2, j4, x2o3, r[3], v[3], tumin, mu, radiusearthkm, xke, j3; /* ------------------------ initialization --------------------- */ // sgp4fix divisor for divide by zero check on inclination // the old check used 1.0 + cos(pi-1.0e-9), but then compared it to // 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency const double temp4 = 1.5e-12; /* ----------- set all near earth variables to zero ------------ */ satrec.isimp = 0; satrec.method = 'n'; satrec.aycof = 0.0; satrec.con41 = 0.0; satrec.cc1 = 0.0; satrec.cc4 = 0.0; satrec.cc5 = 0.0; satrec.d2 = 0.0; satrec.d3 = 0.0; satrec.d4 = 0.0; satrec.delmo = 0.0; satrec.eta = 0.0; satrec.argpdot = 0.0; satrec.omgcof = 0.0; satrec.sinmao = 0.0; satrec.t = 0.0; satrec.t2cof = 0.0; satrec.t3cof = 0.0; satrec.t4cof = 0.0; satrec.t5cof = 0.0; satrec.x1mth2 = 0.0; satrec.x7thm1 = 0.0; satrec.mdot = 0.0; satrec.nodedot = 0.0; satrec.xlcof = 0.0; satrec.xmcof = 0.0; satrec.nodecf = 0.0; /* ----------- set all deep space variables to zero ------------ */ satrec.irez = 0; satrec.d2201 = 0.0; satrec.d2211 = 0.0; satrec.d3210 = 0.0; satrec.d3222 = 0.0; satrec.d4410 = 0.0; satrec.d4422 = 0.0; satrec.d5220 = 0.0; satrec.d5232 = 0.0; satrec.d5421 = 0.0; satrec.d5433 = 0.0; satrec.dedt = 0.0; satrec.del1 = 0.0; satrec.del2 = 0.0; satrec.del3 = 0.0; satrec.didt = 0.0; satrec.dmdt = 0.0; satrec.dnodt = 0.0; satrec.domdt = 0.0; satrec.e3 = 0.0; satrec.ee2 = 0.0; satrec.peo = 0.0; satrec.pgho = 0.0; satrec.pho = 0.0; satrec.pinco = 0.0; satrec.plo = 0.0; satrec.se2 = 0.0; satrec.se3 = 0.0; satrec.sgh2 = 0.0; satrec.sgh3 = 0.0; satrec.sgh4 = 0.0; satrec.sh2 = 0.0; satrec.sh3 = 0.0; satrec.si2 = 0.0; satrec.si3 = 0.0; satrec.sl2 = 0.0; satrec.sl3 = 0.0; satrec.sl4 = 0.0; satrec.gsto = 0.0; satrec.xfact = 0.0; satrec.xgh2 = 0.0; satrec.xgh3 = 0.0; satrec.xgh4 = 0.0; satrec.xh2 = 0.0; satrec.xh3 = 0.0; satrec.xi2 = 0.0; satrec.xi3 = 0.0; satrec.xl2 = 0.0; satrec.xl3 = 0.0; satrec.xl4 = 0.0; satrec.xlamo = 0.0; satrec.zmol = 0.0; satrec.zmos = 0.0; satrec.atime = 0.0; satrec.xli = 0.0; satrec.xni = 0.0; // sgp4fix - note the following variables are also passed directly via satrec. // it is possible to streamline the sgp4init call by deleting the "x" // variables, but the user would need to set the satrec.* values first. we // include the additional assignments in case twoline2rv is not used. satrec.bstar = xbstar; satrec.ecco = xecco; satrec.argpo = xargpo; satrec.inclo = xinclo; satrec.mo = xmo; satrec.no = xno; satrec.nodeo = xnodeo; // sgp4fix add opsmode satrec.operationmode = opsmode; /* ------------------------ earth constants ----------------------- */ // sgp4fix identify constants and allow alternate values getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); ss = 78.0 / radiusearthkm + 1.0; qzms2t = pow(((120.0 - 78.0) / radiusearthkm), 4); x2o3 = 2.0 / 3.0; satrec.init = 'y'; satrec.t = 0.0; initl ( satn, whichconst, satrec.ecco, epoch, satrec.inclo, satrec.no, satrec.method, ainv, ao, satrec.con41, con42, cosio, cosio2, eccsq, omeosq, posq, rp, rteosq, sinio, satrec.gsto, satrec.operationmode ); satrec.error = 0; // sgp4fix remove this check as it is unnecessary // the mrt check in sgp4 handles decaying satellite cases even if the starting // condition is below the surface of te earth // if (rp < 1.0) // { // printf("# *** satn%d epoch elts sub-orbital ***\n", satn); // satrec.error = 5; // } if ((omeosq >= 0.0 ) || ( satrec.no >= 0.0)) { satrec.isimp = 0; if (rp < (220.0 / radiusearthkm + 1.0)) satrec.isimp = 1; sfour = ss; qzms24 = qzms2t; perige = (rp - 1.0) * radiusearthkm; /* - for perigees below 156 km, s and qoms2t are altered - */ if (perige < 156.0) { sfour = perige - 78.0; if (perige < 98.0) sfour = 20.0; qzms24 = pow(((120.0 - sfour) / radiusearthkm), 4.0); sfour = sfour / radiusearthkm + 1.0; } pinvsq = 1.0 / posq; tsi = 1.0 / (ao - sfour); satrec.eta = ao * satrec.ecco * tsi; etasq = satrec.eta * satrec.eta; eeta = satrec.ecco * satrec.eta; psisq = fabs(1.0 - etasq); coef = qzms24 * pow(tsi, 4.0); coef1 = coef / pow(psisq, 3.5); cc2 = coef1 * satrec.no * (ao * (1.0 + 1.5 * etasq + eeta * (4.0 + etasq)) + 0.375 * j2 * tsi / psisq * satrec.con41 * (8.0 + 3.0 * etasq * (8.0 + etasq))); satrec.cc1 = satrec.bstar * cc2; cc3 = 0.0; if (satrec.ecco > 1.0e-4) cc3 = -2.0 * coef * tsi * j3oj2 * satrec.no * sinio / satrec.ecco; satrec.x1mth2 = 1.0 - cosio2; satrec.cc4 = 2.0* satrec.no * coef1 * ao * omeosq * (satrec.eta * (2.0 + 0.5 * etasq) + satrec.ecco * (0.5 + 2.0 * etasq) - j2 * tsi / (ao * psisq) * (-3.0 * satrec.con41 * (1.0 - 2.0 * eeta + etasq * (1.5 - 0.5 * eeta)) + 0.75 * satrec.x1mth2 * (2.0 * etasq - eeta * (1.0 + etasq)) * cos(2.0 * satrec.argpo))); satrec.cc5 = 2.0 * coef1 * ao * omeosq * (1.0 + 2.75 * (etasq + eeta) + eeta * etasq); cosio4 = cosio2 * cosio2; temp1 = 1.5 * j2 * pinvsq * satrec.no; temp2 = 0.5 * temp1 * j2 * pinvsq; temp3 = -0.46875 * j4 * pinvsq * pinvsq * satrec.no; satrec.mdot = satrec.no + 0.5 * temp1 * rteosq * satrec.con41 + 0.0625 * temp2 * rteosq * (13.0 - 78.0 * cosio2 + 137.0 * cosio4); satrec.argpdot = -0.5 * temp1 * con42 + 0.0625 * temp2 * (7.0 - 114.0 * cosio2 + 395.0 * cosio4) + temp3 * (3.0 - 36.0 * cosio2 + 49.0 * cosio4); xhdot1 = -temp1 * cosio; satrec.nodedot = xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * cosio2) + 2.0 * temp3 * (3.0 - 7.0 * cosio2)) * cosio; xpidot = satrec.argpdot+ satrec.nodedot; satrec.omgcof = satrec.bstar * cc3 * cos(satrec.argpo); satrec.xmcof = 0.0; if (satrec.ecco > 1.0e-4) satrec.xmcof = -x2o3 * coef * satrec.bstar / eeta; satrec.nodecf = 3.5 * omeosq * xhdot1 * satrec.cc1; satrec.t2cof = 1.5 * satrec.cc1; // sgp4fix for divide by zero with xinco = 180 deg if (fabs(cosio+1.0) > 1.5e-12) satrec.xlcof = -0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio) / (1.0 + cosio); else satrec.xlcof = -0.25 * j3oj2 * sinio * (3.0 + 5.0 * cosio) / temp4; satrec.aycof = -0.5 * j3oj2 * sinio; satrec.delmo = pow((1.0 + satrec.eta * cos(satrec.mo)), 3); satrec.sinmao = sin(satrec.mo); satrec.x7thm1 = 7.0 * cosio2 - 1.0; /* --------------- deep space initialization ------------- */ - if ((2*pi / satrec.no) >= 225.0) + if ((2*marble_pi / satrec.no) >= 225.0) { satrec.method = 'd'; satrec.isimp = 1; tc = 0.0; inclm = satrec.inclo; dscom ( epoch, satrec.ecco, satrec.argpo, tc, satrec.inclo, satrec.nodeo, satrec.no, snodm, cnodm, sinim, cosim,sinomm, cosomm, day, satrec.e3, satrec.ee2, em, emsq, gam, satrec.peo, satrec.pgho, satrec.pho, satrec.pinco, satrec.plo, rtemsq, satrec.se2, satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4, satrec.sh2, satrec.sh3, satrec.si2, satrec.si3, satrec.sl2, satrec.sl3, satrec.sl4, s1, s2, s3, s4, s5, s6, s7, ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3, sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33, satrec.xgh2, satrec.xgh3, satrec.xgh4, satrec.xh2, satrec.xh3, satrec.xi2, satrec.xi3, satrec.xl2, satrec.xl3, satrec.xl4, nm, z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33, satrec.zmol, satrec.zmos ); dpper ( satrec.e3, satrec.ee2, satrec.peo, satrec.pgho, satrec.pho, satrec.pinco, satrec.plo, satrec.se2, satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4, satrec.sh2, satrec.sh3, satrec.si2, satrec.si3, satrec.sl2, satrec.sl3, satrec.sl4, satrec.t, satrec.xgh2,satrec.xgh3,satrec.xgh4, satrec.xh2, satrec.xh3, satrec.xi2, satrec.xi3, satrec.xl2, satrec.xl3, satrec.xl4, satrec.zmol, satrec.zmos, inclm, satrec.init, satrec.ecco, satrec.inclo, satrec.nodeo, satrec.argpo, satrec.mo, satrec.operationmode ); argpm = 0.0; nodem = 0.0; mm = 0.0; dsinit ( whichconst, cosim, emsq, satrec.argpo, s1, s2, s3, s4, s5, sinim, ss1, ss2, ss3, ss4, ss5, sz1, sz3, sz11, sz13, sz21, sz23, sz31, sz33, satrec.t, tc, satrec.gsto, satrec.mo, satrec.mdot, satrec.no, satrec.nodeo, satrec.nodedot, xpidot, z1, z3, z11, z13, z21, z23, z31, z33, satrec.ecco, eccsq, em, argpm, inclm, mm, nm, nodem, satrec.irez, satrec.atime, satrec.d2201, satrec.d2211, satrec.d3210, satrec.d3222 , satrec.d4410, satrec.d4422, satrec.d5220, satrec.d5232, satrec.d5421, satrec.d5433, satrec.dedt, satrec.didt, satrec.dmdt, dndt, satrec.dnodt, satrec.domdt , satrec.del1, satrec.del2, satrec.del3, satrec.xfact, satrec.xlamo, satrec.xli, satrec.xni ); } /* ----------- set variables if not deep space ----------- */ if (satrec.isimp != 1) { cc1sq = satrec.cc1 * satrec.cc1; satrec.d2 = 4.0 * ao * tsi * cc1sq; temp = satrec.d2 * tsi * satrec.cc1 / 3.0; satrec.d3 = (17.0 * ao + sfour) * temp; satrec.d4 = 0.5 * temp * ao * tsi * (221.0 * ao + 31.0 * sfour) * satrec.cc1; satrec.t3cof = satrec.d2 + 2.0 * cc1sq; satrec.t4cof = 0.25 * (3.0 * satrec.d3 + satrec.cc1 * (12.0 * satrec.d2 + 10.0 * cc1sq)); satrec.t5cof = 0.2 * (3.0 * satrec.d4 + 12.0 * satrec.cc1 * satrec.d3 + 6.0 * satrec.d2 * satrec.d2 + 15.0 * cc1sq * (2.0 * satrec.d2 + cc1sq)); } } // if omeosq = 0 ... /* finally propagate to zero epoch to initialize all others. */ // sgp4fix take out check to let satellites process until they are actually below earth surface // if(satrec.error == 0) sgp4(whichconst, satrec, 0.0, r, v); satrec.init = 'n'; //#include "debug6.cpp" //sgp4fix return boolean. satrec.error contains any error codes return true; } // end sgp4init /*----------------------------------------------------------------------------- * * procedure sgp4 * * this procedure is the sgp4 prediction model from space command. this is an * updated and combined version of sgp4 and sdp4, which were originally * published separately in spacetrack report #3. this version follows the * methodology from the aiaa paper (2006) describing the history and * development of the code. * * author : david vallado 719-573-2600 28 jun 2005 * * inputs : * satrec - initialised structure from sgp4init() call. * tsince - time eince epoch (minutes) * * outputs : * r - position vector km * v - velocity km/sec * return code - non-zero on error. * 1 - mean elements, ecc >= 1.0 or ecc < -0.001 or a < 0.95 er * 2 - mean motion less than 0.0 * 3 - pert elements, ecc < 0.0 or ecc > 1.0 * 4 - semi-latus rectum < 0.0 * 5 - epoch elements are sub-orbital * 6 - satellite has decayed * * locals : * am - * axnl, aynl - * betal - * cosim , sinim , cosomm , sinomm , cnod , snod , cos2u , * sin2u , coseo1 , sineo1 , cosi , sini , cosip , sinip , * cosisq , cossu , sinsu , cosu , sinu * delm - * delomg - * dndt - * eccm - * emsq - * ecose - * el2 - * eo1 - * eccp - * esine - * argpm - * argpp - * omgadf - * pl - * r - * rtemsq - * rdotl - * rl - * rvdot - * rvdotl - * su - * t2 , t3 , t4 , tc * tem5, temp , temp1 , temp2 , tempa , tempe , templ * u , ux , uy , uz , vx , vy , vz * inclm - inclination * mm - mean anomaly * nm - mean motion * nodem - right asc of ascending node * xinc - * xincp - * xl - * xlm - * mp - * xmdf - * xmx - * xmy - * nodedf - * xnode - * nodep - * np - * * coupling : * getgravconst- * dpper * dpspace * * references : * hoots, roehrich, norad spacetrack report #3 1980 * hoots, norad spacetrack report #6 1986 * hoots, schumacher and glover 2004 * vallado, crawford, hujsak, kelso 2006 ----------------------------------------------------------------------------*/ bool sgp4 ( gravconsttype whichconst, elsetrec& satrec, double tsince, double r[3], double v[3] ) { double am , axnl , aynl , betal , cosim , cnod , cos2u, coseo1, cosi , cosip , cosisq, cossu , cosu, delm , delomg, em , emsq , ecose , el2 , eo1 , ep , esine , argpm, argpp , argpdf, pl, mrt = 0.0, mvt , rdotl , rl , rvdot , rvdotl, sinim , sin2u, sineo1, sini , sinip , sinsu , sinu , snod , su , t2 , t3 , t4 , tem5 , temp, temp1, temp2 , tempa, tempe , templ , u , ux , uy , uz , vx , vy , vz , inclm , mm , nm , nodem, xinc , xincp , xl , xlm , mp , xmdf , xmx , xmy , nodedf, xnode , nodep, tc , dndt, twopi, x2o3 , j2 , j3 , tumin, j4 , xke , j3oj2, radiusearthkm, mu, vkmpersec; int ktr; /* ------------------ set mathematical constants --------------- */ // sgp4fix divisor for divide by zero check on inclination // the old check used 1.0 + cos(pi-1.0e-9), but then compared it to // 1.5 e-12, so the threshold was changed to 1.5e-12 for consistency const double temp4 = 1.5e-12; - twopi = 2.0 * pi; + twopi = 2.0 * marble_pi; x2o3 = 2.0 / 3.0; // sgp4fix identify constants and allow alternate values getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 ); vkmpersec = radiusearthkm * xke/60.0; /* --------------------- clear sgp4 error flag ----------------- */ satrec.t = tsince; satrec.error = 0; /* ------- update for secular gravity and atmospheric drag ----- */ xmdf = satrec.mo + satrec.mdot * satrec.t; argpdf = satrec.argpo + satrec.argpdot * satrec.t; nodedf = satrec.nodeo + satrec.nodedot * satrec.t; argpm = argpdf; mm = xmdf; t2 = satrec.t * satrec.t; nodem = nodedf + satrec.nodecf * t2; tempa = 1.0 - satrec.cc1 * satrec.t; tempe = satrec.bstar * satrec.cc4 * satrec.t; templ = satrec.t2cof * t2; if (satrec.isimp != 1) { delomg = satrec.omgcof * satrec.t; delm = satrec.xmcof * (pow((1.0 + satrec.eta * cos(xmdf)), 3) - satrec.delmo); temp = delomg + delm; mm = xmdf + temp; argpm = argpdf - temp; t3 = t2 * satrec.t; t4 = t3 * satrec.t; tempa = tempa - satrec.d2 * t2 - satrec.d3 * t3 - satrec.d4 * t4; tempe = tempe + satrec.bstar * satrec.cc5 * (sin(mm) - satrec.sinmao); templ = templ + satrec.t3cof * t3 + t4 * (satrec.t4cof + satrec.t * satrec.t5cof); } nm = satrec.no; em = satrec.ecco; inclm = satrec.inclo; if (satrec.method == 'd') { tc = satrec.t; dspace ( satrec.irez, satrec.d2201, satrec.d2211, satrec.d3210, satrec.d3222, satrec.d4410, satrec.d4422, satrec.d5220, satrec.d5232, satrec.d5421, satrec.d5433, satrec.dedt, satrec.del1, satrec.del2, satrec.del3, satrec.didt, satrec.dmdt, satrec.dnodt, satrec.domdt, satrec.argpo, satrec.argpdot, satrec.t, tc, satrec.gsto, satrec.xfact, satrec.xlamo, satrec.no, satrec.atime, em, argpm, inclm, satrec.xli, mm, satrec.xni, nodem, dndt, nm ); } // if method = d if (nm <= 0.0) { // printf("# error nm %f\n", nm); satrec.error = 2; // sgp4fix add return return false; } am = pow((xke / nm),x2o3) * tempa * tempa; nm = xke / pow(am, 1.5); em = em - tempe; // fix tolerance for error recognition // sgp4fix am is fixed from the previous nm check if ((em >= 1.0) || (em < -0.001)/* || (am < 0.95)*/ ) { // printf("# error em %f\n", em); satrec.error = 1; // sgp4fix to return if there is an error in eccentricity return false; } // sgp4fix fix tolerance to avoid a divide by zero if (em < 1.0e-6) em = 1.0e-6; mm = mm + satrec.no * templ; xlm = mm + argpm + nodem; emsq = em * em; temp = 1.0 - emsq; nodem = fmod(nodem, twopi); argpm = fmod(argpm, twopi); xlm = fmod(xlm, twopi); mm = fmod(xlm - argpm - nodem, twopi); /* ----------------- compute extra mean quantities ------------- */ sinim = sin(inclm); cosim = cos(inclm); /* -------------------- add lunar-solar periodics -------------- */ ep = em; xincp = inclm; argpp = argpm; nodep = nodem; mp = mm; sinip = sinim; cosip = cosim; if (satrec.method == 'd') { dpper ( satrec.e3, satrec.ee2, satrec.peo, satrec.pgho, satrec.pho, satrec.pinco, satrec.plo, satrec.se2, satrec.se3, satrec.sgh2, satrec.sgh3, satrec.sgh4, satrec.sh2, satrec.sh3, satrec.si2, satrec.si3, satrec.sl2, satrec.sl3, satrec.sl4, satrec.t, satrec.xgh2, satrec.xgh3, satrec.xgh4, satrec.xh2, satrec.xh3, satrec.xi2, satrec.xi3, satrec.xl2, satrec.xl3, satrec.xl4, satrec.zmol, satrec.zmos, satrec.inclo, 'n', ep, xincp, nodep, argpp, mp, satrec.operationmode ); if (xincp < 0.0) { xincp = -xincp; - nodep = nodep + pi; - argpp = argpp - pi; + nodep = nodep + marble_pi; + argpp = argpp - marble_pi; } if ((ep < 0.0 ) || ( ep > 1.0)) { // printf("# error ep %f\n", ep); satrec.error = 3; // sgp4fix add return return false; } } // if method = d /* -------------------- long period periodics ------------------ */ if (satrec.method == 'd') { sinip = sin(xincp); cosip = cos(xincp); satrec.aycof = -0.5*j3oj2*sinip; // sgp4fix for divide by zero for xincp = 180 deg if (fabs(cosip+1.0) > 1.5e-12) satrec.xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip) / (1.0 + cosip); else satrec.xlcof = -0.25 * j3oj2 * sinip * (3.0 + 5.0 * cosip) / temp4; } axnl = ep * cos(argpp); temp = 1.0 / (am * (1.0 - ep * ep)); aynl = ep* sin(argpp) + temp * satrec.aycof; xl = mp + argpp + nodep + temp * satrec.xlcof * axnl; /* --------------------- solve kepler's equation --------------- */ u = fmod(xl - nodep, twopi); eo1 = u; tem5 = 9999.9; ktr = 1; // sgp4fix for kepler iteration // the following iteration needs better limits on corrections while (( fabs(tem5) >= 1.0e-12) && (ktr <= 10) ) { sineo1 = sin(eo1); coseo1 = cos(eo1); tem5 = 1.0 - coseo1 * axnl - sineo1 * aynl; tem5 = (u - aynl * coseo1 + axnl * sineo1 - eo1) / tem5; if(fabs(tem5) >= 0.95) tem5 = tem5 > 0.0 ? 0.95 : -0.95; eo1 = eo1 + tem5; ktr = ktr + 1; } /* ------------- short period preliminary quantities ----------- */ ecose = axnl*coseo1 + aynl*sineo1; esine = axnl*sineo1 - aynl*coseo1; el2 = axnl*axnl + aynl*aynl; pl = am*(1.0-el2); if (pl < 0.0) { // printf("# error pl %f\n", pl); satrec.error = 4; // sgp4fix add return return false; } else { rl = am * (1.0 - ecose); rdotl = sqrt(am) * esine/rl; rvdotl = sqrt(pl) / rl; betal = sqrt(1.0 - el2); temp = esine / (1.0 + betal); sinu = am / rl * (sineo1 - aynl - axnl * temp); cosu = am / rl * (coseo1 - axnl + aynl * temp); su = atan2(sinu, cosu); sin2u = (cosu + cosu) * sinu; cos2u = 1.0 - 2.0 * sinu * sinu; temp = 1.0 / pl; temp1 = 0.5 * j2 * temp; temp2 = temp1 * temp; /* -------------- update for short period periodics ------------ */ if (satrec.method == 'd') { cosisq = cosip * cosip; satrec.con41 = 3.0*cosisq - 1.0; satrec.x1mth2 = 1.0 - cosisq; satrec.x7thm1 = 7.0*cosisq - 1.0; } mrt = rl * (1.0 - 1.5 * temp2 * betal * satrec.con41) + 0.5 * temp1 * satrec.x1mth2 * cos2u; su = su - 0.25 * temp2 * satrec.x7thm1 * sin2u; xnode = nodep + 1.5 * temp2 * cosip * sin2u; xinc = xincp + 1.5 * temp2 * cosip * sinip * cos2u; mvt = rdotl - nm * temp1 * satrec.x1mth2 * sin2u / xke; rvdot = rvdotl + nm * temp1 * (satrec.x1mth2 * cos2u + 1.5 * satrec.con41) / xke; /* --------------------- orientation vectors ------------------- */ sinsu = sin(su); cossu = cos(su); snod = sin(xnode); cnod = cos(xnode); sini = sin(xinc); cosi = cos(xinc); xmx = -snod * cosi; xmy = cnod * cosi; ux = xmx * sinsu + cnod * cossu; uy = xmy * sinsu + snod * cossu; uz = sini * sinsu; vx = xmx * cossu - cnod * sinsu; vy = xmy * cossu - snod * sinsu; vz = sini * cossu; /* --------- position and velocity (in km and km/sec) ---------- */ r[0] = (mrt * ux)* radiusearthkm; r[1] = (mrt * uy)* radiusearthkm; r[2] = (mrt * uz)* radiusearthkm; v[0] = (mvt * ux + rvdot * vx) * vkmpersec; v[1] = (mvt * uy + rvdot * vy) * vkmpersec; v[2] = (mvt * uz + rvdot * vz) * vkmpersec; } // if pl > 0 // sgp4fix for decaying satellites if (mrt < 1.0) { // printf("# decay condition %11.6f \n",mrt); satrec.error = 6; return false; } //#include "debug7.cpp" return true; } // end sgp4 /* ----------------------------------------------------------------------------- * * function gstime * * this function finds the greenwich sidereal time. * * author : david vallado 719-573-2600 1 mar 2001 * * inputs description range / units * jdut1 - julian date in ut1 days from 4713 bc * * outputs : * gstime - greenwich sidereal time 0 to 2pi rad * * locals : * temp - temporary variable for doubles rad * tut1 - julian centuries from the * jan 1, 2000 12 h epoch (ut1) * * coupling : * none * * references : * vallado 2004, 191, eq 3-45 * --------------------------------------------------------------------------- */ double gstime ( double jdut1 ) { - const double twopi = 2.0 * pi; - const double deg2rad = pi / 180.0; + const double twopi = 2.0 * marble_pi; + const double deg2rad = marble_pi / 180.0; double temp, tut1; tut1 = (jdut1 - 2451545.0) / 36525.0; temp = -6.2e-6* tut1 * tut1 * tut1 + 0.093104 * tut1 * tut1 + (876600.0*3600 + 8640184.812866) * tut1 + 67310.54841; // sec temp = fmod(temp * deg2rad / 240.0, twopi); //360/86400 = 1/240, to deg, to rad // ------------------------ check quadrants --------------------- if (temp < 0.0) temp += twopi; return temp; } // end gstime /* ----------------------------------------------------------------------------- * * function getgravconst * * this function gets constants for the propagator. note that mu is identified to * facilitiate comparisons with newer models. the common useage is wgs72. * * author : david vallado 719-573-2600 21 jul 2006 * * inputs : * whichconst - which set of constants to use wgs72old, wgs72, wgs84 * * outputs : * tumin - minutes in one time unit * mu - earth gravitational parameter * radiusearthkm - radius of the earth in km * xke - reciprocal of tumin * j2, j3, j4 - un-normalized zonal harmonic values * j3oj2 - j3 divided by j2 * * locals : * * coupling : * none * * references : * norad spacetrack report #3 * vallado, crawford, hujsak, kelso 2006 --------------------------------------------------------------------------- */ void getgravconst ( gravconsttype whichconst, double& tumin, double& mu, double& radiusearthkm, double& xke, double& j2, double& j3, double& j4, double& j3oj2 ) { switch (whichconst) { // -- wgs-72 low precision str#3 constants -- case wgs72old: mu = 398600.79964; // in km3 / s2 radiusearthkm = 6378.135; // km xke = 0.0743669161; tumin = 1.0 / xke; j2 = 0.001082616; j3 = -0.00000253881; j4 = -0.00000165597; j3oj2 = j3 / j2; break; // ------------ wgs-72 constants ------------ case wgs72: mu = 398600.8; // in km3 / s2 radiusearthkm = 6378.135; // km xke = 60.0 / sqrt(radiusearthkm*radiusearthkm*radiusearthkm/mu); tumin = 1.0 / xke; j2 = 0.001082616; j3 = -0.00000253881; j4 = -0.00000165597; j3oj2 = j3 / j2; break; case wgs84: // ------------ wgs-84 constants ------------ mu = 398600.5; // in km3 / s2 radiusearthkm = 6378.137; // km xke = 60.0 / sqrt(radiusearthkm*radiusearthkm*radiusearthkm/mu); tumin = 1.0 / xke; j2 = 0.00108262998905; j3 = -0.00000253215306; j4 = -0.00000161098761; j3oj2 = j3 / j2; break; default: fprintf(stderr,"unknown gravity option (%d)\n",whichconst); break; } } // end getgravconst diff --git a/src/plugins/render/satellites/sgp4/sgp4unit.h b/src/plugins/render/satellites/sgp4/sgp4unit.h index 5d71430b2..43cbc5892 100644 --- a/src/plugins/render/satellites/sgp4/sgp4unit.h +++ b/src/plugins/render/satellites/sgp4/sgp4unit.h @@ -1,126 +1,126 @@ #ifndef _sgp4unit_ #define _sgp4unit_ /* ---------------------------------------------------------------- * * sgp4unit.h * * this file contains the sgp4 procedures for analytical propagation * of a satellite. the code was originally released in the 1980 and 1986 * spacetrack papers. a detailed discussion of the theory and history * may be found in the 2006 aiaa paper by vallado, crawford, hujsak, * and kelso. * * companion code for * fundamentals of astrodynamics and applications * 2007 * by david vallado * * (w) 719-573-2600, email dvallado@agi.com * * current : * 3 Nov 08 david vallado * put returns in for error codes * changes : * 29 sep 08 david vallado * fix atime for faster operation in dspace * add operationmode for afspc (a) or improved (i) * performance mode * 20 apr 07 david vallado * misc fixes for constants * 11 aug 06 david vallado * chg lyddane choice back to strn3, constants, misc doc * 15 dec 05 david vallado * misc fixes * 26 jul 05 david vallado * fixes for paper * note that each fix is preceded by a * comment with "sgp4fix" and an explanation of * what was changed * 10 aug 04 david vallado * 2nd printing baseline working * 14 may 01 david vallado * 2nd edition baseline * 80 norad * original baseline * ---------------------------------------------------------------- */ #include #include #define SGP4Version "SGP4 Version 2008-11-03" -#define pi 3.14159265358979323846 +#define marble_pi 3.14159265358979323846 // -------------------------- structure declarations ---------------------------- typedef enum { wgs72old, wgs72, wgs84 } gravconsttype; typedef struct elsetrec { long int satnum; int epochyr, epochtynumrev; int error; char operationmode; char init, method; /* Near Earth */ int isimp; double aycof , con41 , cc1 , cc4 , cc5 , d2 , d3 , d4 , delmo , eta , argpdot, omgcof , sinmao , t , t2cof, t3cof , t4cof , t5cof , x1mth2 , x7thm1 , mdot , nodedot, xlcof , xmcof , nodecf; /* Deep Space */ int irez; double d2201 , d2211 , d3210 , d3222 , d4410 , d4422 , d5220 , d5232 , d5421 , d5433 , dedt , del1 , del2 , del3 , didt , dmdt , dnodt , domdt , e3 , ee2 , peo , pgho , pho , pinco , plo , se2 , se3 , sgh2 , sgh3 , sgh4 , sh2 , sh3 , si2 , si3 , sl2 , sl3 , sl4 , gsto , xfact , xgh2 , xgh3 , xgh4 , xh2 , xh3 , xi2 , xi3 , xl2 , xl3 , xl4 , xlamo , zmol , zmos , atime , xli , xni; double a , altp , alta , epochdays, jdsatepoch , nddot , ndot , bstar , rcse , inclo , nodeo , ecco , argpo , mo , no; } elsetrec; // --------------------------- function declarations ---------------------------- bool sgp4init ( gravconsttype whichconst, char opsmode, const int satn, const double epoch, const double xbstar, const double xecco, const double xargpo, const double xinclo, const double xmo, const double xno, const double xnodeo, elsetrec& satrec ); bool sgp4 ( gravconsttype whichconst, elsetrec& satrec, double tsince, double r[3], double v[3] ); double gstime ( double jdut1 ); void getgravconst ( gravconsttype whichconst, double& tumin, double& mu, double& radiusearthkm, double& xke, double& j2, double& j3, double& j4, double& j3oj2 ); #endif