-bin.includes = feature.xml\r
+bin.includes = feature.xml
+root=rootFiles
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.simantics.maps.elevation.server"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.github.benmanes.caffeine"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
--- /dev/null
+# -*- coding: utf-8 -*-
+
+"""
+***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************
+"""
+
+from PyQt5.QtCore import (QCoreApplication, QVariant)
+from qgis.core import (QgsProcessing,
+ QgsFeatureSink,
+ QgsFeature,
+ QgsProcessingException,
+ QgsProcessingAlgorithm,
+ QgsProcessingParameterFeatureSource,
+ QgsProcessingParameterFeatureSink,
+ QgsProcessingParameterVectorLayer,
+ QgsProcessingParameterDistance,
+ QgsVectorDataProvider,
+ QgsFields,
+ QgsField,
+ QgsUnitTypes)
+import processing
+import re
+from operator import itemgetter
+
+class SpanCoordinatesAlgorithm(QgsProcessingAlgorithm):
+ """
+ This is an example algorithm that takes a vector layer and
+ creates a new identical one.
+
+ It is meant to be used as an example of how to create your own
+ algorithms and explain methods and variables used to do it. An
+ algorithm like this will be available in all elements, and there
+ is not need for additional work.
+
+ All Processing algorithms should extend the QgsProcessingAlgorithm
+ class.
+ """
+
+ # Constants used to refer to parameters and outputs. They will be
+ # used when calling the algorithm from another algorithm, or when
+ # calling from the QGIS console.
+
+ PIPE = 'PIPE'
+ SPAN = 'SPAN'
+ TOLERANCE = 'TOLERANCE'
+ MINIMUM_LENGTH = 'MINIMUM_LENGTH'
+ OUTPUT = 'OUTPUT'
+
+ # Constants for feature field names
+ FATHER_ID = 'FatherId'
+ LINESTRING = 'LineString'
+
+ # RegExp for DN values in
+ DN_PATTERN = re.compile(r"DN(\d+)(-.*)?")
+
+ def tr(self, string):
+ """
+ Returns a translatable string with the self.tr() function.
+ """
+ return QCoreApplication.translate('Processing', string)
+
+ def createInstance(self):
+ return SpanCoordinatesAlgorithm()
+
+ def name(self):
+ """
+ Returns the algorithm name, used for identifying the algorithm. This
+ string should be fixed for the algorithm, and must not be localised.
+ The name should be unique within each provider. Names should contain
+ lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'calculateDistrictCSV'
+
+ def displayName(self):
+ """
+ Returns the translated algorithm name, which should be used for any
+ user-visible display of the algorithm name.
+ """
+ return self.tr('Calculate CSV for Apros District')
+
+ def group(self):
+ """
+ Returns the name of the group this algorithm belongs to. This string
+ should be localised.
+ """
+ return self.tr('District network scripts')
+
+ def groupId(self):
+ """
+ Returns the unique ID of the group this algorithm belongs to. This
+ string should be fixed for the algorithm, and must not be localised.
+ The group id should be unique within each provider. Group id should
+ contain lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'districtscripts'
+
+ def shortHelpString(self):
+ """
+ Returns a localised short helper string for the algorithm. This string
+ should provide a basic description about what the algorithm does and the
+ parameters and outputs associated with it..
+ """
+ return self.tr("Calculate a string of coordinate points for a point span")
+
+ def initAlgorithm(self, config=None):
+ """
+ Here we define the inputs and output of the algorithm, along
+ with some other properties.
+ """
+
+ # We add the input vector features source. It can have any kind of
+ # geometry.
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.PIPE,
+ self.tr('Pipeline layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.SPAN,
+ self.tr('Point span layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ tol = QgsProcessingParameterDistance(
+ self.TOLERANCE,
+ self.tr('Location tolerance'),
+ 0.001,
+ minValue = 0.0
+ )
+ tol.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( tol )
+
+ dist = QgsProcessingParameterDistance(
+ self.MINIMUM_LENGTH,
+ self.tr('Minimum span length'),
+ 0.25,
+ minValue = 0.0
+ )
+ dist.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( dist )
+
+ self.addParameter(
+ QgsProcessingParameterFeatureSink(
+ self.OUTPUT,
+ self.tr('Output layer'),
+ QgsProcessing.TypeVectorLine
+ )
+ )
+
+ def processAlgorithm(self, parameters, context, feedback):
+ """
+ Here is where the processing itself takes place.
+ """
+
+ # Retrieve the feature source and sink. The 'dest_id' variable is used
+ # to uniquely identify the feature sink, and must be included in the
+ # dictionary returned by the processAlgorithm function.
+ pipe = self.parameterAsLayer(
+ parameters,
+ self.PIPE,
+ context
+ )
+
+ span = self.parameterAsLayer(
+ parameters,
+ self.SPAN,
+ context
+ )
+
+ eps = self.parameterAsDouble(
+ parameters,
+ self.TOLERANCE,
+ context
+ )
+
+ minLength = self.parameterAsDouble(
+ parameters,
+ self.MINIMUM_LENGTH,
+ context
+ )
+
+ feedback.pushInfo('Tolerance: {} m\nMinimum span length: {} m'.format(eps, minLength))
+
+ sourceFields = span.fields()
+ sourceNames = sourceFields.names()
+ outputFields = QgsFields(sourceFields)
+ if not ('x1' in sourceNames): outputFields.append(QgsField('x1', QVariant.Double))
+ if not ('y1' in sourceNames): outputFields.append(QgsField('y1', QVariant.Double))
+ if not ('z1' in sourceNames): outputFields.append(QgsField('z1', QVariant.Double))
+ if not ('x2' in sourceNames): outputFields.append(QgsField('x2', QVariant.Double))
+ if not ('y2' in sourceNames): outputFields.append(QgsField('y2', QVariant.Double))
+ if not ('z2' in sourceNames): outputFields.append(QgsField('z2', QVariant.Double))
+ if not ('Length' in sourceNames): outputFields.append(QgsField('Length', QVariant.Double))
+ if not ('LineString' in sourceNames): outputFields.append(QgsField('LineString', QVariant.String))
+ if not ('DimensionDN' in sourceNames): outputFields.append(QgsField('DimensionDN', QVariant.Int))
+ if not ('PipeStruct' in sourceNames): outputFields.append(QgsField('PipeStruct', QVariant.String))
+
+ (output, outputId) = self.parameterAsSink(
+ parameters,
+ self.OUTPUT,
+ context,
+ outputFields
+ )
+
+ # If source was not found, throw an exception to indicate that the algorithm
+ # encountered a fatal error. The exception text can be any string, but in this
+ # case we use the pre-built invalidSourceError method to return a standard
+ # helper text for when a source cannot be evaluated
+ if pipe is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.PIPE))
+ if span is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.SPAN))
+
+ # Compute the number of steps to display within the progress bar and
+ # get features from source
+ total = 100.0 / pipe.featureCount() if pipe.featureCount() else 0
+
+ # Dictionary from span feature ids to lengths
+ lengths = dict()
+
+ # Dictionary from span feature ids to lists of lists of QgsPoint objects
+ strings = dict()
+
+ # Dictionary for the PipeStruct field values
+ types = dict()
+
+ spanFeatures = span.getFeatures()
+ pipeFeatures = pipe.getFeatures()
+
+ for counter, feature in enumerate(pipeFeatures):
+ if feedback.isCanceled(): break
+
+ geometry = feature.geometry()
+ if geometry == None: continue
+
+ fatherID = feature[self.FATHER_ID]
+
+ # Length
+ myLength = feature['Length']
+ if myLength == None:
+ myLength = geometry.length()
+
+ oldLength = lengths.get(fatherID, 0.0)
+ lengths[fatherID] = oldLength + myLength
+
+ # Segment points
+ pointList = strings.get(fatherID, [])
+ # feedback.pushInfo('Point list: {}'.format(pointList))
+ mylist = []
+
+ vertices = geometry.vertices()
+ while vertices.hasNext():
+ mylist.append(vertices.next())
+
+ # feedback.pushInfo('Feature {}, Father {}, Points: {}'.format(feature['Id'], fatherID, ";".join(map(lambda x: '{} {}'.format(x.x(), x.y()), mylist))))
+
+ pointList.append(mylist)
+ strings[fatherID] = pointList
+
+ # Store the value of PipeStruct
+ t = feature['PipeStruct']
+ tt = types.get(fatherID, {})
+ types[fatherID] = tt
+ c = tt.get(t, 0)
+ c += myLength
+ tt[t] = c
+
+ # Update the progress bar
+ feedback.setProgress(int(counter * total))
+
+ if feedback.isCanceled():
+ return
+
+ feedback.pushInfo('Done')
+
+ #span.startEditing()
+
+ feedback.pushInfo('Started editing')
+ feedback.pushInfo(str(spanFeatures))
+
+ for feature in spanFeatures:
+ if feedback.isCanceled(): break
+
+ #feedback.pushInfo(str(feature))
+ id = feature['Id']
+ #feedback.pushInfo(str(id))
+
+ # Length
+ myLength = feature['Length']
+
+ # Ignore short stumps
+ if myLength <= minLength:
+ continue
+
+ # Vertices
+ mypoints = list(feature.geometry().vertices())
+ mylist = strings.get(id, None)
+ if mylist == None:
+ feedback.pushInfo('No points for feature {}'.format(id))
+ mylist = [mypoints]
+
+ #feedback.pushInfo('Points: {}'.format("|".join(map(lambda x: ";".join(('{} {}'.format(p.x(), p.y()) for p in x)), mylist))))
+
+ head = feature.geometry().vertices().next()
+ resultList = [head]
+
+ #feedback.pushInfo(str(resultList))
+
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ mylist = list(map(lambda x: list(reversed(x)), mylist))
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ feedback.pushInfo('Warning: No matching start vertex for feature {}'.format(id))
+ mylist = [mypoints]
+ i = 0
+
+ vertices = mylist.pop(i)
+
+ while i != None:
+ tail = vertices[-1]
+ resultList.extend(vertices[1:])
+ if tail.distance(mypoints[-1]) <= eps:
+ break
+
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[0]) <= eps), None)
+ if i != None:
+ vertices = mylist.pop(i)
+ else:
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[-1]) <= eps), None)
+ if i != None:
+ vertices = list(reversed(mylist.pop(i)))
+
+ # feedback.pushInfo(str(resultList))
+
+ # Convert to string
+ result = ";".join(('{} {}'.format(p.x(), p.y()) for p in resultList))
+
+ # feedback.pushInfo('Feature {}: {}'.format(id, result))
+
+ outputFeature = QgsFeature()
+ outputFeature.setFields(outputFields)
+ for i, x in enumerate(feature.attributes()):
+ fieldName = sourceFields[i].name()
+ outputFeature[fieldName] = x
+
+ outputFeature['x1'] = feature['x1']
+ outputFeature['y1'] = feature['y1']
+ outputFeature['z1'] = feature['z1']
+ outputFeature['x2'] = feature['x2']
+ outputFeature['y2'] = feature['y2']
+ outputFeature['z2'] = feature['z2']
+ outputFeature['Length'] = feature['Length'] # myLength
+ outputFeature['LineString'] = result
+
+ # Handle pipe type codes
+ mytypes = list(types.get(id, {}).items())
+ if len(mytypes) == 0:
+ feedback.pushInfo('No type codes for feature {}'.format(id))
+ else:
+ if len(mytypes) > 1:
+ mytypes.sort(key = itemgetter(1))
+ feedback.pushInfo('No unique type code for feature {}: {}'.format(id, mytypes))
+ outputFeature['PipeStruct'] = mytypes[-1][0]
+
+ label = feature['Label']
+ m = self.DN_PATTERN.fullmatch(label)
+ if m:
+ outputFeature['DimensionDN'] = int(m.group(1))
+
+ output.addFeature(outputFeature)
+
+ feedback.pushInfo('Loop done')
+
+ #if feedback.isCanceled():
+ # span.rollBack()
+ #else:
+ # span.commitChanges()
+
+ feedback.pushInfo('Changes committed')
+
+ # Return the results of the algorithm. In this case our only result is
+ # the feature sink which contains the processed features, but some
+ # algorithms may return multiple feature sinks, calculated numeric
+ # statistics, etc. These should all be included in the returned
+ # dictionary, with keys matching the feature corresponding parameter
+ # or output names.
+ return {self.OUTPUT: outputId}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+"""
+***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************
+"""
+
+from PyQt5.QtCore import (QCoreApplication, QVariant)
+from qgis.core import (QgsProcessing,
+ QgsFeatureSink,
+ QgsFeature,
+ QgsProcessingException,
+ QgsProcessingAlgorithm,
+ QgsProcessingParameterFeatureSource,
+ QgsProcessingParameterFeatureSink,
+ QgsProcessingParameterVectorLayer,
+ QgsProcessingParameterDistance,
+ QgsVectorDataProvider,
+ QgsFields,
+ QgsField,
+ QgsUnitTypes)
+import processing
+import re
+from operator import itemgetter
+
+class SpanCoordinatesAlgorithm2(QgsProcessingAlgorithm):
+ """
+ This is an example algorithm that takes a vector layer and
+ creates a new identical one.
+
+ It is meant to be used as an example of how to create your own
+ algorithms and explain methods and variables used to do it. An
+ algorithm like this will be available in all elements, and there
+ is not need for additional work.
+
+ All Processing algorithms should extend the QgsProcessingAlgorithm
+ class.
+ """
+
+ # Constants used to refer to parameters and outputs. They will be
+ # used when calling the algorithm from another algorithm, or when
+ # calling from the QGIS console.
+
+ PIPE = 'PIPE'
+ SPAN = 'SPAN'
+ TOLERANCE = 'TOLERANCE'
+ MINIMUM_LENGTH = 'MINIMUM_LENGTH'
+ OUTPUT = 'OUTPUT'
+
+ # Constants for feature field names
+ FATHER_ID = 'FatherId'
+ LINESTRING = 'LineString'
+
+ # RegExp for DN values in
+ DN_PATTERN = re.compile(r"DN(\d+)(-.*)?")
+
+ def tr(self, string):
+ """
+ Returns a translatable string with the self.tr() function.
+ """
+ return QCoreApplication.translate('Processing', string)
+
+ def createInstance(self):
+ return SpanCoordinatesAlgorithm2()
+
+ def name(self):
+ """
+ Returns the algorithm name, used for identifying the algorithm. This
+ string should be fixed for the algorithm, and must not be localised.
+ The name should be unique within each provider. Names should contain
+ lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'calculateDistrictCSV2'
+
+ def displayName(self):
+ """
+ Returns the translated algorithm name, which should be used for any
+ user-visible display of the algorithm name.
+ """
+ return self.tr('Calculate CSV for Apros District (No coordinates)')
+
+ def group(self):
+ """
+ Returns the name of the group this algorithm belongs to. This string
+ should be localised.
+ """
+ return self.tr('District network scripts')
+
+ def groupId(self):
+ """
+ Returns the unique ID of the group this algorithm belongs to. This
+ string should be fixed for the algorithm, and must not be localised.
+ The group id should be unique within each provider. Group id should
+ contain lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'districtscripts'
+
+ def shortHelpString(self):
+ """
+ Returns a localised short helper string for the algorithm. This string
+ should provide a basic description about what the algorithm does and the
+ parameters and outputs associated with it..
+ """
+ return self.tr("Calculate a string of coordinate points for a point span")
+
+ def initAlgorithm(self, config=None):
+ """
+ Here we define the inputs and output of the algorithm, along
+ with some other properties.
+ """
+
+ # We add the input vector features source. It can have any kind of
+ # geometry.
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.PIPE,
+ self.tr('Pipeline layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.SPAN,
+ self.tr('Point span layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ tol = QgsProcessingParameterDistance(
+ self.TOLERANCE,
+ self.tr('Location tolerance'),
+ 0.001,
+ minValue = 0.0
+ )
+ tol.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( tol )
+
+ dist = QgsProcessingParameterDistance(
+ self.MINIMUM_LENGTH,
+ self.tr('Minimum span length'),
+ 0.25,
+ minValue = 0.0
+ )
+ dist.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( dist )
+
+ self.addParameter(
+ QgsProcessingParameterFeatureSink(
+ self.OUTPUT,
+ self.tr('Output layer'),
+ QgsProcessing.TypeVectorLine
+ )
+ )
+
+ def processAlgorithm(self, parameters, context, feedback):
+ """
+ Here is where the processing itself takes place.
+ """
+
+ # Retrieve the feature source and sink. The 'dest_id' variable is used
+ # to uniquely identify the feature sink, and must be included in the
+ # dictionary returned by the processAlgorithm function.
+ pipe = self.parameterAsLayer(
+ parameters,
+ self.PIPE,
+ context
+ )
+
+ span = self.parameterAsLayer(
+ parameters,
+ self.SPAN,
+ context
+ )
+
+ eps = self.parameterAsDouble(
+ parameters,
+ self.TOLERANCE,
+ context
+ )
+
+ minLength = self.parameterAsDouble(
+ parameters,
+ self.MINIMUM_LENGTH,
+ context
+ )
+
+ feedback.pushInfo('Tolerance: {} m\nMinimum span length: {} m'.format(eps, minLength))
+
+ sourceFields = span.fields()
+ sourceNames = sourceFields.names()
+ outputFields = QgsFields(sourceFields)
+ if not ('x1' in sourceNames): outputFields.append(QgsField('x1', QVariant.Double))
+ if not ('y1' in sourceNames): outputFields.append(QgsField('y1', QVariant.Double))
+ if not ('z1' in sourceNames): outputFields.append(QgsField('z1', QVariant.Double))
+ if not ('x2' in sourceNames): outputFields.append(QgsField('x2', QVariant.Double))
+ if not ('y2' in sourceNames): outputFields.append(QgsField('y2', QVariant.Double))
+ if not ('z2' in sourceNames): outputFields.append(QgsField('z2', QVariant.Double))
+ if not ('Length' in sourceNames): outputFields.append(QgsField('Length', QVariant.Double))
+ if not ('LineString' in sourceNames): outputFields.append(QgsField('LineString', QVariant.String))
+ if not ('DimensionDN' in sourceNames): outputFields.append(QgsField('DimensionDN', QVariant.Int))
+ if not ('PipeStruct' in sourceNames): outputFields.append(QgsField('PipeStruct', QVariant.String))
+
+ (output, outputId) = self.parameterAsSink(
+ parameters,
+ self.OUTPUT,
+ context,
+ outputFields
+ )
+
+ # If source was not found, throw an exception to indicate that the algorithm
+ # encountered a fatal error. The exception text can be any string, but in this
+ # case we use the pre-built invalidSourceError method to return a standard
+ # helper text for when a source cannot be evaluated
+ if pipe is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.PIPE))
+ if span is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.SPAN))
+
+ # Compute the number of steps to display within the progress bar and
+ # get features from source
+ total = 100.0 / pipe.featureCount() if pipe.featureCount() else 0
+
+ # Dictionary from span feature ids to lengths
+ lengths = dict()
+
+ # Dictionary from span feature ids to lists of lists of QgsPoint objects
+ strings = dict()
+
+ # Dictionary for the PipeStruct field values
+ types = dict()
+
+ spanFeatures = span.getFeatures()
+ pipeFeatures = pipe.getFeatures()
+
+ for counter, feature in enumerate(pipeFeatures):
+ if feedback.isCanceled(): break
+
+ geometry = feature.geometry()
+ if geometry == None: continue
+
+ fatherID = feature[self.FATHER_ID]
+
+ # Length
+ myLength = None
+ if feature.fields().lookupField('Length') != -1:
+ myLength = feature['Length']
+ if myLength == None:
+ myLength = geometry.length()
+
+ oldLength = lengths.get(fatherID, 0.0)
+ lengths[fatherID] = oldLength + myLength
+
+ # Segment points
+ pointList = strings.get(fatherID, [])
+ # feedback.pushInfo('Point list: {}'.format(pointList))
+ mylist = []
+
+ vertices = geometry.vertices()
+ while vertices.hasNext():
+ mylist.append(vertices.next())
+
+ # feedback.pushInfo('Feature {}, Father {}, Points: {}'.format(feature['Id'], fatherID, ";".join(map(lambda x: '{} {}'.format(x.x(), x.y()), mylist))))
+
+ pointList.append(mylist)
+ strings[fatherID] = pointList
+
+ # Store the value of PipeStruct
+ t = feature['PipeStruct']
+ tt = types.get(fatherID, {})
+ types[fatherID] = tt
+ c = tt.get(t, 0)
+ c += myLength
+ tt[t] = c
+
+ # Update the progress bar
+ feedback.setProgress(int(counter * total))
+
+ if feedback.isCanceled():
+ return
+
+ feedback.pushInfo('Done')
+
+ #span.startEditing()
+
+ feedback.pushInfo('Started editing')
+ feedback.pushInfo(str(spanFeatures))
+
+ for feature in spanFeatures:
+ if feedback.isCanceled(): break
+
+ f = feature.fields()
+
+ #feedback.pushInfo(str(feature))
+ id = feature['Id']
+ #feedback.pushInfo(str(id))
+
+ # Length
+ myLength = None
+ if f.lookupField('Length') != -1:
+ myLength = feature['Length']
+ if myLength == None:
+ myLength = feature.geometry().length()
+
+ # Ignore short stumps
+ if myLength <= minLength:
+ continue
+
+ # Vertices
+ mypoints = list(feature.geometry().vertices())
+ mylist = strings.get(id, None)
+ if mylist == None:
+ feedback.pushInfo('No points for feature {}'.format(id))
+ mylist = [mypoints]
+
+ #feedback.pushInfo('Points: {}'.format("|".join(map(lambda x: ";".join(('{} {}'.format(p.x(), p.y()) for p in x)), mylist))))
+
+ head = feature.geometry().vertices().next()
+ resultList = [head]
+
+ #feedback.pushInfo(str(resultList))
+
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ mylist = list(map(lambda x: list(reversed(x)), mylist))
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ feedback.pushInfo('Warning: No matching start vertex for feature {}'.format(id))
+ mylist = [mypoints]
+ i = 0
+
+ vertices = mylist.pop(i)
+
+ while i != None:
+ tail = vertices[-1]
+ resultList.extend(vertices[1:])
+ if tail.distance(mypoints[-1]) <= eps:
+ break
+
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[0]) <= eps), None)
+ if i != None:
+ vertices = mylist.pop(i)
+ else:
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[-1]) <= eps), None)
+ if i != None:
+ vertices = list(reversed(mylist.pop(i)))
+
+ # feedback.pushInfo(str(resultList))
+
+ # Convert to string
+ result = ";".join(('{} {}'.format(p.x(), p.y()) for p in resultList))
+
+ # feedback.pushInfo('Feature {}: {}'.format(id, result))
+
+ outputFeature = QgsFeature()
+ outputFeature.setFields(outputFields)
+ for i, x in enumerate(feature.attributes()):
+ fieldName = sourceFields[i].name()
+ outputFeature[fieldName] = x
+
+ vts = list(feature.geometry().vertices())
+ p1 = vts[0]
+ p2 = vts[-1]
+
+ outputFeature['x1'] = feature['x1'] if f.lookupField('x1') != -1 else p1.x()
+ outputFeature['y1'] = feature['y1'] if f.lookupField('y1') != -1 else p1.y()
+ outputFeature['z1'] = feature['z1'] if f.lookupField('z1') != -1 else p1.z()
+ outputFeature['x2'] = feature['x2'] if f.lookupField('x2') != -1 else p2.x()
+ outputFeature['y2'] = feature['y2'] if f.lookupField('y2') != -1 else p2.y()
+ outputFeature['z2'] = feature['z2'] if f.lookupField('z2') != -1 else p2.z()
+ outputFeature['Length'] = feature['Length'] if f.lookupField('Length') != -1 else feature.geometry().length()
+ outputFeature['LineString'] = result
+
+ # Handle pipe type codes
+ mytypes = list(types.get(id, {}).items())
+ if len(mytypes) == 0:
+ feedback.pushInfo('No type codes for feature {}'.format(id))
+ else:
+ if len(mytypes) > 1:
+ mytypes.sort(key = itemgetter(1))
+ feedback.pushInfo('No unique type code for feature {}: {}'.format(id, mytypes))
+ outputFeature['PipeStruct'] = mytypes[-1][0]
+
+ if f.lookupField('Label') != -1:
+ label = feature['Label']
+ m = self.DN_PATTERN.fullmatch(label)
+ if m:
+ outputFeature['DimensionDN'] = int(m.group(1))
+
+ output.addFeature(outputFeature)
+
+ feedback.pushInfo('Loop done')
+
+ #if feedback.isCanceled():
+ # span.rollBack()
+ #else:
+ # span.commitChanges()
+
+ feedback.pushInfo('Changes committed')
+
+ # Return the results of the algorithm. In this case our only result is
+ # the feature sink which contains the processed features, but some
+ # algorithms may return multiple feature sinks, calculated numeric
+ # statistics, etc. These should all be included in the returned
+ # dictionary, with keys matching the feature corresponding parameter
+ # or output names.
+ return {self.OUTPUT: outputId}
--- /dev/null
+# -*- coding: utf-8 -*-
+
+"""
+***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************
+"""
+
+from PyQt5.QtCore import (QCoreApplication, QVariant)
+from qgis.core import (QgsProcessing,
+ QgsFeatureSink,
+ QgsFeature,
+ QgsProcessingException,
+ QgsProcessingAlgorithm,
+ QgsProcessingParameterFeatureSource,
+ QgsProcessingParameterFeatureSink,
+ QgsProcessingParameterVectorLayer,
+ QgsProcessingParameterDistance,
+ QgsVectorDataProvider,
+ QgsFields,
+ QgsField,
+ QgsUnitTypes)
+import processing
+import re
+from operator import itemgetter
+
+class SpanCoordinatesAlgorithm3(QgsProcessingAlgorithm):
+ """
+ This is an example algorithm that takes a vector layer and
+ creates a new identical one.
+
+ It is meant to be used as an example of how to create your own
+ algorithms and explain methods and variables used to do it. An
+ algorithm like this will be available in all elements, and there
+ is not need for additional work.
+
+ All Processing algorithms should extend the QgsProcessingAlgorithm
+ class.
+ """
+
+ # Constants used to refer to parameters and outputs. They will be
+ # used when calling the algorithm from another algorithm, or when
+ # calling from the QGIS console.
+
+ PIPE = 'PIPE'
+ SPAN = 'SPAN'
+ TOLERANCE = 'TOLERANCE'
+ MINIMUM_LENGTH = 'MINIMUM_LENGTH'
+ OUTPUT = 'OUTPUT'
+
+ # Constants for feature field names
+ FATHER_ID = 'FatherId'
+ LINESTRING = 'LineString'
+
+ # RegExp for DN values in
+ DN_PATTERN = re.compile(r"DN(\d+)(-.*)?")
+
+ def tr(self, string):
+ """
+ Returns a translatable string with the self.tr() function.
+ """
+ return QCoreApplication.translate('Processing', string)
+
+ def createInstance(self):
+ return SpanCoordinatesAlgorithm3()
+
+ def name(self):
+ """
+ Returns the algorithm name, used for identifying the algorithm. This
+ string should be fixed for the algorithm, and must not be localised.
+ The name should be unique within each provider. Names should contain
+ lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'calculateDistrictCSV3'
+
+ def displayName(self):
+ """
+ Returns the translated algorithm name, which should be used for any
+ user-visible display of the algorithm name.
+ """
+ return self.tr('Calculate CSV for Apros District (TechTypeData)')
+
+ def group(self):
+ """
+ Returns the name of the group this algorithm belongs to. This string
+ should be localised.
+ """
+ return self.tr('District network scripts')
+
+ def groupId(self):
+ """
+ Returns the unique ID of the group this algorithm belongs to. This
+ string should be fixed for the algorithm, and must not be localised.
+ The group id should be unique within each provider. Group id should
+ contain lowercase alphanumeric characters only and no spaces or other
+ formatting characters.
+ """
+ return 'districtscripts'
+
+ def shortHelpString(self):
+ """
+ Returns a localised short helper string for the algorithm. This string
+ should provide a basic description about what the algorithm does and the
+ parameters and outputs associated with it..
+ """
+ return self.tr("Calculate a string of coordinate points for a point span")
+
+ def initAlgorithm(self, config=None):
+ """
+ Here we define the inputs and output of the algorithm, along
+ with some other properties.
+ """
+
+ # We add the input vector features source. It can have any kind of
+ # geometry.
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.PIPE,
+ self.tr('Pipeline layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ self.addParameter(
+ QgsProcessingParameterVectorLayer(
+ self.SPAN,
+ self.tr('Point span layer'),
+ [QgsProcessing.TypeVectorLine]
+ )
+ )
+
+ tol = QgsProcessingParameterDistance(
+ self.TOLERANCE,
+ self.tr('Location tolerance'),
+ 0.001,
+ minValue = 0.0
+ )
+ tol.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( tol )
+
+ dist = QgsProcessingParameterDistance(
+ self.MINIMUM_LENGTH,
+ self.tr('Minimum span length'),
+ 0.25,
+ minValue = 0.0
+ )
+ dist.setDefaultUnit(QgsUnitTypes.DistanceMeters)
+ self.addParameter( dist )
+
+ self.addParameter(
+ QgsProcessingParameterFeatureSink(
+ self.OUTPUT,
+ self.tr('Output layer'),
+ QgsProcessing.TypeVectorLine
+ )
+ )
+
+ def processAlgorithm(self, parameters, context, feedback):
+ """
+ Here is where the processing itself takes place.
+ """
+
+ # Retrieve the feature source and sink. The 'dest_id' variable is used
+ # to uniquely identify the feature sink, and must be included in the
+ # dictionary returned by the processAlgorithm function.
+ pipe = self.parameterAsLayer(
+ parameters,
+ self.PIPE,
+ context
+ )
+
+ span = self.parameterAsLayer(
+ parameters,
+ self.SPAN,
+ context
+ )
+
+ eps = self.parameterAsDouble(
+ parameters,
+ self.TOLERANCE,
+ context
+ )
+
+ minLength = self.parameterAsDouble(
+ parameters,
+ self.MINIMUM_LENGTH,
+ context
+ )
+
+ feedback.pushInfo('Tolerance: {} m\nMinimum span length: {} m'.format(eps, minLength))
+
+ sourceFields = span.fields()
+ sourceNames = sourceFields.names()
+ outputFields = QgsFields(sourceFields)
+ if not ('x1' in sourceNames): outputFields.append(QgsField('x1', QVariant.Double))
+ if not ('y1' in sourceNames): outputFields.append(QgsField('y1', QVariant.Double))
+ if not ('z1' in sourceNames): outputFields.append(QgsField('z1', QVariant.Double))
+ if not ('x2' in sourceNames): outputFields.append(QgsField('x2', QVariant.Double))
+ if not ('y2' in sourceNames): outputFields.append(QgsField('y2', QVariant.Double))
+ if not ('z2' in sourceNames): outputFields.append(QgsField('z2', QVariant.Double))
+ if not ('Length' in sourceNames): outputFields.append(QgsField('Length', QVariant.Double))
+ if not ('LineString' in sourceNames): outputFields.append(QgsField('LineString', QVariant.String))
+ if not ('TechTypeId' in sourceNames): outputFields.append(QgsField('TechTypeId', QVariant.String))
+ if not ('PipeStruct' in sourceNames): outputFields.append(QgsField('PipeStruct', QVariant.String))
+
+ (output, outputId) = self.parameterAsSink(
+ parameters,
+ self.OUTPUT,
+ context,
+ outputFields
+ )
+
+ # If source was not found, throw an exception to indicate that the algorithm
+ # encountered a fatal error. The exception text can be any string, but in this
+ # case we use the pre-built invalidSourceError method to return a standard
+ # helper text for when a source cannot be evaluated
+ if pipe is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.PIPE))
+ if span is None:
+ raise QgsProcessingException(self.invalidSourceError(parameters, self.SPAN))
+
+ # Compute the number of steps to display within the progress bar and
+ # get features from source
+ total = 100.0 / pipe.featureCount() if pipe.featureCount() else 0
+
+ # Dictionary from span feature ids to lengths
+ lengths = dict()
+
+ # Dictionary from span feature ids to lists of lists of QgsPoint objects
+ strings = dict()
+
+ # Dictionary for the PipeStruct field values
+ types = dict()
+
+ spanFeatures = span.getFeatures()
+ pipeFeatures = pipe.getFeatures()
+
+ for counter, feature in enumerate(pipeFeatures):
+ if feedback.isCanceled(): break
+
+ geometry = feature.geometry()
+ if geometry == None: continue
+
+ fatherID = feature[self.FATHER_ID]
+
+ # Length
+ myLength = None
+ if feature.fields().lookupField('Length') != -1:
+ myLength = feature['Length']
+ if myLength == None:
+ myLength = geometry.length()
+
+ oldLength = lengths.get(fatherID, 0.0)
+ lengths[fatherID] = oldLength + myLength
+
+ # Segment points
+ pointList = strings.get(fatherID, [])
+ # feedback.pushInfo('Point list: {}'.format(pointList))
+ mylist = []
+
+ vertices = geometry.vertices()
+ while vertices.hasNext():
+ mylist.append(vertices.next())
+
+ # feedback.pushInfo('Feature {}, Father {}, Points: {}'.format(feature['Id'], fatherID, ";".join(map(lambda x: '{} {}'.format(x.x(), x.y()), mylist))))
+
+ pointList.append(mylist)
+ strings[fatherID] = pointList
+
+ # Store the value of PipeStruct
+ t = feature['PipeStruct']
+ tt = types.get(fatherID, {})
+ types[fatherID] = tt
+ c = tt.get(t, 0)
+ c += myLength
+ tt[t] = c
+
+ # Update the progress bar
+ feedback.setProgress(int(counter * total))
+
+ if feedback.isCanceled():
+ return
+
+ feedback.pushInfo('Done')
+
+ #span.startEditing()
+
+ feedback.pushInfo('Started editing')
+ feedback.pushInfo(str(spanFeatures))
+
+ for feature in spanFeatures:
+ if feedback.isCanceled(): break
+
+ f = feature.fields()
+
+ #feedback.pushInfo(str(feature))
+ id = feature['Id']
+ #feedback.pushInfo(str(id))
+
+ # Length
+ myLength = None
+ if f.lookupField('Length') != -1:
+ myLength = feature['Length']
+ if myLength == None:
+ myLength = feature.geometry().length()
+
+ # Ignore short stumps
+ if myLength <= minLength:
+ continue
+
+ # Vertices
+ mypoints = list(feature.geometry().vertices())
+ mylist = strings.get(id, None)
+ if mylist == None:
+ feedback.pushInfo('No points for feature {}'.format(id))
+ mylist = [mypoints]
+
+ #feedback.pushInfo('Points: {}'.format("|".join(map(lambda x: ";".join(('{} {}'.format(p.x(), p.y()) for p in x)), mylist))))
+
+ head = feature.geometry().vertices().next()
+ resultList = [head]
+
+ #feedback.pushInfo(str(resultList))
+
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ mylist = list(map(lambda x: list(reversed(x)), mylist))
+ i = next((i for i, x in enumerate(mylist) if head.distance(x[0]) <= eps), None)
+ if i == None:
+ feedback.pushInfo('Warning: No matching start vertex for feature {}'.format(id))
+ mylist = [mypoints]
+ i = 0
+
+ vertices = mylist.pop(i)
+
+ while i != None:
+ tail = vertices[-1]
+ resultList.extend(vertices[1:])
+ if tail.distance(mypoints[-1]) <= eps:
+ break
+
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[0]) <= eps), None)
+ if i != None:
+ vertices = mylist.pop(i)
+ else:
+ i = next((i for i, x in enumerate(mylist) if tail.distance(x[-1]) <= eps), None)
+ if i != None:
+ vertices = list(reversed(mylist.pop(i)))
+
+ # feedback.pushInfo(str(resultList))
+
+ # Convert to string
+ result = ";".join(('{} {}'.format(p.x(), p.y()) for p in resultList))
+
+ # feedback.pushInfo('Feature {}: {}'.format(id, result))
+
+ outputFeature = QgsFeature()
+ outputFeature.setFields(outputFields)
+ for i, x in enumerate(feature.attributes()):
+ fieldName = sourceFields[i].name()
+ outputFeature[fieldName] = x
+
+ vts = list(feature.geometry().vertices())
+ p1 = vts[0]
+ p2 = vts[-1]
+
+ outputFeature['x1'] = feature['x1'] if f.lookupField('x1') != -1 else p1.x()
+ outputFeature['y1'] = feature['y1'] if f.lookupField('y1') != -1 else p1.y()
+ outputFeature['z1'] = feature['z1'] if f.lookupField('z1') != -1 else p1.z()
+ outputFeature['x2'] = feature['x2'] if f.lookupField('x2') != -1 else p2.x()
+ outputFeature['y2'] = feature['y2'] if f.lookupField('y2') != -1 else p2.y()
+ outputFeature['z2'] = feature['z2'] if f.lookupField('z2') != -1 else p2.z()
+ outputFeature['Length'] = feature['Length'] if f.lookupField('Length') != -1 else feature.geometry().length()
+ outputFeature['LineString'] = result
+
+ # Handle pipe type codes
+ mytypes = list(types.get(id, {}).items())
+ if len(mytypes) == 0:
+ feedback.pushInfo('No type codes for feature {}'.format(id))
+ else:
+ if len(mytypes) > 1:
+ mytypes.sort(key = itemgetter(1))
+ feedback.pushInfo('No unique type code for feature {}: {}'.format(id, mytypes))
+ outputFeature['PipeStruct'] = mytypes[-1][0]
+
+ if f.lookupField('TechTypeId') != -1:
+ outputFeature['TechTypeId'] = feature['TechTypeId']
+
+ output.addFeature(outputFeature)
+
+ feedback.pushInfo('Loop done')
+
+ #if feedback.isCanceled():
+ # span.rollBack()
+ #else:
+ # span.commitChanges()
+
+ feedback.pushInfo('Changes committed')
+
+ # Return the results of the algorithm. In this case our only result is
+ # the feature sink which contains the processed features, but some
+ # algorithms may return multiple feature sinks, calculated numeric
+ # statistics, etc. These should all be included in the returned
+ # dictionary, with keys matching the feature corresponding parameter
+ # or output names.
+ return {self.OUTPUT: outputId}
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
+ <classpathentry exported="true" kind="lib" path="lib/commons-io-2.1.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/gt-api-16.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/gt-coverage-16.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/gt-geotiff-16.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/gt-main-16.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/guava-17.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/imageio-ext-geocore-1.1.16.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/imageio-ext-streams-1.1.16.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/imageio-ext-tiff-1.1.16.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/imageio-ext-utilities-1.1.16.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jai_codec-1.1.3.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jai_imageio-1.1.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jdom-1.1.3.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-affine-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-algebra-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-bandcombine-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-bandmerge-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-bandselect-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-binarize-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-border-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-buffer-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-classifier-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-colorconvert-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-colorindexer-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-crop-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-errordiffusion-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-format-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-imagefunction-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-iterators-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-lookup-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-mosaic-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-nullop-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-orderdither-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-piecewise-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-rescale-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-rlookup-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-scale-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-stats-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-translate-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-utilities-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-utils-1.4.0.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-vectorbin-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-warp-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-zonal-1.0.11.jar"/>
+ <classpathentry exported="true" kind="lib" path="lib/jt-zonalstats-1.4.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/hsqldb-2.3.4.jar"/>
<classpathentry exported="true" kind="lib" path="lib/gt-epsg-hsql-16.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/commons-pool-1.5.4.jar"/>
lib/jts-1.13.jar,
.,
lib/gt-epsg-hsql-16.0.jar,
- lib/hsqldb-2.3.4.jar
-Export-Package: org.geotools.geometry,
+ lib/hsqldb-2.3.4.jar,
+ lib/commons-io-2.1.jar,
+ lib/gt-api-16.0.jar,
+ lib/gt-coverage-16.0.jar,
+ lib/gt-geotiff-16.0.jar,
+ lib/gt-main-16.0.jar,
+ lib/guava-17.0.jar,
+ lib/imageio-ext-geocore-1.1.16.jar,
+ lib/imageio-ext-streams-1.1.16.jar,
+ lib/imageio-ext-tiff-1.1.16.jar,
+ lib/imageio-ext-utilities-1.1.16.jar,
+ lib/jai_codec-1.1.3.jar,
+ lib/jai_imageio-1.1.jar,
+ lib/jdom-1.1.3.jar,
+ lib/jt-affine-1.0.11.jar,
+ lib/jt-algebra-1.0.11.jar,
+ lib/jt-bandcombine-1.0.11.jar,
+ lib/jt-bandmerge-1.0.11.jar,
+ lib/jt-bandselect-1.0.11.jar,
+ lib/jt-binarize-1.0.11.jar,
+ lib/jt-border-1.0.11.jar,
+ lib/jt-buffer-1.0.11.jar,
+ lib/jt-classifier-1.0.11.jar,
+ lib/jt-colorconvert-1.0.11.jar,
+ lib/jt-colorindexer-1.0.11.jar,
+ lib/jt-crop-1.0.11.jar,
+ lib/jt-errordiffusion-1.0.11.jar,
+ lib/jt-format-1.0.11.jar,
+ lib/jt-imagefunction-1.0.11.jar,
+ lib/jt-iterators-1.0.11.jar,
+ lib/jt-lookup-1.0.11.jar,
+ lib/jt-mosaic-1.0.11.jar,
+ lib/jt-nullop-1.0.11.jar,
+ lib/jt-orderdither-1.0.11.jar,
+ lib/jt-piecewise-1.0.11.jar,
+ lib/jt-rescale-1.0.11.jar,
+ lib/jt-rlookup-1.0.11.jar,
+ lib/jt-scale-1.0.11.jar,
+ lib/jt-stats-1.0.11.jar,
+ lib/jt-translate-1.0.11.jar,
+ lib/jt-utilities-1.0.11.jar,
+ lib/jt-utils-1.4.0.jar,
+ lib/jt-vectorbin-1.0.11.jar,
+ lib/jt-warp-1.0.11.jar,
+ lib/jt-zonal-1.0.11.jar,
+ lib/jt-zonalstats-1.4.0.jar
+Export-Package: com.vividsolutions.jts,
+ com.vividsolutions.jts.geom,
+ com.vividsolutions.jts.geom.impl,
+ com.vividsolutions.jts.geom.prep,
+ com.vividsolutions.jts.geom.util,
+ com.vividsolutions.jts.geomgraph,
+ com.vividsolutions.jts.geomgraph.index,
+ com.vividsolutions.jts.index.quadtree,
+ com.vividsolutions.jts.index.strtree,
+ it.geosolutions.imageio.stream.input.spi,
+ it.geosolutions.imageio.stream.output.spi,
+ org.geotools.coverage,
+ org.geotools.coverage.grid,
+ org.geotools.coverage.grid.io,
+ org.geotools.gce.geotiff,
+ org.geotools.geometry,
+ org.geotools.geometry.jts,
org.geotools.referencing,
org.opengis.geometry,
org.opengis.referencing,
output.. = bin/
bin.includes = META-INF/,\
.,\
- lib/
+ lib/,\
+ lib/commons-io-2.1.jar,\
+ lib/gt-api-16.0.jar,\
+ lib/gt-coverage-16.0.jar,\
+ lib/gt-geotiff-16.0.jar,\
+ lib/gt-main-16.0.jar,\
+ lib/guava-17.0.jar,\
+ lib/imageio-ext-geocore-1.1.16.jar,\
+ lib/imageio-ext-streams-1.1.16.jar,\
+ lib/imageio-ext-tiff-1.1.16.jar,\
+ lib/imageio-ext-utilities-1.1.16.jar,\
+ lib/jai_codec-1.1.3.jar,\
+ lib/jai_imageio-1.1.jar,\
+ lib/jdom-1.1.3.jar,\
+ lib/jt-affine-1.0.11.jar,\
+ lib/jt-algebra-1.0.11.jar,\
+ lib/jt-bandcombine-1.0.11.jar,\
+ lib/jt-bandmerge-1.0.11.jar,\
+ lib/jt-bandselect-1.0.11.jar,\
+ lib/jt-binarize-1.0.11.jar,\
+ lib/jt-border-1.0.11.jar,\
+ lib/jt-buffer-1.0.11.jar,\
+ lib/jt-classifier-1.0.11.jar,\
+ lib/jt-colorconvert-1.0.11.jar,\
+ lib/jt-colorindexer-1.0.11.jar,\
+ lib/jt-crop-1.0.11.jar,\
+ lib/jt-errordiffusion-1.0.11.jar,\
+ lib/jt-format-1.0.11.jar,\
+ lib/jt-imagefunction-1.0.11.jar,\
+ lib/jt-iterators-1.0.11.jar,\
+ lib/jt-lookup-1.0.11.jar,\
+ lib/jt-mosaic-1.0.11.jar,\
+ lib/jt-nullop-1.0.11.jar,\
+ lib/jt-orderdither-1.0.11.jar,\
+ lib/jt-piecewise-1.0.11.jar,\
+ lib/jt-rescale-1.0.11.jar,\
+ lib/jt-rlookup-1.0.11.jar,\
+ lib/jt-scale-1.0.11.jar,\
+ lib/jt-stats-1.0.11.jar,\
+ lib/jt-translate-1.0.11.jar,\
+ lib/jt-utilities-1.0.11.jar,\
+ lib/jt-utils-1.4.0.jar,\
+ lib/jt-vectorbin-1.0.11.jar,\
+ lib/jt-warp-1.0.11.jar,\
+ lib/jt-zonal-1.0.11.jar,\
+ lib/jt-zonalstats-1.4.0.jar
package org.simantics.district.imports.ui;
import java.lang.reflect.InvocationTargetException;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.apache.commons.csv.CSVRecord;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.ui.IImportWizard;
import org.eclipse.ui.IWorkbench;
-import org.geotools.geometry.DirectPosition2D;
-import org.geotools.referencing.CRS;
-import org.opengis.geometry.DirectPosition;
-import org.opengis.geometry.MismatchedDimensionException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-import org.simantics.Simantics;
-import org.simantics.databoard.Bindings;
-import org.simantics.db.Resource;
-import org.simantics.db.WriteGraph;
-import org.simantics.db.common.request.ObjectsWithType;
-import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.request.Write;
-import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.imports.CSVImportModel;
import org.simantics.district.imports.DistrictImportUtils;
-import org.simantics.district.network.DistrictNetworkUtil;
-import org.simantics.district.network.ontology.DistrictNetworkResource;
-import org.simantics.district.network.ui.DNEdgeBuilder;
-import org.simantics.district.network.ui.DNEdgeBuilder.ResourceVertex;
-import org.simantics.layer0.Layer0;
import org.simantics.utils.ui.ExceptionUtils;
public class CSVImportWizard extends Wizard implements IImportWizard {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
try {
- Path csvFile = model.getSource();
- char delim = model.getDelimiter();
+ monitor.beginTask("Importing CSV", 1);
- List<CSVRecord> rows = DistrictImportUtils.readRows(csvFile, delim, -1);
- monitor.beginTask("Importing CSV", rows.size());
-
- // Path wktFile = model.getWKTFile();
-
- int xCoordColumnIndex = model.getXCoordIndex();
- int yCoordColumnIndex = model.getYCoordIndex();
- int zCoordColumnIndex = model.getZCoordIndex();
- int supplyTempColumnIndex = model.getSupplyTempIndex();
- int returnTempColumnIndex = model.getReturnTempIndex();
- int supplyPressureColumnIndex = model.getSupplyPressureIndex();
- int returnPressureColumnIndex = model.getReturnPressureIndex();
- int dpIndex = model.getDeltaPressureIndex();
- int dtIndex = model.getDeltaTemperatureIndex();
- int heatPowerIndex = model.getHeatPowerIndex();
- int valvePositionIndex = model.getValvePositionIndx();
- int nominalHeadMIndex = model.getNominalHeadMIndex();
- int nominalHeadBIndex = model.getNominalHeadBIndex();
- int nominalFlowIndex = model.getNominalFlowIndex();
- int maximumHeadMIndex = model.getMaximumHeadMIndex();
- int heatLoadDsIndex = model.getHeatLoadDsIndex();
- int massFlowIndex = model.getMassFlowIndex();
- int volFlowIndex = model.getVolFlowIndex();
- int velocityIndex = model.getVelocityIndex();
- int flowAreaIndex = model.getFlowAreaIndex();
- int nominalPressureLossIndex = model.getNominalPressureLossIndex();
- int addressIndex = model.getAddressIndex();
-
- int startXCoordColumnIndex = model.getStartXCoordIndex();
- int startYCoordColumnIndex = model.getStartYCoordIndex();
- int startZValueColumnIndex = model.getStartZCoordIndex();
- int endXCoordColumnIndex = model.getEndXCoordIndex();
- int endYCoordColumnIndex = model.getEndYCoordIndex();
- int endZValueColumnIndex = model.getEndZCoordIndex();
- int diameterColumnIndex= model.getDiameterIndex();
- int outerDiameterColumnIndex = model.getOuterDiamterIndex();
- int nominalMassFlowIndex = model.getNominalMassFlowIndex();
- int tGroundIndex = model.gettGroundIndex();
- int edgeFlowAreaIndex = model.getEdgeFlowAreaIndex();
- int kReturnIndex = model.getkReturnIndex();
- int kSupplyIndex = model.getkSupplyIndex();
- int lengthIndex = model.getLengthIndex();
- int detailedGeometryIndex = model.getDetailedGeometryIndex();
-
- int mappingColumn = model.getComponentMappingIndex();
- int idColumn = model.getIdIndex();
-
- double padding = model.getEdgePadding();
-
- String sourceEPSGCRS = model.getSourceCRS();
-
- MathTransform transform = null;
- boolean doTransform = false;
- // if sourceEPSGCRS is empty || null then ignore transformation
- if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
- CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
- CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
- transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
- doTransform = true;
+ if (model.isVertexImport()) {
+ DistrictImportUtils.importVertices(model);
+ } else {
+ DistrictImportUtils.importEdges(model);
}
- final boolean actualDoTransform = doTransform;
- final MathTransform actualTransform = transform;
- Simantics.getSession().syncRequest(new Write() {
-
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- graph.markUndoPoint();
-
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
-
- Collection<Resource> vertices = graph.syncRequest(new ObjectsWithType(model.getParentDiagram(), Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex));
- List<ResourceVertex> vv = new ArrayList<>(vertices.size());
- for (Resource vertex : vertices) {
- double[] existingCoords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY);
- vv.add(new ResourceVertex(vertex, existingCoords));
- }
-
- for (int k = 1; k < rows.size(); k++) {
- CSVRecord row = rows.get(k);
-
- String mappingValue = row.get(mappingColumn);
-
- try {
- if (model.isVertexImport()) {
- String xCoords = row.get(xCoordColumnIndex);
- String yCoords = row.get(yCoordColumnIndex);
- double xCoord = Double.parseDouble(xCoords);
- double yCoord = Double.parseDouble(yCoords);
-
- double z = 0;
- if (zCoordColumnIndex != -1) {
- String zs = row.get(zCoordColumnIndex);
-
- if (!zs.isEmpty()) {
- try {
- z = Double.parseDouble(zs);
- } catch (NumberFormatException e) {
- throw new DatabaseException(e);
- }
- }
- }
-
- double[] coords;
- if (actualDoTransform) {
- DirectPosition2D targetPos = new DirectPosition2D();
- DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord);
- DirectPosition res = actualTransform.transform(sourcePos, targetPos);
- coords = res.getCoordinate();
- } else {
- coords = new double[] { xCoord, yCoord };
- }
-
- // Switch to (longitude, latitude)
- flipAxes(coords);
-
- Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, model.getComponentMappings().get(mappingValue));
-
- writeStringValue(graph, row, idColumn, vertex, DN.HasId);
-
- graph.claimLiteral(vertex, DN.Vertex_HasElevation, z, Bindings.DOUBLE);
-
- writeValue(graph, row, supplyTempColumnIndex, vertex, DN.Vertex_HasSupplyTemperature);
- writeValue(graph, row, returnTempColumnIndex, vertex, DN.Vertex_HasReturnTemperature);
- writeValue(graph, row, supplyPressureColumnIndex, vertex, DN.Vertex_HasSupplyPressure);
- writeValue(graph, row, returnPressureColumnIndex, vertex, DN.Vertex_HasReturnPressure);
- writeValue(graph, row, dpIndex, vertex, DN.Vertex_HasDeltaPressure);
- writeValue(graph, row, dtIndex, vertex, DN.Vertex_HasDeltaTemperature);
- writeValue(graph, row, heatPowerIndex, vertex, DN.Vertex_HasHeatPower);
- writeValue(graph, row, valvePositionIndex, vertex, DN.Vertex_HasValvePosition);
- writeValue(graph, row, nominalHeadMIndex, vertex, DN.Vertex_HasNominalHeadM);
- writeValue(graph, row, nominalHeadBIndex, vertex, DN.Vertex_HasNominalHeadB);
- writeValue(graph, row, nominalFlowIndex, vertex, DN.Vertex_HasNominalFlow);
- writeValue(graph, row, maximumHeadMIndex, vertex, DN.Vertex_HasMaximumHeadM);
- writeValue(graph, row, heatLoadDsIndex, vertex, DN.Vertex_HasHeatLoadDs);
- writeValue(graph, row, massFlowIndex, vertex, DN.Vertex_HasMassFlow);
- writeValue(graph, row, volFlowIndex, vertex, DN.Vertex_HasVolFlow);
- writeValue(graph, row, velocityIndex, vertex, DN.Vertex_HasVelocity);
- writeValue(graph, row, flowAreaIndex, vertex, DN.Vertex_HasFlowArea);
- writeValue(graph, row, nominalPressureLossIndex, vertex, DN.Vertex_HasNominalPressureLoss);
- writeStringValue(graph, row, addressIndex, vertex, DN.Vertex_HasAddress);
-
- } else {
- String startXCoords = row.get(startXCoordColumnIndex);
- String startYCoords = row.get(startYCoordColumnIndex);
- String endXCoords = row.get(endXCoordColumnIndex);
- String endYCoords = row.get(endYCoordColumnIndex);
-
- double startXCoord = Double.parseDouble(startXCoords); // make negative
- double startYCoord = Double.parseDouble(startYCoords);
-
- double endXCoord = Double.parseDouble(endXCoords); // make negative
- double endYCoord = Double.parseDouble(endYCoords);
-
- double[] startCoords;
- double[] endCoords;
- if (actualDoTransform) {
- DirectPosition2D startTargetPos = new DirectPosition2D();
- DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord);
- DirectPosition startRes = actualTransform.transform(startSourcePos, startTargetPos);
- startCoords = startRes.getCoordinate();
-
- DirectPosition2D endTargetPos = new DirectPosition2D();
- DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord);
- DirectPosition endRes = actualTransform.transform(endSourcePos, endTargetPos);
- endCoords = endRes.getCoordinate();
- } else {
- startCoords = new double[] { startXCoord , startYCoord };
- endCoords = new double[] { endXCoord , endYCoord };
- }
-
- // Switch to (longitude, latitude)
- flipAxes(startCoords);
- flipAxes(endCoords);
-
- Resource edge = DNEdgeBuilder.create(graph, vv, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, endCoords, padding, true);
- writeStringValue(graph, row, idColumn, edge, DN.HasId);
-
- writeValue(graph, row, diameterColumnIndex, edge, DN.Edge_HasDiameter);
- writeValue(graph, row, outerDiameterColumnIndex, edge, DN.Edge_HasOuterDiameter);
- writeValue(graph, row, nominalMassFlowIndex, edge, DN.Edge_HasNominalMassFlow);
- writeValue(graph, row, tGroundIndex, edge, DN.Edge_HasTGround);
- writeValue(graph, row, kReturnIndex, edge, DN.Edge_HasKReturn);
- writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply);
- writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea);
- writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength);
- writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform);
- }
- } catch (MismatchedDimensionException | TransformException | DatabaseException e) {
- throw new DatabaseException(e);
- }
- monitor.worked(1);
- }
- }
- });
} catch (Exception e) {
throw new InvocationTargetException(e);
}
}
}
- private static void flipAxes(double[] coords) {
- double tmp = coords[0];
- coords[0] = coords[1];
- coords[1] = tmp;
- }
- private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
- if (index != -1) {
- String stringValue = row.get(index);
- if (!stringValue.isEmpty()) {
- try {
- graph.claimLiteral(subject, relation, Double.parseDouble(stringValue), Bindings.DOUBLE);
- } catch (NumberFormatException e) {
- throw new DatabaseException(e);
- }
- }
- }
- }
-
- private static void writeStringValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
- if (index != -1) {
- String stringValue = row.get(index);
- if (!stringValue.isEmpty()) {
- try {
- graph.claimLiteral(subject, relation, stringValue, Bindings.STRING);
- } catch (NumberFormatException e) {
- throw new DatabaseException(e);
- }
- }
- }
- }
-
- private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException {
- if (index != -1) {
- String stringValue = row.get(index);
- if (!stringValue.isEmpty()) {
- stringValue = stringValue.substring(1, stringValue.length() - 1);
- String[] coordPairs = stringValue.split(";");
- ArrayList<Double> dd = new ArrayList<>(coordPairs.length * 2);
- for (int i = 0; i < coordPairs.length; i++) {
- String coordPair = coordPairs[i];
- String[] p = coordPair.split(" ");
- double x = Double.parseDouble(p[0]);
- double y = Double.parseDouble(p[1]);
- if (actualTransform != null) {
- DirectPosition2D targetPos = new DirectPosition2D();
- DirectPosition2D sourcePos = new DirectPosition2D(y, x);
- DirectPosition res = actualTransform.transform(sourcePos, targetPos);
- double[] coords = res.getCoordinate();
- x = coords[1];
- y = coords[0];
- }
- dd.add(x);
- dd.add(y);
- }
- double[] detailedGeometryCoords = new double[dd.size()];
- for (int i = 0; i < dd.size(); i++) {
- double d = dd.get(i);
- detailedGeometryCoords[i] = d;
- }
- try {
- graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY);
- } catch (NumberFormatException e) {
- throw new DatabaseException(e);
- }
- }
- }
- }
}
import org.simantics.db.Resource;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.imports.CSVImportModel;
import org.simantics.district.network.ui.function.Functions;
import org.simantics.modeling.ModelingResources;
import org.simantics.utils.ui.widgets.FileOrDirectorySelectionWidget;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.geotools.referencing.CRS;
+import org.simantics.district.imports.CSVImportModel;
import org.simantics.district.imports.ui.controls.DynamicComboFieldEditor;
public class CSVImportWizardPage extends WizardPage {
// Common for vertex and edge
private DynamicComboFieldEditor componentMappingSelector;
private DynamicComboFieldEditor idSelector;
- private DynamicComboFieldEditor labelSelector;
// For vertex import
private DynamicComboFieldEditor xCoordSelector;
private DynamicComboFieldEditor yCoordSelector;
private DynamicComboFieldEditor zValueSelector;
+ private DynamicComboFieldEditor altElevationValueSelector;
private DynamicComboFieldEditor supplyTempValueSelector;
private DynamicComboFieldEditor returnTempValueSelector;
private DynamicComboFieldEditor dpSelector;
private DynamicComboFieldEditor dtSelector;
private DynamicComboFieldEditor heatPowerSelector;
+ private DynamicComboFieldEditor peakPowerSelector;
private DynamicComboFieldEditor nominalHeadMSelector;
private DynamicComboFieldEditor nominalHeadBSelector;
private DynamicComboFieldEditor nominalFlowSelector;
@Override
public void modifyText(ModifyEvent e) {
try {
- double padding = Double.parseDouble("");
- model.setEdgePapping(padding);
+ double padding = Double.parseDouble(edgeConnectionPadding.getText());
+ model.setEdgePadding(padding);
} catch (NumberFormatException ee) {
// ignore
}
validatePageComplete();
}
});
+
+ altElevationValueSelector = new DynamicComboFieldEditor("altElevation", "Alternative Elevation", parent);
+ altElevationValueSelector.addComboListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ widgetDefaultSelected(e);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ model.setAltElevationIndex(Integer.parseInt(altElevationValueSelector.getValue()));
+ validatePageComplete();
+ }
+ });
+
supplyTempValueSelector = new DynamicComboFieldEditor("tempValue", "Supply Temperature value", parent);
supplyTempValueSelector.addComboListener(new SelectionListener() {
validatePageComplete();
}
});
+ peakPowerSelector = new DynamicComboFieldEditor("peakPowerValue", "Peak Power", parent);
+ peakPowerSelector.addComboListener(new SelectionListener() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ widgetDefaultSelected(e);
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ model.setPeakPowerIndex(Integer.parseInt(peakPowerSelector.getValue()));
+ validatePageComplete();
+ }
+ });
nominalHeadMSelector = new DynamicComboFieldEditor("nominalHeadMValue", "nominalHeadM", parent);
nominalHeadMSelector.addComboListener(new SelectionListener() {
xCoordSelector.updateCombo(namesAndValues);
yCoordSelector.updateCombo(namesAndValues);
zValueSelector.updateCombo(namesAndValues);
+ altElevationValueSelector.updateCombo(namesAndValues);
supplyTempValueSelector.updateCombo(namesAndValues);
returnTempValueSelector.updateCombo(namesAndValues);
supplyPressureValueSelector.updateCombo(namesAndValues);
headerIndexAndValues.clear();
try {
- List<CSVRecord> rows = model.getRows(5);
+ List<CSVRecord> rows = model.getRows(5, false);
for (int k = 0; k < rows.size(); k++) {
CSVRecord row = rows.get(k);
if (model.isVertexImport())
setPageComplete(model.getXCoordIndex() != -1 && model.getYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
else
- setPageComplete(model.getStartXCoordIndex() != 1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
+ setPageComplete(model.getStartXCoordIndex() != -1 && model.getStartYCoordIndex() != -1 && model.getEndXCoordIndex() != -1 && model.getEndYCoordIndex() != -1 && model.getComponentMappingIndex() != -1);
}
}
import org.simantics.db.common.request.IndexRoot;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.imports.CSVImportModel;
import org.simantics.district.imports.DistrictImportUtils;
import org.simantics.district.network.ui.function.Functions;
private Composite composite;
private Composite childComposite;
protected Map<String, Resource> componentMappings;
- private Collection<String> distinctMappingIvalues;
private Collection<String> distinctMappingIndexColumnValues;
public ComponentMappingPage(CSVImportModel model) {
*
* @return <code>true</code> if it is ok, and <code>false</code> otherwise
*/
+ @SuppressWarnings("unused")
private boolean checkArray(String[][] table) {
if (table == null) {
return false;
Bundle-SymbolicName: org.simantics.district.imports
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Require-Bundle: org.simantics.db
+Require-Bundle: org.simantics.db,
+ org.simantics,
+ org.simantics.district.geotools,
+ org.simantics.district.network.ontology,
+ org.simantics.district.network,
+ org.simantics.diagram.ontology,
+ org.slf4j.api
Export-Package: org.apache.commons.csv,
org.simantics.district.imports
Bundle-ClassPath: lib/commons-csv-1.4.jar,
-source.. = src/\r
-output.. = bin/\r
-bin.includes = META-INF/,\\r
- .,\\r
- lib/commons-csv-1.4.jar\r
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ lib/commons-csv-1.4.jar,\
+ scl/
--- /dev/null
+import "Files"
+import "Map" as Map
+import "Simantics/DB"
+
+importJava "org.simantics.district.imports.CSVImportModel" where
+ data CSVImportModel
+
+ @JavaName "<init>"
+ csvImportModel :: () -> CSVImportModel
+
+ setParentDiagram :: CSVImportModel -> Resource -> <Proc> ()
+ setSource :: CSVImportModel -> Path -> <Proc> ()
+ setDelimiter :: CSVImportModel -> Character -> <Proc> ()
+
+ // Vertex
+ setXCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setYCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setZCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setAltElevationIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setHeatLoadDsIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setHeatPowerIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setPeakPowerIndex :: CSVImportModel -> Integer -> <Proc> ()
+
+ // Edge
+ setStartXCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setStartYCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setStartZCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setEndXCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setEndYCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setEndZCoordIndex :: CSVImportModel -> Integer -> <Proc> ()
+
+ setLengthIndex :: CSVImportModel -> Integer -> <Proc> ()
+ detailedGeometryIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setDiameterIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setOuterDiameterIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setEdgePadding :: CSVImportModel -> Double -> <Proc> ()
+
+ // Common
+ setSourceCRS :: CSVImportModel -> String -> <Proc> ()
+ setIdIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setAddressIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setComponentMappingIndex :: CSVImportModel -> Integer -> <Proc> ()
+ setComponentMappings :: CSVImportModel -> String -> Resource -> <Proc> ()
+
+importJava "org.simantics.district.imports.DistrictImportUtils" where
+ importVertices :: CSVImportModel -> <Proc> ()
+ importEdges :: CSVImportModel -> <Proc> ()
-package org.simantics.district.imports.ui;
+package org.simantics.district.imports;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
+import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.simantics.db.Resource;
-import org.simantics.district.imports.DistrictImportUtils;
import org.simantics.district.imports.DistrictImportUtils.CSVHeader;
public class CSVImportModel {
private int xCoordIndex = -1;
private int yCoordIndex = -1;
private int zCoordIndex = -1;
+ private int altElevationIndex = -1;
// Edge import
private int startXCoordIndex = -1;
private int idIndex = -1;
private double edgePadding = 0.0001; // default
private int valvePositionIndx = -1;
- private int addressIndex;
- private int lengthIndex;
- private int detailedGeometryIndex;
+ private int addressIndex = -1;
+ private int lengthIndex = -1;
+ private int detailedGeometryIndex = -1;
+ private int peakPowerIndex = -1;
// Third page
return source;
}
- public List<CSVRecord> getRows(int amount) throws IOException {
+ public List<CSVRecord> getRows(int amount, boolean readFirstAsHeader) throws IOException {
if (source != null)
- return DistrictImportUtils.readRows(source, delimiter, amount);
+ return DistrictImportUtils.readRows(source, delimiter, readFirstAsHeader, amount);
else
return Collections.emptyList();
}
public List<Map<String, String>> readRows(int amount) throws IOException {
if (source != null)
- return DistrictImportUtils.readRows(source, delimiter, readFirstAsHeader, amount);
+ return DistrictImportUtils.readRows(source, CSVFormat.newFormat(delimiter), readFirstAsHeader, amount);
else
return Collections.emptyList();
}
this.idIndex = idIndex;
}
- public void setEdgePapping(double edgePadding) {
+ public void setEdgePadding(double edgePadding) {
this.edgePadding = edgePadding;
}
public int getDetailedGeometryIndex() {
return detailedGeometryIndex;
}
+
+ public int getAlternativeElevationIndex() {
+ return altElevationIndex;
+ }
+
+ public void setAltElevationIndex(int parseInt) {
+ this.altElevationIndex = parseInt;
+ }
+
+ public void setPeakPowerIndex(int parseInt) {
+ this.peakPowerIndex = parseInt;
+ }
+
+ public int getPeakPowerIndex() {
+ return peakPowerIndex;
+ }
}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DNEdgeBuilder;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.layer0.Layer0;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.simantics.district.network.DistrictNetworkUtil.ResourceVertex;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.quadtree.Quadtree;
public class DistrictImportUtils {
private DistrictImportUtils() { }
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictImportUtils.class);
+
public static Resource importCSVAsLayer(Path csvFile) throws IOException {
try (CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(Files.newBufferedReader(csvFile))) {
return delimiters;
}
- public static List<Map<String, String>> readRows(Path source, char delimiter, boolean firstAsHeader, int amount) throws IOException {
- return readRows(source, CSVFormat.newFormat(delimiter), firstAsHeader, amount);
- }
-
public static List<Map<String, String>> readRows(Path source, CSVFormat format, boolean firstAsHeader, int amount) throws IOException {
if (firstAsHeader)
format = format.withFirstRecordAsHeader();
}
}
- public static List<CSVRecord> readRows(Path source, char delim, int rowAmount) throws IOException {
+ public static List<CSVRecord> readRows(Path source, char delim, boolean firstAsHeader, int rowAmount) throws IOException {
List<CSVRecord> results = new ArrayList<>();
+ AtomicInteger count = new AtomicInteger(0);
+ consumeCSV(source, delim, firstAsHeader, t -> {
+ results.add(t);
+ int current = count.incrementAndGet();
+ return current < rowAmount;
+ });
+ return results;
+ }
+
+ public static void consumeCSV(Path source, char delim, boolean firstAsHeader, Function<CSVRecord, Boolean> consumer) throws IOException {
CSVFormat format = CSVFormat.newFormat(delim);
+ if (firstAsHeader) {
+ format = format.withFirstRecordAsHeader();
+ }
try (CSVParser parser = format.parse(Files.newBufferedReader(source))) {
Iterator<CSVRecord> records = parser.iterator();
- int rows = 0;
- if (rowAmount == -1) {
- while (records.hasNext()) {
- results.add(records.next());
- rows++;
- }
- } else {
- while (rows < rowAmount && records.hasNext()) {
- results.add(records.next());
- rows++;
+ while (records.hasNext()) {
+ Boolean cont = consumer.apply(records.next());
+ if (!cont) {
+ break;
}
}
}
- return results;
}
return results;
}
+ public static void importVertices(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException {
+
+ Path csvFile = model.getSource();
+ char delim = model.getDelimiter();
+
+ int xCoordColumnIndex = model.getXCoordIndex();
+ int yCoordColumnIndex = model.getYCoordIndex();
+ int zCoordColumnIndex = model.getZCoordIndex();
+ int altElevationIndex = model.getAlternativeElevationIndex();
+ int supplyTempColumnIndex = model.getSupplyTempIndex();
+ int returnTempColumnIndex = model.getReturnTempIndex();
+ int supplyPressureColumnIndex = model.getSupplyPressureIndex();
+ int returnPressureColumnIndex = model.getReturnPressureIndex();
+ int dpIndex = model.getDeltaPressureIndex();
+ int dtIndex = model.getDeltaTemperatureIndex();
+ int heatPowerIndex = model.getHeatPowerIndex();
+ int peakPowerIndex = model.getPeakPowerIndex();
+ int valvePositionIndex = model.getValvePositionIndx();
+ int nominalHeadMIndex = model.getNominalHeadMIndex();
+ int nominalHeadBIndex = model.getNominalHeadBIndex();
+ int nominalFlowIndex = model.getNominalFlowIndex();
+ int maximumHeadMIndex = model.getMaximumHeadMIndex();
+ int heatLoadDsIndex = model.getHeatLoadDsIndex();
+ int massFlowIndex = model.getMassFlowIndex();
+ int volFlowIndex = model.getVolFlowIndex();
+ int velocityIndex = model.getVelocityIndex();
+ int flowAreaIndex = model.getFlowAreaIndex();
+ int nominalPressureLossIndex = model.getNominalPressureLossIndex();
+ int addressIndex = model.getAddressIndex();
+
+ int mappingColumn = model.getComponentMappingIndex();
+ int idColumn = model.getIdIndex();
+
+ String sourceEPSGCRS = model.getSourceCRS();
+
+ MathTransform transform = null;
+ boolean doTransform = false;
+ // if sourceEPSGCRS is empty || null then ignore transformation
+ if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
+ CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
+ CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
+ transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+ doTransform = true;
+ }
+ final boolean actualDoTransform = doTransform;
+ final MathTransform actualTransform = transform;
+
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ try {
+ Layer0Utils.setDependenciesIndexingDisabled(graph, true);
+ graph.markUndoPoint();
+
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ DistrictImportUtils.consumeCSV(csvFile, delim, true, (Function<CSVRecord, Boolean>) row -> {
+ try {
+ String mappingValue = row.get(mappingColumn);
+
+ String xCoords = row.get(xCoordColumnIndex);
+ String yCoords = row.get(yCoordColumnIndex);
+ double xCoord = Double.parseDouble(xCoords);
+ double yCoord = Double.parseDouble(yCoords);
+
+ double z = 0;
+ if (zCoordColumnIndex != -1) {
+ String zs = row.get(zCoordColumnIndex);
+
+ if (!zs.isEmpty()) {
+ try {
+ z = Double.parseDouble(zs);
+ } catch (NumberFormatException e1) {
+ throw new DatabaseException(e1);
+ }
+ }
+ }
+
+ double[] coords;
+ if (actualDoTransform) {
+ DirectPosition2D targetPos = new DirectPosition2D();
+ DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord);
+ DirectPosition res = actualTransform.transform(sourcePos, targetPos);
+ coords = res.getCoordinate();
+ } else {
+ coords = new double[] { xCoord, yCoord };
+ }
+
+ // Switch to (longitude, latitude)
+ flipAxes(coords);
+
+ Resource vertex = DistrictNetworkUtil.createVertex(graph, model.getParentDiagram(), coords, z, model.getComponentMappings().get(mappingValue));
+
+ writeStringValue(graph, row, idColumn, vertex, DN.HasId);
+
+ writeValue(graph, row, altElevationIndex, vertex, DN.Vertex_HasAltElevation);
+
+ writeValue(graph, row, supplyTempColumnIndex, vertex, DN.Vertex_HasSupplyTemperature);
+ writeValue(graph, row, returnTempColumnIndex, vertex, DN.Vertex_HasReturnTemperature);
+ writeValue(graph, row, supplyPressureColumnIndex, vertex, DN.Vertex_HasSupplyPressure);
+ writeValue(graph, row, returnPressureColumnIndex, vertex, DN.Vertex_HasReturnPressure);
+ writeValue(graph, row, dpIndex, vertex, DN.Vertex_HasDeltaPressure);
+ writeValue(graph, row, dtIndex, vertex, DN.Vertex_HasDeltaTemperature);
+ writeValue(graph, row, heatPowerIndex, vertex, DN.Vertex_HasHeatPower);
+ writeValue(graph, row, peakPowerIndex, vertex, DN.Vertex_HasPeakPower);
+ writeValue(graph, row, valvePositionIndex, vertex, DN.Vertex_HasValvePosition);
+ writeValue(graph, row, nominalHeadMIndex, vertex, DN.Vertex_HasNominalHeadM);
+ writeValue(graph, row, nominalHeadBIndex, vertex, DN.Vertex_HasNominalHeadB);
+ writeValue(graph, row, nominalFlowIndex, vertex, DN.Vertex_HasNominalFlow);
+ writeValue(graph, row, maximumHeadMIndex, vertex, DN.Vertex_HasMaximumHeadM);
+ writeValue(graph, row, heatLoadDsIndex, vertex, DN.Vertex_HasHeatLoadDs);
+ writeValue(graph, row, massFlowIndex, vertex, DN.Vertex_HasMassFlow);
+ writeValue(graph, row, volFlowIndex, vertex, DN.Vertex_HasVolFlow);
+ writeValue(graph, row, velocityIndex, vertex, DN.Vertex_HasVelocity);
+ writeValue(graph, row, flowAreaIndex, vertex, DN.Vertex_HasFlowArea);
+ writeValue(graph, row, nominalPressureLossIndex, vertex, DN.Vertex_HasNominalPressureLoss);
+ writeStringValue(graph, row, addressIndex, vertex, DN.Vertex_HasAddress);
+ } catch (DatabaseException | MismatchedDimensionException | TransformException e) {
+ throw new RuntimeException(e);
+ }
+ return true;
+ });
+
+ } catch (IOException e) {
+ LOGGER.error("Could not import", e);
+ throw new DatabaseException(e);
+ } finally {
+ Layer0Utils.setDependenciesIndexingDisabled(graph, false);
+ }
+ }
+ });
+ }
+
+ public static void importEdges(CSVImportModel model) throws NoSuchAuthorityCodeException, FactoryException, DatabaseException {
+
+ Path csvFile = model.getSource();
+ char delim = model.getDelimiter();
+
+
+ int startXCoordColumnIndex = model.getStartXCoordIndex();
+ int startYCoordColumnIndex = model.getStartYCoordIndex();
+ int startZValueColumnIndex = model.getStartZCoordIndex();
+ int endXCoordColumnIndex = model.getEndXCoordIndex();
+ int endYCoordColumnIndex = model.getEndYCoordIndex();
+ int endZValueColumnIndex = model.getEndZCoordIndex();
+ int diameterColumnIndex= model.getDiameterIndex();
+ int outerDiameterColumnIndex = model.getOuterDiamterIndex();
+ int nominalMassFlowIndex = model.getNominalMassFlowIndex();
+ int tGroundIndex = model.gettGroundIndex();
+ int edgeFlowAreaIndex = model.getEdgeFlowAreaIndex();
+ int kReturnIndex = model.getkReturnIndex();
+ int kSupplyIndex = model.getkSupplyIndex();
+ int lengthIndex = model.getLengthIndex();
+ int detailedGeometryIndex = model.getDetailedGeometryIndex();
+
+ int mappingColumn = model.getComponentMappingIndex();
+ int idColumn = model.getIdIndex();
+
+ double padding = model.getEdgePadding();
+
+ String sourceEPSGCRS = model.getSourceCRS();
+
+ MathTransform transform = null;
+ boolean doTransform = false;
+ // if sourceEPSGCRS is empty || null then ignore transformation
+ if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
+ CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
+ CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
+ transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
+ doTransform = true;
+ }
+ final boolean actualDoTransform = doTransform;
+ final MathTransform actualTransform = transform;
+
+ double halfPadding = padding / 2;
+
+ Quadtree vv = Simantics.getSession().syncRequest(new UniqueRead<Quadtree>() {
+
+ @Override
+ public Quadtree perform(ReadGraph graph) throws DatabaseException {
+ Collection<Resource> vertices = graph.syncRequest(new ObjectsWithType(model.getParentDiagram(), Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex));
+ Quadtree vv = new Quadtree();
+ for (Resource vertex : vertices) {
+ double[] coords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY);
+ double x1 = coords[0] - halfPadding;
+ double y1= coords[1] - halfPadding;
+ double x2 = coords[0] + halfPadding;
+ double y2= coords[1] + halfPadding;
+ Envelope e = new Envelope(x1, x2, y1, y2);
+ vv.insert(e, new ResourceVertex(vertex, coords, true));
+ }
+ return vv;
+ }
+ });
+
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ try {
+ Layer0Utils.setDependenciesIndexingDisabled(graph, true);
+ graph.markUndoPoint();
+
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ DistrictImportUtils.consumeCSV(csvFile, delim, true, row -> {
+ try {
+ String mappingValue = row.get(mappingColumn);
+
+ String startXCoords = row.get(startXCoordColumnIndex);
+ String startYCoords = row.get(startYCoordColumnIndex);
+ String startZCoords = row.get(startZValueColumnIndex);
+ String endXCoords = row.get(endXCoordColumnIndex);
+ String endYCoords = row.get(endYCoordColumnIndex);
+ String endZCoords = row.get(endZValueColumnIndex);
+
+ double startXCoord = Double.parseDouble(startXCoords); // make negative
+ double startYCoord = Double.parseDouble(startYCoords);
+ double startZCoord = Double.parseDouble(startZCoords);
+
+ double endXCoord = Double.parseDouble(endXCoords); // make negative
+ double endYCoord = Double.parseDouble(endYCoords);
+ double endZCoord = Double.parseDouble(endZCoords);
+
+ double[] startCoords;
+ double[] endCoords;
+ if (actualDoTransform) {
+ DirectPosition2D startTargetPos = new DirectPosition2D();
+ DirectPosition2D startSourcePos = new DirectPosition2D(startXCoord, startYCoord);
+ DirectPosition startRes = actualTransform.transform(startSourcePos, startTargetPos);
+ startCoords = startRes.getCoordinate();
+
+ DirectPosition2D endTargetPos = new DirectPosition2D();
+ DirectPosition2D endSourcePos = new DirectPosition2D(endXCoord, endYCoord);
+ DirectPosition endRes = actualTransform.transform(endSourcePos, endTargetPos);
+ endCoords = endRes.getCoordinate();
+ } else {
+ startCoords = new double[] { startXCoord , startYCoord };
+ endCoords = new double[] { endXCoord , endYCoord };
+ }
+
+ // Switch to (longitude, latitude)
+ flipAxes(startCoords);
+ flipAxes(endCoords);
+
+ Optional<Resource> oedge = DNEdgeBuilder.create(graph, vv, model.getParentDiagram(), model.getComponentMappings().get(mappingValue), startCoords, startZCoord, endCoords, endZCoord, new double[0], padding, true);
+ if (oedge.isPresent()) {
+ Resource edge = oedge.get();
+ writeStringValue(graph, row, idColumn, edge, DN.HasId);
+
+ writeValue(graph, row, diameterColumnIndex, edge, DN.Edge_HasDiameter);
+ writeValue(graph, row, outerDiameterColumnIndex, edge, DN.Edge_HasOuterDiameter);
+ writeValue(graph, row, nominalMassFlowIndex, edge, DN.Edge_HasNominalMassFlow);
+ writeValue(graph, row, tGroundIndex, edge, DN.Edge_HasTGround);
+ writeValue(graph, row, kReturnIndex, edge, DN.Edge_HasKReturn);
+ writeValue(graph, row, kSupplyIndex, edge, DN.Edge_HasKSupply);
+ writeValue(graph, row, edgeFlowAreaIndex, edge, DN.Edge_HasFlowArea);
+ writeValue(graph, row, lengthIndex, edge, DN.Edge_HasLength);
+ writeDoubleArrayFromString(graph, row, detailedGeometryIndex, edge, DN.Edge_HasGeometry, actualTransform);
+ }
+
+ return true;
+ } catch (DatabaseException | MismatchedDimensionException | TransformException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ } catch (IOException e) {
+ LOGGER.error("Could not import edges {}", model.getSource(), e);
+ } finally {
+ Layer0Utils.setDependenciesIndexingDisabled(graph, false);
+ }
+ }
+ });
+ }
+
+ private static void flipAxes(double[] coords) {
+ double tmp = coords[0];
+ coords[0] = coords[1];
+ coords[1] = tmp;
+ }
+
+ private static void writeValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
+ if (index != -1) {
+ String stringValue = row.get(index);
+ if (!stringValue.isEmpty()) {
+ try {
+ if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
+ stringValue = stringValue.substring(1, stringValue.length() - 1);
+ }
+ graph.claimLiteral(subject, relation, Double.parseDouble(stringValue), Bindings.DOUBLE);
+ } catch (NumberFormatException e) {
+ LOGGER.error("Could not parse {} {} {} {}", row, index, subject, relation, e);
+ //throw new DatabaseException(e);
+ }
+ }
+ }
+ }
+
+ private static void writeStringValue(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation) throws DatabaseException {
+ if (index != -1) {
+ String stringValue = row.get(index);
+ if (!stringValue.isEmpty()) {
+ try {
+ graph.claimLiteral(subject, relation, stringValue, Bindings.STRING);
+ } catch (NumberFormatException e) {
+ throw new DatabaseException(e);
+ }
+ }
+ }
+ }
+
+ private static void writeDoubleArrayFromString(WriteGraph graph, CSVRecord row, int index, Resource subject, Resource relation, MathTransform actualTransform) throws DatabaseException, MismatchedDimensionException, TransformException {
+ if (index != -1) {
+ String stringValue = row.get(index);
+ if (!stringValue.isEmpty()) {
+ if (stringValue.startsWith("\"") && stringValue.endsWith("\"")) {
+ stringValue = stringValue.substring(1, stringValue.length() - 1);
+ }
+ String[] coordPairs = stringValue.split(";");
+ ArrayList<Double> dd = new ArrayList<>(coordPairs.length * 2);
+ for (int i = 0; i < coordPairs.length; i++) {
+ String coordPair = coordPairs[i];
+ String[] p = coordPair.split(" ");
+ double x = Double.parseDouble(p[0]);
+ double y = Double.parseDouble(p[1]);
+ if (actualTransform != null) {
+ DirectPosition2D targetPos = new DirectPosition2D();
+ DirectPosition2D sourcePos = new DirectPosition2D(y, x);
+ DirectPosition res = actualTransform.transform(sourcePos, targetPos);
+ double[] coords = res.getCoordinate();
+ x = coords[1];
+ y = coords[0];
+ }
+ dd.add(x);
+ dd.add(y);
+ }
+ double[] detailedGeometryCoords = new double[dd.size()];
+ for (int i = 0; i < dd.size(); i++) {
+ double d = dd.get(i);
+ detailedGeometryCoords[i] = d;
+ }
+ try {
+ graph.claimLiteral(subject, relation, detailedGeometryCoords, Bindings.DOUBLE_ARRAY);
+ } catch (NumberFormatException e) {
+ throw new DatabaseException(e);
+ }
+ }
+ }
+ }
}
org.eclipse.ui.ide,
org.eclipse.ui.workbench,
org.simantics.district.geotools;bundle-version="1.0.0",
- org.slf4j.api;bundle-version="1.7.25"
+ org.slf4j.api;bundle-version="1.7.25",
+ org.simantics.maps.elevation.server
Export-Package: org.simantics.maps,
org.simantics.maps.debug,
org.simantics.maps.eclipse,
private MapScalingTransform() {
}
public static final double scale = 256.0d / 360.0d;
- public static final AffineTransform INSTANCE = new AffineTransform(scale, 0, 0, scale, 0, 0);
+ public static final AffineTransform INSTANCE = AffineTransform.getScaleInstance(scale, scale);
+ public static final AffineTransform INVERSE = AffineTransform.getScaleInstance(1/scale, 1/scale);
public static double getScaleX() {
return INSTANCE.getScaleX();
Color originalColor = g2d.getColor();
g2d.transform(transform);
- AffineTransform tr = g2d.getTransform();
-
g2d.setTransform(new AffineTransform());
// do the rendering magic
import org.simantics.g2d.participant.MouseUtil;
import org.simantics.g2d.participant.MouseUtil.MouseInfo;
-import org.simantics.maps.MapScalingTransform;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.utils.DPIUtil;
Color originalColor = g2d.getColor();
g2d.transform(transform);
- AffineTransform tr = g2d.getTransform();
-
g2d.setTransform(new AffineTransform());
// do the rendering magic
if (bounds == null)
return; // FIXME
- int zoomLevel = MapScalingTransform.zoomLevel(ot);
MouseInfo mouseInfo = util.getMouseInfo(0);
double startLat;
startLat = 0;
startLon = 0;
}
-
+ Number zoomLevel = SingletonTiffTileInterface.lookup(startLat, startLon);
String str = "X: " + formatValue(startLon, MAX_DIGITS) + ", Y: " + formatValue(startLat, MAX_DIGITS) + ", Z: " + zoomLevel;
g2d.setFont(rulerFont);
FontMetrics fm = g2d.getFontMetrics();
private static final Logger LOGGER = LoggerFactory.getLogger(MapNode.class);
- private final double MAP_SCALE = 1;
- private final int MAX_TILE_LEVEL = 19;
+ //private final double MAP_SCALE = 1;
+ //private final int MAX_TILE_LEVEL = 19;
private final int TILE_PIXEL_SIZE = 256;
private final int VIEWBOX_QUIET_TIME = 500;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.utils.DPIUtil;
import org.simantics.scenegraph.utils.GridUtils;
public class MapScaleNode extends G2DNode {
double offsetY = tr.getTranslateY();
g.setTransform(new AffineTransform());
- Font rulerFont = new Font("Tahoma", Font.PLAIN, 9);
+ Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9));;
//g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(1));
private static final transient int MAX_DIGITS = 0;
private static final transient double EPSILON = 0.01;
private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 2);
- private static final transient String[] SI_UNIT_LARGE_PREFIXES = { "m", "km" };
+ //private static final transient String[] SI_UNIT_LARGE_PREFIXES = { "m", "km" };
private static final transient double[] SCALE_VALUES = { 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 50000000 };
DN.Vertex <T DN.Element
>-- DN.Vertex.HasElevation
@defProperty "Elevation" L0.Double
+ >-- DN.Vertex.HasAltElevation
+ @defProperty "Alternative Elevation" L0.Double
>-- DN.Vertex.HasAddress
@defProperty "Address" L0.String
>-- DN.Vertex.HasSupplyTemperature
>-- DN.Vertex.HasDeltaTemperature
@defProperty "Delta temperature" L0.Double
>-- DN.Vertex.HasHeatPower
- @defProperty "Heat Power" L0.Double
+ @defProperty "Heat Power" L0.Double
+ >-- DN.Vertex.HasPeakPower
+ @defProperty "Peak Power" L0.Double
>-- DN.Vertex.HasNominalHeadM
@defProperty "NominalHeadM" L0.Double
>-- DN.Vertex.HasNominalHeadB
>-- DN.Vertex.HasValvePosition
@defProperty "Valve position" L0.Double
>-- DN.Vertex.HasNominalPressureLoss
- @defProperty "Nominal Pressure Loss" L0.Double
+ @defProperty "Nominal Pressure Loss" L0.Double
+ >-- DN.Vertex.HasPumpInReturnLine
+ @defProperty "Pump in Return Line" L0.Double
+ >-- DN.Vertex.HasHeadPumpMaximum
+ @defProperty "Head pump maximum" L0.Double
+ >-- DN.Vertex.HasHeadPumpNominal
+ @defProperty "Head pump nominal" L0.Double
+ >-- DN.Vertex.HasFrequencyConverterControlled
+ @defProperty "Frequency Converter Controlled" L0.Double
+ >-- DN.Vertex.HasInternalValveMeasurement
+ @defProperty "Internal Valve Measurement" L0.Double
+ >-- DN.Vertex.HasPumpMassFlowNominal
+ @defProperty "Pump Mass Flow Nominal" L0.Double
+ >-- DN.Vertex.HasPumpMeMax
+ @defProperty "Pump Me Max" L0.Double
+ >-- DN.Vertex.HasPumpMeMin
+ @defProperty "Pump Me Min" L0.Double
+ >-- DN.Vertex.HasPumpSpeedMax
+ @defProperty "Pump Speed Max" L0.Double
+ >-- DN.Vertex.HasPumpSpeedMin
+ @defProperty "Pump Speed Min" L0.Double
+ >-- DN.Vertex.HasValveReturnLine
+ @defProperty "Valve Return Line" L0.Double
+ >-- DN.Vertex.HasValveMeMax
+ @defProperty "Valve Me Max" L0.Double
+ >-- DN.Vertex.HasValveMeMin
+ @defProperty "Valve Me Min" L0.Double
+ >-- DN.Vertex.HasValveMinPosition
+ @defProperty "Valve Min Position" L0.Double
+ >-- DN.Vertex.HasValveOutletMode
+ @defProperty "Valve Outlet Mode" L0.Double
+ >-- DN.Vertex.HasValvePressLossNominal
+ @defProperty "Valve Press Loss Nominal" L0.Double
+ >-- DN.Vertex.HasOpeningTime
+ @defProperty "Opening Time" L0.Double
@L0.assert DN.Vertex.HasElevation 0.0
DN.Edge <T DN.Element
DN.VertexDefaultMapping <R L0.HasProperty : DN.VertexMappingParameterType
L0.HasLabel "Default Vertex mapping"
+DN.RightClickDefaultMapping <R L0.HasProperty : DN.VertexMappingParameterType
+ L0.HasLabel "Right click Vertex mapping"
+
+DN.LeftClickDefaultMapping <R L0.HasProperty : DN.VertexMappingParameterType
+ L0.HasLabel "Left click Vertex mapping"
+
+DN.Diagram.DefaultPipeTechTypeId <R L0.HasProperty : SEL.GenericParameterType
+ L0.HasLabel "Default Pipe Tech Type ID"
+
+
// ----------------------------------------------------------------------------
DN.Functions : L0.Library
L0.HasRange L0.Boolean
L0.HasLabel "Split To Multiple Diagrams"
+
+
+DN.Diagram.Visualisations <T L0.Entity
+ >-- DN.Diagram.Visualisations.ShowColorBars
+ @defProperty "Show Color Bars" L0.Boolean
+ >-- DN.Diagram.Visualisations.ShowColorBarTicks
+ @defProperty "Show Color Bar Ticks" L0.Boolean
+ >-- DN.Diagram.Visualisations.ColorBarLocation
+ @defProperty "Color Bar Location" L0.String
+ >-- DN.Diagram.Visualisations.ColorBarSize
+ @defProperty "Color Bar Size" L0.String
+ >-- DN.Diagram.Visualisations.ShowSizeBars
+ @defProperty "Show Size Bars" L0.Boolean
+ >-- DN.Diagram.Visualisations.ShowSizeBarTicks
+ @defProperty "Show Size Bar Ticks" L0.Boolean
+ >-- DN.Diagram.Visualisations.SizeBarLocation
+ @defProperty "Size Bar Location" L0.String
+ >-- DN.Diagram.Visualisations.SizeBarSize
+ @defProperty "Size Bar Size" L0.String
+
+DN.Diagram.Visualisations.ColorContribution <T L0.Entity
+DN.Diagram.Visualisations.SizeContribution <T L0.Entity
+
+DN.Diagram.Visualisations.colorContributions <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributions <R L0.HasProperty
+
+DN.Diagram.Visualisations.colorContributionContributorName <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionLabel <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionModuleName <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionModuleAttribute <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionUnit <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionVariableGain <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionVariableBias <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionDefaultColorMap <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionDefaultMin <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionDefaultMax <R L0.HasProperty
+// for graph persistence only
+DN.Diagram.Visualisations.colorContributionUsed <R L0.HasProperty
+DN.Diagram.Visualisations.colorContributionUseDefault <R L0.HasProperty
+
+DN.Diagram.Visualisations.sizeContributionContributorName <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionLabel <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionModuleName <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionModuleAttribute <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionUnit <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionVariableGain <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionVariableBias <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionDefaultSizeMap <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionDefaultMin <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionDefaultMax <R L0.HasProperty
+// for graph persistence only
+DN.Diagram.Visualisations.sizeContributionUsed <R L0.HasProperty
+DN.Diagram.Visualisations.sizeContributionUseDefault <R L0.HasProperty
+
+
DN.AddLayerToDNDiagramTemplate <T L0.Template
DN.EPSG_4326 : DN.SpatialRefSystem
DN.Mapping.VertexMapping <T DN.Mapping.Base
// Common
>-- DN.Mapping.VertexMapping.ElevationAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ElevationAltAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.SupplyTemperatureAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.ReturnTemperatureAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.SupplyPressureAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.dpAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.dtAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.HeatPowerAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PeakPowerAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.NominalHeadMAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.NominalHeadBAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.NominalFlowAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.NominalPressureLossAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.VertexMapping.NominalMassFlowAttribute --> L0.String <R L0.HasProperty
+ // pumping station
+ >-- DN.Mapping.VertexMapping.HeadPumpMaximumAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.HeadPumpNominalAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.FrequencyConverterControlledAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.InternalValveMeasurementAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpInReturnLineAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpMassFlowNominalAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpMeMaxAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpMeMinAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpSpeedMaxAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.PumpSpeedMinAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValveReturnLineAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValveMeMaxAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValveMeMinAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValveMinPositionAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValveOutletModeAttribute --> L0.String <R L0.HasProperty
+ >-- DN.Mapping.VertexMapping.ValvePressLossNominalAttribute --> L0.String <R L0.HasProperty
+
+ // valve
+ >-- DN.Mapping.VertexMapping.OpeningTimeAttribute --> L0.String <R L0.HasProperty
+
DN.Mapping.EdgeMapping <T DN.Mapping.Base
>-- DN.Mapping.EdgeMapping.LengthAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.EdgeMapping.DiameterAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.EdgeMapping.TGroundAttribute --> L0.String <R L0.HasProperty
>-- DN.Mapping.EdgeMapping.ElevationAttribute --> L0.String <R L0.HasProperty
-
// Allowed connection types
DN.SupplyConnectionType <T STR.ConnectionType
L0.HasLabel "Diagram Background Color"
>-- DN.Diagram.drawMapEnabled ==> "Boolean" <R L0.HasProperty : SEL.GenericParameterType
L0.HasLabel "Draw Map"
+ >-- DN.Diagram.hasVisualisation --> DN.Diagram.Visualisations <R L0.HasProperty
+ L0.HasLabel "Visualisation"
+ >-- DN.Diagram.hasActiveVisualisation --> DN.Diagram.Visualisations <R L0.HasProperty
>-- DN.Diagram.profileUpdateInterval ==> "Long" <R L0.HasProperty : SEL.GenericParameterType
L0.HasLabel "Profile update interval"
@L0.assert DN.Diagram.elementColoringGradientHue
@L0.assert DN.Diagram.drawMapEnabled true
@L0.assert DN.Diagram.profileUpdateInterval
2000 : L0.Long
+ @L0.assert DN.Diagram.DefaultPipeTechTypeId 0
// ----------------------------------------------------------------------------
// Built-in enumerated ScaleProperty & ThicknessProperty instances
DIA.TypeGroup.HasType DN.Edge
DN.ElementColoringStyle : DIA.Style
+DN.ElementSizingStyle : DIA.Style
DN.VertexSizeStyle : DIA.Style
DN.EdgeThicknessStyle : DIA.Style
DN.ArrowLengthStyle : DIA.Style
DN.HideStyle : DIA.Style
DN.VertexSymbolStyle : DIA.Style
DN.ConnectionLineStyle : DIA.Style
+DN.ElevationRectangleStyle : DIA.Style
+
+// Style for user component-specified text grid entries
+DN.DistrictNetworkHoverInfoStyle : DIA.Style
+
+// Style for user component-specified static info text for network branches
+DN.DistrictNetworkStaticInfoStyle : DIA.Style
// Function for dynamic selection of symbols for a vertex
// The input of the function is a DN.Vertex
public final Resource Connection;
public final Resource ConnectionLineStyle;
public final Resource Diagram;
+ public final Resource Diagram_DefaultPipeTechTypeId;
+ public final Resource Diagram_DefaultPipeTechTypeId_Inverse;
public final Resource Diagram_MappedDiagram;
public final Resource Diagram_MappedFromDiagram;
+ public final Resource Diagram_Visualisations;
+ public final Resource Diagram_Visualisations_ColorBarLocation;
+ public final Resource Diagram_Visualisations_ColorBarLocation_Inverse;
+ public final Resource Diagram_Visualisations_ColorBarSize;
+ public final Resource Diagram_Visualisations_ColorBarSize_Inverse;
+ public final Resource Diagram_Visualisations_ColorContribution;
+ public final Resource Diagram_Visualisations_ShowColorBarTicks;
+ public final Resource Diagram_Visualisations_ShowColorBarTicks_Inverse;
+ public final Resource Diagram_Visualisations_ShowColorBars;
+ public final Resource Diagram_Visualisations_ShowColorBars_Inverse;
+ public final Resource Diagram_Visualisations_ShowSizeBarTicks;
+ public final Resource Diagram_Visualisations_ShowSizeBarTicks_Inverse;
+ public final Resource Diagram_Visualisations_ShowSizeBars;
+ public final Resource Diagram_Visualisations_ShowSizeBars_Inverse;
+ public final Resource Diagram_Visualisations_SizeBarLocation;
+ public final Resource Diagram_Visualisations_SizeBarLocation_Inverse;
+ public final Resource Diagram_Visualisations_SizeBarSize;
+ public final Resource Diagram_Visualisations_SizeBarSize_Inverse;
+ public final Resource Diagram_Visualisations_SizeContribution;
+ public final Resource Diagram_Visualisations_colorContributionContributorName;
+ public final Resource Diagram_Visualisations_colorContributionContributorName_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionDefaultColorMap;
+ public final Resource Diagram_Visualisations_colorContributionDefaultColorMap_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionDefaultMax;
+ public final Resource Diagram_Visualisations_colorContributionDefaultMax_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionDefaultMin;
+ public final Resource Diagram_Visualisations_colorContributionDefaultMin_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionLabel;
+ public final Resource Diagram_Visualisations_colorContributionLabel_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionModuleAttribute;
+ public final Resource Diagram_Visualisations_colorContributionModuleAttribute_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionModuleName;
+ public final Resource Diagram_Visualisations_colorContributionModuleName_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionUnit;
+ public final Resource Diagram_Visualisations_colorContributionUnit_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionUseDefault;
+ public final Resource Diagram_Visualisations_colorContributionUseDefault_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionUsed;
+ public final Resource Diagram_Visualisations_colorContributionUsed_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionVariableBias;
+ public final Resource Diagram_Visualisations_colorContributionVariableBias_Inverse;
+ public final Resource Diagram_Visualisations_colorContributionVariableGain;
+ public final Resource Diagram_Visualisations_colorContributionVariableGain_Inverse;
+ public final Resource Diagram_Visualisations_colorContributions;
+ public final Resource Diagram_Visualisations_colorContributions_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionContributorName;
+ public final Resource Diagram_Visualisations_sizeContributionContributorName_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultMax;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultMax_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultMin;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultMin_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultSizeMap;
+ public final Resource Diagram_Visualisations_sizeContributionDefaultSizeMap_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionLabel;
+ public final Resource Diagram_Visualisations_sizeContributionLabel_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionModuleAttribute;
+ public final Resource Diagram_Visualisations_sizeContributionModuleAttribute_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionModuleName;
+ public final Resource Diagram_Visualisations_sizeContributionModuleName_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionUnit;
+ public final Resource Diagram_Visualisations_sizeContributionUnit_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionUseDefault;
+ public final Resource Diagram_Visualisations_sizeContributionUseDefault_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionUsed;
+ public final Resource Diagram_Visualisations_sizeContributionUsed_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionVariableBias;
+ public final Resource Diagram_Visualisations_sizeContributionVariableBias_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributionVariableGain;
+ public final Resource Diagram_Visualisations_sizeContributionVariableGain_Inverse;
+ public final Resource Diagram_Visualisations_sizeContributions;
+ public final Resource Diagram_Visualisations_sizeContributions_Inverse;
public final Resource Diagram_arrowLengthBias;
public final Resource Diagram_arrowLengthBias_Inverse;
public final Resource Diagram_arrowLengthGain;
public final Resource Diagram_elementColoringGradientHue_Inverse;
public final Resource Diagram_elementColoringGradientSaturation;
public final Resource Diagram_elementColoringGradientSaturation_Inverse;
+ public final Resource Diagram_hasActiveVisualisation;
+ public final Resource Diagram_hasActiveVisualisation_Inverse;
+ public final Resource Diagram_hasVisualisation;
+ public final Resource Diagram_hasVisualisation_Inverse;
public final Resource Diagram_nodeScaleBias;
public final Resource Diagram_nodeScaleBias_Inverse;
public final Resource Diagram_nodeScaleGain;
public final Resource Diagram_splitToMultipleEnabled_Inverse;
public final Resource Diagram_trackChangesEnabled;
public final Resource Diagram_trackChangesEnabled_Inverse;
+ public final Resource DistrictNetworkHoverInfoStyle;
+ public final Resource DistrictNetworkStaticInfoStyle;
public final Resource DistrictNodeGroup;
public final Resource DistrictNodeGroup_hasComponentTypeName;
public final Resource DistrictNodeGroup_hasComponentTypeName_Inverse;
public final Resource Edge_ThicknessProperty_value_Inverse;
public final Resource Element;
public final Resource ElementColoringStyle;
+ public final Resource ElementSizingStyle;
+ public final Resource ElevationRectangleStyle;
public final Resource Functions;
public final Resource Functions_arrowLengthPropertyEnumerationValues;
public final Resource Functions_arrowLengthPropertyModifier;
public final Resource Images_MapImage;
public final Resource InLayer;
public final Resource Layer;
+ public final Resource LeftClickDefaultMapping;
+ public final Resource LeftClickDefaultMapping_Inverse;
public final Resource MappedComponent;
public final Resource MappedFromElement;
public final Resource Mapping;
public final Resource Mapping_VertexMapping_DeltaPressureAttribute_Inverse;
public final Resource Mapping_VertexMapping_DeltaTemperatureAttribute;
public final Resource Mapping_VertexMapping_DeltaTemperatureAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ElevationAltAttribute;
+ public final Resource Mapping_VertexMapping_ElevationAltAttribute_Inverse;
public final Resource Mapping_VertexMapping_ElevationAttribute;
public final Resource Mapping_VertexMapping_ElevationAttribute_Inverse;
public final Resource Mapping_VertexMapping_FlowAreaAttribute;
public final Resource Mapping_VertexMapping_FlowAreaAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_FrequencyConverterControlledAttribute;
+ public final Resource Mapping_VertexMapping_FrequencyConverterControlledAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_HeadPumpMaximumAttribute;
+ public final Resource Mapping_VertexMapping_HeadPumpMaximumAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_HeadPumpNominalAttribute;
+ public final Resource Mapping_VertexMapping_HeadPumpNominalAttribute_Inverse;
public final Resource Mapping_VertexMapping_HeatLoadDsAttribute;
public final Resource Mapping_VertexMapping_HeatLoadDsAttribute_Inverse;
public final Resource Mapping_VertexMapping_HeatPowerAttribute;
public final Resource Mapping_VertexMapping_HeatPowerAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_InternalValveMeasurementAttribute;
+ public final Resource Mapping_VertexMapping_InternalValveMeasurementAttribute_Inverse;
public final Resource Mapping_VertexMapping_MassFlowAttribute;
public final Resource Mapping_VertexMapping_MassFlowAttribute_Inverse;
public final Resource Mapping_VertexMapping_MaximumHeadMAttribute;
public final Resource Mapping_VertexMapping_NominalMassFlowAttribute_Inverse;
public final Resource Mapping_VertexMapping_NominalPressureLossAttribute;
public final Resource Mapping_VertexMapping_NominalPressureLossAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_OpeningTimeAttribute;
+ public final Resource Mapping_VertexMapping_OpeningTimeAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PeakPowerAttribute;
+ public final Resource Mapping_VertexMapping_PeakPowerAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpInReturnLineAttribute;
+ public final Resource Mapping_VertexMapping_PumpInReturnLineAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpMassFlowNominalAttribute;
+ public final Resource Mapping_VertexMapping_PumpMassFlowNominalAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpMeMaxAttribute;
+ public final Resource Mapping_VertexMapping_PumpMeMaxAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpMeMinAttribute;
+ public final Resource Mapping_VertexMapping_PumpMeMinAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpSpeedMaxAttribute;
+ public final Resource Mapping_VertexMapping_PumpSpeedMaxAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_PumpSpeedMinAttribute;
+ public final Resource Mapping_VertexMapping_PumpSpeedMinAttribute_Inverse;
public final Resource Mapping_VertexMapping_ReturnPressureAttribute;
public final Resource Mapping_VertexMapping_ReturnPressureAttribute_Inverse;
public final Resource Mapping_VertexMapping_ReturnTemperatureAttribute;
public final Resource Mapping_VertexMapping_SupplyPressureAttribute_Inverse;
public final Resource Mapping_VertexMapping_SupplyTemperatureAttribute;
public final Resource Mapping_VertexMapping_SupplyTemperatureAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValveMeMaxAttribute;
+ public final Resource Mapping_VertexMapping_ValveMeMaxAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValveMeMinAttribute;
+ public final Resource Mapping_VertexMapping_ValveMeMinAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValveMinPositionAttribute;
+ public final Resource Mapping_VertexMapping_ValveMinPositionAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValveOutletModeAttribute;
+ public final Resource Mapping_VertexMapping_ValveOutletModeAttribute_Inverse;
public final Resource Mapping_VertexMapping_ValvePositionAttribute;
public final Resource Mapping_VertexMapping_ValvePositionAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValvePressLossNominalAttribute;
+ public final Resource Mapping_VertexMapping_ValvePressLossNominalAttribute_Inverse;
+ public final Resource Mapping_VertexMapping_ValveReturnLineAttribute;
+ public final Resource Mapping_VertexMapping_ValveReturnLineAttribute_Inverse;
public final Resource Mapping_VertexMapping_VelocityAttribute;
public final Resource Mapping_VertexMapping_VelocityAttribute_Inverse;
public final Resource Mapping_VertexMapping_VolFlowAttribute;
public final Resource ReturnConnectionType;
public final Resource ReturnInConnectionType;
public final Resource ReturnOutConnectionType;
+ public final Resource RightClickDefaultMapping;
+ public final Resource RightClickDefaultMapping_Inverse;
public final Resource SCLMain;
public final Resource SpatialRefSystem;
public final Resource SupplyConnectionType;
public final Resource VertexSymbolStyle;
public final Resource Vertex_HasAddress;
public final Resource Vertex_HasAddress_Inverse;
+ public final Resource Vertex_HasAltElevation;
+ public final Resource Vertex_HasAltElevation_Inverse;
public final Resource Vertex_HasDeltaPressure;
public final Resource Vertex_HasDeltaPressure_Inverse;
public final Resource Vertex_HasDeltaTemperature;
public final Resource Vertex_HasElevation_Inverse;
public final Resource Vertex_HasFlowArea;
public final Resource Vertex_HasFlowArea_Inverse;
+ public final Resource Vertex_HasFrequencyConverterControlled;
+ public final Resource Vertex_HasFrequencyConverterControlled_Inverse;
+ public final Resource Vertex_HasHeadPumpMaximum;
+ public final Resource Vertex_HasHeadPumpMaximum_Inverse;
+ public final Resource Vertex_HasHeadPumpNominal;
+ public final Resource Vertex_HasHeadPumpNominal_Inverse;
public final Resource Vertex_HasHeatLoadDs;
public final Resource Vertex_HasHeatLoadDs_Inverse;
public final Resource Vertex_HasHeatPower;
public final Resource Vertex_HasHeatPower_Inverse;
+ public final Resource Vertex_HasInternalValveMeasurement;
+ public final Resource Vertex_HasInternalValveMeasurement_Inverse;
public final Resource Vertex_HasMassFlow;
public final Resource Vertex_HasMassFlow_Inverse;
public final Resource Vertex_HasMaximumHeadM;
public final Resource Vertex_HasNominalHeadM_Inverse;
public final Resource Vertex_HasNominalPressureLoss;
public final Resource Vertex_HasNominalPressureLoss_Inverse;
+ public final Resource Vertex_HasOpeningTime;
+ public final Resource Vertex_HasOpeningTime_Inverse;
+ public final Resource Vertex_HasPeakPower;
+ public final Resource Vertex_HasPeakPower_Inverse;
+ public final Resource Vertex_HasPumpInReturnLine;
+ public final Resource Vertex_HasPumpInReturnLine_Inverse;
+ public final Resource Vertex_HasPumpMassFlowNominal;
+ public final Resource Vertex_HasPumpMassFlowNominal_Inverse;
+ public final Resource Vertex_HasPumpMeMax;
+ public final Resource Vertex_HasPumpMeMax_Inverse;
+ public final Resource Vertex_HasPumpMeMin;
+ public final Resource Vertex_HasPumpMeMin_Inverse;
+ public final Resource Vertex_HasPumpSpeedMax;
+ public final Resource Vertex_HasPumpSpeedMax_Inverse;
+ public final Resource Vertex_HasPumpSpeedMin;
+ public final Resource Vertex_HasPumpSpeedMin_Inverse;
public final Resource Vertex_HasReturnPressure;
public final Resource Vertex_HasReturnPressure_Inverse;
public final Resource Vertex_HasReturnTemperature;
public final Resource Vertex_HasSupplyPressure_Inverse;
public final Resource Vertex_HasSupplyTemperature;
public final Resource Vertex_HasSupplyTemperature_Inverse;
+ public final Resource Vertex_HasValveMeMax;
+ public final Resource Vertex_HasValveMeMax_Inverse;
+ public final Resource Vertex_HasValveMeMin;
+ public final Resource Vertex_HasValveMeMin_Inverse;
+ public final Resource Vertex_HasValveMinPosition;
+ public final Resource Vertex_HasValveMinPosition_Inverse;
+ public final Resource Vertex_HasValveOutletMode;
+ public final Resource Vertex_HasValveOutletMode_Inverse;
public final Resource Vertex_HasValvePosition;
public final Resource Vertex_HasValvePosition_Inverse;
+ public final Resource Vertex_HasValvePressLossNominal;
+ public final Resource Vertex_HasValvePressLossNominal_Inverse;
+ public final Resource Vertex_HasValveReturnLine;
+ public final Resource Vertex_HasValveReturnLine_Inverse;
public final Resource Vertex_HasVelocity;
public final Resource Vertex_HasVelocity_Inverse;
public final Resource Vertex_HasVolFlow;
public static final String Connection = "http://www.simantics.org/DistrictNetwork-1.0/Connection";
public static final String ConnectionLineStyle = "http://www.simantics.org/DistrictNetwork-1.0/ConnectionLineStyle";
public static final String Diagram = "http://www.simantics.org/DistrictNetwork-1.0/Diagram";
+ public static final String Diagram_DefaultPipeTechTypeId = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/DefaultPipeTechTypeId";
+ public static final String Diagram_DefaultPipeTechTypeId_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/DefaultPipeTechTypeId/Inverse";
public static final String Diagram_MappedDiagram = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/MappedDiagram";
public static final String Diagram_MappedFromDiagram = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/MappedFromDiagram";
+ public static final String Diagram_Visualisations = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations";
+ public static final String Diagram_Visualisations_ColorBarLocation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarLocation";
+ public static final String Diagram_Visualisations_ColorBarLocation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarLocation/Inverse";
+ public static final String Diagram_Visualisations_ColorBarSize = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarSize";
+ public static final String Diagram_Visualisations_ColorBarSize_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorBarSize/Inverse";
+ public static final String Diagram_Visualisations_ColorContribution = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ColorContribution";
+ public static final String Diagram_Visualisations_ShowColorBarTicks = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBarTicks";
+ public static final String Diagram_Visualisations_ShowColorBarTicks_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBarTicks/Inverse";
+ public static final String Diagram_Visualisations_ShowColorBars = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBars";
+ public static final String Diagram_Visualisations_ShowColorBars_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowColorBars/Inverse";
+ public static final String Diagram_Visualisations_ShowSizeBarTicks = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowSizeBarTicks";
+ public static final String Diagram_Visualisations_ShowSizeBarTicks_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowSizeBarTicks/Inverse";
+ public static final String Diagram_Visualisations_ShowSizeBars = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowSizeBars";
+ public static final String Diagram_Visualisations_ShowSizeBars_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/ShowSizeBars/Inverse";
+ public static final String Diagram_Visualisations_SizeBarLocation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarLocation";
+ public static final String Diagram_Visualisations_SizeBarLocation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarLocation/Inverse";
+ public static final String Diagram_Visualisations_SizeBarSize = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarSize";
+ public static final String Diagram_Visualisations_SizeBarSize_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeBarSize/Inverse";
+ public static final String Diagram_Visualisations_SizeContribution = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/SizeContribution";
+ public static final String Diagram_Visualisations_colorContributionContributorName = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionContributorName";
+ public static final String Diagram_Visualisations_colorContributionContributorName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionContributorName/Inverse";
+ public static final String Diagram_Visualisations_colorContributionDefaultColorMap = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultColorMap";
+ public static final String Diagram_Visualisations_colorContributionDefaultColorMap_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultColorMap/Inverse";
+ public static final String Diagram_Visualisations_colorContributionDefaultMax = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultMax";
+ public static final String Diagram_Visualisations_colorContributionDefaultMax_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultMax/Inverse";
+ public static final String Diagram_Visualisations_colorContributionDefaultMin = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultMin";
+ public static final String Diagram_Visualisations_colorContributionDefaultMin_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionDefaultMin/Inverse";
+ public static final String Diagram_Visualisations_colorContributionLabel = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionLabel";
+ public static final String Diagram_Visualisations_colorContributionLabel_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionLabel/Inverse";
+ public static final String Diagram_Visualisations_colorContributionModuleAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionModuleAttribute";
+ public static final String Diagram_Visualisations_colorContributionModuleAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionModuleAttribute/Inverse";
+ public static final String Diagram_Visualisations_colorContributionModuleName = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionModuleName";
+ public static final String Diagram_Visualisations_colorContributionModuleName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionModuleName/Inverse";
+ public static final String Diagram_Visualisations_colorContributionUnit = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUnit";
+ public static final String Diagram_Visualisations_colorContributionUnit_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUnit/Inverse";
+ public static final String Diagram_Visualisations_colorContributionUseDefault = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUseDefault";
+ public static final String Diagram_Visualisations_colorContributionUseDefault_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUseDefault/Inverse";
+ public static final String Diagram_Visualisations_colorContributionUsed = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUsed";
+ public static final String Diagram_Visualisations_colorContributionUsed_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionUsed/Inverse";
+ public static final String Diagram_Visualisations_colorContributionVariableBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionVariableBias";
+ public static final String Diagram_Visualisations_colorContributionVariableBias_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionVariableBias/Inverse";
+ public static final String Diagram_Visualisations_colorContributionVariableGain = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionVariableGain";
+ public static final String Diagram_Visualisations_colorContributionVariableGain_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributionVariableGain/Inverse";
+ public static final String Diagram_Visualisations_colorContributions = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributions";
+ public static final String Diagram_Visualisations_colorContributions_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/colorContributions/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionContributorName = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionContributorName";
+ public static final String Diagram_Visualisations_sizeContributionContributorName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionContributorName/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionDefaultMax = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultMax";
+ public static final String Diagram_Visualisations_sizeContributionDefaultMax_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultMax/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionDefaultMin = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultMin";
+ public static final String Diagram_Visualisations_sizeContributionDefaultMin_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultMin/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionDefaultSizeMap = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultSizeMap";
+ public static final String Diagram_Visualisations_sizeContributionDefaultSizeMap_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionDefaultSizeMap/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionLabel = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionLabel";
+ public static final String Diagram_Visualisations_sizeContributionLabel_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionLabel/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionModuleAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionModuleAttribute";
+ public static final String Diagram_Visualisations_sizeContributionModuleAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionModuleAttribute/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionModuleName = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionModuleName";
+ public static final String Diagram_Visualisations_sizeContributionModuleName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionModuleName/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionUnit = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUnit";
+ public static final String Diagram_Visualisations_sizeContributionUnit_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUnit/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionUseDefault = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUseDefault";
+ public static final String Diagram_Visualisations_sizeContributionUseDefault_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUseDefault/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionUsed = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUsed";
+ public static final String Diagram_Visualisations_sizeContributionUsed_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionUsed/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionVariableBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionVariableBias";
+ public static final String Diagram_Visualisations_sizeContributionVariableBias_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionVariableBias/Inverse";
+ public static final String Diagram_Visualisations_sizeContributionVariableGain = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionVariableGain";
+ public static final String Diagram_Visualisations_sizeContributionVariableGain_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributionVariableGain/Inverse";
+ public static final String Diagram_Visualisations_sizeContributions = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributions";
+ public static final String Diagram_Visualisations_sizeContributions_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/Visualisations/sizeContributions/Inverse";
public static final String Diagram_arrowLengthBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/arrowLengthBias";
public static final String Diagram_arrowLengthBias_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/arrowLengthBias/Inverse";
public static final String Diagram_arrowLengthGain = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/arrowLengthGain";
public static final String Diagram_elementColoringGradientHue_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientHue/Inverse";
public static final String Diagram_elementColoringGradientSaturation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation";
public static final String Diagram_elementColoringGradientSaturation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/elementColoringGradientSaturation/Inverse";
+ public static final String Diagram_hasActiveVisualisation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasActiveVisualisation";
+ public static final String Diagram_hasActiveVisualisation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasActiveVisualisation/Inverse";
+ public static final String Diagram_hasVisualisation = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasVisualisation";
+ public static final String Diagram_hasVisualisation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/hasVisualisation/Inverse";
public static final String Diagram_nodeScaleBias = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleBias";
public static final String Diagram_nodeScaleBias_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleBias/Inverse";
public static final String Diagram_nodeScaleGain = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/nodeScaleGain";
public static final String Diagram_splitToMultipleEnabled_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/splitToMultipleEnabled/Inverse";
public static final String Diagram_trackChangesEnabled = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/trackChangesEnabled";
public static final String Diagram_trackChangesEnabled_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Diagram/trackChangesEnabled/Inverse";
+ public static final String DistrictNetworkHoverInfoStyle = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkHoverInfoStyle";
+ public static final String DistrictNetworkStaticInfoStyle = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkStaticInfoStyle";
public static final String DistrictNodeGroup = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup";
public static final String DistrictNodeGroup_hasComponentTypeName = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup/hasComponentTypeName";
public static final String DistrictNodeGroup_hasComponentTypeName_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/DistrictNodeGroup/hasComponentTypeName/Inverse";
public static final String Edge_ThicknessProperty_value_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Edge/ThicknessProperty/value/Inverse";
public static final String Element = "http://www.simantics.org/DistrictNetwork-1.0/Element";
public static final String ElementColoringStyle = "http://www.simantics.org/DistrictNetwork-1.0/ElementColoringStyle";
+ public static final String ElementSizingStyle = "http://www.simantics.org/DistrictNetwork-1.0/ElementSizingStyle";
+ public static final String ElevationRectangleStyle = "http://www.simantics.org/DistrictNetwork-1.0/ElevationRectangleStyle";
public static final String Functions = "http://www.simantics.org/DistrictNetwork-1.0/Functions";
public static final String Functions_arrowLengthPropertyEnumerationValues = "http://www.simantics.org/DistrictNetwork-1.0/Functions/arrowLengthPropertyEnumerationValues";
public static final String Functions_arrowLengthPropertyModifier = "http://www.simantics.org/DistrictNetwork-1.0/Functions/arrowLengthPropertyModifier";
public static final String Images_MapImage = "http://www.simantics.org/DistrictNetwork-1.0/Images/MapImage";
public static final String InLayer = "http://www.simantics.org/DistrictNetwork-1.0/InLayer";
public static final String Layer = "http://www.simantics.org/DistrictNetwork-1.0/Layer";
+ public static final String LeftClickDefaultMapping = "http://www.simantics.org/DistrictNetwork-1.0/LeftClickDefaultMapping";
+ public static final String LeftClickDefaultMapping_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/LeftClickDefaultMapping/Inverse";
public static final String MappedComponent = "http://www.simantics.org/DistrictNetwork-1.0/MappedComponent";
public static final String MappedFromElement = "http://www.simantics.org/DistrictNetwork-1.0/MappedFromElement";
public static final String Mapping = "http://www.simantics.org/DistrictNetwork-1.0/Mapping";
public static final String Mapping_VertexMapping_DeltaPressureAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/DeltaPressureAttribute/Inverse";
public static final String Mapping_VertexMapping_DeltaTemperatureAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/DeltaTemperatureAttribute";
public static final String Mapping_VertexMapping_DeltaTemperatureAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/DeltaTemperatureAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ElevationAltAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ElevationAltAttribute";
+ public static final String Mapping_VertexMapping_ElevationAltAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ElevationAltAttribute/Inverse";
public static final String Mapping_VertexMapping_ElevationAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ElevationAttribute";
public static final String Mapping_VertexMapping_ElevationAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ElevationAttribute/Inverse";
public static final String Mapping_VertexMapping_FlowAreaAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/FlowAreaAttribute";
public static final String Mapping_VertexMapping_FlowAreaAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/FlowAreaAttribute/Inverse";
+ public static final String Mapping_VertexMapping_FrequencyConverterControlledAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/FrequencyConverterControlledAttribute";
+ public static final String Mapping_VertexMapping_FrequencyConverterControlledAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/FrequencyConverterControlledAttribute/Inverse";
+ public static final String Mapping_VertexMapping_HeadPumpMaximumAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeadPumpMaximumAttribute";
+ public static final String Mapping_VertexMapping_HeadPumpMaximumAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeadPumpMaximumAttribute/Inverse";
+ public static final String Mapping_VertexMapping_HeadPumpNominalAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeadPumpNominalAttribute";
+ public static final String Mapping_VertexMapping_HeadPumpNominalAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeadPumpNominalAttribute/Inverse";
public static final String Mapping_VertexMapping_HeatLoadDsAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeatLoadDsAttribute";
public static final String Mapping_VertexMapping_HeatLoadDsAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeatLoadDsAttribute/Inverse";
public static final String Mapping_VertexMapping_HeatPowerAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeatPowerAttribute";
public static final String Mapping_VertexMapping_HeatPowerAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/HeatPowerAttribute/Inverse";
+ public static final String Mapping_VertexMapping_InternalValveMeasurementAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/InternalValveMeasurementAttribute";
+ public static final String Mapping_VertexMapping_InternalValveMeasurementAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/InternalValveMeasurementAttribute/Inverse";
public static final String Mapping_VertexMapping_MassFlowAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/MassFlowAttribute";
public static final String Mapping_VertexMapping_MassFlowAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/MassFlowAttribute/Inverse";
public static final String Mapping_VertexMapping_MaximumHeadMAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/MaximumHeadMAttribute";
public static final String Mapping_VertexMapping_NominalMassFlowAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/NominalMassFlowAttribute/Inverse";
public static final String Mapping_VertexMapping_NominalPressureLossAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/NominalPressureLossAttribute";
public static final String Mapping_VertexMapping_NominalPressureLossAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/NominalPressureLossAttribute/Inverse";
+ public static final String Mapping_VertexMapping_OpeningTimeAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/OpeningTimeAttribute";
+ public static final String Mapping_VertexMapping_OpeningTimeAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/OpeningTimeAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PeakPowerAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PeakPowerAttribute";
+ public static final String Mapping_VertexMapping_PeakPowerAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PeakPowerAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpInReturnLineAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpInReturnLineAttribute";
+ public static final String Mapping_VertexMapping_PumpInReturnLineAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpInReturnLineAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpMassFlowNominalAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMassFlowNominalAttribute";
+ public static final String Mapping_VertexMapping_PumpMassFlowNominalAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMassFlowNominalAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpMeMaxAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMeMaxAttribute";
+ public static final String Mapping_VertexMapping_PumpMeMaxAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMeMaxAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpMeMinAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMeMinAttribute";
+ public static final String Mapping_VertexMapping_PumpMeMinAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpMeMinAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpSpeedMaxAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpSpeedMaxAttribute";
+ public static final String Mapping_VertexMapping_PumpSpeedMaxAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpSpeedMaxAttribute/Inverse";
+ public static final String Mapping_VertexMapping_PumpSpeedMinAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpSpeedMinAttribute";
+ public static final String Mapping_VertexMapping_PumpSpeedMinAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/PumpSpeedMinAttribute/Inverse";
public static final String Mapping_VertexMapping_ReturnPressureAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ReturnPressureAttribute";
public static final String Mapping_VertexMapping_ReturnPressureAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ReturnPressureAttribute/Inverse";
public static final String Mapping_VertexMapping_ReturnTemperatureAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ReturnTemperatureAttribute";
public static final String Mapping_VertexMapping_SupplyPressureAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/SupplyPressureAttribute/Inverse";
public static final String Mapping_VertexMapping_SupplyTemperatureAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/SupplyTemperatureAttribute";
public static final String Mapping_VertexMapping_SupplyTemperatureAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/SupplyTemperatureAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValveMeMaxAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMeMaxAttribute";
+ public static final String Mapping_VertexMapping_ValveMeMaxAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMeMaxAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValveMeMinAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMeMinAttribute";
+ public static final String Mapping_VertexMapping_ValveMeMinAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMeMinAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValveMinPositionAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMinPositionAttribute";
+ public static final String Mapping_VertexMapping_ValveMinPositionAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveMinPositionAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValveOutletModeAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveOutletModeAttribute";
+ public static final String Mapping_VertexMapping_ValveOutletModeAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveOutletModeAttribute/Inverse";
public static final String Mapping_VertexMapping_ValvePositionAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValvePositionAttribute";
public static final String Mapping_VertexMapping_ValvePositionAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValvePositionAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValvePressLossNominalAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValvePressLossNominalAttribute";
+ public static final String Mapping_VertexMapping_ValvePressLossNominalAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValvePressLossNominalAttribute/Inverse";
+ public static final String Mapping_VertexMapping_ValveReturnLineAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveReturnLineAttribute";
+ public static final String Mapping_VertexMapping_ValveReturnLineAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/ValveReturnLineAttribute/Inverse";
public static final String Mapping_VertexMapping_VelocityAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/VelocityAttribute";
public static final String Mapping_VertexMapping_VelocityAttribute_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/VelocityAttribute/Inverse";
public static final String Mapping_VertexMapping_VolFlowAttribute = "http://www.simantics.org/DistrictNetwork-1.0/Mapping/VertexMapping/VolFlowAttribute";
public static final String ReturnConnectionType = "http://www.simantics.org/DistrictNetwork-1.0/ReturnConnectionType";
public static final String ReturnInConnectionType = "http://www.simantics.org/DistrictNetwork-1.0/ReturnInConnectionType";
public static final String ReturnOutConnectionType = "http://www.simantics.org/DistrictNetwork-1.0/ReturnOutConnectionType";
+ public static final String RightClickDefaultMapping = "http://www.simantics.org/DistrictNetwork-1.0/RightClickDefaultMapping";
+ public static final String RightClickDefaultMapping_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/RightClickDefaultMapping/Inverse";
public static final String SCLMain = "http://www.simantics.org/DistrictNetwork-1.0/SCLMain";
public static final String SpatialRefSystem = "http://www.simantics.org/DistrictNetwork-1.0/SpatialRefSystem";
public static final String SupplyConnectionType = "http://www.simantics.org/DistrictNetwork-1.0/SupplyConnectionType";
public static final String VertexSymbolStyle = "http://www.simantics.org/DistrictNetwork-1.0/VertexSymbolStyle";
public static final String Vertex_HasAddress = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasAddress";
public static final String Vertex_HasAddress_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasAddress/Inverse";
+ public static final String Vertex_HasAltElevation = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasAltElevation";
+ public static final String Vertex_HasAltElevation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasAltElevation/Inverse";
public static final String Vertex_HasDeltaPressure = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasDeltaPressure";
public static final String Vertex_HasDeltaPressure_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasDeltaPressure/Inverse";
public static final String Vertex_HasDeltaTemperature = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasDeltaTemperature";
public static final String Vertex_HasElevation_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasElevation/Inverse";
public static final String Vertex_HasFlowArea = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasFlowArea";
public static final String Vertex_HasFlowArea_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasFlowArea/Inverse";
+ public static final String Vertex_HasFrequencyConverterControlled = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasFrequencyConverterControlled";
+ public static final String Vertex_HasFrequencyConverterControlled_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasFrequencyConverterControlled/Inverse";
+ public static final String Vertex_HasHeadPumpMaximum = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeadPumpMaximum";
+ public static final String Vertex_HasHeadPumpMaximum_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeadPumpMaximum/Inverse";
+ public static final String Vertex_HasHeadPumpNominal = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeadPumpNominal";
+ public static final String Vertex_HasHeadPumpNominal_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeadPumpNominal/Inverse";
public static final String Vertex_HasHeatLoadDs = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeatLoadDs";
public static final String Vertex_HasHeatLoadDs_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeatLoadDs/Inverse";
public static final String Vertex_HasHeatPower = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeatPower";
public static final String Vertex_HasHeatPower_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasHeatPower/Inverse";
+ public static final String Vertex_HasInternalValveMeasurement = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasInternalValveMeasurement";
+ public static final String Vertex_HasInternalValveMeasurement_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasInternalValveMeasurement/Inverse";
public static final String Vertex_HasMassFlow = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasMassFlow";
public static final String Vertex_HasMassFlow_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasMassFlow/Inverse";
public static final String Vertex_HasMaximumHeadM = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasMaximumHeadM";
public static final String Vertex_HasNominalHeadM_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasNominalHeadM/Inverse";
public static final String Vertex_HasNominalPressureLoss = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasNominalPressureLoss";
public static final String Vertex_HasNominalPressureLoss_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasNominalPressureLoss/Inverse";
+ public static final String Vertex_HasOpeningTime = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasOpeningTime";
+ public static final String Vertex_HasOpeningTime_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasOpeningTime/Inverse";
+ public static final String Vertex_HasPeakPower = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPeakPower";
+ public static final String Vertex_HasPeakPower_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPeakPower/Inverse";
+ public static final String Vertex_HasPumpInReturnLine = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpInReturnLine";
+ public static final String Vertex_HasPumpInReturnLine_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpInReturnLine/Inverse";
+ public static final String Vertex_HasPumpMassFlowNominal = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMassFlowNominal";
+ public static final String Vertex_HasPumpMassFlowNominal_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMassFlowNominal/Inverse";
+ public static final String Vertex_HasPumpMeMax = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMeMax";
+ public static final String Vertex_HasPumpMeMax_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMeMax/Inverse";
+ public static final String Vertex_HasPumpMeMin = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMeMin";
+ public static final String Vertex_HasPumpMeMin_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpMeMin/Inverse";
+ public static final String Vertex_HasPumpSpeedMax = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpSpeedMax";
+ public static final String Vertex_HasPumpSpeedMax_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpSpeedMax/Inverse";
+ public static final String Vertex_HasPumpSpeedMin = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpSpeedMin";
+ public static final String Vertex_HasPumpSpeedMin_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasPumpSpeedMin/Inverse";
public static final String Vertex_HasReturnPressure = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasReturnPressure";
public static final String Vertex_HasReturnPressure_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasReturnPressure/Inverse";
public static final String Vertex_HasReturnTemperature = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasReturnTemperature";
public static final String Vertex_HasSupplyPressure_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasSupplyPressure/Inverse";
public static final String Vertex_HasSupplyTemperature = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasSupplyTemperature";
public static final String Vertex_HasSupplyTemperature_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasSupplyTemperature/Inverse";
+ public static final String Vertex_HasValveMeMax = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMeMax";
+ public static final String Vertex_HasValveMeMax_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMeMax/Inverse";
+ public static final String Vertex_HasValveMeMin = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMeMin";
+ public static final String Vertex_HasValveMeMin_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMeMin/Inverse";
+ public static final String Vertex_HasValveMinPosition = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMinPosition";
+ public static final String Vertex_HasValveMinPosition_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveMinPosition/Inverse";
+ public static final String Vertex_HasValveOutletMode = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveOutletMode";
+ public static final String Vertex_HasValveOutletMode_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveOutletMode/Inverse";
public static final String Vertex_HasValvePosition = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValvePosition";
public static final String Vertex_HasValvePosition_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValvePosition/Inverse";
+ public static final String Vertex_HasValvePressLossNominal = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValvePressLossNominal";
+ public static final String Vertex_HasValvePressLossNominal_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValvePressLossNominal/Inverse";
+ public static final String Vertex_HasValveReturnLine = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveReturnLine";
+ public static final String Vertex_HasValveReturnLine_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasValveReturnLine/Inverse";
public static final String Vertex_HasVelocity = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasVelocity";
public static final String Vertex_HasVelocity_Inverse = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasVelocity/Inverse";
public static final String Vertex_HasVolFlow = "http://www.simantics.org/DistrictNetwork-1.0/Vertex/HasVolFlow";
Connection = getResourceOrNull(graph, URIs.Connection);
ConnectionLineStyle = getResourceOrNull(graph, URIs.ConnectionLineStyle);
Diagram = getResourceOrNull(graph, URIs.Diagram);
+ Diagram_DefaultPipeTechTypeId = getResourceOrNull(graph, URIs.Diagram_DefaultPipeTechTypeId);
+ Diagram_DefaultPipeTechTypeId_Inverse = getResourceOrNull(graph, URIs.Diagram_DefaultPipeTechTypeId_Inverse);
Diagram_MappedDiagram = getResourceOrNull(graph, URIs.Diagram_MappedDiagram);
Diagram_MappedFromDiagram = getResourceOrNull(graph, URIs.Diagram_MappedFromDiagram);
+ Diagram_Visualisations = getResourceOrNull(graph, URIs.Diagram_Visualisations);
+ Diagram_Visualisations_ColorBarLocation = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarLocation);
+ Diagram_Visualisations_ColorBarLocation_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarLocation_Inverse);
+ Diagram_Visualisations_ColorBarSize = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarSize);
+ Diagram_Visualisations_ColorBarSize_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorBarSize_Inverse);
+ Diagram_Visualisations_ColorContribution = getResourceOrNull(graph, URIs.Diagram_Visualisations_ColorContribution);
+ Diagram_Visualisations_ShowColorBarTicks = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBarTicks);
+ Diagram_Visualisations_ShowColorBarTicks_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBarTicks_Inverse);
+ Diagram_Visualisations_ShowColorBars = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBars);
+ Diagram_Visualisations_ShowColorBars_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowColorBars_Inverse);
+ Diagram_Visualisations_ShowSizeBarTicks = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowSizeBarTicks);
+ Diagram_Visualisations_ShowSizeBarTicks_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowSizeBarTicks_Inverse);
+ Diagram_Visualisations_ShowSizeBars = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowSizeBars);
+ Diagram_Visualisations_ShowSizeBars_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_ShowSizeBars_Inverse);
+ Diagram_Visualisations_SizeBarLocation = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarLocation);
+ Diagram_Visualisations_SizeBarLocation_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarLocation_Inverse);
+ Diagram_Visualisations_SizeBarSize = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarSize);
+ Diagram_Visualisations_SizeBarSize_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeBarSize_Inverse);
+ Diagram_Visualisations_SizeContribution = getResourceOrNull(graph, URIs.Diagram_Visualisations_SizeContribution);
+ Diagram_Visualisations_colorContributionContributorName = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionContributorName);
+ Diagram_Visualisations_colorContributionContributorName_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionContributorName_Inverse);
+ Diagram_Visualisations_colorContributionDefaultColorMap = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultColorMap);
+ Diagram_Visualisations_colorContributionDefaultColorMap_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultColorMap_Inverse);
+ Diagram_Visualisations_colorContributionDefaultMax = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultMax);
+ Diagram_Visualisations_colorContributionDefaultMax_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultMax_Inverse);
+ Diagram_Visualisations_colorContributionDefaultMin = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultMin);
+ Diagram_Visualisations_colorContributionDefaultMin_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionDefaultMin_Inverse);
+ Diagram_Visualisations_colorContributionLabel = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionLabel);
+ Diagram_Visualisations_colorContributionLabel_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionLabel_Inverse);
+ Diagram_Visualisations_colorContributionModuleAttribute = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionModuleAttribute);
+ Diagram_Visualisations_colorContributionModuleAttribute_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionModuleAttribute_Inverse);
+ Diagram_Visualisations_colorContributionModuleName = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionModuleName);
+ Diagram_Visualisations_colorContributionModuleName_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionModuleName_Inverse);
+ Diagram_Visualisations_colorContributionUnit = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUnit);
+ Diagram_Visualisations_colorContributionUnit_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUnit_Inverse);
+ Diagram_Visualisations_colorContributionUseDefault = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUseDefault);
+ Diagram_Visualisations_colorContributionUseDefault_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUseDefault_Inverse);
+ Diagram_Visualisations_colorContributionUsed = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUsed);
+ Diagram_Visualisations_colorContributionUsed_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionUsed_Inverse);
+ Diagram_Visualisations_colorContributionVariableBias = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionVariableBias);
+ Diagram_Visualisations_colorContributionVariableBias_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionVariableBias_Inverse);
+ Diagram_Visualisations_colorContributionVariableGain = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionVariableGain);
+ Diagram_Visualisations_colorContributionVariableGain_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributionVariableGain_Inverse);
+ Diagram_Visualisations_colorContributions = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributions);
+ Diagram_Visualisations_colorContributions_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_colorContributions_Inverse);
+ Diagram_Visualisations_sizeContributionContributorName = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionContributorName);
+ Diagram_Visualisations_sizeContributionContributorName_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionContributorName_Inverse);
+ Diagram_Visualisations_sizeContributionDefaultMax = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultMax);
+ Diagram_Visualisations_sizeContributionDefaultMax_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultMax_Inverse);
+ Diagram_Visualisations_sizeContributionDefaultMin = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultMin);
+ Diagram_Visualisations_sizeContributionDefaultMin_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultMin_Inverse);
+ Diagram_Visualisations_sizeContributionDefaultSizeMap = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultSizeMap);
+ Diagram_Visualisations_sizeContributionDefaultSizeMap_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionDefaultSizeMap_Inverse);
+ Diagram_Visualisations_sizeContributionLabel = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionLabel);
+ Diagram_Visualisations_sizeContributionLabel_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionLabel_Inverse);
+ Diagram_Visualisations_sizeContributionModuleAttribute = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionModuleAttribute);
+ Diagram_Visualisations_sizeContributionModuleAttribute_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionModuleAttribute_Inverse);
+ Diagram_Visualisations_sizeContributionModuleName = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionModuleName);
+ Diagram_Visualisations_sizeContributionModuleName_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionModuleName_Inverse);
+ Diagram_Visualisations_sizeContributionUnit = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUnit);
+ Diagram_Visualisations_sizeContributionUnit_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUnit_Inverse);
+ Diagram_Visualisations_sizeContributionUseDefault = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUseDefault);
+ Diagram_Visualisations_sizeContributionUseDefault_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUseDefault_Inverse);
+ Diagram_Visualisations_sizeContributionUsed = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUsed);
+ Diagram_Visualisations_sizeContributionUsed_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionUsed_Inverse);
+ Diagram_Visualisations_sizeContributionVariableBias = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionVariableBias);
+ Diagram_Visualisations_sizeContributionVariableBias_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionVariableBias_Inverse);
+ Diagram_Visualisations_sizeContributionVariableGain = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionVariableGain);
+ Diagram_Visualisations_sizeContributionVariableGain_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributionVariableGain_Inverse);
+ Diagram_Visualisations_sizeContributions = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributions);
+ Diagram_Visualisations_sizeContributions_Inverse = getResourceOrNull(graph, URIs.Diagram_Visualisations_sizeContributions_Inverse);
Diagram_arrowLengthBias = getResourceOrNull(graph, URIs.Diagram_arrowLengthBias);
Diagram_arrowLengthBias_Inverse = getResourceOrNull(graph, URIs.Diagram_arrowLengthBias_Inverse);
Diagram_arrowLengthGain = getResourceOrNull(graph, URIs.Diagram_arrowLengthGain);
Diagram_elementColoringGradientHue_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientHue_Inverse);
Diagram_elementColoringGradientSaturation = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation);
Diagram_elementColoringGradientSaturation_Inverse = getResourceOrNull(graph, URIs.Diagram_elementColoringGradientSaturation_Inverse);
+ Diagram_hasActiveVisualisation = getResourceOrNull(graph, URIs.Diagram_hasActiveVisualisation);
+ Diagram_hasActiveVisualisation_Inverse = getResourceOrNull(graph, URIs.Diagram_hasActiveVisualisation_Inverse);
+ Diagram_hasVisualisation = getResourceOrNull(graph, URIs.Diagram_hasVisualisation);
+ Diagram_hasVisualisation_Inverse = getResourceOrNull(graph, URIs.Diagram_hasVisualisation_Inverse);
Diagram_nodeScaleBias = getResourceOrNull(graph, URIs.Diagram_nodeScaleBias);
Diagram_nodeScaleBias_Inverse = getResourceOrNull(graph, URIs.Diagram_nodeScaleBias_Inverse);
Diagram_nodeScaleGain = getResourceOrNull(graph, URIs.Diagram_nodeScaleGain);
Diagram_splitToMultipleEnabled_Inverse = getResourceOrNull(graph, URIs.Diagram_splitToMultipleEnabled_Inverse);
Diagram_trackChangesEnabled = getResourceOrNull(graph, URIs.Diagram_trackChangesEnabled);
Diagram_trackChangesEnabled_Inverse = getResourceOrNull(graph, URIs.Diagram_trackChangesEnabled_Inverse);
+ DistrictNetworkHoverInfoStyle = getResourceOrNull(graph, URIs.DistrictNetworkHoverInfoStyle);
+ DistrictNetworkStaticInfoStyle = getResourceOrNull(graph, URIs.DistrictNetworkStaticInfoStyle);
DistrictNodeGroup = getResourceOrNull(graph, URIs.DistrictNodeGroup);
DistrictNodeGroup_hasComponentTypeName = getResourceOrNull(graph, URIs.DistrictNodeGroup_hasComponentTypeName);
DistrictNodeGroup_hasComponentTypeName_Inverse = getResourceOrNull(graph, URIs.DistrictNodeGroup_hasComponentTypeName_Inverse);
Edge_ThicknessProperty_value_Inverse = getResourceOrNull(graph, URIs.Edge_ThicknessProperty_value_Inverse);
Element = getResourceOrNull(graph, URIs.Element);
ElementColoringStyle = getResourceOrNull(graph, URIs.ElementColoringStyle);
+ ElementSizingStyle = getResourceOrNull(graph, URIs.ElementSizingStyle);
+ ElevationRectangleStyle = getResourceOrNull(graph, URIs.ElevationRectangleStyle);
Functions = getResourceOrNull(graph, URIs.Functions);
Functions_arrowLengthPropertyEnumerationValues = getResourceOrNull(graph, URIs.Functions_arrowLengthPropertyEnumerationValues);
Functions_arrowLengthPropertyModifier = getResourceOrNull(graph, URIs.Functions_arrowLengthPropertyModifier);
Images_MapImage = getResourceOrNull(graph, URIs.Images_MapImage);
InLayer = getResourceOrNull(graph, URIs.InLayer);
Layer = getResourceOrNull(graph, URIs.Layer);
+ LeftClickDefaultMapping = getResourceOrNull(graph, URIs.LeftClickDefaultMapping);
+ LeftClickDefaultMapping_Inverse = getResourceOrNull(graph, URIs.LeftClickDefaultMapping_Inverse);
MappedComponent = getResourceOrNull(graph, URIs.MappedComponent);
MappedFromElement = getResourceOrNull(graph, URIs.MappedFromElement);
Mapping = getResourceOrNull(graph, URIs.Mapping);
Mapping_VertexMapping_DeltaPressureAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_DeltaPressureAttribute_Inverse);
Mapping_VertexMapping_DeltaTemperatureAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_DeltaTemperatureAttribute);
Mapping_VertexMapping_DeltaTemperatureAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_DeltaTemperatureAttribute_Inverse);
+ Mapping_VertexMapping_ElevationAltAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ElevationAltAttribute);
+ Mapping_VertexMapping_ElevationAltAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ElevationAltAttribute_Inverse);
Mapping_VertexMapping_ElevationAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ElevationAttribute);
Mapping_VertexMapping_ElevationAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ElevationAttribute_Inverse);
Mapping_VertexMapping_FlowAreaAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_FlowAreaAttribute);
Mapping_VertexMapping_FlowAreaAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_FlowAreaAttribute_Inverse);
+ Mapping_VertexMapping_FrequencyConverterControlledAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_FrequencyConverterControlledAttribute);
+ Mapping_VertexMapping_FrequencyConverterControlledAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_FrequencyConverterControlledAttribute_Inverse);
+ Mapping_VertexMapping_HeadPumpMaximumAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeadPumpMaximumAttribute);
+ Mapping_VertexMapping_HeadPumpMaximumAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeadPumpMaximumAttribute_Inverse);
+ Mapping_VertexMapping_HeadPumpNominalAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeadPumpNominalAttribute);
+ Mapping_VertexMapping_HeadPumpNominalAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeadPumpNominalAttribute_Inverse);
Mapping_VertexMapping_HeatLoadDsAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeatLoadDsAttribute);
Mapping_VertexMapping_HeatLoadDsAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeatLoadDsAttribute_Inverse);
Mapping_VertexMapping_HeatPowerAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeatPowerAttribute);
Mapping_VertexMapping_HeatPowerAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_HeatPowerAttribute_Inverse);
+ Mapping_VertexMapping_InternalValveMeasurementAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_InternalValveMeasurementAttribute);
+ Mapping_VertexMapping_InternalValveMeasurementAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_InternalValveMeasurementAttribute_Inverse);
Mapping_VertexMapping_MassFlowAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_MassFlowAttribute);
Mapping_VertexMapping_MassFlowAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_MassFlowAttribute_Inverse);
Mapping_VertexMapping_MaximumHeadMAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_MaximumHeadMAttribute);
Mapping_VertexMapping_NominalMassFlowAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_NominalMassFlowAttribute_Inverse);
Mapping_VertexMapping_NominalPressureLossAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_NominalPressureLossAttribute);
Mapping_VertexMapping_NominalPressureLossAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_NominalPressureLossAttribute_Inverse);
+ Mapping_VertexMapping_OpeningTimeAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_OpeningTimeAttribute);
+ Mapping_VertexMapping_OpeningTimeAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_OpeningTimeAttribute_Inverse);
+ Mapping_VertexMapping_PeakPowerAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PeakPowerAttribute);
+ Mapping_VertexMapping_PeakPowerAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PeakPowerAttribute_Inverse);
+ Mapping_VertexMapping_PumpInReturnLineAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpInReturnLineAttribute);
+ Mapping_VertexMapping_PumpInReturnLineAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpInReturnLineAttribute_Inverse);
+ Mapping_VertexMapping_PumpMassFlowNominalAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMassFlowNominalAttribute);
+ Mapping_VertexMapping_PumpMassFlowNominalAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMassFlowNominalAttribute_Inverse);
+ Mapping_VertexMapping_PumpMeMaxAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMeMaxAttribute);
+ Mapping_VertexMapping_PumpMeMaxAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMeMaxAttribute_Inverse);
+ Mapping_VertexMapping_PumpMeMinAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMeMinAttribute);
+ Mapping_VertexMapping_PumpMeMinAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpMeMinAttribute_Inverse);
+ Mapping_VertexMapping_PumpSpeedMaxAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpSpeedMaxAttribute);
+ Mapping_VertexMapping_PumpSpeedMaxAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpSpeedMaxAttribute_Inverse);
+ Mapping_VertexMapping_PumpSpeedMinAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpSpeedMinAttribute);
+ Mapping_VertexMapping_PumpSpeedMinAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_PumpSpeedMinAttribute_Inverse);
Mapping_VertexMapping_ReturnPressureAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ReturnPressureAttribute);
Mapping_VertexMapping_ReturnPressureAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ReturnPressureAttribute_Inverse);
Mapping_VertexMapping_ReturnTemperatureAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ReturnTemperatureAttribute);
Mapping_VertexMapping_SupplyPressureAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_SupplyPressureAttribute_Inverse);
Mapping_VertexMapping_SupplyTemperatureAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_SupplyTemperatureAttribute);
Mapping_VertexMapping_SupplyTemperatureAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_SupplyTemperatureAttribute_Inverse);
+ Mapping_VertexMapping_ValveMeMaxAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMeMaxAttribute);
+ Mapping_VertexMapping_ValveMeMaxAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMeMaxAttribute_Inverse);
+ Mapping_VertexMapping_ValveMeMinAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMeMinAttribute);
+ Mapping_VertexMapping_ValveMeMinAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMeMinAttribute_Inverse);
+ Mapping_VertexMapping_ValveMinPositionAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMinPositionAttribute);
+ Mapping_VertexMapping_ValveMinPositionAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveMinPositionAttribute_Inverse);
+ Mapping_VertexMapping_ValveOutletModeAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveOutletModeAttribute);
+ Mapping_VertexMapping_ValveOutletModeAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveOutletModeAttribute_Inverse);
Mapping_VertexMapping_ValvePositionAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValvePositionAttribute);
Mapping_VertexMapping_ValvePositionAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValvePositionAttribute_Inverse);
+ Mapping_VertexMapping_ValvePressLossNominalAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValvePressLossNominalAttribute);
+ Mapping_VertexMapping_ValvePressLossNominalAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValvePressLossNominalAttribute_Inverse);
+ Mapping_VertexMapping_ValveReturnLineAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveReturnLineAttribute);
+ Mapping_VertexMapping_ValveReturnLineAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_ValveReturnLineAttribute_Inverse);
Mapping_VertexMapping_VelocityAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_VelocityAttribute);
Mapping_VertexMapping_VelocityAttribute_Inverse = getResourceOrNull(graph, URIs.Mapping_VertexMapping_VelocityAttribute_Inverse);
Mapping_VertexMapping_VolFlowAttribute = getResourceOrNull(graph, URIs.Mapping_VertexMapping_VolFlowAttribute);
ReturnConnectionType = getResourceOrNull(graph, URIs.ReturnConnectionType);
ReturnInConnectionType = getResourceOrNull(graph, URIs.ReturnInConnectionType);
ReturnOutConnectionType = getResourceOrNull(graph, URIs.ReturnOutConnectionType);
+ RightClickDefaultMapping = getResourceOrNull(graph, URIs.RightClickDefaultMapping);
+ RightClickDefaultMapping_Inverse = getResourceOrNull(graph, URIs.RightClickDefaultMapping_Inverse);
SCLMain = getResourceOrNull(graph, URIs.SCLMain);
SpatialRefSystem = getResourceOrNull(graph, URIs.SpatialRefSystem);
SupplyConnectionType = getResourceOrNull(graph, URIs.SupplyConnectionType);
VertexSymbolStyle = getResourceOrNull(graph, URIs.VertexSymbolStyle);
Vertex_HasAddress = getResourceOrNull(graph, URIs.Vertex_HasAddress);
Vertex_HasAddress_Inverse = getResourceOrNull(graph, URIs.Vertex_HasAddress_Inverse);
+ Vertex_HasAltElevation = getResourceOrNull(graph, URIs.Vertex_HasAltElevation);
+ Vertex_HasAltElevation_Inverse = getResourceOrNull(graph, URIs.Vertex_HasAltElevation_Inverse);
Vertex_HasDeltaPressure = getResourceOrNull(graph, URIs.Vertex_HasDeltaPressure);
Vertex_HasDeltaPressure_Inverse = getResourceOrNull(graph, URIs.Vertex_HasDeltaPressure_Inverse);
Vertex_HasDeltaTemperature = getResourceOrNull(graph, URIs.Vertex_HasDeltaTemperature);
Vertex_HasElevation_Inverse = getResourceOrNull(graph, URIs.Vertex_HasElevation_Inverse);
Vertex_HasFlowArea = getResourceOrNull(graph, URIs.Vertex_HasFlowArea);
Vertex_HasFlowArea_Inverse = getResourceOrNull(graph, URIs.Vertex_HasFlowArea_Inverse);
+ Vertex_HasFrequencyConverterControlled = getResourceOrNull(graph, URIs.Vertex_HasFrequencyConverterControlled);
+ Vertex_HasFrequencyConverterControlled_Inverse = getResourceOrNull(graph, URIs.Vertex_HasFrequencyConverterControlled_Inverse);
+ Vertex_HasHeadPumpMaximum = getResourceOrNull(graph, URIs.Vertex_HasHeadPumpMaximum);
+ Vertex_HasHeadPumpMaximum_Inverse = getResourceOrNull(graph, URIs.Vertex_HasHeadPumpMaximum_Inverse);
+ Vertex_HasHeadPumpNominal = getResourceOrNull(graph, URIs.Vertex_HasHeadPumpNominal);
+ Vertex_HasHeadPumpNominal_Inverse = getResourceOrNull(graph, URIs.Vertex_HasHeadPumpNominal_Inverse);
Vertex_HasHeatLoadDs = getResourceOrNull(graph, URIs.Vertex_HasHeatLoadDs);
Vertex_HasHeatLoadDs_Inverse = getResourceOrNull(graph, URIs.Vertex_HasHeatLoadDs_Inverse);
Vertex_HasHeatPower = getResourceOrNull(graph, URIs.Vertex_HasHeatPower);
Vertex_HasHeatPower_Inverse = getResourceOrNull(graph, URIs.Vertex_HasHeatPower_Inverse);
+ Vertex_HasInternalValveMeasurement = getResourceOrNull(graph, URIs.Vertex_HasInternalValveMeasurement);
+ Vertex_HasInternalValveMeasurement_Inverse = getResourceOrNull(graph, URIs.Vertex_HasInternalValveMeasurement_Inverse);
Vertex_HasMassFlow = getResourceOrNull(graph, URIs.Vertex_HasMassFlow);
Vertex_HasMassFlow_Inverse = getResourceOrNull(graph, URIs.Vertex_HasMassFlow_Inverse);
Vertex_HasMaximumHeadM = getResourceOrNull(graph, URIs.Vertex_HasMaximumHeadM);
Vertex_HasNominalHeadM_Inverse = getResourceOrNull(graph, URIs.Vertex_HasNominalHeadM_Inverse);
Vertex_HasNominalPressureLoss = getResourceOrNull(graph, URIs.Vertex_HasNominalPressureLoss);
Vertex_HasNominalPressureLoss_Inverse = getResourceOrNull(graph, URIs.Vertex_HasNominalPressureLoss_Inverse);
+ Vertex_HasOpeningTime = getResourceOrNull(graph, URIs.Vertex_HasOpeningTime);
+ Vertex_HasOpeningTime_Inverse = getResourceOrNull(graph, URIs.Vertex_HasOpeningTime_Inverse);
+ Vertex_HasPeakPower = getResourceOrNull(graph, URIs.Vertex_HasPeakPower);
+ Vertex_HasPeakPower_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPeakPower_Inverse);
+ Vertex_HasPumpInReturnLine = getResourceOrNull(graph, URIs.Vertex_HasPumpInReturnLine);
+ Vertex_HasPumpInReturnLine_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpInReturnLine_Inverse);
+ Vertex_HasPumpMassFlowNominal = getResourceOrNull(graph, URIs.Vertex_HasPumpMassFlowNominal);
+ Vertex_HasPumpMassFlowNominal_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpMassFlowNominal_Inverse);
+ Vertex_HasPumpMeMax = getResourceOrNull(graph, URIs.Vertex_HasPumpMeMax);
+ Vertex_HasPumpMeMax_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpMeMax_Inverse);
+ Vertex_HasPumpMeMin = getResourceOrNull(graph, URIs.Vertex_HasPumpMeMin);
+ Vertex_HasPumpMeMin_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpMeMin_Inverse);
+ Vertex_HasPumpSpeedMax = getResourceOrNull(graph, URIs.Vertex_HasPumpSpeedMax);
+ Vertex_HasPumpSpeedMax_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpSpeedMax_Inverse);
+ Vertex_HasPumpSpeedMin = getResourceOrNull(graph, URIs.Vertex_HasPumpSpeedMin);
+ Vertex_HasPumpSpeedMin_Inverse = getResourceOrNull(graph, URIs.Vertex_HasPumpSpeedMin_Inverse);
Vertex_HasReturnPressure = getResourceOrNull(graph, URIs.Vertex_HasReturnPressure);
Vertex_HasReturnPressure_Inverse = getResourceOrNull(graph, URIs.Vertex_HasReturnPressure_Inverse);
Vertex_HasReturnTemperature = getResourceOrNull(graph, URIs.Vertex_HasReturnTemperature);
Vertex_HasSupplyPressure_Inverse = getResourceOrNull(graph, URIs.Vertex_HasSupplyPressure_Inverse);
Vertex_HasSupplyTemperature = getResourceOrNull(graph, URIs.Vertex_HasSupplyTemperature);
Vertex_HasSupplyTemperature_Inverse = getResourceOrNull(graph, URIs.Vertex_HasSupplyTemperature_Inverse);
+ Vertex_HasValveMeMax = getResourceOrNull(graph, URIs.Vertex_HasValveMeMax);
+ Vertex_HasValveMeMax_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValveMeMax_Inverse);
+ Vertex_HasValveMeMin = getResourceOrNull(graph, URIs.Vertex_HasValveMeMin);
+ Vertex_HasValveMeMin_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValveMeMin_Inverse);
+ Vertex_HasValveMinPosition = getResourceOrNull(graph, URIs.Vertex_HasValveMinPosition);
+ Vertex_HasValveMinPosition_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValveMinPosition_Inverse);
+ Vertex_HasValveOutletMode = getResourceOrNull(graph, URIs.Vertex_HasValveOutletMode);
+ Vertex_HasValveOutletMode_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValveOutletMode_Inverse);
Vertex_HasValvePosition = getResourceOrNull(graph, URIs.Vertex_HasValvePosition);
Vertex_HasValvePosition_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValvePosition_Inverse);
+ Vertex_HasValvePressLossNominal = getResourceOrNull(graph, URIs.Vertex_HasValvePressLossNominal);
+ Vertex_HasValvePressLossNominal_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValvePressLossNominal_Inverse);
+ Vertex_HasValveReturnLine = getResourceOrNull(graph, URIs.Vertex_HasValveReturnLine);
+ Vertex_HasValveReturnLine_Inverse = getResourceOrNull(graph, URIs.Vertex_HasValveReturnLine_Inverse);
Vertex_HasVelocity = getResourceOrNull(graph, URIs.Vertex_HasVelocity);
Vertex_HasVelocity_Inverse = getResourceOrNull(graph, URIs.Vertex_HasVelocity_Inverse);
Vertex_HasVolFlow = getResourceOrNull(graph, URIs.Vertex_HasVolFlow);
org.simantics.district.network.ui.adapters,
org.simantics.district.network.ui.breakdown,
org.simantics.district.network.ui.function,
- org.simantics.district.network.ui.nodes
+ org.simantics.district.network.ui.nodes,
+ org.simantics.district.network.ui.participants
Require-Bundle: org.eclipse.e4.ui.model.workbench;bundle-version="1.1.100.v20150407-1430",
org.eclipse.swt,
org.simantics.g2d,
org.eclipse.jface,
org.simantics.scl.osgi,
org.simantics.district.route,
- org.simantics.scenegraph.profile
+ org.simantics.scenegraph.profile,
+ org.simantics.district.geotools;bundle-version="1.0.0",
+ org.simantics.maps.elevation.server,
+ org.eclipse.e4.core.services,
+ org.eclipse.osgi.services;bundle-version="3.6.0",
+ org.eclipse.nebula.widgets.nattable.core,
+ org.simantics.district.imports
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: javax.annotation;version="1.0.0";resolution:=optional,
javax.inject;version="1.0.0"
<target interface="org.simantics.scenegraph.profile.Style">
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/ConnectionLineStyle"
- class="org.simantics.district.network.ui.nodes.ConnectionLineStyle">
+ class="org.simantics.district.network.ui.styles.ConnectionLineStyle">
+ </resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkHoverInfoStyle"
+ class="org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle">
+ <this />
+ </resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/DistrictNetworkStaticInfoStyle"
+ class="org.simantics.district.network.ui.styles.DistrictNetworkStaticInfoStyle">
+ <this />
+ </resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/ElevationRectangleStyle"
+ class="org.simantics.district.network.ui.styles.ElevationRectangleStyle">
</resource>
</target>
<elements xsi:type="commands:Command" xmi:id="_Uv6NEOJdEei2MexsDMErvQ" elementId="org.simantics.district.network.ui.command.changemapbackgroundcolor" commandName="Change Map Background Color"/>
<elements xsi:type="commands:Command" xmi:id="_eTLe0PhxEeiSu98FclGtqA" elementId="org.simantics.district.network.ui.command.toggletrackchanges" commandName="Toggle Track Changes"/>
<elements xsi:type="commands:Command" xmi:id="_f4ugUPhxEeiSu98FclGtqA" elementId="org.simantics.district.network.ui.command.splittomultiplediagrams" commandName="Split to multiple diagrams"/>
+ <elements xsi:type="commands:Command" xmi:id="_RJIeMFn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.command.copydistrictvertex" commandName="Copy District Vertex">
+ <parameters xmi:id="_lH-1cFoDEem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.commandparameter.0" name="cut"/>
+ </elements>
+ <elements xsi:type="commands:Command" xmi:id="_T3or0Fn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.command.pastedistrictvertex" commandName="Paste District Vertex"/>
+ <elements xsi:type="commands:Command" xmi:id="_CLKOUHVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.command.changeroutepointtovertex" commandName="Change Route Point to Vertex"/>
+ <elements xsi:type="commands:Command" xmi:id="_Ee0TAHVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.command.changevertextoroutepoint" commandName="Change Vertex to Route Point"/>
+ <elements xsi:type="commands:Command" xmi:id="_QcEKQIAGEemKlokjSaREFQ" elementId="org.simantics.district.network.ui.command.importcsv" commandName="Import CSV"/>
+ <elements xsi:type="commands:Command" xmi:id="_VWtY8LqWEemcscVaZzEyWw" elementId="org.simantics.district.network.ui.command.importtechtypecsv" commandName="Import Tech Type CSV"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_Js7rUMMAEea1mdgpHNVHMA" featurename="menuContributions" parentElementId="xpath:/">
<elements xsi:type="menu:MenuContribution" xmi:id="_T-jiEN8NEeaigNyzMJBOrg" elementId="org.simantics.district.network.ui.menucontribution.districtDiagramPopup" parentId="#DistrictDiagramPopup">
<children xsi:type="menu:HandledMenuItem" xmi:id="_ZE-9sOGeEei2MexsDMErvQ" elementId="org.simantics.district.network.ui.handledmenuitem.toggledrawmap" label="Toggle Draw Map" iconURI="platform:/plugin/com.famfamfam.silk/icons/map_add.png" command="_qillYOGQEeiIMuq1qhQJRQ"/>
<children xsi:type="menu:HandledMenuItem" xmi:id="_bd3S0OJdEei2MexsDMErvQ" elementId="org.simantics.district.network.ui.handledmenuitem.changebackgroundcolor" label="Change Background Color" iconURI="platform:/plugin/com.famfamfam.silk/icons/palette.png" command="_Uv6NEOJdEei2MexsDMErvQ"/>
<children xsi:type="menu:DynamicMenuContribution" xmi:id="_jK8QQD9EEemjkrTOYZxVwQ" elementId="org.simantics.district.network.ui.dynamicmenucontribution.elementActions" label="Element Actions" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.NetworkElementActionMenuContribution"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_aqopoFn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.handledmenuitem.copy" label="Copy" enabled="false" command="_RJIeMFn_Eem2uLDOwusbsQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_dGH0oFn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.handledmenuitem.paste" label="Paste" command="_T3or0Fn_Eem2uLDOwusbsQ"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_ajCQAFoDEem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.handledmenuitem.cut" label="Cut" command="_RJIeMFn_Eem2uLDOwusbsQ">
+ <parameters xmi:id="_qNYB8FoDEem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.parameter.0" name="org.simantics.district.network.ui.commandparameter.0" value="true"/>
+ </children>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_KOAqcHVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.handledmenuitem.changevertextoroutepoint" label="Change Vertex to Route Point" command="_Ee0TAHVvEemS_rRAHnCQSw"/>
+ <children xsi:type="menu:HandledMenuItem" xmi:id="_NgV94HVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.handledmenuitem.changeroutepointtovertex" label="Change Route Point to Vertex" command="_CLKOUHVvEemS_rRAHnCQSw"/>
</elements>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_dbiHcMMBEea1mdgpHNVHMA" featurename="handlers" parentElementId="xpath:/">
<elements xsi:type="commands:Handler" xmi:id="_WmQDoOJdEei2MexsDMErvQ" elementId="org.simantics.district.network.ui.handler.2" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ChangeMapBackgroundColorHandler" command="_Uv6NEOJdEei2MexsDMErvQ"/>
<elements xsi:type="commands:Handler" xmi:id="_h3ZzgPhxEeiSu98FclGtqA" elementId="org.simantics.district.network.ui.handler.3" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ToggleTrackChanges" command="_eTLe0PhxEeiSu98FclGtqA"/>
<elements xsi:type="commands:Handler" xmi:id="_kc-uoPhxEeiSu98FclGtqA" elementId="org.simantics.district.network.ui.handler.4" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ToggleSplitToMultipleDiagrams" command="_f4ugUPhxEeiSu98FclGtqA"/>
+ <elements xsi:type="commands:Handler" xmi:id="_WEwqsFn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.handler.5" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.CopyDistrictVertexHandler" command="_RJIeMFn_Eem2uLDOwusbsQ"/>
+ <elements xsi:type="commands:Handler" xmi:id="_X7QSQFn_Eem2uLDOwusbsQ" elementId="org.simantics.district.network.ui.handler.6" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.PasteDistrictVertexHandler" command="_T3or0Fn_Eem2uLDOwusbsQ"/>
+ <elements xsi:type="commands:Handler" xmi:id="_F9vvIHVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.handler.7" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ChangeRoutePointToVertexHandler" command="_CLKOUHVvEemS_rRAHnCQSw"/>
+ <elements xsi:type="commands:Handler" xmi:id="_H7TA8HVvEemS_rRAHnCQSw" elementId="org.simantics.district.network.ui.handler.8" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.contributions.ChangeVertexToRoutePointHandler" command="_Ee0TAHVvEemS_rRAHnCQSw"/>
+ <elements xsi:type="commands:Handler" xmi:id="_akE8EIAGEemKlokjSaREFQ" elementId="org.simantics.district.network.ui.handler.9" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.table.ImportCSVHandler" command="_QcEKQIAGEemKlokjSaREFQ"/>
+ <elements xsi:type="commands:Handler" xmi:id="_XjbIILqWEemcscVaZzEyWw" elementId="org.simantics.district.network.ui.handler.10" contributionURI="bundleclass://org.simantics.district.network.ui/org.simantics.district.network.ui.table.ImportTechTypeCSVHandler" command="_VWtY8LqWEemcscVaZzEyWw"/>
</fragments>
</fragment:ModelFragments>
name="District Network Breakdown"
restorable="true">
</e4view>
+ <e4view
+ class="org.simantics.district.network.ui.table.DistrictCSVTableView"
+ icon="platform:/plugin/com.famfamfam.silk/icons/table_edit.png"
+ id="org.simantics.district.network.ui.table.csvTableView"
+ name="District CSV Import Table"
+ restorable="true"
+ allowMultiple="false">
+ </e4view>
+ <e4view
+ class="org.simantics.district.network.ui.techtype.table.TechTypeTableView"
+ icon="platform:/plugin/com.famfamfam.silk/icons/table_edit.png"
+ id="org.simantics.district.network.ui.techtype.table.techtypeTableView"
+ name="Tech Type Table"
+ restorable="true"
+ allowMultiple="false">
+ </e4view>
+ <e4view
+ class="org.simantics.district.network.ui.visualisations.DynamicVisualisationsView"
+ icon="platform:/plugin/com.famfamfam.silk/icons/table_edit.png"
+ id="org.simantics.district.network.ui.visualisations.dynamicVisualisationsView"
+ name="District Visualisations"
+ restorable="true"
+ allowMultiple="false">
+ </e4view>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
package org.simantics.district.network.ui;\r
\r
+import org.eclipse.ui.IWorkbenchPartReference;\r
import org.eclipse.ui.PartInitException;\r
import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
import org.simantics.modeling.ui.diagramEditor.DiagramViewer;\r
public class DistrictDiagramEditor extends DiagramEditor {\r
\r
public static final String ID = "org.simantics.district.network.ui.diagrameditor";\r
- \r
+\r
@Override\r
protected DiagramViewer createViewer() throws PartInitException {\r
return new DistrictDiagramViewer();\r
}\r
+\r
+ @Override\r
+ public void partHidden(IWorkbenchPartReference partRef) {\r
+ // we do not want to have disposer for district diagram viewer\r
+ // to add disposer with default settings uncomment the following line\r
+ // super.partHidden(partRef);\r
+ }\r
}\r
import java.awt.Color;
import java.awt.geom.AffineTransform;
+import java.util.Collections;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.simantics.db.procedure.Listener;
import org.simantics.diagram.ui.DiagramModelHints;
import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.participants.DNPointerInteractor;
+import org.simantics.district.network.ui.participants.DynamicVisualisationContributionsParticipant;
+import org.simantics.district.network.ui.participants.ElevationServerParticipant;
import org.simantics.district.network.ui.participants.MapRulerPainter;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.impl.CanvasContext;
import org.simantics.g2d.diagram.handler.PickRequest.PickFilter;
import org.simantics.maps.eclipse.MapPainter;
import org.simantics.maps.sg.commands.MapCommands;
import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
+import org.simantics.scenegraph.g2d.events.command.Command;
import org.simantics.scenegraph.g2d.events.command.CommandEvent;
import org.simantics.scenegraph.g2d.events.command.Commands;
import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DistrictDiagramViewer extends DiagramViewer {
- private static final Logger LOGGER = LoggerFactory.getLogger(DistrictDiagramViewer.class);
+ @SuppressWarnings("unused")
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictDiagramViewer.class);
@Override
protected void addDiagramParticipants(ICanvasContext ctx) {
ctx.add(new MapPainter(tr));
ctx.add(new NetworkDrawingParticipant(tr));
+ ctx.add(new ElevationServerParticipant(tr));
+ ctx.add(new DynamicVisualisationContributionsParticipant(tr));
}
protected String getPopupId() {
// super.loadPageSettings() does async-db-operations
setupDrawMapEnabled();
setupBackgroundColor();
+ setupColoringObjects();
+ setupColorBarOptions();
+ setupSizingObjects();
+ setupSizeBarOptions();
}
private void setupDrawMapEnabled() {
result -> queueBackgroundColorChangeEvent(result),
() -> DistrictDiagramViewer.this.isDisposed()));
}
-
+
private void queueBackgroundColorChangeEvent(RGB.Integer result) {
if (result != null) {
Color backgroundColor = new Color(result.red, result.green, result.blue);
}
}
+ private void setupColoringObjects() {
+ sessionContext.getSession().asyncRequest(new ColoringObjectsRequest(getInputResource()), new ColoringObjectsListener(
+ result -> queueColoringObjectsChangeEvent(result),
+ () -> DistrictDiagramViewer.this.isDisposed()));
+ }
+
+
+ private void setupColorBarOptions() {
+ sessionContext.getSession().asyncRequest(new ColorBarOptionsRequest(getInputResource()), new ColorBarOptionsListener(
+ result -> queueColorBarOptionsChangeEvent(result),
+ () -> DistrictDiagramViewer.this.isDisposed()));
+ }
+
+ private void setupSizingObjects() {
+ sessionContext.getSession().asyncRequest(new SizingObjectsRequest(getInputResource()), new SizingObjectsListener(
+ result -> queueSizingObjectsChangeEvent(result),
+ () -> DistrictDiagramViewer.this.isDisposed()));
+ }
+
+
+ private void setupSizeBarOptions() {
+ sessionContext.getSession().asyncRequest(new SizeBarOptionsRequest(getInputResource()), new SizeBarOptionsListener(
+ result -> queueSizeBarOptionsChangeEvent(result),
+ () -> DistrictDiagramViewer.this.isDisposed()));
+ }
+
+ public static final Key KEY_MAP_COLOR_BAR_OPTIONS = new KeyOf(ColorBarOptions.class, "colorBarOptions");
+ public static final Command MAP_COLOR_BAR_OPTIONS_CHANGE = new Command("colorBarOptionsChange");
+ public static final Key KEY_MAP_SIZE_BAR_OPTIONS = new KeyOf(SizeBarOptions.class, "sizeBarOptions");
+ public static final Command MAP_SIZE_BAR_OPTIONS_CHANGE = new Command("sizeBarOptionsChange");
+
+ public static final Key KEY_MAP_COLORING_OBJECTS = new KeyOf(Map.class, "coloringObjects");
+ public static final Command MAP_COLORING_OBJECTS_CHANGE = new Command("coloringObjectsChange");
+
+ public static final Key KEY_MAP_SIZING_OBJECTS = new KeyOf(Map.class, "sizingObjects");
+ public static final Command MAP_SIZING_OBJECTS_CHANGE = new Command("sizingObjectsChange");
+
+
+ private void queueColoringObjectsChangeEvent(Map<String, DynamicColorContribution> result) {
+ if (result != null) {
+ canvasContext.getDefaultHintContext().setHint(KEY_MAP_COLORING_OBJECTS, result);
+ canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), MAP_COLORING_OBJECTS_CHANGE));
+ }
+ }
+
+ private void queueColorBarOptionsChangeEvent(ColorBarOptions result) {
+ if (result != null) {
+ canvasContext.getDefaultHintContext().setHint(KEY_MAP_COLOR_BAR_OPTIONS, result);
+ canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), MAP_COLOR_BAR_OPTIONS_CHANGE));
+ }
+ }
+
+ private void queueSizingObjectsChangeEvent(Map<String, DynamicSizeContribution> result) {
+ if (result != null) {
+ canvasContext.getDefaultHintContext().setHint(KEY_MAP_SIZING_OBJECTS, result);
+ canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), MAP_SIZING_OBJECTS_CHANGE));
+ }
+ }
+
+ private void queueSizeBarOptionsChangeEvent(SizeBarOptions result) {
+ if (result != null) {
+ canvasContext.getDefaultHintContext().setHint(KEY_MAP_SIZE_BAR_OPTIONS, result);
+ canvasContext.getEventQueue().queueEvent(new CommandEvent(canvasContext, System.currentTimeMillis(), MAP_SIZE_BAR_OPTIONS_CHANGE));
+ }
+ }
+
private static class DrawMapEnabledRequest extends UnaryRead<Resource, Boolean> {
public DrawMapEnabledRequest(Resource diagram) {
private static class MapBackgroundColorListener implements Listener<RGB.Integer> {
- private static final Logger LOGGER = LoggerFactory.getLogger(DrawMapEnabledListener.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MapBackgroundColorListener.class);
private Consumer<RGB.Integer> callback;
private Supplier<Boolean> isDisposed;
return isDisposed.get();
}
}
+
+ private static class ColorBarOptionsRequest extends UnaryRead<Resource, ColorBarOptions> {
+
+ public ColorBarOptionsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public ColorBarOptions perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+ if (activeVisualisation != null) {
+ return DistrictNetworkUtil.colorBarOptions(graph, activeVisualisation);
+ }
+ return ColorBarOptions.useDefault();
+ }
+ }
+
+ private static class ColoringObjectsRequest extends UnaryRead<Resource, Map<String,DynamicColorContribution>> {
+
+ public ColoringObjectsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public Map<String, DynamicColorContribution> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+ if (activeVisualisation != null) {
+ return DistrictNetworkUtil.colorContributions(graph, activeVisualisation);
+ }
+ return Collections.emptyMap();
+ }
+ }
+
+ private static class ColoringObjectsListener implements Listener<Map<String,DynamicColorContribution>> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ColoringObjectsListener.class);
+
+ private Consumer<Map<String,DynamicColorContribution>> callback;
+ private Supplier<Boolean> isDisposed;
+
+ public ColoringObjectsListener(Consumer<Map<String,DynamicColorContribution>> callback, Supplier<Boolean> isDisposed) {
+ this.callback = callback;
+ this.isDisposed = isDisposed;
+ }
+
+ @Override
+ public void execute(Map<String,DynamicColorContribution> result) {
+ callback.accept(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen ColorBarOptions", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return isDisposed.get();
+ }
+ }
+
+ private static class ColorBarOptionsListener implements Listener<ColorBarOptions> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ColorBarOptionsListener.class);
+
+ private Consumer<ColorBarOptions> callback;
+ private Supplier<Boolean> isDisposed;
+
+ public ColorBarOptionsListener(Consumer<ColorBarOptions> callback, Supplier<Boolean> isDisposed) {
+ this.callback = callback;
+ this.isDisposed = isDisposed;
+ }
+
+ @Override
+ public void execute(ColorBarOptions result) {
+ callback.accept(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen ColorBarOptions", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return isDisposed.get();
+ }
+ }
+
+ private static class SizeBarOptionsRequest extends UnaryRead<Resource, SizeBarOptions> {
+
+ public SizeBarOptionsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public SizeBarOptions perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+ if (activeVisualisation != null) {
+ return DistrictNetworkUtil.sizeBarOptions(graph, activeVisualisation);
+ }
+ return SizeBarOptions.useDefault();
+ }
+ }
+
+ private static class SizeBarOptionsListener implements Listener<SizeBarOptions> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SizeBarOptionsListener.class);
+
+ private Consumer<SizeBarOptions> callback;
+ private Supplier<Boolean> isDisposed;
+
+ public SizeBarOptionsListener(Consumer<SizeBarOptions> callback, Supplier<Boolean> isDisposed) {
+ this.callback = callback;
+ this.isDisposed = isDisposed;
+ }
+
+ @Override
+ public void execute(SizeBarOptions result) {
+ callback.accept(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen SizeBarOptions", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return isDisposed.get();
+ }
+ }
+
+ private static class SizingObjectsRequest extends UnaryRead<Resource, Map<String, DynamicSizeContribution>> {
+
+ public SizingObjectsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public Map<String, DynamicSizeContribution> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource activeVisualisation = graph.getPossibleObject(parameter, DN.Diagram_hasActiveVisualisation);
+ if (activeVisualisation != null) {
+ return DistrictNetworkUtil.sizeContributions(graph, activeVisualisation);
+ }
+ return Collections.emptyMap();
+ }
+ }
+
+ private static class SizingObjectsListener implements Listener<Map<String,DynamicSizeContribution>> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SizingObjectsListener.class);
+
+ private Consumer<Map<String,DynamicSizeContribution>> callback;
+ private Supplier<Boolean> isDisposed;
+
+ public SizingObjectsListener(Consumer<Map<String, DynamicSizeContribution>> callback, Supplier<Boolean> isDisposed) {
+ this.callback = callback;
+ this.isDisposed = isDisposed;
+ }
+
+ @Override
+ public void execute(Map<String, DynamicSizeContribution> result) {
+ callback.accept(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen ColorBarOptions", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return isDisposed.get();
+ }
+ }
}
}
private boolean zoomToPage() {
- int currentZoomLevel = MapScalingTransform.zoomLevel(util.getTransform());
-
util.setTransform(new AffineTransform(2,0,0,2,270,270));
return true;
}
int tarZoomLevel = MapScalingTransform.zoomLevel(tar);
if (tarZoomLevel < 20 && tarZoomLevel > 0) {
toBeX = Math.pow(2.0, tarZoomLevel);
- }
- else {
+ } else if (tarZoomLevel > 20) {
+ toBeX = Math.pow(2.0, 20);
+ } else if (tarZoomLevel < 0) {
+ toBeX = 2;
+ } else {
toBeX = targetX;
}
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
+import org.simantics.district.network.ui.adapters.DistrictNetworkEdgeElement;
import org.simantics.district.network.ui.adapters.DistrictNetworkVertexElement;
+import org.simantics.district.network.ui.nodes.DistrictNetworkEdgeNode;
import org.simantics.district.network.ui.nodes.DistrictNetworkVertexNode;
+import org.simantics.district.network.ui.nodes.HoverSensitiveNode;
import org.simantics.district.network.ui.nodes.NetworkDrawingNode;
import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
import org.simantics.g2d.element.IElement;
import org.simantics.scenegraph.Node;
import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.IG2DNode;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
public class NetworkDrawingParticipant extends AbstractDiagramParticipant {
- @Dependency
+ public static final String NETWORK_DRAWING_NODE = "networkDrawingNode";
+
+ @Dependency
PickContext pick;
/**
@SGInit
public void initSG(G2DParentNode parent) {
- node = parent.addNode("networkDrawingNode", NetworkDrawingNode.class);
+ node = parent.addNode(NETWORK_DRAWING_NODE, NetworkDrawingNode.class);
node.setTransform(transform);
node.setNetworkDrawingParticipant(this);
}
node.setDiagram(newDiagram);
}
- public boolean pickHoveredElement(Point2D currentMousePos) {
- PickRequest req = new PickRequest(currentMousePos).context(getContext());
+ public boolean pickHoveredElement(Point2D currentMousePos, boolean isConnectionTool) {
+ PickRequest req = new PickRequest(new Rectangle2D.Double(currentMousePos.getX(), currentMousePos.getY(), 1e-8, 1e-8)).context(getContext());
List<IElement> pickables = new ArrayList<IElement>();
pick.pick(diagram, req, pickables);
List<IElement> snap = new ArrayList<>(diagram.getSnapshot());
- snap.removeAll(pickables);
+ // snap.removeAll(pickables);
boolean changed = false;
- for (IElement sn : snap) {
- Node node = sn.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
+ changed = hoverVertexNodes(snap, false, isConnectionTool, changed, currentMousePos);
+ changed = hoverEdgeNodes(snap, false, isConnectionTool, changed, currentMousePos);
+ changed = hoverVertexNodes(pickables, true, isConnectionTool, changed, currentMousePos);
+ changed = hoverEdgeNodes(pickables, true, isConnectionTool, changed, currentMousePos);
+ return changed;
+ }
+
+ private boolean hoverVertexNodes(List<IElement> elements, boolean hover, boolean isConnectionTool, boolean changed, Point2D p) {
+ for (IElement elem : elements) {
+ Node node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
if (node instanceof DistrictNetworkVertexNode) {
- if (((DistrictNetworkVertexNode) node).hover(false) && !changed) {
- changed = true;
+ changed = ((DistrictNetworkVertexNode) node).hover(hover, isConnectionTool) || changed;
+ if (hover)
+ ((DistrictNetworkVertexNode) node).setMousePosition(p);
+ }
+ }
+ return changed;
+ }
+
+ private boolean hoverEdgeNodes(List<IElement> elements, boolean hover, boolean isConnectionTool, boolean changed, Point2D p) {
+ for (IElement elem : elements) {
+ Node node = elem.getHint(DistrictNetworkEdgeElement.KEY_DN_EDGE_NODE);
+ if (node instanceof DistrictNetworkEdgeNode) {
+ for (IG2DNode n : ((DistrictNetworkEdgeNode) node).getNodes()) {
+ if (n instanceof HoverSensitiveNode) {
+ changed = ((HoverSensitiveNode)n).hover(hover, isConnectionTool) || changed;
+ if (hover)
+ ((HoverSensitiveNode)n).setMousePosition(p);
+ }
}
}
}
-
+ return changed;
+ }
+
+ public boolean isHoveringOverNode(Point2D currentMousePos) {
+ PickRequest req = new PickRequest(currentMousePos).context(getContext());
+ List<IElement> pickables = new ArrayList<IElement>();
+ pick.pick(diagram, req, pickables);
for (IElement elem : pickables) {
Node node = elem.getHint(DistrictNetworkVertexElement.KEY_DN_VERTEX_NODE);
if (node instanceof DistrictNetworkVertexNode) {
- if (((DistrictNetworkVertexNode) node).hover(true) && !changed) {
- changed = true;
- }
+ return true;
}
}
- return changed;
+ return false;
}
public AffineTransform getTransform() {
-package org.simantics.district.network.ui;\r
-\r
-import java.util.Collections;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.district.network.ontology.DistrictNetworkResource;\r
-\r
-public class OpenDiagramFromConfigurationAdapter\r
- extends org.simantics.modeling.ui.diagramEditor.OpenDiagramFromConfigurationAdapter {\r
-\r
- @Override\r
- public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException {\r
- Resource diagram = getDiagram(g, r, Collections.emptySet());\r
- if (diagram == null)\r
- return false;\r
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(g);\r
- return g.isInstanceOf(diagram, DN.Diagram) && !isLocked(g, diagram);\r
- }\r
-\r
- @Override\r
- protected String getEditorId() {\r
- return DistrictDiagramEditor.ID;\r
- }\r
-}\r
+package org.simantics.district.network.ui;
+
+import java.util.Collections;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+
+public class OpenDiagramFromConfigurationAdapter
+ extends org.simantics.modeling.ui.diagramEditor.OpenDiagramFromConfigurationAdapter {
+
+ @Override
+ public boolean canHandle(ReadGraph g, Resource r) throws DatabaseException {
+ Resource diagram = getDiagram(g, r, Collections.emptySet());
+ if (diagram == null)
+ return false;
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(g);
+ return g.isInstanceOf(diagram, DN.Diagram) && !isLocked(g, diagram);
+ }
+
+ @Override
+ protected String getEditorId(ReadGraph g, Resource composite) throws DatabaseException {
+ return DistrictDiagramEditor.ID;
+ }
+}
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.nodes.SVGNode;
+import org.simantics.scenegraph.utils.NodeUtil;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
import org.slf4j.Logger;
Rectangle2D bounds = getBounds(s);
switch (policy) {
case PICK_CONTAINED_OBJECTS: return pickContainedObjects(edge, bounds);
- case PICK_INTERSECTING_OBJECTS: return pickIntersectingObjects(edge, bounds);
+ case PICK_INTERSECTING_OBJECTS: return pickIntersectingObjects(e, edge, bounds);
}
return false;
}
return eminx >= bsminx && eminy >= boundsMinY && emaxx <= bsmaxx && emaxy <= boundsMaxY;
}
- private boolean pickIntersectingObjects(DistrictNetworkEdge edge, Rectangle2D bounds) {
- double tolerance = (bounds.getHeight() + bounds.getHeight()) * 1 / MapScalingTransform.getScaleX();
- Line2D line = new Line2D.Double(edge.getStartPoint(), edge.getEndPoint());
+ private boolean pickIntersectingObjects(IElement e, DistrictNetworkEdge edge, Rectangle2D bounds) {
+ double dx = bounds.getWidth() / MapScalingTransform.getScaleX();
+ double dy = bounds.getHeight() / MapScalingTransform.getScaleY();
+
+ // Half the diagonal + half of the line width
+ DistrictNetworkEdgeNode node = e.getHint(KEY_DN_EDGE_NODE);
+ AffineTransform at = NodeUtil.getLocalToGlobalTransform(node);
+
+ Path2D path = node.getPath();
+ if (path == null)
+ return false;
+
+ double lineWidth = node.getStrokeWidth(at, true);
+ double tolerance = Math.sqrt(dx * dx + dy * dy) / 2 + lineWidth / 2;
+
double sx = bounds.getCenterX() / MapScalingTransform.getScaleX();
double sy = bounds.getCenterY() / MapScalingTransform.getScaleY();
- double ssx = ModelledCRS.xToLongitude(sx);
- double ssy = ModelledCRS.yToLatitude(-sy); // Invert for Simantics diagram coordinate system
- double distSq = line.ptSegDistSq(ssx, ssy);
-// System.out.println("s: " + sx + ", " + sy);
-// System.out.println("ss: " + ssx + ", " + ssy);
-// System.out.println("p1: " + edge.getStartPoint());
-// System.out.println("p2: " + edge.getEndPoint());
-// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")");
-// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance);
- return distSq <= tolerance * tolerance;
+
+ double coords[] = new double[6];
+ Point2D prevPoint = new Point2D.Double(), curPoint = new Point2D.Double();
+ Line2D line = new Line2D.Double();
+ for (PathIterator it = path.getPathIterator(null); !it.isDone(); it.next()) {
+ int type = it.currentSegment(coords);
+ switch (type) {
+ case PathIterator.SEG_MOVETO:
+ curPoint.setLocation(coords[0], coords[1]);
+ break;
+ case PathIterator.SEG_LINETO:
+ prevPoint.setLocation(curPoint);
+ curPoint.setLocation(coords[0], coords[1]);
+ line.setLine(prevPoint, curPoint);
+ double distSq = line.ptSegDistSq(sx, sy);
+// System.out.println("s: " + sx + ", " + sy);
+// System.out.println("ss: " + ssx + ", " + ssy);
+// System.out.println("p1: " + edge.getStartPoint());
+// System.out.println("p2: " + edge.getEndPoint());
+// System.out.println("line: " + "(" + line.getX1() + ", " + line.getY1() + ", " + line.getX2() + ", " + line.getY2() + ")");
+// System.out.println("distance from line is " + Math.sqrt(distSq) + " with tolerance " + tolerance);
+ if (distSq <= tolerance * tolerance)
+ return true;
+ break;
+ default:
+ LOGGER.error("Invalid edge path", new IllegalStateException());
+ return false;
+ }
+ }
+
+ return false;
}
private Rectangle2D getBounds(Shape shape) {
public boolean pickTest(IElement e, Shape s, PickPolicy policy) {
DistrictNetworkVertexNode node = e.getHint(KEY_DN_VERTEX_NODE);
Rectangle2D boundsInLocal = node.getBounds();
- ICanvasContext ctx = DiagramNodeUtil.getCanvasContext(node);
- AffineTransform canvasTransform = ctx.getHintStack().getHint(Hints.KEY_CANVAS_TRANSFORM);
- Rectangle2D scaledBounds = new Rectangle2D.Double(boundsInLocal.getX(), boundsInLocal.getY(), boundsInLocal.getWidth() / canvasTransform.getScaleX() * 2, boundsInLocal.getHeight() / canvasTransform.getScaleY() * 2);
Rectangle2D bounds = getBounds(s);
switch (policy) {
case PICK_CONTAINED_OBJECTS:
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
import javax.inject.Named;
import org.simantics.db.layer0.SelectionHints;
import org.simantics.db.procedure.Procedure;
import org.simantics.db.request.Read;
+import org.simantics.district.network.DistrictNetworkUtil;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.function.Functions;
import org.simantics.district.network.ui.internal.Activator;
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
for (Map.Entry<Resource, Collection<NamedResource>> entry : results.entrySet()) {
- Resource newMapping = entry.getKey();
- Collection<NamedResource> elements = entry.getValue();
- for (NamedResource element : elements) {
- graph.deny(element.getResource(), DN.HasMapping);
- graph.claim(element.getResource(), DN.HasMapping, newMapping);
- }
+ List<Resource> elements = entry.getValue().stream()
+ .map(NamedResource::getResource)
+ .collect(Collectors.toList());
+ DistrictNetworkUtil.changeMappingType(graph, entry.getKey(), elements);
}
}
});
private Map<NamedResource, Map<String, Resource>> possibleMappings = new HashMap<>();
- private Resource defaultVertexMapping;
-
protected SelectMappingDialog(Shell parentShell, CompletableFuture<Map<NamedResource, Collection<NamedResource>>> elements) {
super(parentShell);
this.elements = elements;
setTitle("Change mappings");
}
- public Resource getDefaultVertexMapping() {
- return defaultVertexMapping;
- }
-
@Override
protected Control createDialogArea(Composite parent) {
composite = (Composite) super.createDialogArea(parent);
--- /dev/null
+package org.simantics.district.network.ui.contributions;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DNEdgeBuilder;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ModelledCRS;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.district.network.ui.NetworkDrawingParticipant;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
+import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ChangeRoutePointToVertexHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChangeRoutePointToVertexHandler.class);
+ static List<Resource> elements;
+ static boolean cut = true;
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ if (elements.size() != 1)
+ return false;
+ try {
+ return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource selection : elements) {
+ if (!graph.isInstanceOf(selection, DN.Edge)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
+ return false;
+ }
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart mActiveEditorPart, @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, ParameterizedCommand command) {
+ final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+
+ Resource edge = elements.get(0);
+ try {
+ Point2D mouseClicked = mouseClickedOnEditor(mActiveEditorPart);
+ if (mouseClicked != null) {
+
+ IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+ if (activeEditorPart == null)
+ return;
+ if (!(activeEditorPart instanceof DistrictDiagramEditor))
+ return;
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+ Resource diagram = editor.getInputResource();
+
+ Simantics.getSession().asyncRequest(new ReadRequest() {
+
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ double[] detailedGeom = graph.getPossibleRelatedValue(edge, DN.Edge_HasGeometry, Bindings.DOUBLE_ARRAY);
+ if (detailedGeom != null) {
+ double closestDistance = Double.MAX_VALUE;
+ Point2D closestPoint = null;
+ int j = 0;
+ for (int i = 0; i < detailedGeom.length; i += 2) {
+ double x = detailedGeom[i];
+ double y = detailedGeom[i + 1];
+ Point2D currentPoint = new Point2D.Double(x, y);
+ double currentDistance = mouseClicked.distance(currentPoint);
+ if (currentDistance < closestDistance) {
+ closestDistance = currentDistance;
+ closestPoint = currentPoint;
+ j = i;
+ }
+ }
+
+ final Point2D finalClosestPoint = closestPoint;
+
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ Resource currentStartVertex = graph.getSingleObject(edge, DN.HasStartVertex);
+ double[] currentStartVertexCoords = graph.getRelatedValue(currentStartVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+ Resource currentEndVertex = graph.getSingleObject(edge, DN.HasEndVertex);
+ double[] currentEndVertexCoords = graph.getRelatedValue(currentEndVertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+
+ double[] detailedLeftEdgeGeometryCoords = new double[j];
+ for (int k = 0; k < j; k += 2) {
+ double x = detailedGeom[k];
+ double y = detailedGeom[k + 1];
+ detailedLeftEdgeGeometryCoords[k] = x;
+ detailedLeftEdgeGeometryCoords[k + 1] = y;
+ }
+
+ double[] detailedRightEdgeGeometryCoords = new double[detailedGeom.length - j - 2];
+ int i = 0;
+ for (int k = j + 2; k < detailedGeom.length; k += 2) {
+ double x = detailedGeom[k];
+ double y = detailedGeom[k + 1];
+ detailedRightEdgeGeometryCoords[i++] = x;
+ detailedRightEdgeGeometryCoords[i++] = y;
+ }
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ RemoverUtil.remove(graph, edge);
+
+ ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ // we might have closest point
+ if (finalClosestPoint != null) {
+ Resource mapping = graph.getSingleObject(diagram, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
+ double x = finalClosestPoint.getX();
+ double y = finalClosestPoint.getY();
+ double[] midVertexCoords = new double[] { x, y };
+
+ Resource createdVertex = DistrictNetworkUtil.createVertex(graph, diagram, midVertexCoords, Double.MAX_VALUE, mapping);
+
+ Optional<Resource> leftEdge = DNEdgeBuilder.create(graph, diagram, currentStartVertexCoords, Double.MAX_VALUE, midVertexCoords, Double.MAX_VALUE, detailedLeftEdgeGeometryCoords, 0.001);
+ Optional<Resource> rightEdge = DNEdgeBuilder.create(graph, diagram, midVertexCoords, Double.MAX_VALUE, currentEndVertexCoords, Double.MAX_VALUE, detailedRightEdgeGeometryCoords, 0.001);
+ }
+ }
+ });
+ }, 500, TimeUnit.MILLISECONDS);
+
+ }
+ });
+
+ } else {
+ // no can do - or it would be possible to split the edge here in to two different edges
+ }
+ }
+ });
+ } else {
+ LOGGER.warn("No mouseClicked for editor {}", mActiveEditorPart);
+ }
+ } catch (InvocationTargetException e) {
+ LOGGER.error("Could not change route point to vertex", e);
+ }
+ }
+
+ private static Point2D mouseClickedOnEditor(MPart mActiveEditorPart) throws InvocationTargetException {
+ IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+ if (activeEditorPart == null)
+ return null;
+ if (!(activeEditorPart instanceof DistrictDiagramEditor))
+ return null;
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+
+ ICanvasContext ctx = editor.getAdapter(ICanvasContext.class);
+ NetworkDrawingParticipant drawingParticipant = ctx.getAtMostOneItemOfClass(NetworkDrawingParticipant.class);
+ AffineTransform drawingTransform = drawingParticipant.getTransform();
+ MouseUtil util = ctx.getAtMostOneItemOfClass(MouseUtil.class);
+ MouseInfo mouseInfo = util.getMousePressedInfo(0);
+ if (mouseInfo == null) {
+ return null;
+ }
+ Point2D canvasPosition = mouseInfo.canvasPosition;
+ Point2D transformed = null;
+ try {
+ transformed = drawingTransform.inverseTransform(canvasPosition, new Point2D.Double());
+ } catch (NoninvertibleTransformException e) {
+ LOGGER.error("Could not create inverse transform of {}", drawingTransform, e);
+ throw new InvocationTargetException(e);
+ }
+ double x = ModelledCRS.xToLongitude(transformed.getX());
+ double y = ModelledCRS.yToLatitude(-transformed.getY());
+ return new Point2D.Double(x, y);
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.contributions;
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DNEdgeBuilder;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ModelledCRS;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.district.network.ui.NetworkDrawingParticipant;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.participant.MouseUtil;
+import org.simantics.g2d.participant.MouseUtil.MouseInfo;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
+import org.simantics.ui.workbench.e4.E4WorkbenchUtils;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ChangeVertexToRoutePointHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChangeVertexToRoutePointHandler.class);
+ static List<Resource> elements;
+ static boolean cut = true;
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ if (elements.size() != 1)
+ return false;
+ try {
+ return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource selection : elements) {
+ if (graph.isInstanceOf(selection, DN.Vertex)) {
+ Collection<Resource> startingEdge = graph.getObjects(selection, DN.HasStartVertex_Inverse);
+ Collection<Resource> endingEdge = graph.getObjects(selection, DN.HasEndVertex_Inverse);
+ return startingEdge.size() == 1 && endingEdge.size() == 1;
+ }
+ }
+ return false;
+ }
+ });
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
+ return false;
+ }
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart mActiveEditorPart, @Named(IServiceConstants.ACTIVE_SELECTION) Object selection, ParameterizedCommand command) {
+ final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+
+ Resource vertex = elements.get(0);
+ try {
+ Point2D mouseClicked = mouseClickedOnEditor(mActiveEditorPart);
+ if (mouseClicked != null) {
+
+ IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+ if (activeEditorPart == null)
+ return;
+ if (!(activeEditorPart instanceof DistrictDiagramEditor))
+ return;
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+ Resource diagram = editor.getInputResource();
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ // we support only single start & end edge
+ Resource startingEdge = graph.getSingleObject(vertex, DN.HasEndVertex_Inverse);
+ Resource endingEdge = graph.getSingleObject(vertex, DN.HasStartVertex_Inverse);
+ double[] startingDetailed = graph.getPossibleRelatedValue(startingEdge, DN.Edge_HasGeometry);
+ double[] endingDetailed = graph.getPossibleRelatedValue(endingEdge, DN.Edge_HasGeometry);
+ Resource endingVertex = graph.getSingleObject(endingEdge, DN.HasEndVertex);
+ int length = startingDetailed.length + 2 + endingDetailed.length;
+ double[] newDetailed = new double[length];
+ for (int i = 0; i < startingDetailed.length; i++) {
+ double d = startingDetailed[i];
+ newDetailed[i] = d;
+ }
+ double[] coords = graph.getRelatedValue2(vertex, DIA.HasLocation);
+ int currentVertexIndex = startingDetailed.length;
+ newDetailed[currentVertexIndex] = coords[0];
+ newDetailed[currentVertexIndex + 1] = coords[1];
+ int f = startingDetailed.length + 2;
+ for (int i = 0; i < endingDetailed.length; i++) {
+ double d = endingDetailed[i];
+ newDetailed[f + i] = d;
+ }
+ graph.deny(startingEdge, DN.Edge_HasGeometry);
+ graph.claimLiteral(startingEdge, DN.Edge_HasGeometry, newDetailed, Bindings.DOUBLE_ARRAY);
+
+ graph.deny(startingEdge, DN.HasEndVertex);
+ graph.claim(startingEdge, DN.HasEndVertex, endingVertex);
+
+ RemoverUtil.remove(graph, vertex);
+ }
+ });
+ } else {
+ LOGGER.warn("No mouseClicked for editor {}", mActiveEditorPart);
+ }
+ } catch (InvocationTargetException e) {
+ LOGGER.error("Could not change route point to vertex", e);
+ }
+ }
+
+ private static Point2D mouseClickedOnEditor(MPart mActiveEditorPart) throws InvocationTargetException {
+ IEditorPart activeEditorPart = E4WorkbenchUtils.getActiveIEditorPart(mActiveEditorPart);
+ if (activeEditorPart == null)
+ return null;
+ if (!(activeEditorPart instanceof DistrictDiagramEditor))
+ return null;
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditorPart;
+
+ ICanvasContext ctx = editor.getAdapter(ICanvasContext.class);
+ NetworkDrawingParticipant drawingParticipant = ctx.getAtMostOneItemOfClass(NetworkDrawingParticipant.class);
+ AffineTransform drawingTransform = drawingParticipant.getTransform();
+ MouseUtil util = ctx.getAtMostOneItemOfClass(MouseUtil.class);
+ MouseInfo mouseInfo = util.getMousePressedInfo(0);
+ if (mouseInfo == null) {
+ return null;
+ }
+ Point2D canvasPosition = mouseInfo.canvasPosition;
+ Point2D transformed = null;
+ try {
+ transformed = drawingTransform.inverseTransform(canvasPosition, new Point2D.Double());
+ } catch (NoninvertibleTransformException e) {
+ LOGGER.error("Could not create inverse transform of {}", drawingTransform, e);
+ throw new InvocationTargetException(e);
+ }
+ double x = ModelledCRS.xToLongitude(transformed.getX());
+ double y = ModelledCRS.yToLatitude(-transformed.getY());
+ return new Point2D.Double(x, y);
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.contributions;
+
+import java.util.List;
+
+import javax.inject.Named;
+
+import org.eclipse.core.commands.ParameterizedCommand;
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.request.Read;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CopyDistrictVertexHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CopyDistrictVertexHandler.class);
+ static List<Resource> elements;
+ static boolean cut = true;
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ if (elements.size() != 1)
+ return false;
+ try {
+ return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource selection : elements) {
+ if (!graph.isInstanceOf(selection, DN.Element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
+ return false;
+ }
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection, ParameterizedCommand command) {
+ final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ // we store these to a static variable for pasting.. maybe not the best solution
+ CopyDistrictVertexHandler.elements = elements;
+ Object cut = command.getParameterMap().get("org.simantics.district.network.ui.commandparameter.0");
+ CopyDistrictVertexHandler.cut = cut != null;
+ }
+}
import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.swt.widgets.Display;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.ui.scl.SCLScripts;
import org.simantics.scl.compiler.top.ValueNotFound;
import org.simantics.scl.osgi.SCLOsgi;
import org.simantics.scl.runtime.SCLContext;
import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.reporting.SCLReportingHandler;
import org.simantics.scl.runtime.tuple.Tuple2;
import org.simantics.utils.ui.ISelectionUtils;
import org.slf4j.Logger;
static private Logger LOGGER = LoggerFactory.getLogger(NetworkElementActionMenuContribution.class);
@AboutToShow
- public void aboutToShow(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection, List<MMenuElement> items) {
+ public void aboutToShow(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection, Display display, List<MMenuElement> items) {
final List<Resource> vertices = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
if (vertices.size() != 1)
return;
List<MMenuElement> children = subMenu.getChildren();
subMenu.setLabel("Component Actions");
items.add(subMenu);
-
+
for (Tuple2 action : actions) {
String label = (String) action.c0;
@SuppressWarnings("rawtypes")
@Execute
public void execute() {
+ // Handler that only opens the SCL script console on demand
+ SCLReportingHandler handler = new SCLReportingHandler() {
+
+ private SCLReportingHandler handler;
+
+ // Get a handler for the SCL script console view
+ private SCLReportingHandler getHandler() {
+ if (handler == null) {
+ handler = SCLScripts.getOrCreateConsoleCommandSession().second;
+ }
+ return handler;
+ }
+
+ @Override
+ public void printError(String error) {
+ display.asyncExec(() -> {
+ getHandler().printError(error);
+ });
+ }
+
+ @Override
+ public void printCommand(String command) {
+ display.asyncExec(() -> {
+ getHandler().printCommand(command);
+ });
+ }
+
+ @Override
+ public void print(String text) {
+ display.asyncExec(() -> {
+ getHandler().print(text);
+ });
+ }
+
+ @Override
+ public void didWork(double amount) {
+ display.asyncExec(() -> {
+ getHandler().didWork(amount);
+ });
+ }
+ };
+
Simantics.getSession().asyncRequest(new WriteRequest() {
@SuppressWarnings("unchecked")
@Override
graph.markUndoPoint();
Layer0Utils.addCommentMetadata(graph, label + " for " + v.getName(graph));
- Simantics.applySCLWrite(graph, function, v);
+ SCLContext context = SCLContext.getCurrent();
+ Object oldHandler = context.put(SCLReportingHandler.REPORTING_HANDLER, handler);
+ try {
+ Simantics.applySCLWrite(graph, function, v);
+ }
+ finally {
+ context.put(SCLReportingHandler.REPORTING_HANDLER, oldHandler);
+ }
}
- }, (DatabaseException e) -> LOGGER.error("Running command " + label + " for " + vertex + " failed", e));
+ }, (DatabaseException e) -> {
+ if (e != null) LOGGER.error("Running command " + label + " for " + vertex + " failed", e);
+ });
}
};
--- /dev/null
+package org.simantics.district.network.ui.contributions;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.utils.threads.ThreadUtils;
+import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PasteDistrictVertexHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PasteDistrictVertexHandler.class);
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ if (elements.size() < 1)
+ return false;
+ try {
+ return Simantics.getSession().syncRequest(new Read<Boolean>() {
+
+ @Override
+ public Boolean perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource selection : elements) {
+ if (!graph.isInstanceOf(selection, DN.Element)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
+ return false;
+ }
+ }
+
+ private static Resource doCopy(WriteGraph graph, Resource diagram, Resource target, Resource source) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ double[] location = graph.getRelatedValue(target, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+ double elevation = graph.getRelatedValue(target, DN.Vertex_HasElevation, Bindings.DOUBLE);
+ Resource vertex = DistrictNetworkUtil.createVertex(graph, diagram, location, elevation);
+ copySourceToTarget(graph, source, vertex);
+ return vertex;
+ }
+
+ private static void copySourceToTarget(WriteGraph graph, Resource source, Resource target) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ graph.deny(target, DN.HasMapping);
+
+ Collection<Statement> statements = graph.getStatements(source, L0.HasProperty);
+ Collection<Statement> assertedStatements = graph.getAssertedStatements(source, L0.HasProperty);
+ statements.removeAll(assertedStatements);
+ for (Statement stm : statements) {
+ if (!graph.hasStatement(target, stm.getPredicate())) {
+ graph.claim(target, stm.getPredicate(), stm.getObject());
+ }
+ }
+ }
+
+ private static void copyVertexInverses(WriteGraph graph, Resource sourceElement, Resource targetElement) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Collection<Resource> sourceStartVertex_inverse = graph.getObjects(sourceElement, DN.HasStartVertex_Inverse);
+ Collection<Resource> sourceEndVertex_inverse = graph.getObjects(sourceElement, DN.HasEndVertex_Inverse);
+ Collection<Resource> targetStartVertex_inverse = graph.getObjects(targetElement, DN.HasStartVertex_Inverse);
+ Collection<Resource> targetEndVertex_inverse = graph.getObjects(targetElement, DN.HasEndVertex_Inverse);
+ graph.deny(sourceElement, DN.HasStartVertex_Inverse);
+ graph.deny(sourceElement, DN.HasEndVertex_Inverse);
+ graph.deny(targetElement, DN.HasStartVertex_Inverse);
+ graph.deny(targetElement, DN.HasEndVertex_Inverse);
+ for (Resource startVertexInverse : sourceStartVertex_inverse) {
+ graph.claim(targetElement, DN.HasStartVertex_Inverse, startVertexInverse);
+ }
+ for (Resource targetVertexInverse : targetStartVertex_inverse) {
+ graph.claim(sourceElement, DN.HasStartVertex_Inverse, targetVertexInverse);
+ }
+ for (Resource endVertexInverse : sourceEndVertex_inverse) {
+ graph.claim(targetElement, DN.HasEndVertex_Inverse, endVertexInverse);
+ }
+ for (Resource targetVertexInverse : targetEndVertex_inverse) {
+ graph.claim(sourceElement, DN.HasEndVertex_Inverse, targetVertexInverse);
+ }
+ }
+
+ private static void deleteExistingTarget(WriteGraph graph, Resource target) throws DatabaseException {
+ RemoverUtil.remove(graph, target);
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection) {
+ final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
+ final List<Resource> copiedElements = CopyDistrictVertexHandler.elements; // TODO: this could be implemented more nicely with clipboard ?
+ boolean cut = CopyDistrictVertexHandler.cut;
+
+ Resource targetElement = elements.get(0);
+ Resource sourceElement = copiedElements.get(0);
+
+ try {
+ Map<Resource, Object> sourceCopyAttributes = new HashMap<>();
+ Map<Resource, Object> targetCopyAttributes = new HashMap<>();
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ Resource sourceMappedElement = graph.getPossibleObject(sourceElement, DN.MappedComponent);
+ sourceCopyAttributes.putAll(copyAttributes(graph, sourceElement, sourceMappedElement));
+ Resource targetMappedElement = graph.getPossibleObject(targetElement, DN.MappedComponent);
+ targetCopyAttributes.putAll(copyAttributes(graph, targetElement, targetMappedElement));
+ if (sourceMappedElement != null && cut)
+ RemoverUtil.remove(graph, sourceMappedElement);
+ if (targetMappedElement != null)
+ RemoverUtil.remove(graph, targetMappedElement);
+ }
+ });
+ ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+ try {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+
+ Resource diagram = graph.getSingleObject(sourceElement, L0.PartOf);
+ Resource newTarget = doCopy(graph, diagram, targetElement, sourceElement);
+ if (cut) {
+ Resource newSource = doCopy(graph, diagram, sourceElement, targetElement);
+ for (Map.Entry<Resource, Object> attrValue : targetCopyAttributes.entrySet()) {
+ graph.claimLiteral(newSource, attrValue.getKey(), attrValue.getValue());
+ }
+ copyVertexInverses(graph, sourceElement, newSource);
+ deleteExistingTarget(graph, sourceElement);
+ }
+ for (Map.Entry<Resource, Object> attrValue : sourceCopyAttributes.entrySet()) {
+ graph.claimLiteral(newTarget, attrValue.getKey(), attrValue.getValue());
+ }
+ copyVertexInverses(graph, targetElement, newTarget);
+ deleteExistingTarget(graph, targetElement);
+ }
+ });
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ }, 500, TimeUnit.MILLISECONDS);
+
+// ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+// Simantics.getSession().asyncRequest(new WriteRequest() {
+//
+// @Override
+// public void perform(WriteGraph graph) throws DatabaseException {
+// DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+// //copyMapping(graph, DN, sourceElement, targetElement);
+// copyLocation(graph, DN, sourceElement, targetElement, cut);
+// copyVertexInverses(graph, DN, sourceElement, targetElement, cut);
+// copyElevation(graph, DN, sourceElement, targetElement, cut);
+// }
+//
+// private void copyMapping(WriteGraph graph, DistrictNetworkResource DN, Resource sourceElement, Resource targetElement) throws DatabaseException {
+// Resource sourceMapping = graph.getSingleObject(sourceElement, DN.Mapping);
+// Resource targetMapping = graph.getSingleObject(targetElement, DN.Mapping);
+// if (cut) {
+// graph.deny(sourceElement, DN.Mapping);
+// graph.claim(sourceElement, DN.Mapping, targetMapping);
+// }
+// graph.deny(targetElement, DN.Mapping);
+// graph.claim(targetElement, DN.Mapping, sourceMapping);
+// }
+//
+// private void copyElevation(WriteGraph graph, DistrictNetworkResource DN, Resource sourceElement, Resource targetElement, boolean cut) throws DatabaseException {
+// double sourceElevation = graph.getRelatedValue(sourceElement, DN.Vertex_HasElevation, Bindings.DOUBLE);
+// double targetElevation = graph.getRelatedValue(targetElement, DN.Vertex_HasElevation, Bindings.DOUBLE);
+// if (cut) {
+// graph.deny(sourceElement, DN.Vertex_HasElevation);
+// graph.claimLiteral(sourceElement, DN.Vertex_HasElevation, targetElevation, Bindings.DOUBLE);
+// }
+// graph.deny(targetElement, DN.Vertex_HasElevation);
+// graph.claimLiteral(targetElement, DN.Vertex_HasElevation, sourceElevation, Bindings.DOUBLE);
+// }
+//
+// private void copyLocation(WriteGraph graph, DistrictNetworkResource DN, Resource sourceElement, Resource targetElement, boolean cut) throws DatabaseException {
+// DiagramResource DIA = DiagramResource.getInstance(graph);
+// double[] sourceLocation = graph.getRelatedValue(sourceElement, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+// double[] targetLocation = graph.getRelatedValue(targetElement, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+// if (cut) {
+// graph.deny(sourceElement, DIA.HasLocation);
+// graph.claimLiteral(sourceElement, DIA.HasLocation, targetLocation, Bindings.DOUBLE_ARRAY);
+// }
+// graph.deny(targetElement, DIA.HasLocation);
+// graph.claimLiteral(targetElement, DIA.HasLocation, sourceLocation, Bindings.DOUBLE_ARRAY);
+// }
+//
+
+//
+//
+// });
+// }, 500, TimeUnit.MILLISECONDS);
+
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private static Map<Resource, Object> copyAttributes(WriteGraph graph, Resource sourceElement, Resource mappedElement) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ Resource mapping = graph.getSingleObject(sourceElement, DN.HasMapping);
+ Collection<Statement> statements = graph.getStatements(mapping, L0.HasProperty);
+ Collection<Statement> mappingAttributeStatements = statements.stream().filter(stm -> {
+ try {
+ Resource predicate = stm.getPredicate();
+ Resource hasDomain = graph.getPossibleObject(predicate, L0.HasDomain);
+ if (hasDomain != null && hasDomain.equals(DN.Mapping_VertexMapping)) {
+ // filter out x and y and z
+ Resource vertexAttribute = attributeMappingToVertexAttribute(graph, DN, predicate);
+ return vertexAttribute != null;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }).collect(Collectors.toList());
+ Resource component = graph.getPossibleObject(mappedElement, ModelingResources.getInstance(graph).ElementToComponent);
+ Variable variable = Variables.getVariable(graph, component);
+ Map<Resource, Object> predValues = new HashMap<>();
+ for (Statement stm : mappingAttributeStatements) {
+ String propertyName = graph.getPossibleValue(stm.getObject());
+ if (propertyName != null) {
+ Object propertyValue = variable.getPossiblePropertyValue(graph, propertyName);
+ if (propertyValue != null) {
+ predValues.put(attributeMappingToVertexAttribute(graph, DN, stm.getPredicate()), propertyValue);
+ } else {
+ System.err.println("no property value for " + variable.getURI(graph) + " and property " + propertyName);
+ }
+ } else {
+ System.err.println("stm.getObject() is not string " + stm.getObject());
+ }
+ }
+ return predValues;
+ }
+
+ private static Resource attributeMappingToVertexAttribute(ReadGraph graph, DistrictNetworkResource DN, Resource attribute) throws DatabaseException {
+ Resource attr = null;
+ if (attribute.equals(DN.Mapping_VertexMapping_ElevationAttribute))
+ attr = null; // ignore elevation as well
+ else if (attribute.equals(DN.Mapping_VertexMapping_AddressAttribute))
+ attr = DN.Vertex_HasAddress;
+ else if (attribute.equals(DN.Mapping_VertexMapping_DeltaPressureAttribute))
+ attr = DN.Vertex_HasDeltaPressure;
+ else if (attribute.equals(DN.Mapping_VertexMapping_DeltaTemperatureAttribute))
+ attr = DN.Vertex_HasDeltaTemperature;
+ else if (attribute.equals(DN.Mapping_VertexMapping_dpAttribute))
+ attr = DN.Vertex_HasDeltaPressure;
+ else if (attribute.equals(DN.Mapping_VertexMapping_dtAttribute))
+ attr = DN.Vertex_HasDeltaTemperature;
+ else if (attribute.equals(DN.Mapping_VertexMapping_FlowAreaAttribute))
+ attr = DN.Vertex_HasFlowArea;
+ else if (attribute.equals(DN.Mapping_VertexMapping_HeatLoadDsAttribute))
+ attr = DN.Vertex_HasHeatLoadDs;
+ else if (attribute.equals(DN.Mapping_VertexMapping_HeatPowerAttribute))
+ attr = DN.Vertex_HasHeatPower;
+ else if (attribute.equals(DN.Mapping_VertexMapping_MassFlowAttribute))
+ attr = DN.Vertex_HasMassFlow;
+ else if (attribute.equals(DN.Mapping_VertexMapping_MaximumHeadMAttribute))
+ attr = DN.Vertex_HasMaximumHeadM;
+ else if (attribute.equals(DN.Mapping_VertexMapping_NominalFlowAttribute))
+ attr = DN.Vertex_HasNominalFlow;
+ else if (attribute.equals(DN.Mapping_VertexMapping_NominalHeadBAttribute))
+ attr = DN.Vertex_HasNominalHeadB_Inverse;
+ else if (attribute.equals(DN.Mapping_VertexMapping_NominalHeadMAttribute))
+ attr = DN.Vertex_HasNominalHeadM;
+ else if (attribute.equals(DN.Mapping_VertexMapping_NominalMassFlowAttribute))
+ attr = DN.Vertex_HasNominalFlow;
+ else if (attribute.equals(DN.Mapping_VertexMapping_NominalPressureLossAttribute))
+ attr = DN.Vertex_HasNominalPressureLoss;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ReturnPressureAttribute))
+ attr = DN.Vertex_HasReturnPressure;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ReturnTemperatureAttribute))
+ attr = DN.Vertex_HasReturnTemperature;
+ else if (attribute.equals(DN.Mapping_VertexMapping_SupplyPressureAttribute))
+ attr = DN.Vertex_HasSupplyPressure;
+ else if (attribute.equals(DN.Mapping_VertexMapping_SupplyTemperatureAttribute))
+ attr = DN.Vertex_HasSupplyTemperature;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValvePositionAttribute))
+ attr = DN.Vertex_HasValvePosition;
+ else if (attribute.equals(DN.Mapping_VertexMapping_VelocityAttribute))
+ attr = DN.Vertex_HasVelocity;
+ else if (attribute.equals(DN.Mapping_VertexMapping_VolFlowAttribute))
+ attr = DN.Vertex_HasVolFlow;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpInReturnLineAttribute))
+ attr = DN.Vertex_HasPumpInReturnLine;
+ else if (attribute.equals(DN.Mapping_VertexMapping_HeadPumpMaximumAttribute))
+ attr = DN.Vertex_HasHeadPumpMaximum;
+ else if (attribute.equals(DN.Mapping_VertexMapping_HeadPumpNominalAttribute))
+ attr = DN.Vertex_HasHeadPumpNominal;
+ else if (attribute.equals(DN.Mapping_VertexMapping_FrequencyConverterControlledAttribute))
+ attr = DN.Vertex_HasFrequencyConverterControlled;
+ else if (attribute.equals(DN.Mapping_VertexMapping_InternalValveMeasurementAttribute))
+ attr = DN.Vertex_HasInternalValveMeasurement;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpMassFlowNominalAttribute))
+ attr = DN.Vertex_HasPumpMassFlowNominal;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpMeMaxAttribute))
+ attr = DN.Vertex_HasPumpMeMax;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpMeMinAttribute))
+ attr = DN.Vertex_HasPumpMeMin;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpSpeedMaxAttribute))
+ attr = DN.Vertex_HasPumpSpeedMax;
+ else if (attribute.equals(DN.Mapping_VertexMapping_PumpSpeedMinAttribute))
+ attr = DN.Vertex_HasPumpSpeedMin;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValveReturnLineAttribute))
+ attr = DN.Vertex_HasValveReturnLine;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValveMeMaxAttribute))
+ attr = DN.Vertex_HasValveMeMax;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValveMeMinAttribute))
+ attr = DN.Vertex_HasValveMeMin;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValveMinPositionAttribute))
+ attr = DN.Vertex_HasValveMinPosition;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValveOutletModeAttribute))
+ attr = DN.Vertex_HasValveOutletMode;
+ else if (attribute.equals(DN.Mapping_VertexMapping_ValvePressLossNominalAttribute))
+ attr = DN.Vertex_HasValvePressLossNominal;
+ else if (attribute.equals(DN.Mapping_VertexMapping_OpeningTimeAttribute))
+ attr = DN.Vertex_HasOpeningTime;
+ else if (attribute.equals(DN.Mapping_VertexMapping_XAttribute))
+ attr = null; // ignore this!
+ else if (attribute.equals(DN.Mapping_VertexMapping_YAttribute))
+ attr = null; // ignore this!
+ return attr;
+ }
+}
import org.simantics.db.common.request.ObjectsWithType;
import org.simantics.db.common.request.ReadRequest;
import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.RuntimeDatabaseException;
import org.simantics.db.exception.ServiceException;
import org.simantics.db.layer0.variable.Variables;
import org.simantics.db.layer0.variable.Variables.Role;
import org.simantics.db.procedure.Procedure;
+import org.simantics.district.network.DistrictNetworkUtil;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.layer0.Layer0;
import org.simantics.modeling.ModelingResources;
@SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
public static Object defaultVertexMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
- System.out.println(graph.getURI(resource));
- System.out.println(context.getURI(graph));
-
Resource diagram = resolveElement(graph, context);
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
return baseMappingModifier(graph, diagram, DN.VertexDefaultMapping, DN.Mapping_VertexMapping, context);
}
-
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+ public static Object rightClickVertexMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+ Resource diagram = resolveElement(graph, context);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ return baseMappingModifier(graph, diagram, DN.RightClickDefaultMapping, DN.Mapping_VertexMapping, context);
+ }
+
+ @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
+ public static Object leftClickVertexMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
+ Resource diagram = resolveElement(graph, context);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ return baseMappingModifier(graph, diagram, DN.LeftClickDefaultMapping, DN.Mapping_VertexMapping, context);
+ }
+
@SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
public static Object mappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
@SCLValue(type = "ReadGraph -> Resource -> a -> b")
public static Object enumerationValues(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
Variable var = (Variable) context;
- System.out.println(graph.getURI(resource));
- System.out.println(var.getURI(graph));
return Collections.emptyList();
}
private static class DefaultMappingsDialog extends SelectionStatusDialog {
private Combo vertexMappingCombo;
+ private Combo rightClickMappingCombo;
+ private Combo leftClickMappingCombo;
private Combo edgeMappingCombo;
- private Combo crsCombo;
+ //private Combo crsCombo;
private Composite composite;
private Resource configuration;
private Resource defaultVertexMapping;
private Resource defaultEdgeMapping;
- private Resource defaultCRS;
+ private Resource rightClickVertexMapping;
+ private Resource leftClickVertexMapping;
+ //private Resource defaultCRS;
- private Combo compositeMappingCombo;
- private Combo componentMappingCombo;
+ //private Combo compositeMappingCombo;
+ //private Combo componentMappingCombo;
protected DefaultMappingsDialog(Shell parentShell, Resource configuration) {
super(parentShell);
return defaultVertexMapping;
}
+ public Resource getRightClickVertexMapping() {
+ return rightClickVertexMapping;
+ }
+
+ public Resource getLeftClickVertexMapping() {
+ return leftClickVertexMapping;
+ }
+
public Resource getDefaultEdgeMapping() {
return defaultEdgeMapping;
}
composite = (Composite) super.createDialogArea(parent);
createMappingsGroup(composite);
- createExistingCompositeGroup(composite);
- createCRSSettingsGroup(composite);
+ //createExistingCompositeGroup(composite);
+ //createCRSSettingsGroup(composite);
// compute default values
Simantics.getSession().asyncRequest(new ReadRequest() {
composite.getDisplay().asyncExec(() -> {
vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
+ rightClickMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
+ leftClickMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
edgeMappingCombo.setItems(edgeMappings.keySet().toArray(new String[edgeMappings.size()]));
- crsCombo.setItems(crss.keySet().toArray(new String[crss.size()]));
+ //crsCombo.setItems(crss.keySet().toArray(new String[crss.size()]));
- compositeMappingCombo.setItems(composites.keySet().toArray(new String[composites.size()]));
+ //compositeMappingCombo.setItems(composites.keySet().toArray(new String[composites.size()]));
vertexMappingCombo.select(0);
+ rightClickMappingCombo.select(0);
+ leftClickMappingCombo.select(0);
edgeMappingCombo.select(0);
- crsCombo.select(0);
+ //crsCombo.select(0);
- if (!composites.isEmpty())
- compositeMappingCombo.select(0);
+ //if (!composites.isEmpty())
+ // compositeMappingCombo.select(0);
});
}
vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
-
+
+ Label rightClickMappingLabel = new Label(cmposite, SWT.NONE);
+ rightClickMappingLabel.setText("Default right click mapping");
+
+ rightClickMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
+
+ Label leftClickMappingLabel = new Label(cmposite, SWT.NONE);
+ leftClickMappingLabel.setText("Default left click mapping");
+
+ leftClickMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
+
Label edgeMappingLabel = new Label(cmposite, SWT.NONE);
edgeMappingLabel.setText("Default edge mapping");
Label compositeMappingLabel = new Label(cmposite, SWT.NONE);
compositeMappingLabel.setText("Select composite");
- compositeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
- GridDataFactory.fillDefaults().grab(true, false).applyTo(compositeMappingCombo);
- compositeMappingCombo.addSelectionListener(new SelectionAdapter() {
-
- @Override
- public void widgetSelected(SelectionEvent e) {
- super.widgetSelected(e);
- recalculateMappapleComponents();
- }
- });
-
- Label compojnentMappingLabel = new Label(cmposite, SWT.NONE);
- compojnentMappingLabel.setText("Select component");
+// compositeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+// GridDataFactory.fillDefaults().grab(true, false).applyTo(compositeMappingCombo);
+// compositeMappingCombo.addSelectionListener(new SelectionAdapter() {
+//
+// @Override
+// public void widgetSelected(SelectionEvent e) {
+// super.widgetSelected(e);
+// recalculateMappapleComponents();
+// }
+// });
- componentMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
- GridDataFactory.fillDefaults().grab(true, false).applyTo(componentMappingCombo);
+// Label compojnentMappingLabel = new Label(cmposite, SWT.NONE);
+// compojnentMappingLabel.setText("Select component");
+//
+// componentMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+// GridDataFactory.fillDefaults().grab(true, false).applyTo(componentMappingCombo);
}
protected void recalculateMappapleComponents() {
Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
vertexMappingLabel.setText("Default CRS");
- crsCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
- GridData textData = new GridData(SWT.FILL, SWT.CENTER, true, false);
- crsCombo.setLayoutData(textData);
+ //crsCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ //GridData textData = new GridData(SWT.FILL, SWT.CENTER, true, false);
+ //crsCombo.setLayoutData(textData);
}
protected void computeResult() {
defaultVertexMapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex()));
defaultEdgeMapping = edgeMappings.get(edgeMappingCombo.getItem(edgeMappingCombo.getSelectionIndex()));
- defaultCRS = crss.get(crsCombo.getItem(crsCombo.getSelectionIndex()));
+ rightClickVertexMapping = vertexMappings.get(rightClickMappingCombo.getItem(rightClickMappingCombo.getSelectionIndex()));
+ leftClickVertexMapping = vertexMappings.get(leftClickMappingCombo.getItem(leftClickMappingCombo.getSelectionIndex()));
+ //defaultCRS = crss.get(crsCombo.getItem(crsCombo.getSelectionIndex()));
}
public Resource getCRS() {
- return defaultCRS;
+ return crss.get("EPSG_4326"); // this is only supported
}
}
procedure.execute(null);
return;
}
- Simantics.getSession().asyncRequest(
- NewCompositeActionFactory.createCompositeRequest(target, defaultName, compositeType),
- new Procedure<Resource>() {
- @Override
- public void execute(Resource composite) {
- Simantics.getSession().asyncRequest(new WriteRequest() {
-
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
- Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram);
- graph.claim(diagram, DN.EdgeDefaultMapping, dialog.getDefaultEdgeMapping());
- graph.claim(diagram, DN.VertexDefaultMapping, dialog.getDefaultVertexMapping());
- graph.claim(diagram, DN.HasSpatialRefSystem, dialog.getCRS());
-
- // Generated name prefix from composite name
- String compositeName = graph.getRelatedValue2(composite, Layer0.getInstance(graph).HasName, Bindings.STRING);
- graph.claimLiteral(diagram, Layer0X.getInstance(graph).HasGeneratedNamePrefix, "N" + compositeName.substring(compositeName.length() - 1, compositeName.length()));
- }
- });
- DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true);
- procedure.execute(composite);
- }
-
- @Override
- public void exception(Throwable t) {
- LOGGER.error("Failed to create composite, see exception for details.", t);
- procedure.exception(t);
- }
- });
+ Simantics.getSession().asyncRequest(new WriteResultRequest<Resource>() {
+
+ @Override
+ public Resource perform(WriteGraph graph) throws DatabaseException {
+ return DistrictNetworkUtil.createNetworkDiagram(graph, target, compositeType, defaultName,
+ dialog.getDefaultEdgeMapping(),
+ dialog.getDefaultVertexMapping(),
+ dialog.getRightClickVertexMapping(),
+ dialog.getLeftClickVertexMapping(),
+ dialog.getCRS()
+ );
+ }
+
+
+ }, new Procedure<Resource>() {
+
+ @Override
+ public void execute(Resource composite) {
+ DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true);
+ procedure.execute(composite);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Failed to create composite, see exception for details.", t);
+ procedure.exception(t);
+ }
+ });
}
public static Collection<Resource> getDistrictDiagrams(ReadGraph graph) throws DatabaseException {
package org.simantics.district.network.ui.internal;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.ui.internal.workbench.E4Workbench;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
import org.osgi.util.tracker.ServiceTracker;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.DistrictNetworkUIUtil;
import org.simantics.district.network.ui.breakdown.SubgraphProvider;
import org.simantics.district.route.RouteService;
+import org.simantics.modeling.ModelingResources;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class Activator extends AbstractUIPlugin {
+ private static final class HighlightSelectionEventHandler implements EventHandler {
+ @Override
+ public void handleEvent(Event event) {
+ Object data = event.getProperty("org.eclipse.e4.data");
+ if (data instanceof Variable[]) {
+ Variable[] propertyTableComponents = (Variable[]) data;
+ try {
+ // convert components to dh components
+ List<Resource> dnElements = Simantics.getSession().syncRequest(new UniqueRead<List<Resource>>() {
+
+ @Override
+ public List<Resource> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ return Arrays.asList(propertyTableComponents).stream().map(var -> {
+ try {
+ Resource res = var.getRepresents(graph);
+ Resource element = graph.getSingleObject(res, MOD.ComponentToElement);
+ return graph.getSingleObject(element, DN.MappedFromElement);
+ } catch (Exception e) {
+ String varURI = var.toString();
+ try {
+ varURI = var.getURI(graph);
+ } catch (DatabaseException ex) {
+ LOGGER.error("Unable to resole uri for {}", var, ex);
+ }
+ LOGGER.error("Could not get dn element for {}", varURI, e);
+ return null;
+ }
+ }).collect(Collectors.toList());
+ }
+ });
+ DistrictNetworkUIUtil.openDNDiagramWithSelection(Display.getDefault(), dnElements);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not convert variables to dn elements", propertyTableComponents, e);
+ }
+ }
+ }
+ }
+
+ // This is hard coded for now.. the same value is used for multipropertytable to
+ // send the events we are here listening and interested in
+ private static final String PROPERTY_TABLE_HIGHLIGHT = "PROPERTY_TABLE_HIGHLIGHT";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
+
public static final String PLUGIN_ID = "org.simantics.district.network.ui";
private static Activator instance;
private ServiceTracker<SubgraphProvider, SubgraphProvider> subgraphProviderTracker;
private ServiceTracker<RouteService, RouteService> routeServiceTracker;
+ private HighlightSelectionEventHandler eventHandler;
+
@Override
public void start(BundleContext context) throws Exception {
Activator.instance = this;
subgraphProviderTracker.open();
routeServiceTracker = new ServiceTracker<>(context, RouteService.class.getName(), null);
routeServiceTracker.open();
+
+ initializeEventListener();
}
@Override
public void stop(BundleContext context) throws Exception {
subgraphProviderTracker.close();
routeServiceTracker.close();
-
+ deinitializeEventListener();
Activator.instance = null;
Activator.context = null;
}
return routeServiceTracker.getService();
}
+ private void initializeEventListener() {
+ @SuppressWarnings("restriction")
+ IEclipseContext contxt = E4Workbench.getServiceContext();
+ IEventBroker broker = contxt.get(IEventBroker.class);
+ eventHandler = new HighlightSelectionEventHandler();
+ if (broker != null) {
+ broker.subscribe(PROPERTY_TABLE_HIGHLIGHT, eventHandler);
+ } else {
+ LOGGER.info("EventBroker is somehow null for {}", this);
+ }
+ }
+
+ private void deinitializeEventListener() {
+ @SuppressWarnings("restriction")
+ IEclipseContext contxt = E4Workbench.getServiceContext();
+ IEventBroker broker = contxt.get(IEventBroker.class);
+ if (broker != null) {
+ broker.unsubscribe(eventHandler);
+ } else {
+ LOGGER.info("EventBroker is somehow null for {}", this);
+ }
+ }
}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.Graphics2D;
+
+public interface DeferredNode {
+ void renderDeferred(Graphics2D g);
+}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.utils.datastructures.Pair;
+
+public class DeferredRenderingNode extends G2DNode {
+
+ private static final long serialVersionUID = 1L;
+
+ List<Pair<AffineTransform, DeferredNode>> queue = new LinkedList<>();
+
+ @Override
+ public void render(Graphics2D g2d) {
+ AffineTransform currentTransform = g2d.getTransform();
+
+ ListIterator<Pair<AffineTransform, DeferredNode>> listIterator = queue.listIterator();
+ while (listIterator.hasNext()) {
+ Pair<AffineTransform, DeferredNode> node = listIterator.next();
+ listIterator.remove();
+
+ g2d.setTransform(node.first);
+ node.second.renderDeferred(g2d);
+ }
+
+ g2d.setTransform(currentTransform);
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ public void deferNode(AffineTransform transform, DeferredNode node) {
+ queue.add(new Pair<>(transform, node));
+ }
+}
import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.ISelectionPainterNode;
+import org.simantics.scenegraph.INode.PropertySetter;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.g2d.G2DParentNode;
import org.simantics.scenegraph.g2d.nodes.SVGNode;
private transient Rectangle2D symbolRect;
private transient AffineTransform symbolTransform;
+ private boolean hidden = false;
+
private Double arrowLength;
private static double startX;
g2d.transform(getTransform());
}
- Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-
- Color oldColor = g2d.getColor();
- BasicStroke oldStroke = (BasicStroke) g2d.getStroke();
-
- BasicStroke bs = null;
+ double scale = 1.0;
if (scaleStroke) {
- double scale = GeometryUtils.getScale(g2d.getTransform());
- scale = Math.max(10000, Math.min(scale, 50000));
- double str = stroke != null ? Math.abs(stroke) : 1.0;
- bs = GeometryUtils.scaleStroke(STROKE, (float) (str / scale));
- } else {
- bs = STROKE;
+ AffineTransform tr = g2d.getTransform();
+ scale = DistrictNetworkNodeUtils.getScale(tr);
}
- int zoomLevel = MapScalingTransform.zoomLevel(ot);
- path = calculatePath(edge, path, zoomLevel > 15);
-
- if (isSelected()) {
- g2d.setColor(SELECTION_COLOR);
- g2d.setStroke(GeometryUtils.scaleStroke(bs, 4f));
- g2d.draw(path);
- }
-
- g2d.setColor(dynamicColor != null ? dynamicColor : color);
- g2d.setStroke(bs);
- g2d.draw(path);
-
- // Draw arrow
- if (arrowLength != null) {
- g2d.setColor(Color.BLACK);
- g2d.setStroke(new BasicStroke(bs.getLineWidth(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
-
- double l = arrowLength;
- double w = 2 * (double) bs.getLineWidth() * Math.signum(l);
- if (Math.abs(w) > Math.abs(l)) w = l;
- double offset = 2 * (double) bs.getLineWidth();
-
- double centerX = (startX + endX) / 2, centerY = (startY + endY) / 2;
- double deltaX = endX - startX, deltaY = endY - startY;
- double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- deltaX /= length;
- deltaY /= length;
-
- double x0 = centerX - l/2 * deltaX + offset * deltaY;
- double y0 = centerY - l/2 * deltaY - offset * deltaX;
- double x1 = centerX + (l/2 - w) * deltaX + offset * deltaY;
- double y1 = centerY + (l/2 - w) * deltaY - offset * deltaX;
+
+ if (!hidden) {
+ Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ Color oldColor = g2d.getColor();
+ BasicStroke oldStroke = (BasicStroke) g2d.getStroke();
+
+ BasicStroke bs = null;
+ if (scaleStroke) {
+ bs = GeometryUtils.scaleStroke(STROKE, getStrokeWidth(scale));
+ } else {
+ bs = STROKE;
+ }
- g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+ int zoomLevel = MapScalingTransform.zoomLevel(ot);
+ path = calculatePath(edge, path, zoomLevel > 15);
+
+ if (isSelected()) {
+ g2d.setColor(SELECTION_COLOR);
+ g2d.setStroke(GeometryUtils.scaleAndOffsetStrokeWidth(bs, 1.f, (float)(2 * STROKE.getLineWidth() / scale)));
+ g2d.draw(path);
+ }
+
+ g2d.setColor(dynamicColor != null ? dynamicColor : color);
+ g2d.setStroke(bs);
+ g2d.draw(path);
+
+ // Draw arrow
+ if (arrowLength != null) {
+ g2d.setColor(Color.BLACK);
+ float lw = STROKE.getLineWidth() / (float)scale;
+ g2d.setStroke(new BasicStroke(lw, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
+
+ double l = arrowLength;
+ double w = 2 * (double) lw * Math.signum(l);
+ if (Math.abs(w) > Math.abs(l)) w = l;
+ double offset = 2 * (double) lw;
+
+ double centerX = (startX + endX) / 2, centerY = (startY + endY) / 2;
+ double deltaX = endX - startX, deltaY = endY - startY;
+ double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ deltaX /= length;
+ deltaY /= length;
+
+ double x0 = centerX - l/2 * deltaX + offset * deltaY;
+ double y0 = centerY - l/2 * deltaY - offset * deltaX;
+ double x1 = centerX + (l/2 - w) * deltaX + offset * deltaY;
+ double y1 = centerY + (l/2 - w) * deltaY - offset * deltaX;
+
+ g2d.draw(new Line2D.Double(x0, y0, x1, y1));
+
+ Path2D path = new Path2D.Double();
+ path.moveTo(x1 + w * deltaX, y1 + w * deltaY);
+ path.lineTo(x1 + w * deltaY, y1 - w * deltaX);
+ path.lineTo(x1 - w * deltaY, y1 + w * deltaX);
+ path.closePath();
+ g2d.fill(path);
+ }
- Path2D path = new Path2D.Double();
- path.moveTo(x1 + w * deltaX, y1 + w * deltaY);
- path.lineTo(x1 + w * deltaY, y1 - w * deltaX);
- path.lineTo(x1 - w * deltaY, y1 + w * deltaX);
- path.closePath();
- g2d.fill(path);
+ // Reset
+ g2d.setStroke(oldStroke);
+ g2d.setColor(oldColor);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
}
-
- // Reset
- g2d.setStroke(oldStroke);
- g2d.setColor(oldColor);
-
- // Render SVG symbol
- double viewScaleRecip = 10;
- if (scaleStroke) {
- double scale = GeometryUtils.getScale(g2d.getTransform());
- scale = Math.max(10000, Math.min(scale, 50000));
- viewScaleRecip /= scale;
- }
-
- Point2D p = getCenterPoint();
- symbolRect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, NORMAL, symbolRect, viewScaleRecip);
- symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(symbolRect, symbolTransform);
-
+
for (INode nn : getNodes()) {
G2DNode g2dNode = (G2DNode)nn;
- g2dNode.setTransform(symbolTransform);
+ if (g2dNode instanceof SVGNode) {
+ // Render SVG symbol
+ double viewScaleRecip = 10;
+ if (scaleStroke) {
+ viewScaleRecip /= scale;
+ }
+
+ Point2D p = getCenterPoint();
+ symbolRect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, NORMAL, symbolRect, viewScaleRecip);
+ symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(symbolRect, symbolTransform);
+
+ g2dNode.setTransform(symbolTransform);
+ }
g2dNode.render(g2d);
}
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
-
if (ot != null)
g2d.setTransform(ot);
}
+ public float getStrokeWidth(AffineTransform tr, boolean selection) {
+ double scale = DistrictNetworkNodeUtils.getScale(tr);
+ float width = STROKE.getLineWidth() * getStrokeWidth(scale);
+ if (selection) width = width + (float) (2 * STROKE.getLineWidth() / scale);
+ return width;
+ }
+
+ private float getStrokeWidth(double scale) {
+ if (scaleStroke) {
+ double str = stroke != null ? Math.abs(stroke) : 1.0;
+ float strokeWidth = (float) (str / scale);
+ return strokeWidth;
+ }
+ else {
+ return 1.f;
+ }
+ }
+
+ public Path2D getPath() {
+ return path;
+ }
+
private Point2D getCenterPoint() {
if (centerPoint == null)
centerPoint = new Point2D.Double();
((SVGNode)nn).setData(value);
}
+
+ @PropertySetter(value = "hidden")
+ public void setHidden(Boolean value) {
+ this.hidden = value;
+ }
}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.simantics.district.network.ui.styles.DistrictNetworkHoverInfoStyle;
+import org.simantics.maps.MapScalingTransform;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.utils.DPIUtil;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.scl.runtime.Lists;
+import org.simantics.scl.runtime.tuple.Tuple3;
+
+public class DistrictNetworkHoverInfoNode extends G2DNode implements HoverSensitiveNode, DeferredNode {
+
+ private static final Font FONT = new Font("Tahoma", Font.PLAIN, (int)(DPIUtil.upscale(9) * MapScalingTransform.getScaleY() + 0.5));
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String NODE_KEY = "DISTRICT_NETWORK_HOVER_INFO";
+
+ private static final int W1 = 50;
+ private static final int W2 = 30;
+ private static final int PAD = 5;
+
+ private List<Tuple3> labels;
+
+ @SuppressWarnings("unused")
+ private Point2D origin;
+
+ private boolean hover = false;
+
+ private Point2D mousePosition;
+
+ private static AtomicReference<DistrictNetworkHoverInfoNode> activeNode = new AtomicReference<>();
+
+ @Override
+ public void render(Graphics2D g) {
+ if (!hover || activeNode.get() != this)
+ return;
+
+ ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(this, RTreeNode.class);
+ DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkHoverInfoStyle.HOVER_INFO_DEFERRED) : null;
+ if (deferred != null)
+ deferred.deferNode(g.getTransform(), this);
+ else
+ renderDeferred(g);
+ }
+
+ @Override
+ public void renderDeferred(Graphics2D g) {
+ AffineTransform ot = g.getTransform();
+ Font of = g.getFont();
+ doRender(g);
+ g.setFont(of);
+ g.setTransform(ot);
+ }
+
+ private void doRender(Graphics2D g) {
+ g.transform(MapScalingTransform.INVERSE);
+ g.translate(mousePosition.getX(), mousePosition.getY());
+ //g.translate(origin.getX(), origin.getY());
+ double scale = 1.5 / g.getTransform().getScaleX();
+ g.scale(scale, scale);
+
+ g.setFont(FONT);
+ double rowHeight = g.getFontMetrics().getHeight() * 1.1;
+
+ // let's calculate the max width
+ Optional<Integer> max = labels.stream().map(t -> g.getFontMetrics().stringWidth((String) t.c2)).max(Comparator.naturalOrder());
+ int width = max.orElse(10);
+ g.setColor(Color.WHITE);
+ int totalHeight = (int)Math.round(rowHeight * labels.size());
+ g.fillRect(-(W1 + PAD + W2 + 5), -(totalHeight + (int)Math.round(rowHeight)), (W1 + PAD + W2 + width + 10), totalHeight + 5);
+
+ g.setColor(Color.BLACK);
+
+ for (Tuple3 t : labels) {
+ g.translate(0.f, -rowHeight);
+
+ if (t.c0 != null) {
+ g.drawString((String) t.c0, -(W1 + PAD + W2), 0.f);
+ }
+
+ if (t.c1 != null) {
+ int width1 = g.getFontMetrics().stringWidth((String) t.c1);
+ g.drawString((String) t.c1, - width1, 0.f);
+ }
+
+ if (t.c2 != null) {
+ g.drawString((String) t.c2, PAD, 0.f);
+ }
+ }
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setLabels(List<Tuple3> list) {
+ this.labels = Lists.reverse(list);
+ }
+
+ public void setOrigin(Point2D origin) {
+ this.origin = origin;
+ }
+
+ @Override
+ public boolean hover(boolean hover, boolean isConnectionTool) {
+ hover = hover && activeNode.updateAndGet(current -> current == null ? this : current) == this;
+ boolean changed = hover != this.hover;
+ this.hover = hover;
+
+ if (changed) {
+ if (!hover) activeNode.updateAndGet(current -> current == this ? null : current);
+ repaint();
+ }
+
+ return changed;
+ }
+
+ @Override
+ public void setMousePosition(Point2D p) {
+ mousePosition = p;
+ }
+
+ @Override
+ public void delete() {
+ super.delete();
+ activeNode.getAndUpdate(current -> current == this ? null : current);
+ }
+}
public static double calculateScaleRecip(AffineTransform tr) {
int zoomLevel = MapScalingTransform.zoomLevel(tr);
- double scale = GeometryUtils.getScale(tr);
- double sqrt = Math.sqrt(scale / zoomLevel);
- double viewScaleRecip = (sqrt / zoomLevel);
- return viewScaleRecip;
+ return 1.0 / (getScale(tr) * Math.sqrt(zoomLevel));
+ }
+
+ static double getScale(AffineTransform tr) {
+ double scale;
+ scale = GeometryUtils.getScale(tr);
+ scale = Math.max(4096, scale); //Math.min(scale, 32768));
+ return scale;
}
}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.district.network.ui.styles.DistrictNetworkStaticInfoStyle;
+import org.simantics.maps.MapScalingTransform;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.utils.DPIUtil;
+import org.simantics.scenegraph.utils.NodeUtil;
+
+public class DistrictNetworkStaticInfoNode extends G2DNode implements DeferredNode {
+
+ private static final Font FONT = new Font("Tahoma", Font.PLAIN, (int)(DPIUtil.upscale(9) * MapScalingTransform.getScaleY() + 0.5));
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Point2D UNIT_X = new Point2D.Double(1.0, 0.0);
+
+ public static final String NODE_KEY = "DISTRICT_NETWORK_STATIC_INFO";
+
+ String info = null;
+ Point2D origin = new Point2D.Double();
+ Point2D direction = UNIT_X;
+
+ @Override
+ public void render(Graphics2D g) {
+ ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(this, RTreeNode.class);
+ DeferredRenderingNode deferred = root != null ? (DeferredRenderingNode) root.getNode(DistrictNetworkStaticInfoStyle.STATIC_INFO_DEFERRED) : null;
+ if (deferred != null)
+ deferred.deferNode(g.getTransform(), this);
+ else
+ renderDeferred(g);
+ }
+
+ @Override
+ public void renderDeferred(Graphics2D g) {
+ if (info == null || "".equals(info))
+ return;
+
+ AffineTransform oldTransform = g.getTransform();
+
+ // There has to be a better way to calculate the zoom level in this context...
+ AffineTransform baseTransform;
+ try {
+ baseTransform = ((G2DParentNode)getParent()).getTransform().createInverse();
+ } catch (NoninvertibleTransformException e) {
+ baseTransform = new AffineTransform();
+ }
+
+ baseTransform.preConcatenate(oldTransform);
+ int zoomLevel = MapScalingTransform.zoomLevel(baseTransform);
+ if (zoomLevel < 15)
+ return;
+
+ Font oldFont = g.getFont();
+ Color oldColor = g.getColor();
+ Object oldAA = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+ doRender(g);
+
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAA);
+ g.setTransform(oldTransform);
+ g.setColor(oldColor);
+ g.setFont(oldFont);
+ }
+
+ private void doRender(Graphics2D g) {
+ g.translate(origin.getX(), origin.getY());
+ double scale = 1.5 / g.getTransform().getScaleX();
+ g.scale(scale, scale);
+
+ g.setFont(FONT);
+ int width1 = g.getFontMetrics().stringWidth(info);
+// int height = g.getFontMetrics().getHeight();
+
+ g.transform(AffineTransform.getRotateInstance(direction.getX(), direction.getY()));
+ g.translate(0, 10);
+
+// g.setColor(Color.WHITE);
+// g.fillRect(-width1/2 - 5, -height-2, width1+10, height+4);
+
+ g.setColor(Color.BLACK);
+
+ g.drawString(info, -width1/2, 0);
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ public void setLocation(Point2D origin, Point2D direction) {
+ this.origin = origin;
+ this.direction = direction;
+ }
+
+ public void setInfo(String info) {
+ this.info = info;
+ }
+}
import java.awt.geom.Rectangle2D;
import org.simantics.district.network.ui.adapters.DistrictNetworkVertex;
+import org.simantics.maps.MapScalingTransform;
import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.ISelectionPainterNode;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.IG2DNode;
import org.simantics.scenegraph.g2d.nodes.SVGNode;
import org.simantics.scenegraph.utils.GeometryUtils;
import org.simantics.scenegraph.utils.NodeUtil;
-public class DistrictNetworkVertexNode extends G2DParentNode implements ISelectionPainterNode {
+public class DistrictNetworkVertexNode extends G2DParentNode implements ISelectionPainterNode, HoverSensitiveNode {
//private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkVertexNode.class);
private static final long serialVersionUID = -2641639101400236719L;
- private static final double left = -0.00005;
+ private static final double left = -15;
private static final double top = left;
- public static final double width = 0.0001;
+ public static final double width = 30;
private static final double height = width;
private static final BasicStroke STROKE = new BasicStroke((float)width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
private static final Color SELECTION_COLOR = new Color(255, 0, 255, 96);
private static final Rectangle2D NORMAL = new Rectangle2D.Double(left, top, width, height);
- private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 3, top * 3, width * 3, height * 3);
+ private static final Rectangle2D HOVERED = new Rectangle2D.Double(left * 2, top * 2, width * 2, height * 2);
private DistrictNetworkVertex vertex;
private transient Rectangle2D rect;
private transient AffineTransform symbolTransform;
- private double nodeSize = 1;
+ private double nodeSize = 1.0;
+
+ private boolean hidden = false;
@Override
public void init() {
@Override
public void render(Graphics2D g2d) {
- if (nodeSize <= 0.0)
- return;
-
AffineTransform ot = null;
AffineTransform t = getTransform();
if (t != null && !t.isIdentity()) {
g2d.transform(t);
}
- Object oaaHint = null;
- Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
- if (aaHint != RenderingHints.VALUE_ANTIALIAS_OFF) {
- oaaHint = aaHint;
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
- }
-
- Color oldColor = g2d.getColor();
- Color newColor = dynamicColor != null ? dynamicColor : color;
- boolean changeColor = !oldColor.equals(newColor);
-
+ // Translate lat and lon to X and Y
+ Point2D p = point = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point);
+
double viewScaleRecip = 1;
if (scaleStroke) {
viewScaleRecip *= DistrictNetworkNodeUtils.calculateScaleRecip(g2d.getTransform());
}
- double scaleRecip = viewScaleRecip * nodeSize;
-
- // Translate lat and lon to X and Y
- Point2D p = point = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point);
- Rectangle2D toDraw = rect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip);
-
- if (NodeUtil.isSelected(this, 1)) {
- changeColor = true;
- g2d.setColor(SELECTION_COLOR);
- BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float) (viewScaleRecip*0.5));
- g2d.setStroke(ss);
- g2d.draw(toDraw);
- }
-
- // render
- if (changeColor)
- g2d.setColor(newColor);
- g2d.fill(toDraw);
- // Reset settings
- if (changeColor)
- g2d.setColor(oldColor);
- if (oaaHint != null)
- g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
+ if (!hidden && nodeSize > 0.0) {
+ Object oaaHint = null;
+ Object aaHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
+ if (aaHint != RenderingHints.VALUE_ANTIALIAS_OFF) {
+ oaaHint = aaHint;
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
+ }
+
+ Color oldColor = g2d.getColor();
+ Color newColor = dynamicColor != null ? dynamicColor : color;
+ boolean changeColor = !oldColor.equals(newColor);
+
+ double scaleRecip = viewScaleRecip * nodeSize;
+
+ Rectangle2D toDraw = rect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, scaleRecip);
+
+ if (NodeUtil.isSelected(this, 1)) {
+ changeColor = true;
+ g2d.setColor(SELECTION_COLOR);
+ BasicStroke ss = GeometryUtils.scaleStroke(STROKE, (float)viewScaleRecip);
+ g2d.setStroke(ss);
+ g2d.draw(toDraw);
+ }
+
+ // render
+ if (changeColor)
+ g2d.setColor(newColor);
+ g2d.fill(toDraw);
+
+ // Reset settings
+ if (changeColor)
+ g2d.setColor(oldColor);
+ if (oaaHint != null)
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
+ }
// Render SVG symbol
for (INode nn : getNodes()) {
G2DNode g2dNode = (G2DNode)nn;
if (nn instanceof SVGNode) {
+ Rectangle2D toDraw = rect = DistrictNetworkNodeUtils.calculateDrawnGeometry(p, hover ? HOVERED : NORMAL, rect, viewScaleRecip);
symbolTransform = DistrictNetworkNodeUtils.getTransformToRectangle(toDraw, symbolTransform);
g2dNode.setTransform(symbolTransform);
}
+
g2dNode.render(g2d);
}
@Override
public Rectangle2D getBoundsInLocal() {
+ updateBounds();
return bounds;
}
private Rectangle2D calculateBounds(Rectangle2D rect) {
Point2D calcPoint = DistrictNetworkNodeUtils.calculatePoint2D(vertex.getPoint(), point);
- AffineTransform at = getTransform();
+ AffineTransform at = NodeUtil.getLocalToGlobalTransform(this);
+ at.concatenate(MapScalingTransform.INSTANCE);
double x = calcPoint.getX();
double y = calcPoint.getY();
- double widthh = width / at.getScaleX();
- double heighth = height / at.getScaleY();
- return new Rectangle2D.Double(x - widthh, y - heighth, widthh * 2, heighth * 2).getBounds2D();
+ double scaleRecip = DistrictNetworkNodeUtils.calculateScaleRecip(at);
+ double widthh = width * scaleRecip * nodeSize;
+ double heighth = height * scaleRecip * nodeSize;
+ if (rect == null)
+ rect = new Rectangle2D.Double();
+ rect.setRect(x - widthh/2, y - heighth/2, widthh, heighth);
+ return rect;
}
public void setVertex(DistrictNetworkVertex vertex) {
updateBounds();
}
- public boolean hover(boolean hover) {
-// if (hover && LOGGER.isDebugEnabled())
-// LOGGER.debug("Hovering " + this);
- boolean changed = false;
- if (this.hover != hover) {
- this.hover = hover;
- changed = true;
+ @Override
+ public boolean hover(boolean hover, boolean isConnectionTool) {
+ // Only react to hover when the connection tool is active
+ boolean doHover = hover && isConnectionTool;
+ boolean changed = this.hover != doHover;
+ this.hover = doHover;
+
+ for (IG2DNode child : getNodes()) {
+ if (child instanceof HoverSensitiveNode)
+ changed = ((HoverSensitiveNode)child).hover(hover, isConnectionTool) || changed;
}
+
return changed;
}
+
+ @Override
+ public void setMousePosition(Point2D p) {
+ for (IG2DNode child : getNodes()) {
+ if (child instanceof HoverSensitiveNode)
+ ((HoverSensitiveNode) child).setMousePosition(p);
+ }
+ }
public void setColor(Color color) {
this.color = color;
this.dynamicColor = color;
}
+ @PropertySetter(value = "hidden")
+ public void setHidden(Boolean value) {
+ this.hidden = value;
+ }
}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicColorMap.RGBIntensity;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.utils.DPIUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicVisualisationContributionsNode extends G2DNode {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationContributionsNode.class);
+
+ public static final String ID = "dynamicVisualisationContributionsNode";
+
+ private static final long serialVersionUID = 7400966702826774761L;
+
+ protected boolean enabled = true;
+
+ private Map<String, DynamicColorContribution> dynamicColoringContributions;
+ private Map<String, DynamicSizeContribution> dynamicSizingContributions;
+
+ private ColorBarOptions colorBarsOptions = ColorBarOptions.useDefault();
+ private SizeBarOptions sizeBarsOptions = SizeBarOptions.useDefault();
+
+ @Override
+ public void render(Graphics2D g2d) {
+ if (!enabled)
+ return;
+
+ AffineTransform ot = g2d.getTransform();
+ Color oldColor = g2d.getColor();
+
+ try {
+ g2d.transform(transform);
+ g2d.setTransform(new AffineTransform());
+
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ return; // FIXME
+
+ renderColors(g2d);
+ renderSizes(g2d);
+ } finally {
+ g2d.setColor(oldColor);
+ g2d.setTransform(ot);
+ }
+ }
+
+ private double colorBarBoxWidth = 300;
+ private double colorBarBoxHeight = 50;
+ private double colorBarBoxPadding = 20;
+
+ private void renderColors(Graphics2D g2d) {
+ if (colorBarsOptions == null || !colorBarsOptions.isShowColorBars()) {
+ return;
+ }
+ ColorBarsLocation location = colorBarsOptions.getLocation();
+ ColorBarsSize size = colorBarsOptions.getSize();
+ double colorBarBoxLeft = getColorBarBoxLeft(g2d, location, size);
+ double colorBarBoxTopInitial = getColorBarBoxTop(g2d, location, size);
+ double colorBarBoxWidth = getColorBarBoxWidth(size);
+ double colorBarBoxHeight = getColorBarBoxHeight(size);
+
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ return; // FIXME
+
+ int i = 0;
+
+ if (dynamicColoringContributions != null) {
+ for (Entry<String, DynamicColorContribution> object : dynamicColoringContributions.entrySet()) {
+ DynamicColorContribution cc = object.getValue();
+
+ if (!cc.isUsed())
+ break;
+
+ double min = cc.getDefaultMin();
+ double max = cc.getDefaultMax();
+ String unit = cc.getUnit();
+ String label = cc.getLabel();
+
+ DynamicColorMap map = cc.getDefaultColorMap();
+
+ double colorBarBoxTop = (colorBarBoxTopInitial + (colorBarBoxHeight * i));
+ i++;
+
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
+ g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.95f));
+
+ Rectangle2D vertical = new Rectangle2D.Double(colorBarBoxLeft, colorBarBoxTop, colorBarBoxWidth, colorBarBoxHeight);
+ g2d.fill(vertical);
+
+ double colorVerticalLeft = colorBarBoxLeft + 5;
+ double colorVerticalTop = colorBarBoxTop + 15;
+ double colorVerticalHeigth = colorBarBoxHeight - 30;
+ List<RGBIntensity> intensities = map.getIntensities();
+ double colorVerticalWidth = (colorBarBoxWidth - 10) / intensities.size();
+
+ Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9));
+ g2d.setFont(rulerFont);
+ g2d.setColor(Color.BLACK);
+
+ String str = Double.toString(max);
+ g2d.drawString(str, (int)(colorBarBoxLeft + colorBarBoxWidth - 30), (int)(colorBarBoxTop + colorBarBoxHeight));
+
+ str = Double.toString(min);
+ g2d.drawString(str, (int)colorBarBoxLeft + 1, (int)(colorBarBoxTop + colorBarBoxHeight));
+
+
+ for (RGBIntensity intensity : intensities) {
+
+ g2d.setColor(new Color((float)intensity.getRed(), (float)intensity.getGreen(), (float)intensity.getBlue(), 1f));
+ Rectangle2D colorVertical = new Rectangle2D.Double(colorVerticalLeft, colorVerticalTop, colorVerticalWidth, colorVerticalHeigth);
+ g2d.fill(colorVertical);
+ colorVerticalLeft = colorVerticalLeft + colorVerticalWidth;
+ }
+ g2d.setColor(Color.BLACK);
+ str = object.getKey() + " - " + label + " [" + unit + "]";
+ g2d.drawString(str, (int)colorBarBoxLeft + 5, (int)colorBarBoxTop + 10);
+ }
+ }
+ }
+
+ private double getColorBarBoxTop(Graphics2D g2d, ColorBarsLocation location, ColorBarsSize size) {
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ throw new IllegalStateException();
+ switch (location) {
+ case NORTH: {
+ return colorBarBoxPadding;
+ }
+ case SOUTH: {
+ return bounds.getMaxY() - colorBarBoxPadding;
+ }
+ case EAST:
+ case WEST: {
+ return (bounds.getMaxY() / 2) - (getColorBarBoxHeight(size) / 2);
+ }
+ default:
+ return 0;
+ }
+ }
+
+ private double getColorBarBoxLeft(Graphics2D g2d, ColorBarsLocation location, ColorBarsSize size) {
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ throw new IllegalStateException();
+ switch (location) {
+ case EAST: {
+ double right = bounds.getMaxX() - colorBarBoxPadding;
+ return right - getColorBarBoxWidth(size);
+ }
+ case WEST: {
+ return colorBarBoxPadding;
+ }
+ case NORTH:
+ case SOUTH: {
+ double left = (bounds.getMaxX() / 2) - (getColorBarBoxWidth(size) / 2);
+ return left;
+ }
+ default:
+ return 0;
+ }
+ }
+
+ private double getColorBarBoxWidth(ColorBarsSize size) {
+ return size.getSize() * colorBarBoxWidth;
+ }
+
+ private double getColorBarBoxHeight(ColorBarsSize size) {
+ return size.getSize() * colorBarBoxHeight;
+ }
+
+ private void renderSizes(Graphics2D g2d) {
+ if (sizeBarsOptions == null || !sizeBarsOptions.isShowSizeBars()) {
+ return;
+ }
+ SizeBarsLocation location = sizeBarsOptions.getLocation();
+ SizeBarsSize sizeb = sizeBarsOptions.getSize();
+ double sizeBarBoxLeft = getSizeBarBoxLeft(g2d, location, sizeb);
+ double sizeBarBoxTopInitial = getSizeBarBoxTop(g2d, location, sizeb);
+ double sizeBarBoxWidth = getSizeBarBoxWidth(sizeb);
+ double sizeBarBoxHeight = getSizeBarBoxHeight(sizeb);
+
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ return; // FIXME
+
+ int i = 0;
+
+ for (Entry<String, DynamicSizeContribution> object : dynamicSizingContributions.entrySet()) {
+ DynamicSizeContribution cc = object.getValue();
+
+ double min = cc.getDefaultMin();
+ double max = cc.getDefaultMax();
+ String unit = cc.getUnit();
+ String label = cc.getLabel();
+
+ DynamicSizeMap map = cc.getDefaultSizeMap();
+
+ List<Double> sizes = map.getSizes();
+
+ double sizeBarBoxTop = (sizeBarBoxTopInitial + (colorBarBoxHeight * i));
+ i++;
+// double backgroundBoxPaddingRight = 20;
+// double backgroundBoxHeight = 50;
+// double backgroundBoxWidth = 300;
+// double backgroundBoxRight = bounds.getMaxX() - backgroundBoxPaddingRight;
+// double backgroundBoxLeft = backgroundBoxRight - backgroundBoxWidth;
+// double backgroundBoxTop = bounds.getMaxY();// + (initialPosition + (position * i));
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
+ g2d.setColor(new Color(0.9f, 0.9f, 0.9f, 0.95f));
+
+ Rectangle2D vertical = new Rectangle2D.Double(sizeBarBoxLeft, sizeBarBoxTop, colorBarBoxWidth, colorBarBoxHeight);
+ g2d.fill(vertical);
+
+ double sizeVerticalLeft = sizeBarBoxLeft + 5;
+ double sizeVerticalTop = sizeBarBoxTop + 15;
+ double sizeVerticalHeigth = colorBarBoxHeight - 30;
+
+ double sizeVerticalWidth = (sizeBarBoxWidth - 10) / sizes.size();
+
+ Font rulerFont = new Font("Tahoma", Font.PLAIN, DPIUtil.upscale(9));
+ g2d.setFont(rulerFont);
+ g2d.setColor(Color.BLACK);
+
+ String str = Double.toString(max);
+ g2d.drawString(str, (int)(sizeBarBoxLeft + sizeBarBoxWidth - 30), (int)(sizeBarBoxTop + sizeBarBoxHeight));
+
+ str = Double.toString(min);
+ g2d.drawString(str, (int)sizeBarBoxLeft + 1, (int)(sizeBarBoxTop + sizeBarBoxHeight));
+
+
+ g2d.setColor(new Color((float)0, (float)0, (float)0.8, 0.8f));
+ for (Double size: sizes) {
+
+ Ellipse2D ellipse = new Ellipse2D.Double(sizeVerticalLeft + sizeVerticalWidth / 2, (sizeVerticalTop), size * sizeVerticalHeigth, size * sizeVerticalHeigth);
+ g2d.fill(ellipse);
+
+ sizeVerticalLeft = sizeVerticalLeft + sizeVerticalWidth;
+ }
+ g2d.setColor(Color.BLACK);
+ str = object.getKey() + " - " + label + " [" + unit + "]";
+ g2d.drawString(str, (int)sizeBarBoxLeft + 5, (int)sizeBarBoxTop + 10);
+ }
+ }
+
+ private double getSizeBarBoxTop(Graphics2D g2d, SizeBarsLocation location, SizeBarsSize size) {
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ throw new IllegalStateException();
+ switch (location) {
+ case NORTH: {
+ return colorBarBoxPadding;
+ }
+ case SOUTH: {
+ return bounds.getMaxY() - colorBarBoxPadding;
+ }
+ case EAST:
+ case WEST: {
+ return (bounds.getMaxY() / 2) - (getSizeBarBoxHeight(size) / 2);
+ }
+ default:
+ return 0;
+ }
+ }
+
+ private double getSizeBarBoxLeft(Graphics2D g2d, SizeBarsLocation location, SizeBarsSize size) {
+ Rectangle2D bounds = g2d.getClipBounds();
+ if (bounds == null)
+ throw new IllegalStateException();
+ switch (location) {
+ case EAST: {
+ double right = bounds.getMaxX() - colorBarBoxPadding;
+ return right - getSizeBarBoxWidth(size);
+ }
+ case WEST: {
+ return colorBarBoxPadding;
+ }
+ case NORTH:
+ case SOUTH: {
+ double left = (bounds.getMaxX() / 2) - (getSizeBarBoxWidth(size) / 2);
+ return left;
+ }
+ default:
+ return 0;
+ }
+ }
+
+ private double getSizeBarBoxWidth(SizeBarsSize size) {
+ return size.getSize() * colorBarBoxWidth;
+ }
+
+ private double getSizeBarBoxHeight(SizeBarsSize size) {
+ return size.getSize() * colorBarBoxHeight;
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public void setDynamicColoringObjects(Map<String,DynamicColorContribution> dynamicColoringObjects) {
+ this.dynamicColoringContributions = dynamicColoringObjects;
+ }
+
+ public void setColorBarOptions(ColorBarOptions colorBarsOptions) {
+ this.colorBarsOptions = colorBarsOptions;
+ }
+
+ public void setDynamicSizingObjects(Map<String, DynamicSizeContribution> dynamicSizingObjects) {
+ this.dynamicSizingContributions = dynamicSizingObjects;
+ }
+
+ public void setSizeBarOptions(SizeBarOptions sizeBarOptions) {
+ this.sizeBarsOptions = sizeBarOptions;
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Stroke;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.utils.GeometryUtils;
+
+public class ElevationServerNode extends G2DNode {
+
+ private static final long serialVersionUID = 3832908017166017921L;
+
+ private static final Stroke DASHED_STROKE = new BasicStroke(2.0f,
+ BasicStroke.CAP_ROUND,
+ BasicStroke.JOIN_ROUND,
+ 4.0f, new float[]{4.0f}, 0.0f);
+
+ private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
+
+ public static final String ID = "elevationServerNode";
+
+ private Collection<Rectangle2D> rectangles;
+
+ @Override
+ public void render(Graphics2D g2d) {
+
+ Color old = g2d.getColor();
+ Stroke oldStroke = g2d.getStroke();
+
+ g2d.setColor(BLUE_ALPHA);
+ BasicStroke stroke = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+ g2d.setStroke(stroke);
+
+ double scale = getTransform().getScaleY();
+
+ for (Rectangle2D rect : getRectangles()) {
+
+ Point2D point = new Point2D.Double(rect.getY(), rect.getX());
+ Point2D result = DistrictNetworkNodeUtils.calculatePoint2D(point, null);
+
+ Point2D point2 = new Point2D.Double(rect.getY() + rect.getHeight(), rect.getX() + rect.getWidth());
+ Point2D result2 = DistrictNetworkNodeUtils.calculatePoint2D(point2, null);
+
+ double x = result.getX() * scale;
+ double y = result.getY() * scale;
+ double width = result2.getX() * scale - result.getX() * scale;
+ double height = result2.getY() * scale - result.getY() * scale;
+
+ Rectangle2D translated = new Rectangle2D.Double(x, y - Math.abs(height), width, Math.abs(height));
+ g2d.draw(translated);
+ }
+
+ g2d.setStroke(oldStroke);
+ g2d.setColor(old);
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ Rectangle2D bounds = new Rectangle2D.Double();
+ for (Rectangle2D rect : getRectangles()) {
+ bounds.add(rect);
+ }
+ return bounds;
+ }
+
+ public void setRectangles(Collection<Rectangle2D> rectangles) {
+ this.rectangles = rectangles;
+ }
+
+ public Collection<Rectangle2D> getRectangles() {
+ if (rectangles == null)
+ return Collections.emptyList();
+ return rectangles;
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.nodes;
+
+import java.awt.geom.Point2D;
+
+public interface HoverSensitiveNode {
+ boolean hover(boolean hover, boolean isConnectionTool);
+ default void setMousePosition(Point2D p) {};
+}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.simantics.Simantics;
import org.simantics.db.Resource;
import org.simantics.db.WriteGraph;
import org.simantics.db.common.request.WriteRequest;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Write;
import org.simantics.diagram.elements.DiagramNodeUtil;
import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.district.network.DNEdgeBuilder;
+import org.simantics.district.network.DistrictNetworkUtil;
import org.simantics.district.network.ModelledCRS;
-import org.simantics.district.network.ui.DNEdgeBuilder;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.NetworkDrawingParticipant;
import org.simantics.g2d.canvas.Hints;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.g2d.canvas.IToolMode;
import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
import org.simantics.scenegraph.g2d.G2DNode;
import org.simantics.scenegraph.g2d.events.EventTypes;
import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
import org.simantics.scenegraph.utils.GeometryUtils;
import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.utils.threads.ThreadUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class NetworkDrawingNode extends G2DNode {
+ private static final Logger LOGGER = LoggerFactory.getLogger(NetworkDrawingNode.class);
+
+ static class DrawingNode {
+
+ private List<Point2D> routeNodes = new ArrayList<>();
+ }
+
private static final long serialVersionUID = -3475301184009620573L;
private Point2D currentMousePos = null;
-
- private List<Point2D> nodes = new ArrayList<>();
- private Resource diagramResource;
+ private List<DrawingNode> nodes = new ArrayList<>();
+ private DrawingNode currentRouteNode = null;
- private boolean committed;
+ private Resource diagramResource;
private NetworkDrawingParticipant participant;
4.0f, new float[]{4.0f}, 0.0f);
private static final Color BLUE_ALPHA = new Color(0, 0, 255, 100);
+ private static final Color RED_ALPHA = new Color(255, 0, 0, 100);
private boolean scaleStroke = true;
public void render(Graphics2D g2d) {
if (nodes.isEmpty())
return;
-
- Path2D path = new Path2D.Double();
- Iterator<Point2D> nodeIter = nodes.iterator();
- if (nodeIter.hasNext()) {
- Point2D node = nodeIter.next();
- path.moveTo(node.getX(), node.getY());
- }
- while (nodeIter.hasNext()) {
- Point2D node = nodeIter.next();
- path.lineTo(node.getX(), node.getY());
- }
- if (currentMousePos != null)
- path.lineTo(currentMousePos.getX(), currentMousePos.getY());
-
+
Color old = g2d.getColor();
Stroke oldStroke = g2d.getStroke();
-
- if (DASHED_STROKE != null) {
- if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
- BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
- g2d.setStroke(bs);
- } else {
- g2d.setStroke(DASHED_STROKE);
+
+ Iterator<DrawingNode> dnodeIterator = nodes.iterator();
+ while (dnodeIterator.hasNext()) {
+ Path2D path = new Path2D.Double();
+ DrawingNode dnode = dnodeIterator.next();
+ Iterator<Point2D> nodeIter = dnode.routeNodes.iterator();
+ if (nodeIter.hasNext()) {
+ Point2D node = nodeIter.next();
+ path.moveTo(node.getX(), node.getY());
}
+ while (nodeIter.hasNext()) {
+ Point2D node = nodeIter.next();
+ path.lineTo(node.getX(), node.getY());
+ }
+ if (!dnodeIterator.hasNext()) {
+ if (currentMousePos != null)
+ path.lineTo(currentMousePos.getX(), currentMousePos.getY());
+ }
+
+ if (DASHED_STROKE != null) {
+ if (scaleStroke && DASHED_STROKE instanceof BasicStroke) {
+ BasicStroke bs = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+ g2d.setStroke(bs);
+ } else {
+ g2d.setStroke(DASHED_STROKE);
+ }
+ }
+
+ g2d.setColor(BLUE_ALPHA);
+ g2d.draw(path);
+
+ g2d.setColor(RED_ALPHA);
+ BasicStroke stroke = GeometryUtils.scaleStroke(DASHED_STROKE, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform())));
+ g2d.setStroke(stroke);
+ Point2D currentPoint = path.getCurrentPoint();
+ g2d.draw(new Rectangle2D.Double(currentPoint.getX() - 0.0001 / 2, currentPoint.getY() - 0.0001 / 2, 0.0001, 0.0001));
}
- g2d.setColor(BLUE_ALPHA);
-
- g2d.draw(path);
-
g2d.setStroke(oldStroke);
g2d.setColor(old);
}
// nodes to path2d
IToolMode mode = getToolMode();
if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
- Point2D start = null;
- Point2D end = null;
- Iterator<Point2D> nodeIter = nodes.iterator();
- while (nodeIter.hasNext()) {
- if (end == null) {
- start = nodeIter.next();
- if (!nodeIter.hasNext()) {
- break;
- }
- } else {
- start = end;
- }
+ // ok, new routenode starts from here
+ Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
+ Point2D.Double pos = new Point2D.Double(localPos.getX(), localPos.getY());
+ if (currentRouteNode != null) {
+ //currentRouteNode.routeNodes.add(pos);
+ currentRouteNode = new DrawingNode();
+ currentRouteNode.routeNodes.add(pos);
+ nodes.add(currentRouteNode);
+ } else {
+ // ok, this must be creation of dh_point
+ double scale = getTransform().getScaleY();
+ double x = ModelledCRS.xToLongitude(pos.getX() / scale);
+ double y = ModelledCRS.yToLatitude(-pos.getY() / scale);
- end = nodeIter.next();
+ boolean leftButton = e.button == MouseEvent.LEFT_BUTTON;
- createEdge(start, end);
+ ThreadUtils.getNonBlockingWorkExecutor().schedule(() -> {
+ Simantics.getSession().asyncRequest(new Write() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.markUndoPoint();
+ Resource mapping = null;
+ if (leftButton) {
+ mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).LeftClickDefaultMapping);
+ } else {
+ mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).RightClickDefaultMapping);
+ }
+ if (mapping == null) {
+ mapping = graph.getSingleObject(diagramResource, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
+ }
+ DistrictNetworkUtil.createVertex(graph, diagramResource, new double[] { x, y }, Double.MAX_VALUE, mapping);
+ }
+ });
+ }, 100, TimeUnit.MILLISECONDS);
}
-
- nodes.clear();
- committed = true;
-
repaint();
-
return true;
}
return super.mouseDoubleClicked(e);
}
- private void createEdge(Point2D start, Point2D end) {
+ private void createEdge(DrawingNode node) {
+
+ Point2D start = node.routeNodes.get(0);
+ Point2D end = node.routeNodes.get(node.routeNodes.size() - 1);
double currentPadding = DistrictNetworkVertexNode.width;
AffineTransform test = getTransform();
double[] startCoords = new double[] { startLon, startLat };
double[] endCoords = new double[] { endLon, endLat };
+ double[] detailedGeometryCoords = new double[node.routeNodes.size() * 2];
+ int i = 0;
+ for (Point2D p : node.routeNodes) {
+ double lat = ModelledCRS.yToLatitude(-p.getY() / scaleY);
+ double lon = ModelledCRS.xToLongitude(p.getX() / scaleX);
+ detailedGeometryCoords[i++] = lon;
+ detailedGeometryCoords[i++] = lat;
+ }
+
DNEdgeBuilder builder = new DNEdgeBuilder(diagramResource, diagram);
Simantics.getSession().asyncRequest(new WriteRequest() {
-
+
@Override
public void perform(WriteGraph graph) throws DatabaseException {
- builder.create(graph, startCoords, endCoords, padding);
+ builder.create(graph, startCoords, Double.MAX_VALUE, endCoords, Double.MAX_VALUE, detailedGeometryCoords, padding);
}
});
-
+
}
@Override
// check ToolMode
IToolMode mode = getToolMode();
if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
- if (committed) {
- committed = false;
- return false;
- }
if (e.button == MouseEvent.RIGHT_BUTTON && !nodes.isEmpty()) {
nodes.remove(nodes.size() - 1);
} else if (e.button == MouseEvent.LEFT_BUTTON) {
Point2D localPos = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
- nodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+ if (currentRouteNode == null && canStartEdge(localPos)) {
+ // ok, we can start from here
+ currentRouteNode = new DrawingNode();
+ currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+ nodes.add(currentRouteNode);
+ } else if (currentRouteNode != null && canStartEdge(localPos)) {
+ // let's commit our new routenode
+ currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+ Iterator<DrawingNode> nodeIter = nodes.iterator();
+ while (nodeIter.hasNext()) {
+ createEdge(nodeIter.next());
+ }
+ currentRouteNode = null;
+ nodes.clear();
+ } else if (currentRouteNode != null) {
+ currentRouteNode.routeNodes.add(new Point2D.Double(localPos.getX(), localPos.getY()));
+ }
}
repaint();
return true;
}
return super.mouseClicked(e);
}
-
+
+ private boolean canStartEdge(Point2D currentPos) {
+ return participant.isHoveringOverNode(currentPos);
+ }
+
private IToolMode getToolMode() {
return participant.getHint(Hints.KEY_TOOL);
}
@Override
protected boolean mouseMoved(MouseMovedEvent e) {
IToolMode mode = getToolMode();
- if (mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK)) {
- boolean repaint = false;
- Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
- if (participant.pickHoveredElement(p)) {
- repaint = true;
- }
- if (!nodes.isEmpty()) {
- currentMousePos = p;
-
- repaint();
- return true;
- }
- currentMousePos = null;
- if (repaint == true)
- repaint();
+ boolean repaint = false;
+ Point2D p = NodeUtil.worldToLocal(this, e.controlPosition, new Point2D.Double());
+ boolean isConnectionTool = mode == Hints.CONNECTTOOL || e.hasAnyModifier(MouseEvent.ALT_MASK | MouseEvent.ALT_GRAPH_MASK);
+ if (participant.pickHoveredElement(p, isConnectionTool)) {
+ repaint = true;
}
+ if (!nodes.isEmpty()) {
+ currentMousePos = p;
+
+ repaint();
+ return true;
+ }
+ currentMousePos = null;
+ if (repaint == true)
+ repaint();
return super.mouseMoved(e);
}
@Override
protected boolean keyPressed(KeyPressedEvent e) {
if (e.keyCode == java.awt.event.KeyEvent.VK_ESCAPE) {
+ currentRouteNode = null;
nodes.clear();
repaint();
return true;
--- /dev/null
+package org.simantics.district.network.ui.participants;
+
+import java.awt.geom.AffineTransform;
+import java.util.Map;
+
+import org.simantics.district.network.ui.DistrictDiagramViewer;
+import org.simantics.district.network.ui.nodes.DynamicVisualisationContributionsNode;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintListener;
+import org.simantics.utils.datastructures.hints.IHintObservable;
+
+public class DynamicVisualisationContributionsParticipant extends AbstractCanvasParticipant {
+
+ IHintListener hintListener = new HintListenerAdapter() {
+ public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {
+ ICanvasContext cc = getContext();
+ if (cc != null) {
+ updateNode();
+ cc.getContentContext().setDirty();
+ }
+ }
+ };
+
+ private DynamicVisualisationContributionsNode node;
+ private AffineTransform transform;
+
+ public DynamicVisualisationContributionsParticipant(AffineTransform tr) {
+ this.transform = tr;
+ }
+
+ @Override
+ public void addedToContext(ICanvasContext ctx) {
+ super.addedToContext(ctx);
+ getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_COLORING_OBJECTS, hintListener);
+ getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS, hintListener);
+ getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS, hintListener);
+ getHintStack().addKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS, hintListener);
+ }
+
+ @Override
+ public void removedFromContext(ICanvasContext ctx) {
+ getHintStack().removeKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_COLORING_OBJECTS, hintListener);
+ getHintStack().removeKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS, hintListener);
+ getHintStack().removeKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS, hintListener);
+ getHintStack().removeKeyHintListener(getThread(), DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS, hintListener);
+ super.removedFromContext(ctx);
+ }
+
+ @SGInit
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode(DynamicVisualisationContributionsNode.ID, DynamicVisualisationContributionsNode.class);
+ node.setTransform(transform);
+ node.setEnabled(true);
+ node.setZIndex(1000);
+ }
+
+ @EventHandler(priority = 0)
+ protected boolean handleKeyEvent(CommandEvent e) {
+ if (e.command.equals(DistrictDiagramViewer.MAP_COLOR_BAR_OPTIONS_CHANGE)) {
+ System.out.println(e);
+ return true;
+ }
+ return false;
+ }
+
+// @Override
+// protected boolean handleCommand(CommandEvent e) {
+// if (e.command.equals(DistrictDiagramViewer.MAP_COLOR_BAR_OPTIONS_CHANGE)) {
+// ICanvasContext context = (ICanvasContext) e.getContext();
+// ColorBarOptions options = context.getHintStack().getHint(DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS);
+// this.colorBarsOptions = options;
+// repaint();
+// return true;
+// } else {
+// return super.handleCommand(e);
+// }
+// }
+
+ protected void updateNode() {
+ node.setDynamicColoringObjects(getDynamicColoringObjects());
+ node.setColorBarOptions(getColorBarOptions());
+ node.setDynamicSizingObjects(getDynamicSizingObjects());
+ node.setSizeBarOptions(getSizeBarOptions());
+ }
+
+ private Map<String,DynamicColorContribution> getDynamicColoringObjects() {
+ Map<String,DynamicColorContribution> objects = getHint(DistrictDiagramViewer.KEY_MAP_COLORING_OBJECTS);
+ return objects;
+ }
+
+ private ColorBarOptions getColorBarOptions() {
+ ColorBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_COLOR_BAR_OPTIONS);
+ return options;
+ }
+
+ private Map<String, DynamicSizeContribution> getDynamicSizingObjects() {
+ Map<String, DynamicSizeContribution> objects = getHint(DistrictDiagramViewer.KEY_MAP_SIZING_OBJECTS);
+ return objects;
+ }
+
+ private SizeBarOptions getSizeBarOptions() {
+ SizeBarOptions options = getHint(DistrictDiagramViewer.KEY_MAP_SIZE_BAR_OPTIONS);
+ return options;
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.participants;
+
+import java.awt.geom.AffineTransform;
+
+import org.simantics.district.network.ui.nodes.ElevationServerNode;
+import org.simantics.g2d.canvas.impl.SGNodeReflection.SGInit;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+
+public class ElevationServerParticipant extends AbstractDiagramParticipant {
+
+ private ElevationServerNode node;
+
+ private AffineTransform transform;
+
+ public ElevationServerParticipant(AffineTransform transform) {
+ this.transform = transform;
+ }
+
+ @SGInit
+ public void initSG(G2DParentNode parent) {
+ node = parent.addNode(ElevationServerNode.ID, ElevationServerNode.class);
+ node.setTransform(transform);
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.styles;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.nodes.DistrictNetworkNodeUtils;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.G2DNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.scenegraph.utils.GeometryUtils;
+import org.simantics.scl.compiler.top.ValueNotFound;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.structural.stubs.StructuralResource2;
+
+public class ConnectionLineStyle extends StyleBase<List<Point2D>> {
+
+ public static class ConnectionLineNode extends G2DNode {
+ private static final BasicStroke STROKE = new BasicStroke(1.f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.f, new float[] {4.f, 2.f}, 0.f);
+ private static final Color[] colors = { Color.RED, Color.GREEN, Color.BLUE, Color.ORANGE, Color.CYAN, Color.PINK };
+
+ private float strokeWidth;
+ private Line2D[] lines;
+
+ public ConnectionLineNode() {
+ super();
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Rectangle2D getBoundsInLocal() {
+ return null;
+ }
+
+ @Override
+ public Rectangle2D getBoundsInLocal(boolean b) {
+ return null;
+ }
+
+ @Override
+ public Rectangle2D getBounds() {
+ return null;
+ }
+
+ public void setStrokeWidth(float w) {
+ strokeWidth = w;
+ }
+
+ public void setPoints(List<Point2D> result) {
+ Point2D p0 = DistrictNetworkNodeUtils.calculatePoint2D(result.get(0), null);
+ lines = new Line2D[result.size() - 1];
+ for (int i = 1; i < result.size(); i++)
+ {
+ Point2D p = result.get(i);
+ lines[i-1] = p != null ? new Line2D.Double(p0, DistrictNetworkNodeUtils.calculatePoint2D(p, null)) : null;
+ }
+ }
+
+ @Override
+ public void render(Graphics2D g2d) {
+ if (lines == null || lines.length == 0)
+ return;
+
+ // Keep fixed line width on screen
+ float scaleRecip = (float) GeometryUtils.getScale(g2d.getTransform());
+ g2d.setStroke(GeometryUtils.scaleStroke(STROKE, strokeWidth / scaleRecip));
+
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i] != null) {
+ g2d.setColor(colors[i % colors.length]);
+ g2d.draw(lines[i]);
+ }
+ }
+ }
+ }
+
+ @Override
+ public List<Point2D> calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem)
+ throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ Resource vertex = groupItem;
+ if (!graph.isInstanceOf(vertex, DN.Vertex))
+ return Collections.emptyList();
+
+ double[] coords = graph.getRelatedValue(vertex, DiagramResource.getInstance(graph).HasLocation);
+
+ Resource component = DistrictNetworkUtil.getMappedComponentCached(graph, vertex);
+ if (component == null)
+ return Collections.emptyList();
+
+ Resource componentType = graph.getPossibleType(component, STR.Component);
+ if (componentType == null)
+ return Collections.emptyList();
+
+ Function1<Resource, List<Resource>> fun = getConnectedComponentsFunctionCached(graph, componentType);
+ if (fun == null)
+ return Collections.emptyList();
+
+ List<Resource> components = Simantics.applySCLRead(graph, fun, component);
+
+ if (components == null || components.isEmpty())
+ return Collections.emptyList();
+
+ List<Point2D> result = new ArrayList<>(components.size() + 1);
+ result.add(new Point2D.Double(coords[0], coords[1]));
+ for (Resource comp : components) {
+ Resource e = comp != null ? graph.getPossibleObject(comp, MOD.ComponentToElement) : null;
+ Resource mappingElement = e != null ? graph.getPossibleObject(e, DN.MappedFromElement) : null;
+ if (mappingElement != null) {
+ double[] coords2 = graph.getRelatedValue(mappingElement, DiagramResource.getInstance(graph).HasLocation);
+ result.add(new Point2D.Double(coords2[0], coords2[1]));
+ }
+ else {
+ result.add(null);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void applyStyleForNode(EvaluationContext observer, INode parent, List<Point2D> result) {
+ if (result == null || result.size() < 2) {
+ ProfileVariables.denyChild(parent, "*", "districtNetworkConnection");
+ return;
+ }
+
+ ConnectionLineNode node = ProfileVariables.claimChild(parent, "*", "districtNetworkConnection", ConnectionLineNode.class, observer);
+ if (node == null)
+ return;
+
+ node.setPoints(result);
+ node.setZIndex(0);
+ node.setStrokeWidth(2.f);
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode parent) {
+ ProfileVariables.denyChild(parent, "*", "districtNetworkConnection");
+ }
+
+ private static Function1<Resource, List<Resource>> getConnectedComponentsFunctionCached(ReadGraph graph, Resource componentType)
+ throws DatabaseException {
+ return graph.syncRequest(new ConnectedComponentsFunctionRequest(componentType), TransientCacheListener.instance());
+ }
+
+ private static final class ConnectedComponentsFunctionRequest
+ extends ResourceRead<Function1<Resource, List<Resource>>> {
+ public ConnectedComponentsFunctionRequest(Resource resource) {
+ super(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Function1<Resource, List<Resource>> perform(ReadGraph graph) throws DatabaseException {
+ Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, "Actions");
+ if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
+ return null;
+
+ String uri = graph.getURI(actionsModule);
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ sclContext.put("graph", graph);
+ return (Function1<Resource, List<Resource>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, "getConnectedComponents");
+ } catch (ValueNotFound e1) {
+ return null;
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.styles;
+
+import java.awt.geom.Point2D;
+import java.util.Collections;
+import java.util.List;
+
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.exception.MissingVariableException;
+import org.simantics.db.layer0.exception.MissingVariableValueException;
+import org.simantics.db.layer0.exception.PendingVariableException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.ui.nodes.DeferredRenderingNode;
+import org.simantics.district.network.ui.nodes.DistrictNetworkHoverInfoNode;
+import org.simantics.district.network.ui.nodes.DistrictNetworkNodeUtils;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.scl.compiler.top.ValueNotFound;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.tuple.Tuple3;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DistrictNetworkHoverInfoStyle extends StyleBase<DistrictNetworkHoverInfoStyle.StyleResult> {
+
+ public static final String HOVER_INFO_DEFERRED = "hoverInfo";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkHoverInfoStyle.class);
+
+ private static final String ACTIONS_MODULE = "Actions";
+ private static final String HOVER_CONTRIBUTION = "hoverContribution";
+
+ public class StyleResult {
+ Point2D origin;
+ List<Tuple3> labels;
+
+ public StyleResult(Point2D origin, List<Tuple3> labels) {
+ this.origin = origin;
+ this.labels = labels;
+ }
+
+ public Point2D getOrigin() {
+ return origin;
+ }
+
+ public List<Tuple3> getLabels() {
+ return labels;
+ }
+ }
+
+ public DistrictNetworkHoverInfoStyle(Resource style) throws DatabaseException {
+ super(style);
+ }
+
+ String currentRowKey;
+
+ protected Resource getConfigurationComponent(ReadGraph graph, Resource element) throws DatabaseException {
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ Resource mappedElement = graph.getPossibleObject(element, DN.MappedComponent);
+ return mappedElement != null ? graph.getPossibleObject(mappedElement, MOD.ElementToComponent) : null;
+ }
+
+ @Override
+ public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry,
+ Resource mapElement, Variable configuration) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
+ Variable activeVariable = org.simantics.db.layer0.variable.Variables.getPossibleVariable(graph, variableURI);
+ if (activeVariable == null)
+ return null;
+
+ Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
+ if (module == null)
+ return null;
+
+ Resource moduleType = graph.getPossibleType(module, STR.Component);
+ if (moduleType == null)
+ return null;
+
+ Function1<Variable, List<Tuple3>> function = getUCTextGridFunctionCached(graph, moduleType);
+ if (function == null)
+ return null;
+
+ List<Tuple3> result;
+ try {
+ Variable variable = Variables.getVariable(graph, module);
+ Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
+ if (moduleVariable == null)
+ moduleVariable = variable;
+
+ result = Simantics.applySCLRead(graph, function, moduleVariable);
+ } catch (PendingVariableException | MissingVariableValueException e) {
+ result = Collections.singletonList(new Tuple3("<pending>", "", ""));
+ } catch (MissingVariableException e) {
+ // the requested variable is missing from the UC
+ String message = e.getMessage();
+ LOGGER.warn("Missing variable for calculating style with function {} {}", function, message);
+ result = Collections.singletonList(new Tuple3("<" + message +">", "", ""));
+ }
+
+ Point2D point;
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ if (graph.isInstanceOf(mapElement, DN.Vertex)) {
+ double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
+ point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
+ }
+ else if (graph.isInstanceOf(mapElement, DN.Edge)) {
+ Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
+ double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
+ Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
+ double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
+ point = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2), null);
+ }
+ else {
+ return null;
+ }
+
+ return new StyleResult(point, result);
+ }
+
+ @Override
+ public void applyStyleForNode(EvaluationContext observer, INode parent, StyleResult results) {
+ if (results == null) {
+ cleanupStyleForNode(observer, parent);
+ return;
+ }
+
+ DistrictNetworkHoverInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkHoverInfoNode.NODE_KEY, DistrictNetworkHoverInfoNode.class, observer);
+ if (node == null)
+ return;
+
+ ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
+ if (root != null) {
+ DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", HOVER_INFO_DEFERRED, DeferredRenderingNode.class, observer);
+ deferred.setZIndex(Integer.MAX_VALUE);
+ }
+
+ node.setLabels(results.getLabels());
+ node.setOrigin(results.getOrigin());
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext observer, INode node) {
+ ProfileVariables.denyChild(node, "*", DistrictNetworkHoverInfoNode.NODE_KEY);
+ }
+
+ private static Function1<Variable, List<Tuple3>> getUCTextGridFunctionCached(ReadGraph graph, Resource componentType)
+ throws DatabaseException {
+ return graph.syncRequest(new UCTextGridFunctionRequest(componentType), TransientCacheListener.instance());
+ }
+
+ private static final class UCTextGridFunctionRequest extends ResourceRead<Function1<Variable, List<Tuple3>>> {
+ public UCTextGridFunctionRequest(Resource resource) {
+ super(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Function1<Variable, List<Tuple3>> perform(ReadGraph graph) throws DatabaseException {
+ Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
+ if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
+ return null;
+
+ String uri = graph.getURI(actionsModule);
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ sclContext.put("graph", graph);
+ return (Function1<Variable, List<Tuple3>>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, HOVER_CONTRIBUTION);
+ } catch (ValueNotFound e1) {
+ return null;
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.styles;
+
+import java.awt.geom.Point2D;
+import java.util.Set;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.exception.MissingVariableException;
+import org.simantics.db.layer0.exception.MissingVariableValueException;
+import org.simantics.db.layer0.exception.PendingVariableException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.diagram.profile.StyleBase;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.MidBranchEdgeSetRequest;
+import org.simantics.district.network.ui.nodes.DeferredRenderingNode;
+import org.simantics.district.network.ui.nodes.DistrictNetworkNodeUtils;
+import org.simantics.district.network.ui.nodes.DistrictNetworkStaticInfoNode;
+import org.simantics.layer0.Layer0;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.nodes.spatial.RTreeNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.simantics.scenegraph.utils.NodeUtil;
+import org.simantics.scl.compiler.top.ValueNotFound;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+public class DistrictNetworkStaticInfoStyle extends StyleBase<DistrictNetworkStaticInfoStyle.StyleResult> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkStaticInfoStyle.class);
+
+ private static final String ACTIONS_MODULE = "Actions";
+ private static final String PIPELINE_INFO = "pipelineInfo";
+
+ public static final String STATIC_INFO_DEFERRED = "staticInfo";
+
+ public static class StyleResult {
+ public StyleResult(Point2D p1, Point2D p2, String info) {
+ this.p1 = p1;
+ this.p2 = p2;
+ this.info = info;
+ }
+
+ public Point2D p1;
+ public Point2D p2;
+ public String info;
+ }
+
+ public DistrictNetworkStaticInfoStyle(Resource style) {
+ super(style);
+ }
+
+ @Override
+ public StyleResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource mapElement)
+ throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ boolean isEdge = graph.isInstanceOf(mapElement, DN.Edge);
+ boolean isVertex = graph.isInstanceOf(mapElement, DN.Vertex);
+ if (!isEdge && !isVertex)
+ return null;
+
+ if (isEdge) {
+ Resource diagram = graph.getSingleObject(mapElement, Layer0.getInstance(graph).PartOf);
+ Set<Resource> edgesToUse = graph.syncRequest(new MidBranchEdgeSetRequest(diagram), TransientCacheListener.instance());
+ if (!edgesToUse.contains(mapElement))
+ return null;
+ }
+
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+ Resource module = DistrictNetworkUtil.getMappedComponentCached(graph, mapElement);
+ if (module == null)
+ return null;
+
+ Resource moduleType = graph.getPossibleType(module, STR.Component);
+ if (moduleType == null)
+ return null;
+
+ Function1<Variable, String> function = getUCPipelineInfoFunctionCached(graph, moduleType);
+ if (function == null)
+ return null;
+
+ String result;
+ try {
+ Variable variable = Variables.getVariable(graph, module);
+ Variable moduleVariable = Variables.possibleActiveVariable(graph, variable);
+ if (moduleVariable == null)
+ moduleVariable = variable;
+
+ result = Simantics.applySCLRead(graph, function, moduleVariable);
+ } catch (PendingVariableException | MissingVariableValueException e) {
+ result = null;
+ } catch (MissingVariableException e) {
+ // the requested variable is missing from the UC
+ String message = e.getMessage();
+ LOGGER.warn("Missing variable for calculating style with function {} {}", function, message);
+ result = "<" + message + ">";
+ }
+
+ if (isVertex) {
+ double[] coords = graph.getRelatedValue(mapElement, DIA.HasLocation);
+ Point2D p = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords[0], coords[1]), null);
+ return new StyleResult(p, p, result);
+ }
+ else if (isEdge) {
+ Resource v1 = graph.getSingleObject(mapElement, DN.HasStartVertex);
+ double[] coords1 = graph.getRelatedValue(v1, DIA.HasLocation);
+ Resource v2 = graph.getSingleObject(mapElement, DN.HasEndVertex);
+ double[] coords2 = graph.getRelatedValue(v2, DIA.HasLocation);
+ Point2D p1 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords1[0], coords1[1]), null);
+ Point2D p2 = DistrictNetworkNodeUtils.calculatePoint2D(new Point2D.Double(coords2[0], coords2[1]), null);
+
+ return new StyleResult(p1, p2, result);
+ }
+
+ return null;
+ }
+
+ @Override
+ public void applyStyleForNode(EvaluationContext evaluationContext, INode parent, StyleResult result) {
+ if (result == null) {
+ cleanupStyleForNode(evaluationContext, parent);
+ return;
+ }
+
+ ParentNode<?> root = (ParentNode<?>) NodeUtil.getNearestParentOfType(parent, RTreeNode.class);
+ if (root != null) {
+ DeferredRenderingNode deferred = ProfileVariables.claimChild(root, "", STATIC_INFO_DEFERRED, DeferredRenderingNode.class, evaluationContext);
+ deferred.setZIndex(Integer.MAX_VALUE-1);
+ }
+
+ DistrictNetworkStaticInfoNode node = ProfileVariables.claimChild(parent, "*", DistrictNetworkStaticInfoNode.NODE_KEY, DistrictNetworkStaticInfoNode.class, evaluationContext);
+ if (node == null)
+ return;
+
+ Point2D p1 = result.p1;
+ Point2D p2 = result.p2;
+
+ if (p1.equals(p2)) {
+ node.setLocation(p1, new Point2D.Double(1.0, 0.0));
+ }
+ else {
+ double sign = Math.signum(p1.getX() - p2.getX());
+ Point2D.Double origin = new Point2D.Double(0.5 * (p1.getX() + p2.getX()), 0.5 * (p1.getY() + p2.getY()));
+ Point2D direction = new Point2D.Double(0.5 * sign * (p1.getX() - p2.getX()), 0.5 * sign * (p1.getY() - p2.getY()));
+
+ node.setLocation(origin, direction);
+ }
+
+ node.setInfo(result.info);
+ }
+
+ private static Function1<Variable, String> getUCPipelineInfoFunctionCached(ReadGraph graph, Resource componentType)
+ throws DatabaseException {
+ return graph.syncRequest(new UCPipelineInfoRequest(componentType), TransientCacheListener.instance());
+ }
+
+ private static final class UCPipelineInfoRequest extends ResourceRead<Function1<Variable, String>> {
+ public UCPipelineInfoRequest(Resource resource) {
+ super(resource);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Function1<Variable, String> perform(ReadGraph graph) throws DatabaseException {
+ Resource actionsModule = Layer0Utils.getPossibleChild(graph, resource, ACTIONS_MODULE);
+ if (actionsModule == null || !graph.isInstanceOf(actionsModule, Layer0.getInstance(graph).SCLModule))
+ return null;
+
+ String uri = graph.getURI(actionsModule);
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ sclContext.put("graph", graph);
+ return (Function1<Variable, String>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, PIPELINE_INFO);
+ } catch (ValueNotFound e1) {
+ return null;
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
+ ProfileVariables.denyChild(node, "*", DistrictNetworkStaticInfoNode.NODE_KEY);
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.styles;
+
+import java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ui.nodes.ElevationServerNode;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.scenegraph.g2d.IG2DNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.Group;
+import org.simantics.scenegraph.profile.Style;
+import org.simantics.scenegraph.profile.common.ObserverGroupListener;
+import org.simantics.scenegraph.utils.NodeUtil;
+
+public class ElevationRectangleStyle implements Style {
+
+ private ObserverGroupListener listener = null;
+ private double priority;
+
+ @Override
+ public void activate(RequestProcessor backend, Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer) throws DatabaseException {
+ if (listener != null && !listener.isDisposed())
+ return;
+ listener = new ObserverGroupListener(this, group, observer);
+ group.trackItems(backend, runtimeDiagram, listener);
+ }
+
+ @Override
+ public void deactivate(Resource runtimeDiagram, Resource entry, Group group, EvaluationContext observer) {
+ if (listener != null && !listener.isDisposed()) {
+ setRectangles(observer, Collections.emptyList());
+ listener.dispose();
+ observer.update();
+ }
+ }
+
+ @Override
+ public void apply(Resource entry, Group group, EvaluationContext observer) {
+ apply2(entry, observer);
+ }
+
+ @Override
+ public void apply2(Object item, EvaluationContext observer) {
+ setRectangles(observer, SingletonTiffTileInterface.getBoundingBoxes());
+ }
+
+ private void setRectangles(EvaluationContext observer, Collection<Rectangle2D> rectangles) {
+ IG2DNode node = NodeUtil.getNearestChildByClass(observer.getSceneGraph(), ElevationServerNode.class);
+ if (node != null) {
+ ((ElevationServerNode) node).setRectangles(rectangles);
+ }
+ }
+
+ @Override
+ public void setPriority(double priority) {
+ this.priority = priority;
+ }
+
+ @Override
+ public double getPriority() {
+ return priority;
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+
+public class ColumnHeaderTableDataProvider implements IDataProvider {
+
+ @Override
+ public Object getDataValue(int columnIndex, int rowIndex) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public int getColumnCount() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int getRowCount() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import java.util.Set;
+
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.coordinate.Range;
+import org.eclipse.nebula.widgets.nattable.ui.action.IKeyAction;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.events.KeyEvent;
+
+public class CustomPasteDataAction implements IKeyAction {
+
+ private DistrictCSVTable table;
+
+ public CustomPasteDataAction(DistrictCSVTable table) {
+ this.table = table;
+ }
+
+ @Override
+ public void run(NatTable natTable, KeyEvent event) {
+ Object data = table.cpb.getContents(TextTransfer.getInstance());
+ if (data instanceof String) {
+ String textData = (String) data;
+ String[][] fullData = computeData(textData);
+
+ int[] cols = table.selectionLayer.getSelectedColumnPositions();
+ int firstCol = cols[0];
+ int column = table.selectionLayer.getColumnIndexByPosition(firstCol);
+ Set<Range> ranges = table.selectionLayer.getSelectedRowPositions();
+ if (!ranges.isEmpty()) {
+ int rowPosition = ranges.iterator().next().start;
+ int[] columns = new int[fullData.length];
+ columns[0] = column;
+ for (int i = 1; i < fullData.length; i++)
+ columns[i] = table.selectionLayer.getColumnIndexByPosition(firstCol + i);
+ table.bodyDataLayer.doCommand(new CustomPasteDataCommand(table.bodyDataLayer, columns, rowPosition, fullData));
+ }
+ }
+ }
+
+ private static String[][] computeData(String textData) {
+ String separator;
+ if (textData.contains(",") && !textData.contains(";")) {
+ separator = ",";
+ } else if (textData.contains(";") && !textData.contains("\t")) {
+ separator = ";";
+ } else {
+ separator = "\\t";
+ }
+
+ textData = textData.replaceAll("\\r", "");
+
+ String[] rows = textData.split("\\n");
+
+ String[][] cells = new String[rows.length][];
+ for(int i=0;i<rows.length;++i)
+ cells[i] = rows[i].split(separator, -1);
+
+ String[][] fullData = cells; //transpose(cells);
+
+ return fullData;
+ }
+
+ private static String[][] transpose(String[][] cells) {
+ int rowCount = 0;
+ for(String[] cols : cells)
+ rowCount = Math.max(rowCount, cols.length);
+ String[][] result = new String[rowCount][cells.length];
+ for(int i=0;i<cells.length;++i) {
+ String[] cols = cells[i];
+ int j;
+ for(j=0;j<cols.length;++j)
+ result[j][i] = cols[j];
+ for(;j<rowCount;++j)
+ result[j][i] = "";
+ }
+ return result;
+
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractMultiColumnCommand;
+import org.eclipse.nebula.widgets.nattable.command.ILayerCommand;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+
+public class CustomPasteDataCommand extends AbstractMultiColumnCommand {
+
+ int pasteRow;
+ String[][] data;
+
+ protected CustomPasteDataCommand(ILayer layer, int[] columnPositions, int pasteRow, String[][] data) {
+ super(layer, columnPositions);
+ this.pasteRow = pasteRow;
+ this.data = data;
+ }
+
+ protected CustomPasteDataCommand(CustomPasteDataCommand pasteDataCommand) {
+ super(pasteDataCommand);
+ this.pasteRow = pasteDataCommand.pasteRow;
+ this.data = pasteDataCommand.data;
+ }
+ @Override
+ public ILayerCommand cloneCommand() {
+ return new CustomPasteDataCommand(this);
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.copy.command.CopyDataCommandHandler;
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+import org.eclipse.nebula.widgets.nattable.freeze.CompositeFreezeLayer;
+import org.eclipse.nebula.widgets.nattable.freeze.FreezeLayer;
+import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultColumnHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.DefaultRowHeaderDataLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.group.ColumnGroupHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.group.ColumnGroupModel;
+import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
+import org.eclipse.nebula.widgets.nattable.hover.HoverLayer;
+import org.eclipse.nebula.widgets.nattable.hover.config.BodyHoverStylingBindings;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.ILayer;
+import org.eclipse.nebula.widgets.nattable.layer.IUniqueIndexLayer;
+import org.eclipse.nebula.widgets.nattable.reorder.RowReorderLayer;
+import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
+import org.eclipse.nebula.widgets.nattable.ui.matcher.KeyEventMatcher;
+import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Composite;
+
+public class DistrictCSVTable extends Composite {
+
+ NatTable table;
+ private TableDataProvider bodyDataProvider;
+ DataLayer bodyDataLayer;
+ private IConfigRegistry summaryConfigRegistry;
+ private IUniqueIndexLayer summaryRowLayer;
+ private ViewportLayer viewportLayer;
+ private CompositeFreezeLayer compositeFreezeLayer;
+ private FreezeLayer freezeLayer;
+ //private TableDataSortModel sortModel;
+ private ColumnHideShowLayer columnHideShowLayer;
+ private ColumnGroupModel columnGroupModel = new ColumnGroupModel();
+ private ColumnHeaderTableDataProvider columnHeaderDataProvider;
+ Clipboard cpb;
+ public SelectionLayer selectionLayer;
+
+ public DistrictCSVTable(Composite parent, int style) {
+ super(parent, style);
+ defaultInitializeUI();
+ }
+
+ private void defaultInitializeUI() {
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(this);
+ createTable(this);
+ }
+
+ private void createTable(Composite parent) {
+
+ // build the body layer stack
+ // Usually you would create a new layer stack by extending AbstractIndexLayerTransform and
+ // setting the ViewportLayer as underlying layer. But in this case using the ViewportLayer
+ // directly as body layer is also working.
+ bodyDataProvider = new TableDataProvider();
+ bodyDataLayer = new DataLayer(bodyDataProvider);
+
+ RowReorderLayer rowReorderLayer =
+ new RowReorderLayer(columnHideShowLayer = new ColumnHideShowLayer(bodyDataLayer));
+
+ HoverLayer hoverLayer = new HoverLayer(rowReorderLayer, false);
+ // we need to ensure that the hover styling is removed when the mouse
+ // cursor moves out of the cell area
+ hoverLayer.addConfiguration(new BodyHoverStylingBindings(hoverLayer));
+
+ selectionLayer = new SelectionLayer(hoverLayer);
+ viewportLayer = new ViewportLayer(selectionLayer);
+ viewportLayer.setRegionName(GridRegion.BODY);
+ freezeLayer = new FreezeLayer(selectionLayer);
+ compositeFreezeLayer = new CompositeFreezeLayer(freezeLayer, viewportLayer, selectionLayer);
+
+ // build the column header layer
+ columnHeaderDataProvider = new ColumnHeaderTableDataProvider();
+ DataLayer columnHeaderDataLayer = new DefaultColumnHeaderDataLayer(columnHeaderDataProvider);
+ columnHeaderDataLayer.setRowsResizableByDefault(false);
+ columnHeaderDataLayer.setColumnsResizableByDefault(true);
+ ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(columnHeaderDataLayer, compositeFreezeLayer, selectionLayer);
+ ColumnGroupHeaderLayer columnGroupHeaderLayer = new ColumnGroupHeaderLayer(columnHeaderLayer, selectionLayer, columnGroupModel);
+ columnGroupHeaderLayer.setCalculateHeight(true);
+
+ // build the row header layer
+ IDataProvider rowHeaderDataProvider = new RowHeaderTableDataProvider(bodyDataProvider);
+ DataLayer rowHeaderDataLayer = new DefaultRowHeaderDataLayer(rowHeaderDataProvider);
+ rowHeaderDataLayer.setRowsResizableByDefault(false);
+ rowHeaderDataLayer.setColumnsResizableByDefault(false);
+ RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer, compositeFreezeLayer, selectionLayer);
+
+ // build the corner layer
+ IDataProvider cornerDataProvider = new DefaultCornerDataProvider(columnHeaderDataProvider, rowHeaderDataProvider);
+ DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
+ ILayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, columnGroupHeaderLayer);
+
+ // build the grid layer
+ GridLayer gridLayer = new GridLayer(compositeFreezeLayer, columnGroupHeaderLayer, rowHeaderLayer, cornerLayer);
+
+ table = new NatTable(parent, NatTable.DEFAULT_STYLE_OPTIONS | SWT.BORDER, gridLayer, false);
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(table);
+
+ // Register a CopyDataCommandHandler that also copies the headers and
+ // uses the configured IDisplayConverters
+ CopyDataCommandHandler copyHandler = new CopyDataCommandHandler(
+ selectionLayer,
+ columnHeaderDataLayer,
+ rowHeaderDataLayer);
+ copyHandler.setCopyFormattedText(true);
+ gridLayer.registerCommandHandler(copyHandler);
+
+ // initialize paste handler with SWT clipboard
+ cpb = new Clipboard(getDisplay());
+ PasteDataCommandHandler pasteHandler = new PasteDataCommandHandler(bodyDataProvider, bodyDataLayer, selectionLayer, cpb);
+ bodyDataLayer.registerCommandHandler(pasteHandler);
+
+ table.addConfiguration(new DefaultNatTableStyleConfiguration());
+ table.addConfiguration(new EditingSupportConfiguration(bodyDataProvider));
+
+ table.addConfiguration(new AbstractRegistryConfiguration() {
+
+ @Override
+ public void configureRegistry(IConfigRegistry configRegistry) {
+ }
+
+ @Override
+ public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
+ super.configureUiBindings(uiBindingRegistry);
+ // ui binding to perform a paste action on pressing CTRL+V
+ uiBindingRegistry.registerFirstKeyBinding(new KeyEventMatcher(SWT.MOD1, 'v'), new CustomPasteDataAction(DistrictCSVTable.this));
+ }
+ });
+
+ table.configure();
+ }
+
+ @Override
+ public void dispose() {
+ cpb.dispose();
+ super.dispose();
+ }
+
+ public String[][] getCurrentData() {
+ return bodyDataProvider.getCurrentData();
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class DistrictCSVTableUI extends Composite {
+
+ public DistrictCSVTableUI(Composite parent, int style) {
+ super(parent, style);
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.swt.widgets.Composite;
+
+public class DistrictCSVTableView {
+
+ @Inject ESelectionService selectionService;
+
+ private DistrictCSVTable table;
+
+ @Inject
+ public void init(MPart part, MApplication app) {
+ MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar();
+ toolBar.setToBeRendered(true);
+ toolBar.getChildren().add(createImportCSVDataToolItem(app));
+ part.setToolbar(toolBar);
+ }
+
+ private MHandledToolItem createImportCSVDataToolItem(MApplication app) {
+ MHandledToolItem createHandledToolItem = MMenuFactory.INSTANCE.createHandledToolItem();
+ // Command is contributed via fragment
+ createHandledToolItem.setCommand(app.getCommand("org.simantics.district.network.ui.command.importcsv")); //$NON-NLS-1$
+ createHandledToolItem.setLabel("Import CSV");
+ createHandledToolItem.setIconURI("platform:/plugin/com.famfamfam.silk/icons/table_edit.png"); //$NON-NLS-1$
+ return createHandledToolItem;
+ }
+
+ @PostConstruct
+ public void postConstruct(Composite parent) {
+ table = new DistrictCSVTable(parent, 0);
+
+ }
+
+ @PreDestroy
+ public void dispose() {
+ table.dispose();
+ table = null;
+ }
+
+ public String[][] getCurrentData() {
+ return table.getCurrentData();
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
+import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
+import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
+
+public class EditingSupportConfiguration extends AbstractRegistryConfiguration {
+
+ private TableDataProvider bodyDataProvider;
+
+ public EditingSupportConfiguration(TableDataProvider bodyDataProvider) {
+ this.bodyDataProvider = bodyDataProvider;
+ }
+
+ @Override
+ public void configureRegistry(IConfigRegistry configRegistry) {
+ configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, new IEditableRule() {
+ @Override
+ public boolean isEditable(ILayerCell cell, IConfigRegistry configRegistry) {
+ return bodyDataProvider.isEditable(cell.getColumnIndex(), cell.getRowIndex());
+ }
+
+ @Override
+ public boolean isEditable(int columnIndex, int rowIndex) {
+ return bodyDataProvider.isEditable(columnIndex, rowIndex);
+ }
+ });
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.SelectionStatusDialog;
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.IndexRoot;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ui.function.Functions;
+import org.simantics.modeling.ModelingResources;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ImportCSVHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ImportCSVHandler.class);
+
+ @Inject
+ EPartService partService;
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell s) {
+ // here we can import based on the current CSV table data
+ MPart activePart = partService.getActivePart();
+ Object object = activePart.getObject();
+ // this object is the part wrapped by e4part
+ DistrictCSVTableView view = (DistrictCSVTableView) object;
+ String[][] data = view.getCurrentData();
+
+ SelectionDialog d = new SelectionDialog(s);
+
+ if (d.open() == Dialog.CANCEL)
+ return;
+
+ String sourceEPSGCRS = d.getSourceCRS();//"EPSG:3067";
+
+ Resource targetDiagram = d.getTargetDiagram();
+ Resource mappingType = d.getMappingType();
+
+ try {
+ MathTransform transform = null;
+ boolean doTransform = false;
+ // if sourceEPSGCRS is empty || null then ignore transformation
+ if (sourceEPSGCRS != null && !sourceEPSGCRS.isEmpty()) {
+ CoordinateReferenceSystem sourceCRS = CRS.decode(sourceEPSGCRS);
+ CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
+ transform = CRS.findMathTransform(sourceCRS, targetCRS, false);
+ doTransform = true;
+ }
+
+ final MathTransform finalTransform = transform;
+
+ int x = xColumn(data);
+ int y = yColumn(data);
+ int z = zColumn(data);
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ for (int i = 1; i < data.length; i++) {
+ try {
+ String[] rows = data[i];
+ String xCoords = rows[x];
+ String yCoords = rows[y];
+ double xCoord = Double.parseDouble(xCoords);
+ double yCoord = Double.parseDouble(yCoords);
+ DirectPosition2D targetPos = new DirectPosition2D();
+ DirectPosition2D sourcePos = new DirectPosition2D(xCoord, yCoord);
+ DirectPosition res = finalTransform.transform(sourcePos, targetPos);
+ double[] coords = res.getCoordinate();
+ flipAxes(coords);
+ Resource vertex = DistrictNetworkUtil.createVertex(graph, targetDiagram, coords, z, mappingType);
+ } catch (Exception e) {
+ LOGGER.error("", e);
+ }
+ }
+ }
+ });
+ } catch (Exception e) {
+ LOGGER.error("", e);
+ }
+
+
+ }
+
+ private static void flipAxes(double[] coords) {
+ double tmp = coords[0];
+ coords[0] = coords[1];
+ coords[1] = tmp;
+ }
+
+
+ private int zColumn(String[][] data) {
+ return column("z", data);
+ }
+
+ private int yColumn(String[][] data) {
+ return column("y", data);
+ }
+
+ private int xColumn(String[][] data) {
+ return column("x", data);
+ }
+
+ private int column(String expected, String[][] data) {
+ String[] columns = data[0]; // first row should be headers
+ for (int i = 0; i < columns.length; i++) {
+ String col = columns[i];
+ if (col.equals(expected)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static class SelectionDialog extends SelectionStatusDialog {
+
+ private Map<String, Resource> diagrams = new HashMap<>();
+ private Map<String, Resource> vertexMappings = new HashMap<>();
+
+ private Composite composite;
+ private Combo networkDiagramSelectionCombo;
+ private Combo sourceCRSCombo;
+ private Combo vertexMappingCombo;
+ private String sourceCRS;
+ private Resource diagram;
+ private Resource mapping;
+
+ public SelectionDialog(Shell parent) {
+ super(parent);
+ }
+
+ public Resource getMappingType() {
+ return mapping;
+ }
+
+ public Resource getTargetDiagram() {
+ return diagram;
+ }
+
+ public String getSourceCRS() {
+ return "EPSG:" + sourceCRS;
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ composite = (Composite) super.createDialogArea(parent);
+ createMappingsGroup(composite);
+ computeContent();
+ return composite;
+ }
+
+ private void computeContent() {
+ Simantics.getSession().asyncRequest(new ReadRequest() {
+
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+
+ Resource indexRoot = graph.sync(new IndexRoot(graph.sync(new PossibleActiveModel(Simantics.getProjectResource()))));
+ vertexMappings = Functions.getVertexMappings(graph, indexRoot);
+
+ Collection<Resource> diagramss = Functions.getDistrictDiagrams(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource projectResource = Simantics.getProjectResource();
+ String projectURI = graph.getURI(projectResource);
+ for (Resource diagram : diagramss) {
+ Resource composite = graph.getSingleObject(diagram, MOD.DiagramToComposite);
+ String compositeURI = graph.getURI(composite);
+ String path = compositeURI.replace(projectURI, "");
+ diagrams.put(path, diagram);
+ }
+
+ composite.getDisplay().asyncExec(() -> {
+
+ vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
+
+ networkDiagramSelectionCombo.setItems(diagrams.keySet().toArray(new String[diagrams.size()]));
+ if (diagrams.size() > 0) {
+ networkDiagramSelectionCombo.select(0);
+ }
+ Set<String> codes = CRS.getSupportedCodes("EPSG");
+ sourceCRSCombo.setItems(codes.toArray(new String[codes.size()]));
+ sourceCRSCombo.addModifyListener(new ModifyListener() {
+
+ @Override
+ public void modifyText(ModifyEvent e) {
+ String currentText = sourceCRSCombo.getText();
+ if (codes.contains(currentText)) {
+ // Select this
+ String[] items = sourceCRSCombo.getItems();
+ int i;
+ for (i = 0; i < items.length; i++) {
+ String item = items[i];
+ if (currentText.equals(item)) {
+ break;
+ }
+ }
+ if (i != 0) {
+ sourceCRSCombo.select(i);
+ } else {
+ System.err.println("Should not happen");
+ }
+ }
+ }
+ });
+ });
+ }
+ });
+ }
+
+ private void createMappingsGroup(Composite parent) {
+ Group group= new Group(parent, SWT.NONE);
+ group.setFont(parent.getFont());
+ group.setText("Select Diagram & CRS");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ group.setLayout(new GridLayout(1, false));
+
+ Composite cmposite = new Composite(group, SWT.NONE);
+ cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ cmposite.setLayout(new GridLayout(2, false));
+
+ Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
+ vertexMappingLabel.setText("Select Vertex Mapping");
+
+ vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
+
+ Label selectNetworkDiagramLabel = new Label(cmposite, SWT.NONE);
+ selectNetworkDiagramLabel.setText("Select Network Diagram");
+
+ networkDiagramSelectionCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(networkDiagramSelectionCombo);
+
+ Label label = new Label(cmposite, SWT.NONE);
+ label.setText("Select Source Coordinate Reference System");
+
+ sourceCRSCombo = new Combo(cmposite, SWT.NONE);
+ sourceCRSCombo.setToolTipText("Select the coordinate reference system that is used in the source material for possible transformation to target coordinate reference system (EPSG:4326)");
+
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(sourceCRSCombo);
+ }
+
+ @Override
+ protected void computeResult() {
+ mapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex()));
+ diagram = diagrams.get(networkDiagramSelectionCombo.getItem(networkDiagramSelectionCombo.getSelectionIndex()));
+ sourceCRS = sourceCRSCombo.getItem(sourceCRSCombo.getSelectionIndex());
+ }
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import java.util.Collection;
+
+import org.eclipse.nebula.widgets.nattable.command.AbstractLayerCommandHandler;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.event.ColumnVisualUpdateEvent;
+import org.eclipse.nebula.widgets.nattable.layer.event.StructuralRefreshEvent;
+import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PasteDataCommandHandler extends AbstractLayerCommandHandler<CustomPasteDataCommand> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(PasteDataCommandHandler.class);
+
+ private final SelectionLayer selectionLayer;
+ private final DataLayer dataLayer;
+ private final Clipboard cpb;
+ private final TableDataProvider provider;
+
+ public PasteDataCommandHandler(TableDataProvider provider, DataLayer dataLayer, SelectionLayer selectionLayer, Clipboard cpb) {
+ this.provider = provider;
+ this.dataLayer = dataLayer;
+ this.selectionLayer = selectionLayer;
+ this.cpb = cpb;
+ }
+
+ @Override
+ public Class<CustomPasteDataCommand> getCommandClass() {
+ return CustomPasteDataCommand.class;
+ }
+
+ @Override
+ protected boolean doCommand(CustomPasteDataCommand command) {
+ String[][] fullData = command.data;
+ int pasteRow = command.pasteRow;
+ Collection<Integer> pasteColumn = command.getColumnPositions();
+ if (pasteRow > -1) {
+ provider.setDataValues(pasteColumn, pasteRow, fullData);
+ dataLayer.fireLayerEvent(new StructuralRefreshEvent(dataLayer));
+ }
+ return true;
+ }
+}
+
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+
+public class RowHeaderTableDataProvider implements IDataProvider {
+
+ protected final IDataProvider bodyDataProvider;
+
+ public RowHeaderTableDataProvider(IDataProvider bodyDataProvider) {
+ this.bodyDataProvider = bodyDataProvider;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return 1;
+ }
+
+ @Override
+ public int getRowCount() {
+ return this.bodyDataProvider.getRowCount();
+ }
+
+ @Override
+ public Object getDataValue(int columnIndex, int rowIndex) {
+ return Integer.valueOf(rowIndex + 1);
+ }
+
+ @Override
+ public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.table;
+
+import java.util.Collection;
+
+import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
+
+public class TableDataProvider implements IDataProvider {
+
+ private String[][] data = null;
+
+ @Override
+ public Object getDataValue(int columnIndex, int rowIndex) {
+ if (data == null) {
+ return null;
+ } else {
+ return data[rowIndex][columnIndex];
+ }
+ }
+
+ @Override
+ public void setDataValue(int columnIndex, int rowIndex, Object newValue) {
+
+ }
+
+ @Override
+ public int getColumnCount() {
+ if (data == null) {
+ return 10;
+ } else {
+ return data[0].length;
+ }
+ }
+
+ @Override
+ public int getRowCount() {
+ if (data == null) {
+ return 10;
+ } else {
+ return data.length;
+ }
+ }
+
+ public boolean isEditable(int columnIndex, int rowIndex) {
+ return false;
+ }
+
+ public void setDataValues(Collection<Integer> pasteColumn, int pasteRow, String[][] fullData) {
+ // start always from row index 0 and column index 0
+ this.data = fullData;
+ }
+
+ public String[][] getCurrentData() {
+ return data;
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.ui.visualisations;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.Listener;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.profile.ActiveDynamicVisualisationsRequest;
+import org.simantics.district.network.profile.DynamicVisualisationsRequest;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicColoringObject;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions.DynamicSizingObject;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
+import org.simantics.ui.workbench.IResourceEditorPart;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicVisualisationsUI extends Composite {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsUI.class);
+
+ private Resource diagramResource;
+ private VisualisationListener listener;
+ private DynamicVisualisation visualisation;
+
+ private Button showSizeButton;
+ private Button sizeTicksButton;
+ private Combo sizeLocationCombo;
+ private Combo sizeSizeCombo;
+ private Button showColorButton;
+ private Button colorTicksButton;
+ private Combo colorLocationCombo;
+ private Combo colorSizeCombo;
+
+ private Combo templateSelectionCombo;
+
+ private List<Supplier<Pair<String, DynamicColorContribution>>> colorSuppliers;
+
+ public DynamicVisualisationsUI(Composite parent, int style) {
+ super(parent, style);
+
+ defaultInitializeUI();
+ }
+
+ private void defaultInitializeUI() {
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(this);
+ GridLayoutFactory.fillDefaults().numColumns(1).margins(5, 5).applyTo(this);
+
+ Composite selectionComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(selectionComposite);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(selectionComposite);
+
+ Label templateNameLabel = new Label(selectionComposite, SWT.NONE);
+ templateNameLabel.setText("Visualisation template");
+ templateSelectionCombo = new Combo(selectionComposite, SWT.READ_ONLY);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(templateSelectionCombo);
+ templateSelectionCombo.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String item = templateSelectionCombo.getItem(templateSelectionCombo.getSelectionIndex());
+ for (NamedResource template : visualisations) {
+ if (item.equals(template.getName())) {
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setActiveVisualisation(graph, diagramResource, template.getResource());
+ }
+ });
+ break;
+ }
+ }
+ }
+ });
+
+ Composite coloringObjectsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(coloringObjectsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(coloringObjectsComposite);
+ initializeColoringObjects(coloringObjectsComposite);
+
+ Composite colorBarsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(colorBarsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(colorBarsComposite);
+ initializeColorBars(colorBarsComposite);
+
+ Composite objectSizesComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(objectSizesComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(objectSizesComposite);
+ initializeObjectSizes(objectSizesComposite);
+
+ Composite sizeBarsComposite = new Composite(this, SWT.NONE);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(sizeBarsComposite);
+ GridLayoutFactory.fillDefaults().numColumns(1).applyTo(sizeBarsComposite);
+ initializeSizeBars(sizeBarsComposite);
+
+ Button saveVisualisationTemplateButton = new Button(this, SWT.NONE);
+ saveVisualisationTemplateButton.setText("Save");
+ saveVisualisationTemplateButton.setEnabled(visualisation == null || visualisation.getVisualisationResource() != null);
+ saveVisualisationTemplateButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ persistVisualisationTemplate(visualisation.getName(), Optional.of(visualisation.getVisualisationResource()));
+ }
+ });
+
+ Button saveVisualisationTemplateAsButton = new Button(this, SWT.NONE);
+ saveVisualisationTemplateAsButton.setText("Save as visualisation template");
+ saveVisualisationTemplateAsButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ showSaveVisualisationTemplateDialog(e.widget.getDisplay().getActiveShell());
+ }
+ });
+
+ }
+
+ private void showSaveVisualisationTemplateDialog(Shell shell) {
+
+ InputDialog dialog = new InputDialog(shell, "Save visualisation template", "Give template a name", "", new IInputValidator() {
+
+ @Override
+ public String isValid(String newText) {
+ if (newText == null || newText.isEmpty())
+ return "Name cannot be empty";
+ return null;
+ }
+ });
+
+ if (dialog.open() == Dialog.OK) {
+ String name = dialog.getValue();
+ persistVisualisationTemplate(name, Optional.empty());
+ }
+ }
+
+ private void persistVisualisationTemplate(String templateName, Optional<Resource> existing) {
+
+ List<Pair<String, DynamicColorContribution>> colorCollect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+
+ String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
+ String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
+
+ ColorBarOptions colorBarOptions = new ColorBarOptions()
+ .showColorBars(showColorButton.getSelection())
+ .showColorBarsTicks(colorTicksButton.getSelection())
+ .withLocation(ColorBarsLocation.valueOf(colorLocation))
+ .withSize(ColorBarsSize.valueOf(colorSize));
+
+ List<Pair<String, DynamicSizeContribution>> sizeCollect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+
+ String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
+ String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
+
+ SizeBarOptions sizeBarOptions = new SizeBarOptions()
+ .showSizeBars(showSizeButton.getSelection())
+ .showSizeBarsTicks(sizeTicksButton.getSelection())
+ .withLocation(SizeBarsLocation.valueOf(sizeLocation))
+ .withSize(SizeBarsSize.valueOf(sizeSize));
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource exist;
+ if (existing.isPresent()) {
+ exist = existing.get();
+ } else {
+ exist = DistrictNetworkUtil.createVisualisation(graph, diagramResource, templateName);
+ }
+
+ DistrictNetworkUtil.setColorContributions(graph, exist, colorCollect);
+
+ DistrictNetworkUtil.setColorBarOptions(graph, exist, colorBarOptions);
+ DistrictNetworkUtil.setSizeContributions(graph, exist, sizeCollect);
+ DistrictNetworkUtil.setSizeBarOptions(graph, exist, sizeBarOptions);
+ }
+ });
+ }
+
+ private void initializeColoringObjects(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Coloring Objects");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
+
+ {
+ createColoringObjectHeaderRow(group);
+ }
+ colorSuppliers = new ArrayList<>();
+ {
+ try {
+ Collection<DynamicColoringObject> result = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicColoringObject>>() {
+
+ @Override
+ public Collection<DynamicColoringObject> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicColoringObjects(graph);
+ }
+ });
+
+ for (DynamicColoringObject object : result) {
+ colorSuppliers.add(createColoringObjectRow(group, object));
+ }
+
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not create coloring objecst", e);
+ }
+ }
+ {
+ Button applyButton = new Button(group, SWT.NONE);
+ applyButton.setText("Apply");
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ List<Pair<String, DynamicColorContribution>> collect = colorSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setColorContributions(graph, visualisation.getVisualisationResource(), collect);
+ }
+ });
+ }
+ });
+ }
+ }
+
+ private void createColoringObjectHeaderRow(Composite parent) {
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Label");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Used");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Variable");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Min");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Max");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Unit");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("ColorMap");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Default");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+ }
+
+ private Map<String, ColoringObjectRow> coloringRows = new HashMap<>();
+ private Map<String, SizingObjectRow> sizingRows = new HashMap<>();
+
+ private VisualisationsListener visualisationsListener;
+
+ private Collection<NamedResource> visualisations;
+
+ private List<Supplier<Pair<String, DynamicSizeContribution>>> sizeSuppliers;
+
+ private static class ColoringObjectRow {
+
+ private final Label label;
+ private final Button usedButton;
+ private final Combo variableCombo;
+ private final Text minText;
+ private final Text maxText;
+ private final Label unit;
+ private final Combo colorMapCombo;
+ private final Button defaultButton;
+
+ public ColoringObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
+ Combo colorMapCombo, Button defaultButton) {
+ super();
+ this.label = label;
+ this.usedButton = usedButton;
+ this.variableCombo = variableCombo;
+ this.minText = minText;
+ this.maxText = maxText;
+ this.unit = unit;
+ this.colorMapCombo = colorMapCombo;
+ this.defaultButton = defaultButton;
+ }
+
+ public void update(DynamicColorContribution colorContribution) {
+ String[] items = variableCombo.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (colorContribution.getLabel().equals(items[i])) {
+ variableCombo.select(i);
+ break;
+ }
+ }
+ minText.setText(Double.toString(colorContribution.getDefaultMin()));
+ maxText.setText(Double.toString(colorContribution.getDefaultMax()));
+ unit.setText(colorContribution.getUnit());
+
+ // color map only supports single for now
+ colorMapCombo.setItems(colorContribution.getDefaultColorMap().getLabel());
+ colorMapCombo.select(0);
+// String[] colorItems = colorMapCombo.getItems();
+// for (int i = 0; i < colorItems.length; i++) {
+//
+// if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
+// colorMapCombo.select(i);
+// break;
+// }
+// }
+ usedButton.setSelection(colorContribution.isUsed());
+ defaultButton.setSelection(colorContribution.isUseDefault());
+
+ minText.setEnabled(!colorContribution.isUseDefault());
+ maxText.setEnabled(!colorContribution.isUseDefault());
+ colorMapCombo.setEnabled(!colorContribution.isUseDefault());
+ }
+ }
+
+ private static class SizingObjectRow {
+
+ private final Label label;
+ private final Button usedButton;
+ private final Combo variableCombo;
+ private final Text minText;
+ private final Text maxText;
+ private final Label unit;
+ private final Combo sizeMapCombo;
+ private final Button defaultButton;
+
+ public SizingObjectRow(Label label, Button usedButton, Combo variableCombo, Text minText, Text maxText, Label unit,
+ Combo sizeMapCombo, Button defaultButton) {
+ super();
+ this.label = label;
+ this.usedButton = usedButton;
+ this.variableCombo = variableCombo;
+ this.minText = minText;
+ this.maxText = maxText;
+ this.unit = unit;
+ this.sizeMapCombo = sizeMapCombo;
+ this.defaultButton = defaultButton;
+ }
+
+ public void update(DynamicSizeContribution sizeContribution) {
+ String[] items = variableCombo.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (sizeContribution.getLabel().equals(items[i])) {
+ variableCombo.select(i);
+ break;
+ }
+ }
+ minText.setText(Double.toString(sizeContribution.getDefaultMin()));
+ maxText.setText(Double.toString(sizeContribution.getDefaultMax()));
+ unit.setText(sizeContribution.getUnit());
+
+ // color map only supports single for now
+ sizeMapCombo.setItems(sizeContribution.getDefaultSizeMap().getLabel());
+ sizeMapCombo.select(0);
+// String[] colorItems = colorMapCombo.getItems();
+// for (int i = 0; i < colorItems.length; i++) {
+//
+// if (colorContribution.getDefaultColorMap().getLabel().equals(colorItems[i])) {
+// colorMapCombo.select(i);
+// break;
+// }
+// }
+ }
+ }
+
+ private Supplier<Pair<String, DynamicColorContribution>> createColoringObjectRow(Composite parent, DynamicColoringObject object) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(object.getColoringObject().getName());
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ Map<String, DynamicColorContribution> colorContributions = object.getColorContributions();
+
+ Button usedButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
+
+ Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
+ variableCombo.setItems(colorContributions.keySet().toArray(new String[colorContributions.size()]));
+
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
+
+ Text minText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(minText);
+
+ Text maxText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).hint(150, SWT.DEFAULT).align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
+
+ Label unit = new Label(parent, SWT.NONE);
+ unit.setText("");
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
+
+ Combo colorMapCombo = new Combo(parent, SWT.READ_ONLY);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(colorMapCombo);
+
+ Button defaultButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
+ defaultButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ int index = variableCombo.getSelectionIndex();
+ if (index >= 0) {
+ String key = variableCombo.getItem(index);
+ DynamicColorContribution cont = colorContributions.get(key);
+
+ minText.setText(Double.toString(cont.getDefaultMin()));
+ minText.setEnabled(!defaultButton.getSelection());
+ maxText.setText(Double.toString(cont.getDefaultMax()));
+ maxText.setEnabled(!defaultButton.getSelection());
+ unit.setText(cont.getUnit());
+
+ colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
+ colorMapCombo.select(0);
+ colorMapCombo.setEnabled(!defaultButton.getSelection());
+ }
+ }
+ });
+
+ variableCombo.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // handle update for others
+ int index = variableCombo.getSelectionIndex();
+ if (index >= 0) {
+ String key = variableCombo.getItem(index);
+ DynamicColorContribution cont = colorContributions.get(key);
+
+ if (minText.getText().isEmpty()) {
+ minText.setText(Double.toString(cont.getDefaultMin()));
+ }
+ if (maxText.getText().isEmpty()) {
+ maxText.setText(Double.toString(cont.getDefaultMax()));
+ }
+ unit.setText(cont.getUnit());
+
+ colorMapCombo.setItems(cont.getDefaultColorMap().getLabel());
+ colorMapCombo.select(0);
+
+ defaultButton.setSelection(true);
+ }
+ }
+ });
+
+ coloringRows.put(object.getColoringObject().getName(), new ColoringObjectRow(label, usedButton, variableCombo, minText, maxText, unit, colorMapCombo, defaultButton));
+
+ return new Supplier<Pair<String, DynamicColorContribution>>() {
+
+ @Override
+ public Pair<String, DynamicColorContribution> get() {
+ int selectionIndex = variableCombo.getSelectionIndex();
+ if (selectionIndex >= 0) {
+ String key = variableCombo.getItem(selectionIndex);
+ DynamicColorContribution cont = colorContributions.get(key);
+ if (cont != null) {
+ String colorMap = colorMapCombo.getItem(colorMapCombo.getSelectionIndex());
+ try {
+ Map<String, DynamicColorMap> colorMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicColorMap>>() {
+
+ @Override
+ public Map<String, DynamicColorMap> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicColorMaps(graph);
+ }
+ });
+ DynamicColorMap dColorMap = colorMaps.get(colorMap);
+ String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+
+ DynamicColorContribution dcc = new DynamicColorContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+ dcc.setUsed(usedButton.getSelection());
+ dcc.setUseDefault(defaultButton.getSelection());
+
+ return Pair.make(object.getColoringObject().getName(), dcc);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not get DynamicColorContribution", e);
+ }
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ private void createSizingObjectHeaderRow(Composite parent) {
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Label");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Used");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Variable");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Min");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Max");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Unit");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("SizeMap");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Default");
+ GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.CENTER).applyTo(label);
+ }
+
+ private Supplier<Pair<String, DynamicSizeContribution>> createSizingObjectRow(Composite parent, DynamicSizingObject object) {
+ Label label = new Label(parent, SWT.NONE);
+ label.setText(object.getSizingObject().getName());
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(label);
+
+ Map<String, DynamicSizeContribution> sizeContributions = object.getSizeContributions();
+
+ Button usedButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(usedButton);
+
+ Combo variableCombo = new Combo(parent, SWT.READ_ONLY);
+ variableCombo.setItems(sizeContributions.keySet().toArray(new String[sizeContributions.size()]));
+
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(variableCombo);
+
+ Text minText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(minText);
+
+ Text maxText = new Text(parent, SWT.BORDER);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(maxText);
+
+ Label unit = new Label(parent, SWT.NONE);
+ unit.setText("");
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(unit);
+
+ Combo sizeMapCombo = new Combo(parent, SWT.READ_ONLY);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(sizeMapCombo);
+
+ Button defaultButton = new Button(parent, SWT.CHECK);
+ GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo(defaultButton);
+
+ variableCombo.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // handle update for others
+ String key = variableCombo.getItem(variableCombo.getSelectionIndex());
+ DynamicSizeContribution cont = sizeContributions.get(key);
+
+ if (minText.getText().isEmpty()) {
+ minText.setText(Double.toString(cont.getDefaultMin()));
+ }
+ if (maxText.getText().isEmpty()) {
+ maxText.setText(Double.toString(cont.getDefaultMax()));
+ }
+ unit.setText(cont.getUnit());
+
+ sizeMapCombo.setItems(cont.getDefaultSizeMap().getLabel());
+ sizeMapCombo.select(0);
+
+ defaultButton.setSelection(true);
+ }
+ });
+
+ sizingRows.put(object.getSizingObject().getName(), new SizingObjectRow(label, usedButton, variableCombo, minText, maxText, unit, sizeMapCombo, defaultButton));
+
+ return new Supplier<Pair<String, DynamicSizeContribution>>() {
+
+ @Override
+ public Pair<String, DynamicSizeContribution> get() {
+ int selectionIndex = variableCombo.getSelectionIndex();
+ if (selectionIndex >= 0) {
+ String key = variableCombo.getItem(selectionIndex);
+ DynamicSizeContribution cont = sizeContributions.get(key);
+ if (cont != null) {
+ String sizeMap = sizeMapCombo.getItem(sizeMapCombo.getSelectionIndex());
+ try {
+ Map<String, DynamicSizeMap> sizeMaps = Simantics.getSession().syncRequest(new UniqueRead<Map<String, DynamicSizeMap>>() {
+
+ @Override
+ public Map<String, DynamicSizeMap> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicSizeMaps(graph);
+ }
+ });
+ DynamicSizeMap dColorMap = sizeMaps.get(sizeMap);
+ String label = variableCombo.getItem(variableCombo.getSelectionIndex());
+
+ DynamicSizeContribution dsc = new DynamicSizeContribution(label, cont.getModuleName(), cont.getAttributeName(), unit.getText(), cont.getVariableGain(), cont.getVariableBias(), dColorMap, Double.parseDouble(minText.getText()), Double.parseDouble(maxText.getText()));
+ dsc.setUsed(usedButton.getSelection());
+ dsc.setUseDefault(defaultButton.getSelection());
+
+ return Pair.make(object.getSizingObject().getName(), dsc);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not get DynamicColorContribution", e);
+ }
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ private void initializeColorBars(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Color Bars");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
+
+ createColorBars(group);
+ }
+
+ private void createColorBars(Composite parent) {
+
+ showColorButton = new Button(parent, SWT.CHECK);
+ showColorButton.setText("Show");
+
+ colorTicksButton = new Button(parent, SWT.CHECK);
+ colorTicksButton.setText("Ticks");
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Location");
+ colorLocationCombo = new Combo(parent, SWT.READ_ONLY);
+ colorLocationCombo.setItems(Stream.of(ColorBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Size");
+ colorSizeCombo = new Combo(parent, SWT.READ_ONLY);
+ colorSizeCombo.setItems(Stream.of(ColorBarsSize.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ Button applyButton = new Button(parent, SWT.NONE);
+ applyButton.setText("Apply");
+
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // persist changes
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor instanceof IResourceEditorPart) {
+
+ String colorLocation = colorLocationCombo.getItem(colorLocationCombo.getSelectionIndex());
+ String colorSize = colorSizeCombo.getItem(colorSizeCombo.getSelectionIndex());
+
+ ColorBarOptions options = new ColorBarOptions()
+ .showColorBars(showColorButton.getSelection())
+ .showColorBarsTicks(colorTicksButton.getSelection())
+ .withLocation(ColorBarsLocation.valueOf(colorLocation))
+ .withSize(ColorBarsSize.valueOf(colorSize));
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setColorBarOptions(graph, visualisation.getVisualisationResource(), options);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ private void initializeObjectSizes(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Object Sizes");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(8).margins(5, 5).applyTo(group);
+
+ {
+ createSizingObjectHeaderRow(group);
+ createObjectSizes(group);
+ }
+ }
+
+ private void createObjectSizes(Composite parent) {
+
+ sizeSuppliers = new ArrayList<>();
+ try {
+ Collection<DynamicSizingObject> resultSizing = Simantics.getSession().syncRequest(new UniqueRead<Collection<DynamicSizingObject>>() {
+
+ @Override
+ public Collection<DynamicSizingObject> perform(ReadGraph graph) throws DatabaseException {
+ return DynamicVisualisationsContributions.dynamicSizingObjects(graph);
+ }
+ });
+
+ for (DynamicSizingObject object : resultSizing) {
+ sizeSuppliers.add(createSizingObjectRow(parent, object));
+ }
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not create object sizes", e);
+ }
+
+ {
+ Button applyButton = new Button(parent, SWT.NONE);
+ applyButton.setText("Apply");
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ List<Pair<String, DynamicSizeContribution>> collect = sizeSuppliers.stream().map(s -> s.get()).filter(Objects::nonNull).collect(Collectors.toList());
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setSizeContributions(graph, visualisation.getVisualisationResource(), collect);
+ }
+ });
+ }
+ });
+ }
+ }
+
+ private void initializeSizeBars(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ group.setText("Size Bars");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ GridLayoutFactory.fillDefaults().numColumns(2).margins(5, 5).applyTo(group);
+
+ createSizeBars(group);
+ }
+
+ private void createSizeBars(Composite parent) {
+ showSizeButton = new Button(parent, SWT.CHECK);
+ showSizeButton.setText("Show");
+
+ sizeTicksButton = new Button(parent, SWT.CHECK);
+ sizeTicksButton.setText("Ticks");
+
+ Label label = new Label(parent, SWT.NONE);
+ label.setText("Location");
+ sizeLocationCombo = new Combo(parent, SWT.READ_ONLY);
+ sizeLocationCombo.setItems(Stream.of(SizeBarsLocation.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ label = new Label(parent, SWT.NONE);
+ label.setText("Size");
+ sizeSizeCombo = new Combo(parent, SWT.READ_ONLY);
+ sizeSizeCombo.setItems(Stream.of(SizeBarsSize.values()).map(size -> size.toString()).toArray(String[]::new));
+
+ Button applyButton = new Button(parent, SWT.READ_ONLY);
+ applyButton.setText("Apply");
+
+ applyButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ // persist changes
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor instanceof IResourceEditorPart) {
+
+ String sizeLocation = sizeLocationCombo.getItem(sizeLocationCombo.getSelectionIndex());
+ String sizeSize = sizeSizeCombo.getItem(sizeSizeCombo.getSelectionIndex());
+
+ SizeBarOptions options = new SizeBarOptions()
+ .showSizeBars(showSizeButton.getSelection())
+ .showSizeBarsTicks(sizeTicksButton.getSelection())
+ .withLocation(SizeBarsLocation.valueOf(sizeLocation))
+ .withSize(SizeBarsSize.valueOf(sizeSize));
+
+ Simantics.getSession().asyncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkUtil.setSizeBarOptions(graph, visualisation.getVisualisationResource(), options);
+ }
+ });
+ }
+ }
+ });
+ }
+
+ public void setDiagramResource(Resource diagramResource) {
+ if (this.diagramResource != diagramResource) {
+ this.diagramResource = diagramResource;
+ updateListening();
+ }
+ }
+
+ private void updateListening() {
+ if (visualisationsListener != null)
+ visualisationsListener.dispose();
+ visualisationsListener = new VisualisationsListener(this);
+ Simantics.getSession().asyncRequest(new DynamicVisualisationsRequest(diagramResource), visualisationsListener);
+
+ if (listener != null)
+ listener.dispose();
+ listener = new VisualisationListener(this);
+ Simantics.getSession().asyncRequest(new ActiveDynamicVisualisationsRequest(diagramResource), listener);
+ }
+
+ private static class VisualisationsListener implements Listener<Collection<NamedResource>> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationsListener.class);
+
+ private boolean disposed;
+ private DynamicVisualisationsUI ui;
+
+ public VisualisationsListener(DynamicVisualisationsUI ui) {
+ this.ui = ui;
+ }
+
+ @Override
+ public void execute(Collection<NamedResource> result) {
+ ui.updateVisualisations(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen visualisation", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return disposed || ui.isDisposed();
+ }
+
+ public void dispose() {
+ this.disposed = true;
+ }
+ }
+
+ private static class VisualisationListener implements Listener<DynamicVisualisation> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(VisualisationListener.class);
+
+ private boolean disposed;
+ private DynamicVisualisationsUI ui;
+
+ public VisualisationListener(DynamicVisualisationsUI ui) {
+ this.ui = ui;
+ }
+
+ @Override
+ public void execute(DynamicVisualisation result) {
+ ui.updateVisualisation(result);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not listen visualisation", t);
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return disposed || ui.isDisposed();
+ }
+
+ public void dispose() {
+ this.disposed = true;
+ }
+ }
+
+ public void updateVisualisation(DynamicVisualisation result) {
+ this.visualisation = result;
+ if (visualisation != null) {
+ Display.getDefault().asyncExec(() -> {
+ if (getParent().isDisposed())
+ return;
+
+
+ String[] items = templateSelectionCombo.getItems();
+ for (int i = 0; i < items.length; i++) {
+ if (visualisation.getName().equals(items[i])) {
+ templateSelectionCombo.select(i);
+ break;
+ }
+ }
+
+ Map<String, DynamicColorContribution> colorContributions = visualisation.getColorContributions();
+ for (Entry<String, DynamicColorContribution> entry : colorContributions.entrySet()) {
+
+ ColoringObjectRow coloringObjectRow = coloringRows.get(entry.getKey());
+ if (coloringObjectRow != null) {
+
+ coloringObjectRow.update(entry.getValue());
+
+ } else {
+ LOGGER.info("No coloring object visualisation row for key {}", entry.getKey());
+ }
+ }
+ ColorBarOptions colorOptions = visualisation.getColorBarOptions();
+ showColorButton.setSelection(colorOptions.isShowColorBars());
+ colorTicksButton.setSelection(colorOptions.isShowColorBarsTicks());
+ for (int i = 0; i < colorLocationCombo.getItems().length; i++) {
+ String item = colorLocationCombo.getItem(i);
+ if (item.equals(colorOptions.getLocation().toString())) {
+ colorLocationCombo.select(i);
+ break;
+ }
+ }
+ for (int i = 0; i < colorSizeCombo.getItems().length; i++) {
+ String item = colorSizeCombo.getItem(i);
+ if (item.equals(colorOptions.getSize().toString())) {
+ colorSizeCombo.select(i);
+ break;
+ }
+ }
+
+ Map<String, DynamicSizeContribution> sizeContributions = visualisation.getSizeContributions();
+ for (Entry<String, DynamicSizeContribution> entry : sizeContributions.entrySet()) {
+
+ SizingObjectRow sizingObjectRow = sizingRows.get(entry.getKey());
+ if (sizingObjectRow != null) {
+
+ sizingObjectRow.update(entry.getValue());
+
+ } else {
+ LOGGER.info("No sizing object visualisation row for key {}", entry.getKey());
+ }
+ }
+ SizeBarOptions sizeOptions = visualisation.getSizeBarOptions();
+ showSizeButton.setSelection(sizeOptions.isShowSizeBars());
+ sizeTicksButton.setSelection(sizeOptions.isShowSizeBarsTicks());
+ for (int i = 0; i < sizeLocationCombo.getItems().length; i++) {
+ String item = sizeLocationCombo.getItem(i);
+ if (item.equals(sizeOptions.getLocation().toString())) {
+ sizeLocationCombo.select(i);
+ break;
+ }
+ }
+ for (int i = 0; i < sizeSizeCombo.getItems().length; i++) {
+ String item = sizeSizeCombo.getItem(i);
+ if (item.equals(sizeOptions.getSize().toString())) {
+ sizeSizeCombo.select(i);
+ break;
+ }
+ }
+ });
+ }
+ }
+
+ public void updateVisualisations(Collection<NamedResource> result) {
+ this.visualisations = result;
+
+ Display.getDefault().asyncExec(() -> {
+ if (getParent().isDisposed())
+ return;
+ templateSelectionCombo.setItems(visualisations.stream().map(NamedResource::getName).collect(Collectors.toList()).toArray(new String[visualisations.size()]));
+ });
+ }
+}
--- /dev/null
+package org.simantics.district.network.ui.visualisations;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.e4.ui.workbench.modeling.IPartListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.ui.workbench.IResourceEditorInput;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+public class DynamicVisualisationsView {
+
+ @Inject
+ ESelectionService selectionService;
+
+ @Inject
+ EPartService partService;
+
+ private DynamicVisualisationsUI ui;
+
+ @PostConstruct
+ public void postConstruct(Composite parent) {
+ ui = new DynamicVisualisationsUI(parent, 0);
+
+ IEditorPart editor = WorkbenchUtils.getActiveEditor();
+ if (editor instanceof DistrictDiagramEditor)
+ setDiagramResource(editor.getEditorInput());
+
+ partService.addPartListener(partListener);
+ }
+
+ @PreDestroy
+ public void dispose() {
+ partService.removePartListener(partListener);
+ ui.dispose();
+ ui = null;
+ }
+
+ private void setDiagramResourceFromCompatibilityEditor(MPart part) {
+ if (part.getObject() instanceof CompatibilityEditor) {
+ CompatibilityEditor editor = (CompatibilityEditor) part.getObject();
+ IEditorPart editorPart = editor.getEditor();
+ setDiagramResource(editorPart.getEditorInput());
+ }
+ }
+
+ private void setDiagramResource(IEditorInput input) {
+ if (input instanceof IResourceEditorInput) {
+ ui.setDiagramResource(((IResourceEditorInput) input).getResource());
+ }
+ }
+
+ private IPartListener partListener = new IPartListener() {
+
+ @Override
+ public void partVisible(MPart part) {
+ setDiagramResourceFromCompatibilityEditor(part);
+ }
+
+ @Override
+ public void partHidden(MPart part) {
+ }
+
+ @Override
+ public void partDeactivated(MPart part) {
+ }
+
+ @Override
+ public void partBroughtToTop(MPart part) {
+ setDiagramResourceFromCompatibilityEditor(part);
+ }
+
+ @Override
+ public void partActivated(MPart part) {
+ setDiagramResourceFromCompatibilityEditor(part);
+ }
+ };
+}
org.simantics.diagram,
org.simantics.scenegraph.profile;bundle-version="1.0.0",
org.simantics;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.maps.elevation.server;bundle-version="1.0.0",
+ org.simantics.modeling,
+ org.simantics.db.indexing,
+ org.simantics.scl.osgi
Export-Package: org.simantics.district.network,
org.simantics.district.network.changeset,
- org.simantics.district.network.profile
+ org.simantics.district.network.profile,
+ org.simantics.district.network.visualisations,
+ org.simantics.district.network.visualisations.model
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/ElementColoringStyle"
class="org.simantics.district.network.profile.DNElementColorStyle">
</resource>
+ <resource uri="http://www.simantics.org/DistrictNetwork-1.0/ElementSizingStyle"
+ class="org.simantics.district.network.profile.DNElementSizeStyle">
+ </resource>
<resource uri="http://www.simantics.org/DistrictNetwork-1.0/VertexSizeStyle"
class="org.simantics.district.network.profile.VertexSizeStyle">
</resource>
()
importJava "org.simantics.district.network.DistrictNetworkUtil" where
- createVertex :: Resource -> Vector Double -> Resource -> <WriteGraph, Proc> Resource
- createEdge :: Resource -> Resource -> <WriteGraph, Proc> Resource
+ createVertex :: Resource -> Vector Double -> Double -> Resource -> <WriteGraph, Proc> Resource
+ createEdge :: Resource -> Resource -> Vector Double -> <WriteGraph, Proc> Resource
"""
Tries to look for the Resource representing the configuration component
"""
dnElementsMappedToComponents :: [Resource] -> <ReadGraph> [Resource]
dnElementsMappedToComponents mappedComponents = mapMaybe possibleDNElementMappedToComponent mappedComponents
+
+
+importJava "org.simantics.district.network.DistrictNetworkUtil" where
+ createNetworkDiagram :: Resource -> Resource -> String -> Resource -> Resource -> Resource -> Resource -> Resource -> <WriteGraph, Proc> Resource
+ changeMappingType :: Resource -> [Resource] -> <WriteGraph, Proc> ()
+ findDNElementById :: Resource -> String -> <ReadGraph, Proc> Maybe Resource
+ findDNElementByXYCoordinates :: Resource -> Double -> Double -> Double -> <ReadGraph, Proc> [Resource]
+
print ""
forI (sortStrings (map showEdge es)) (\i s -> print "* e\(i): \(s)")
+"""
+Get a set of vertices that acts as break points between network branches.
+"""
+branchPoints :: Resource -> <ReadGraph> [Resource]
+branchPoints networkDiagram = runProc let
+ in
+ filter isBranchPoint vertices
+ where
+ all = if isInstanceOf networkDiagram DIA.Diagram
+ then networkDiagram # L0.ConsistsOf
+ else singleObject networkDiagram MOD.CompositeToDiagram # L0.ConsistsOf
+ vertices = filter (flip isInstanceOf DN.Vertex) all
+ isBranchPoint v = length (v # DN.HasEndVertex_Inverse) != 1 || length (v # DN.HasStartVertex_Inverse) != 1
+
"""
Get a set of the edges that are at the middle points of each span between branch points.
"""
--- /dev/null
+// Example: (�p supply�, �S_PC�, �PO11_PRESSURE�, �bar(g)�, 0.1, 1.0, �summer�, 50.0, 120.0)
+// Above �p supply� is label and there may be several UC types contributing to the same label. Default colorMap �summer�.
+
+importJava "org.simantics.district.network.visualisations.model.DynamicColorMap" where
+ data DynamicColorMap
+
+ @JavaName "<init>"
+ dynamicColorMap :: String -> [RGBIntensity] -> DynamicColorMap
+
+importJava "org.simantics.district.network.visualisations.model.DynamicColorMap$RGBIntensity" where
+ data RGBIntensity
+
+ @JavaName "<init>"
+ rgbIntensity :: Double -> Double -> Double -> RGBIntensity
+
+importJava "org.simantics.district.network.visualisations.model.DynamicColorContribution" where
+ data DynamicColorContribution
+
+ @JavaName "<init>"
+ dynamicColorContribution :: String -> String -> String -> String -> Double -> Double -> DynamicColorMap -> Double -> Double -> DynamicColorContribution
+
--- /dev/null
+// Example: (�supply flow�, �S_FLOW�, �SP_VALUE�, �kg/s�, 1.0, 0.0, �linearSizesMedium�, 10.0, 1500.0)
+
+importJava "org.simantics.district.network.visualisations.model.DynamicSizeMap" where
+ data DynamicSizeMap
+
+ @JavaName "<init>"
+ dynamicSizeMap :: String -> [Double] -> DynamicSizeMap
+
+importJava "org.simantics.district.network.visualisations.model.DynamicSizeContribution" where
+ data DynamicSizeContribution
+
+ @JavaName "<init>"
+ dynamicSizeContribution :: String -> String -> String -> String -> Double -> Double -> DynamicSizeMap -> Double -> Double -> DynamicSizeContribution
-package org.simantics.district.network.ui;
+package org.simantics.district.network;
import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Optional;
import org.simantics.databoard.Bindings;
import org.simantics.db.Resource;
import org.simantics.diagram.synchronization.SynchronizationHints;
import org.simantics.diagram.synchronization.graph.GraphSynchronizationHints;
import org.simantics.diagram.synchronization.graph.layer.GraphLayerManager;
-import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.DistrictNetworkUtil.ResourceVertex;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.g2d.diagram.IDiagram;
import org.simantics.layer0.Layer0;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.quadtree.Quadtree;
public class DNEdgeBuilder {
-
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DNEdgeBuilder.class);
+
private Resource diagramResource;
private IDiagram diagram;
private GraphLayerManager glm;
glm = context.get(GraphSynchronizationHints.GRAPH_LAYER_MANAGER);
}
- public static Resource create(WriteGraph graph, Resource diagramResource, double[] start, double[] end, double padding) throws DatabaseException {
+ public static Optional<Resource> create(WriteGraph graph, Resource diagramResource, double[] start, double startElevation, double[] end, double endElevation, double[] detailedGeometryCoords, double padding) throws DatabaseException {
Collection<Resource> vertices = graph.syncRequest(new ObjectsWithType(diagramResource, Layer0.getInstance(graph).ConsistsOf, DistrictNetworkResource.getInstance(graph).Vertex));
- List<ResourceVertex> vv = new ArrayList<>(vertices.size());
+ double halfPadding = padding / 2;
+
+ Quadtree vv = new Quadtree();
for (Resource vertex : vertices) {
- double[] existingCoords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY);
- vv.add(new ResourceVertex(vertex, existingCoords));
+ double[] coords = graph.getRelatedValue2(vertex, DiagramResource.getInstance(graph).HasLocation, Bindings.DOUBLE_ARRAY);
+ double x1 = coords[0] - halfPadding;
+ double y1= coords[1] - halfPadding;
+ double x2 = coords[0] + halfPadding;
+ double y2= coords[1] + halfPadding;
+ Envelope e = new Envelope(x1, x2, y1, y2);
+ vv.insert(e, new ResourceVertex(vertex, coords, false));
}
- return create(graph, vv, diagramResource, null, start, end, padding, false);
+ return create(graph, vv, diagramResource, null, start, startElevation, end, endElevation, detailedGeometryCoords, padding, true);
}
- public static Resource create(WriteGraph graph, Collection<ResourceVertex> vertices, Resource diagramResource, Resource mapping, double[] start, double[] end, double padding, boolean writeElevationToEdgeFromPoints) throws DatabaseException {
-
+ public static Optional<Resource> create(WriteGraph graph, Quadtree vertices, Resource diagramResource, Resource mapping, double[] start, double startElevation, double[] end, double endElevation, double[] detailedGeometryCoords, double padding, boolean writeElevationToEdgeFromPoints) throws DatabaseException {
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ // 2. Add vertices
+ Resource startVertex = getOrCreateVertex(graph, diagramResource, vertices, start, startElevation, padding, null);
+ Resource endVertex = getOrCreateVertex(graph, diagramResource, vertices, end, endElevation, padding, startVertex);
+ if (startVertex.equals(endVertex)) {
+ LOGGER.info("Circular edges are not supported, startVertex: {}, endVertex: {}", startVertex, endVertex);
+ return Optional.empty();
+ }
// 1. Get diagram edge to construct
- Resource edge = getOrCreateEdge(graph, diagramResource, mapping);
+ Resource edge = getOrCreateEdge(graph, diagramResource, mapping, detailedGeometryCoords);
- // 2. Add vertices
- Resource startVertex = getOrCreateVertex(graph, diagramResource, vertices, start, padding, null);
- Resource endVertex = getOrCreateVertex(graph, diagramResource, vertices, end, padding, startVertex);
if (writeElevationToEdgeFromPoints) {
graph.claimLiteral(edge, DN.Edge_HasElevation, calculateElevationFromVertices(graph, startVertex, endVertex), Bindings.DOUBLE);
}
// });
// }
//
- return edge;
+ return Optional.of(edge);
}
private static double calculateElevationFromVertices(WriteGraph graph, Resource startVertex, Resource endVertex) throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
return 0;
}
- public void create(WriteGraph graph, double[] start, double[] end, double padding) throws DatabaseException {
-
- Resource edge = create(graph, diagramResource, start, end, padding);
+ public void create(WriteGraph graph, double[] start, double startElevation, double[] end, double endElevation, double[] detailedGeometryCoords, double padding) throws DatabaseException {
+ Optional<Resource> edge = create(graph, diagramResource, start, startElevation, end, endElevation, detailedGeometryCoords, padding);
// 7. Put the element on all the currently active layers if possible.
if (glm != null) {
- putOnActiveLayer(graph, edge);
+ putOnActiveLayer(graph, edge.get());
}
- Layer0Utils.addCommentMetadata(graph, "Added edge " + edge);
+ Layer0Utils.addCommentMetadata(graph, "Added edge " + edge.get());
graph.markUndoPoint();
}
glm.putElementOnVisibleLayers(diagram, graph, res);
}
- private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Collection<ResourceVertex> vertices, double[] coords, double padding, Resource startVertex) throws DatabaseException {
+ private static Resource getOrCreateVertex(WriteGraph graph, Resource diagramResource, Quadtree qtree, double[] coords, double elevation, double padding, Resource startVertex) throws DatabaseException {
Resource vertex = null;
double halfPadding = padding / 2;
double maxDistance = Double.MAX_VALUE;
+ double x1 = coords[0] - halfPadding;
+ double y1= coords[1] - halfPadding;
+ double x2 = coords[0] + halfPadding;
+ double y2= coords[1] + halfPadding;
+ Envelope e = new Envelope(x1, x2, y1, y2);
+
+ List<?> result = qtree.query(e);
+ @SuppressWarnings("unchecked")
+ List<ResourceVertex> vertices = (List<ResourceVertex>) result;
for (ResourceVertex vertx : vertices) {
Rectangle2D existing = new Rectangle2D.Double(vertx.coords[0] - halfPadding, vertx.coords[1] - halfPadding, padding, padding);
- Rectangle2D tobecreated = new Rectangle2D.Double(coords[0] - halfPadding, coords[1] - halfPadding, padding, padding);
+ Rectangle2D tobecreated = new Rectangle2D.Double(x1, y1, padding, padding);
if (existing.intersects(tobecreated)) {
double dist = Math.sqrt((Math.pow(coords[0] - vertx.coords[0], 2) + (Math.pow(coords[1] - vertx.coords[1], 2))));
- if (dist <= maxDistance && !vertx.vertex.equals(startVertex)) {
+ if (dist <= maxDistance && vertx.vertex != startVertex) {
vertex = vertx.vertex;
maxDistance = dist;
}
}
}
if (vertex == null) {
- vertex = DistrictNetworkUtil.createVertex(graph, diagramResource, coords);
- vertices.add(new ResourceVertex(vertex, coords));
+ vertex = DistrictNetworkUtil.createVertex(graph, diagramResource, coords, elevation);
+ qtree.insert(e, new ResourceVertex(vertex, coords, false));
}
return vertex;
}
- private static Resource getOrCreateEdge(WriteGraph graph, Resource diagramResource, Resource mapping) throws DatabaseException {
- return DistrictNetworkUtil.createEdge(graph, diagramResource, mapping);
+ private static Resource getOrCreateEdge(WriteGraph graph, Resource diagramResource, Resource mapping, double[] detailedGeometryCoords) throws DatabaseException {
+ return DistrictNetworkUtil.createEdge(graph, diagramResource, mapping, detailedGeometryCoords);
}
- public static class ResourceVertex {
-
- final Resource vertex;
- final double[] coords;
-
- public ResourceVertex(Resource vertex, double[] coords) {
- this.vertex = vertex;
- this.coords = coords;
- }
- }
}
package org.simantics.district.network;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.simantics.databoard.Bindings;
import org.simantics.datatypes.literal.RGB;
import org.simantics.db.Resource;
import org.simantics.db.WriteGraph;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.IndexRoot;
import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.common.utils.OrderedSetUtils;
import org.simantics.db.exception.BindingException;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
import org.simantics.db.exception.ServiceException;
+import org.simantics.db.indexing.IndexUtils;
import org.simantics.db.layer0.request.PossibleVariable;
import org.simantics.db.layer0.variable.Variable;
import org.simantics.diagram.stubs.DiagramResource;
import org.simantics.diagram.synchronization.graph.layer.GraphLayer;
import org.simantics.diagram.synchronization.graph.layer.IGraphLayerUtil;
import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.visualisations.DynamicVisualisationsContributions;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsLocation;
+import org.simantics.district.network.visualisations.model.ColorBarOptions.ColorBarsSize;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsLocation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions.SizeBarsSize;
import org.simantics.layer0.Layer0;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.adapters.NewCompositeActionFactory;
import org.simantics.operation.Layer0X;
+import org.simantics.utils.datastructures.Pair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class DistrictNetworkUtil {
- public static Resource createEdge(WriteGraph graph, Resource composite) throws DatabaseException {
- return createEdge(graph, composite, graph.getPossibleObject(composite, DistrictNetworkResource.getInstance(graph).EdgeDefaultMapping));
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictNetworkUtil.class);
+
+ public static Resource createEdge(WriteGraph graph, Resource composite, double[] detailedGeometryCoords) throws DatabaseException {
+ return createEdge(graph, composite, graph.getPossibleObject(composite, DistrictNetworkResource.getInstance(graph).EdgeDefaultMapping), detailedGeometryCoords);
}
- public static Resource createEdge(WriteGraph graph, Resource composite, Resource mapping) throws DatabaseException {
+ public static Resource createEdge(WriteGraph graph, Resource composite, Resource mapping, double[] detailedGeometryCoords) throws DatabaseException {
Layer0 L0 = Layer0.getInstance(graph);
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
if (mapping == null) {
});
}
+ // add detailed geometry (if any)
+ graph.claimLiteral(edge, DN.Edge_HasGeometry, detailedGeometryCoords, Bindings.DOUBLE_ARRAY);
return edge;
}
- public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords) throws DatabaseException {
+ /**
+ * @param graph
+ * @param composite
+ * @param coords
+ * @param elevation Double.MAX_VALUE to fetch elevation from elevation server (if enabled and has data)
+ * @return
+ * @throws DatabaseException
+ */
+ public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords, double elevation) throws DatabaseException {
Resource defaultVertexMapping = graph.getPossibleObject(composite, DistrictNetworkResource.getInstance(graph).VertexDefaultMapping);
- return createVertex(graph, composite, coords, defaultVertexMapping);
+ return createVertex(graph, composite, coords, elevation, defaultVertexMapping);
}
- public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords, Resource mapping) throws DatabaseException {
+ /**
+ * @param graph
+ * @param composite
+ * @param coords
+ * @param elevation Double.MAX_VALUE to fetch elevation from elevation server (if enabled and has data)
+ * @param mapping
+ * @return
+ * @throws DatabaseException
+ */
+ public static Resource createVertex(WriteGraph graph, Resource composite, double[] coords, double elevation, Resource mapping) throws DatabaseException {
+ // Double.MAX_VALUE is our secret to lookup elevation from elevation server
+ if (elevation == Double.MAX_VALUE) {
+ // ok, resolve from server or default to 0
+ if (MapsElevationServerPreferences.useElevationServer()) {
+ // ok! we use new elevation API to resolve possible elevations for the starting points
+ try {
+ elevation = SingletonTiffTileInterface.lookup(coords[1], coords[0]).doubleValue();
+ } catch (Exception ee) {
+ LOGGER.error("Could not get elevation from tiff interface", ee);
+ }
+ } else {
+ elevation = 0;
+ }
+ }
+
Layer0 L0 = Layer0.getInstance(graph);
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
DiagramResource DIA = DiagramResource.getInstance(graph);
Resource vertex = graph.newResource();
graph.claim(vertex, L0.InstanceOf, DN.Vertex);
graph.claimLiteral(vertex, DIA.HasLocation, coords);
+ graph.claimLiteral(vertex, DN.Vertex_HasElevation, elevation, Bindings.DOUBLE);
graph.claim(vertex, DN.HasMapping, null, mapping);
DistrictNetworkResource.getInstance(graph).Diagram_backgroundColor,
Bindings.getBindingUnchecked(RGB.Integer.class));
}
+
+ public static Resource createNetworkDiagram(WriteGraph graph, Resource target, Resource compositeType, String defaultName, Resource defaultEdgeMapping, Resource defaultVertexMapping, Resource rightClickVertexMapping, Resource leftClickVertexMapping, Resource crs) throws DatabaseException {
+ Resource composite = NewCompositeActionFactory.createComposite(graph, target, defaultName, compositeType);
+
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram);
+ graph.claim(diagram, DN.EdgeDefaultMapping, defaultEdgeMapping);
+ graph.claim(diagram, DN.VertexDefaultMapping, defaultVertexMapping);
+ graph.claim(diagram, DN.RightClickDefaultMapping, rightClickVertexMapping);
+ graph.claim(diagram, DN.LeftClickDefaultMapping, leftClickVertexMapping);
+ graph.claim(diagram, DN.HasSpatialRefSystem, crs);
+
+ // Generated name prefix from composite name
+ String compositeName = graph.getRelatedValue2(composite, Layer0.getInstance(graph).HasName, Bindings.STRING);
+ graph.claimLiteral(diagram, Layer0X.getInstance(graph).HasGeneratedNamePrefix, "N" + compositeName.substring(compositeName.length() - 1, compositeName.length()));
+
+ return composite;
+ }
public static final class MappedComponentRequest extends ResourceRead<Resource> {
public MappedComponentRequest(Resource element) {
}
}
+ public static class ResourceVertex {
+
+ public final boolean isConsumer;
+ public final Resource vertex;
+ public final double[] coords;
+
+ public ResourceVertex(Resource vertex, double[] coords, boolean isConsumer) {
+ this.vertex = vertex;
+ this.coords = coords;
+ this.isConsumer = isConsumer;
+ }
+ }
+
+ public static void changeMappingType(WriteGraph graph, Resource newMapping, List<Resource> elements) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource element : elements) {
+ graph.deny(element, DN.HasMapping);
+ graph.claim(element, DN.HasMapping, newMapping);
+ }
+ }
+
+ public static Stream<Resource> findDNElementsById(ReadGraph graph, Resource context, String idToFind) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ return IndexUtils.findByType(graph,
+ graph.syncRequest(new IndexRoot(context)),
+ DN.Element
+ ).stream().filter(element -> {
+ try {
+ String id = graph.getPossibleRelatedValue(element, DN.HasId, Bindings.STRING);
+ return id != null && id.contains(idToFind);
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not read id for element {]", element, e);
+ return false;
+ }
+ });
+ }
+
+ public static Resource findDNElementById(ReadGraph graph, Resource context, String idToFind) throws DatabaseException {
+ List<Resource> elements = findDNElementsById(graph, context, idToFind).collect(Collectors.toList());
+ if (elements.size() == 1) {
+ return elements.iterator().next();
+ }
+ return null;
+ }
+
+ public static List<Resource> findDNElementByXYCoordinates(ReadGraph graph, Resource context, double lat, double lon, double padding) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ List<Resource> results = new ArrayList<>();
+ Collection<Resource> vertices = IndexUtils.findByType(graph, graph.syncRequest(new IndexRoot(context)), DN.Vertex);
+ Rectangle2D rect = new Rectangle2D.Double(lat, lon, padding, padding);
+ for (Resource vertex : vertices) {
+ double[] location = graph.getRelatedValue(vertex, DIA.HasLocation, Bindings.DOUBLE_ARRAY);
+ if (rect.contains(location[0], location[1])) {
+ results.add(vertex);
+ }
+ }
+ return results;
+ }
+
+ public static ColorBarOptions colorBarOptions(ReadGraph graph, Resource visualisation) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ if (visualisation != null) {
+ String colorBarLocation = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ColorBarLocation, Bindings.STRING);
+ String colorBarSize = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ColorBarSize, Bindings.STRING);
+ Boolean show = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ShowColorBars, Bindings.BOOLEAN);
+ Boolean showTicks = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ShowColorBarTicks, Bindings.BOOLEAN);
+ if (colorBarLocation != null) {
+ return new ColorBarOptions()
+ .showColorBars(show != null ? show : false)
+ .showColorBarsTicks(showTicks != null ? showTicks : false)
+ .withLocation(ColorBarsLocation.valueOf(colorBarLocation))
+ .withSize(ColorBarsSize.valueOf(colorBarSize));
+ }
+ }
+ return ColorBarOptions.useDefault();
+ }
+
+ public static void setColorBarOptions(WriteGraph graph, Resource visualisation, ColorBarOptions options) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ColorBarLocation, options.getLocation().toString(), Bindings.STRING);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ColorBarSize, options.getSize().toString(), Bindings.STRING);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowColorBars, options.isShowColorBars(), Bindings.BOOLEAN);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowColorBarTicks, options.isShowColorBarsTicks(), Bindings.BOOLEAN);
+ }
+
+ public static Resource createVisualisation(WriteGraph graph, Resource diagram, String visualisationName) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource visualisation = graph.newResource();
+ graph.claim(visualisation, L0.InstanceOf, DN.Diagram_Visualisations);
+ graph.claimLiteral(visualisation, L0.HasName, visualisationName);
+ graph.claim(diagram, DN.Diagram_hasVisualisation, visualisation);
+ return visualisation;
+ }
+
+ public static SizeBarOptions sizeBarOptions(ReadGraph graph, Resource visualisation) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ if (visualisation != null) {
+ String sizeBarLocation = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_SizeBarLocation, Bindings.STRING);
+ String sizeBarSize = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_SizeBarSize, Bindings.STRING);
+ Boolean show = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ShowSizeBars, Bindings.BOOLEAN);
+ Boolean showTicks = graph.getPossibleRelatedValue(visualisation, DN.Diagram_Visualisations_ShowSizeBarTicks, Bindings.BOOLEAN);
+ if (sizeBarLocation != null) {
+ return new SizeBarOptions()
+ .showSizeBars(show != null ? show : false)
+ .showSizeBarsTicks(showTicks != null ? showTicks : false)
+ .withLocation(SizeBarsLocation.valueOf(sizeBarLocation))
+ .withSize(SizeBarsSize.valueOf(sizeBarSize));
+ }
+ }
+ return SizeBarOptions.useDefault();
+ }
+
+ public static void setSizeBarOptions(WriteGraph graph, Resource visualisation, SizeBarOptions options) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_SizeBarLocation, options.getLocation().toString(), Bindings.STRING);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_SizeBarSize, options.getSize().toString(), Bindings.STRING);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowSizeBars, options.isShowSizeBars(), Bindings.BOOLEAN);
+ graph.claimLiteral(visualisation, DN.Diagram_Visualisations_ShowSizeBarTicks, options.isShowSizeBarsTicks(), Bindings.BOOLEAN);
+ }
+
+ public static Map<String, DynamicColorContribution> colorContributions(ReadGraph graph, Resource visualisation) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ if (visualisation == null) {
+ return Collections.emptyMap();
+ }
+ Map<String, DynamicColorContribution> contributions = new HashMap<>();
+
+ Map<String, DynamicColorMap> colorMaps = DynamicVisualisationsContributions.dynamicColorMaps(graph);
+
+ Collection<Resource> colorContributions = graph.getObjects(visualisation, DN.Diagram_Visualisations_colorContributions);
+ for (Resource colorContribution : colorContributions) {
+ String ucName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionContributorName, Bindings.STRING);
+ String label = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionLabel, Bindings.STRING);
+ String moduleName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionModuleName, Bindings.STRING);
+ String attributeName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionModuleAttribute, Bindings.STRING);
+ String unit = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionUnit, Bindings.STRING);
+ Double variableGain = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionVariableGain, Bindings.DOUBLE);
+ Double variableBias = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionVariableBias, Bindings.DOUBLE);
+ String dynamicColorMap = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultColorMap, Bindings.STRING);
+ Double defaultMin = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultMin, Bindings.DOUBLE);
+ Double defaultMax = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultMax, Bindings.DOUBLE);
+ Boolean used = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionUsed, Bindings.BOOLEAN);
+ Boolean useDefault = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_colorContributionUseDefault, Bindings.BOOLEAN);
+ DynamicColorContribution dynamicColorContribution = new DynamicColorContribution(label, moduleName, attributeName, unit, variableGain, variableBias, colorMaps.get(dynamicColorMap), defaultMin, defaultMax);
+ dynamicColorContribution.setUsed(used != null ? used : false);
+ dynamicColorContribution.setUseDefault(useDefault != null ? useDefault : false);
+ contributions.put(ucName, dynamicColorContribution);
+ }
+ return contributions;
+ }
+
+ public static void setColorContributions(WriteGraph graph, Resource visualisation, List<Pair<String, DynamicColorContribution>> collect) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Layer0 L0 = Layer0.getInstance(graph);
+
+ graph.deny(visualisation, DN.Diagram_Visualisations_colorContributions);
+ for (Pair<String, DynamicColorContribution> coll : collect) {
+ Resource colorContribution = graph.newResource();
+ graph.claim(colorContribution, L0.InstanceOf, DN.Diagram_Visualisations_ColorContribution);
+ graph.claimLiteral(colorContribution, L0.HasName, coll.first);
+
+ DynamicColorContribution contr = coll.second;
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionContributorName, coll.first);
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionLabel, contr.getLabel());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionModuleName, contr.getModuleName());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionModuleAttribute, contr.getAttributeName());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionUnit, contr.getUnit());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionVariableGain, contr.getVariableGain());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionVariableBias, contr.getVariableBias());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultColorMap, contr.getDefaultColorMap().getLabel());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultMin, contr.getDefaultMin());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionDefaultMax, contr.getDefaultMax());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionUsed, contr.isUsed());
+ graph.claimLiteral(colorContribution, DN.Diagram_Visualisations_colorContributionUseDefault, contr.isUseDefault());
+
+ graph.claim(visualisation, DN.Diagram_Visualisations_colorContributions, colorContribution);
+ }
+ }
+
+ public static Map<String, DynamicSizeContribution> sizeContributions(ReadGraph graph, Resource visualisation) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ if (visualisation == null) {
+ return Collections.emptyMap();
+ }
+ Map<String, DynamicSizeContribution> contributions = new HashMap<>();
+
+ Map<String, DynamicSizeMap> sizeMaps = DynamicVisualisationsContributions.dynamicSizeMaps(graph);
+
+ Collection<Resource> colorContributions = graph.getObjects(visualisation, DN.Diagram_Visualisations_sizeContributions);
+ for (Resource colorContribution : colorContributions) {
+ String ucName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionContributorName, Bindings.STRING);
+ String label = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionLabel, Bindings.STRING);
+ String moduleName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionModuleName, Bindings.STRING);
+ String attributeName = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionModuleAttribute, Bindings.STRING);
+ String unit = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionUnit, Bindings.STRING);
+ Double variableGain = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionVariableGain, Bindings.DOUBLE);
+ Double variableBias = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionVariableBias, Bindings.DOUBLE);
+ String dynamicSizeMap = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultSizeMap, Bindings.STRING);
+ Double defaultMin = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultMin, Bindings.DOUBLE);
+ Double defaultMax = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionDefaultMax, Bindings.DOUBLE);
+ Boolean used = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionUsed, Bindings.BOOLEAN);
+ Boolean useDefault = graph.getRelatedValue(colorContribution, DN.Diagram_Visualisations_sizeContributionUseDefault, Bindings.BOOLEAN);
+ DynamicSizeContribution dsc = new DynamicSizeContribution(label, moduleName, attributeName, unit, variableGain, variableBias, sizeMaps.get(dynamicSizeMap), defaultMin, defaultMax);
+ dsc.setUsed(used != null ? used : false);
+ dsc.setUseDefault(useDefault != null ? useDefault : false);
+ contributions.put(ucName, dsc);
+ }
+ return contributions;
+ }
+
+ public static void setSizeContributions(WriteGraph graph, Resource visualisation, List<Pair<String, DynamicSizeContribution>> collect) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Layer0 L0 = Layer0.getInstance(graph);
+
+ graph.deny(visualisation, DN.Diagram_Visualisations_sizeContributions);
+ for (Pair<String, DynamicSizeContribution> coll : collect) {
+ Resource sizeContribution = graph.newResource();
+ graph.claim(sizeContribution, L0.InstanceOf, DN.Diagram_Visualisations_SizeContribution);
+ graph.claimLiteral(sizeContribution, L0.HasName, coll.first);
+
+ DynamicSizeContribution contr = coll.second;
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionContributorName, coll.first);
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionLabel, contr.getLabel());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionModuleName, contr.getModuleName());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionModuleAttribute, contr.getAttributeName());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUnit, contr.getUnit());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionVariableGain, contr.getVariableGain());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionVariableBias, contr.getVariableBias());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultSizeMap, contr.getDefaultSizeMap().getLabel());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultMin, contr.getDefaultMin());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionDefaultMax, contr.getDefaultMax());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUsed, contr.isUsed());
+ graph.claimLiteral(sizeContribution, DN.Diagram_Visualisations_sizeContributionUseDefault, contr.isUseDefault());
+
+ graph.claim(visualisation, DN.Diagram_Visualisations_sizeContributions, sizeContribution);
+ }
+ }
+
+ public static void setActiveVisualisation(WriteGraph graph, Resource diagram, Resource visualisationTemplate) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ graph.deny(diagram, DN.Diagram_hasActiveVisualisation);
+ graph.claim(diagram, DN.Diagram_hasActiveVisualisation, visualisationTemplate);
+ }
+
}
package org.simantics.district.network.changeset;
-import java.util.Arrays;
import java.util.Map;
import org.simantics.db.MetadataI;
public class DistrictChangeListener extends GenericChangeListener<DependencyChangesRequest, DependencyChanges> {
- private static final Logger LOGGER = LoggerFactory.getLogger(DistrictChangeListener.class);
+ @SuppressWarnings("unused")
+ private static final Logger LOGGER = LoggerFactory.getLogger(DistrictChangeListener.class);
@Override
public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.util.Map;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.DistrictNetworkUtil;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.visualisations.model.ColorBarOptions;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.district.network.visualisations.model.SizeBarOptions;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Jani Simomaa
+ */
+public class ActiveDynamicVisualisationsRequest extends ResourceRead<DynamicVisualisation> {
+
+ public ActiveDynamicVisualisationsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public DynamicVisualisation perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Resource visualisationResource = graph.getPossibleObject(resource, DN.Diagram_hasActiveVisualisation);
+ if (visualisationResource != null) {
+ String name = graph.getRelatedValue(visualisationResource, Layer0.getInstance(graph).HasName);
+ Map<String, DynamicColorContribution> colorContributions = DistrictNetworkUtil.colorContributions(graph, visualisationResource);
+ ColorBarOptions colorBarOptions = DistrictNetworkUtil.colorBarOptions(graph, visualisationResource);
+ Map<String, DynamicSizeContribution> sizeContributions = DistrictNetworkUtil.sizeContributions(graph, visualisationResource);
+ SizeBarOptions sizeBarOptions = DistrictNetworkUtil.sizeBarOptions(graph, visualisationResource);
+ DynamicVisualisation visualisation = new DynamicVisualisation(name, visualisationResource, colorContributions, colorBarOptions, sizeContributions, sizeBarOptions);
+ return visualisation;
+ }
+ return null;
+ }
+
+}
package org.simantics.district.network.profile;
-import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.procedure.adapter.TransientCacheListener;
-import org.simantics.db.common.request.ResourceRead;
import org.simantics.db.exception.DatabaseException;
import org.simantics.layer0.Layer0;
import org.simantics.scenegraph.INode;
public class ArrowLengthStyle extends ThrottledStyleBase<Double> {
private static final Double PENDING = Double.NaN;
- private static final Double ONE = 1.0;
@Override
public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException {
// Prevent PendingVariableExceptions from coming through
boolean wasSynchronous = graph.setSynchronous(true);
try {
- Double length = ONE;
if (ds.arrowLengthProperty.isPresent()) {
- length = Simantics.applySCLRead(graph, ds.arrowLengthProperty.get(), groupItem);
- // System.out.println("read thickness: " + thickness + " : " + ds.arrowLengthProperty);
- if (length == null) {
- length = ONE;
- } else {
- length = length * ds.arrowLengthGain + ds.arrowLengthBias;
- }
+ Double length = Simantics.applySCLRead(graph, ds.arrowLengthProperty.get(), groupItem);
+ return length != null ? length * ds.arrowLengthGain + ds.arrowLengthBias : null;
+ }
+ else {
+ return null;
}
-
- return length;
}
finally {
graph.setSynchronous(wasSynchronous);
for (INode nn : n.getNodes())
ProfileVariables.claimNodeProperty(nn, "arrowLength", null, evaluationContext);
}
-
- private static final class MidBranchEdgeSetRequest extends ResourceRead<Set<Resource>> {
- private MidBranchEdgeSetRequest(Resource resource) {
- super(resource);
- }
-
- @Override
- public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
- List<Resource> edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource);
- return new HashSet<>(edges);
- }
- }
-
}
package org.simantics.district.network.profile;
import java.awt.Color;
+import java.util.Map;
import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
import org.simantics.db.exception.DatabaseException;
-import org.simantics.diagram.profile.StyleBase;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
import org.simantics.scenegraph.profile.EvaluationContext;
import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* @author Tuukka Lehtonen
*/
public class DNElementColorStyle extends ThrottledStyleBase<Color> {
- private static final boolean DEBUG = false;
+ private static final Logger LOGGER = LoggerFactory.getLogger(DNElementColorStyle.class);
+
+ private static final boolean DEBUG = false;
@Override
public Color calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException {
- DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance());
- // Prevent PendingVariableExceptions from coming through
- boolean wasSynchronous = graph.setSynchronous(true);
- try {
+
+ DynamicVisualisation dv = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram),
+ TransientCacheAsyncListener.instance());
+
+ DiagramSettings ds = graph.syncRequest(new DiagramSettingsRequest(runtimeDiagram), TransientCacheAsyncListener.instance());
+ // Prevent PendingVariableExceptions from coming through
+ boolean wasSynchronous = graph.setSynchronous(true);
+ try {
+ if (dv != null) {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource mapping = graph.getSingleObject(groupItem, DN.HasMapping);
+
+ Map<String, DynamicColorContribution> colorContributions = dv.getColorContributions();
+ String mappingName = graph.getRelatedValue(mapping, L0.HasName);
+ DynamicColorContribution dcc = colorContributions.get(mappingName);
+ if (dcc != null && dcc.isUsed()) {
+
+ Resource mappedComponent = graph.getPossibleObject(groupItem, DN.MappedComponent);
+ if (mappedComponent != null) {
+
+ Resource component = graph.getSingleObject(mappedComponent, MOD.ElementToComponent);
+ Variable variable = Variables.getVariable(graph, component);
+ Variable possibleActiveVariable = Variables.possibleActiveVariable(graph, variable);
+ if (possibleActiveVariable != null) {
+
+ Variable module = possibleActiveVariable.getPossibleChild(graph, dcc.getModuleName());
+ if (module != null) {
+ Variable attribute = module.getPossibleProperty(graph, dcc.getAttributeName());
+ if (attribute != null) {
+ Double possibleValue = attribute.getPossibleValue(graph, Bindings.DOUBLE);
+ if (possibleValue != null) {
+ // here we do the adjusting according to spec in #15038
+ double adjustedValue = possibleValue.doubleValue() * dcc.getVariableGain() + dcc.getVariableBias();
+ DynamicColorMap defaultColorMap = dcc.getDefaultColorMap();
+ Color color = defaultColorMap.getColor(adjustedValue, dcc.getDefaultMin(), dcc.getDefaultMax());
+ return color;
+ } else {
+ LOGGER.warn("No value for {}", attribute.getURI(graph));
+ }
+ } else {
+ LOGGER.warn("Wrong attribute name {} for {} !!", dcc.getAttributeName(), module.getURI(graph));
+ }
+ } else {
+ LOGGER.warn("Wrong modulename {} for {} !!", dcc.getModuleName(), possibleActiveVariable.getURI(graph));
+ }
+ } else {
+ LOGGER.debug("No active experiment for {}", variable.getURI(graph));
+ }
+ } else {
+ LOGGER.debug("No mapped component for {} to calculate dynamic color style", groupItem);
+ }
+ }
+ }
+
+ // the old implementation here
if (ds.elementColoringFunction.isPresent()) {
if (DEBUG)
System.out.print("elementColoringFunction: " + ds.elementColoringFunction + "(" + groupItem + "): ");
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.util.Map;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.g2d.G2DSceneGraph;
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Jani Simomaa
+ */
+public class DNElementSizeStyle extends ThrottledStyleBase<Double> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DNElementSizeStyle.class);
+ private static final boolean DEBUG = false;
+
+ private static final Double PENDING = Double.NaN;
+ private static final Double ONE = 1.0;
+
+ @Override
+ public Double calculateThrottledStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource groupItem) throws DatabaseException {
+
+ DynamicVisualisation dv = graph.syncRequest(new RuntimeDynamicVisualisationsRequest(runtimeDiagram),
+ TransientCacheAsyncListener.instance());
+
+ // Prevent PendingVariableExceptions from coming through
+ boolean wasSynchronous = graph.setSynchronous(true);
+ try {
+ if (dv != null) {
+ Layer0 L0 = Layer0.getInstance(graph);
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ ModelingResources MOD = ModelingResources.getInstance(graph);
+ Resource mapping = graph.getSingleObject(groupItem, DN.HasMapping);
+
+ Map<String, DynamicSizeContribution> sizeContributions = dv.getSizeContributions();
+ String mappingName = graph.getRelatedValue(mapping, L0.HasName);
+ DynamicSizeContribution dsc = sizeContributions.get(mappingName);
+ if (dsc != null && dsc.isUsed()) {
+
+ Resource mappedComponent = graph.getPossibleObject(groupItem, DN.MappedComponent);
+ if (mappedComponent != null) {
+
+ Resource component = graph.getSingleObject(mappedComponent, MOD.ElementToComponent);
+ Variable variable = Variables.getVariable(graph, component);
+ Variable possibleActiveVariable = Variables.possibleActiveVariable(graph, variable);
+ if (possibleActiveVariable != null) {
+
+ Variable module = possibleActiveVariable.getPossibleChild(graph, dsc.getModuleName());
+ if (module != null) {
+ Variable attribute = module.getPossibleProperty(graph, dsc.getAttributeName());
+ if (attribute != null) {
+ Double possibleValue = attribute.getPossibleValue(graph, Bindings.DOUBLE);
+ if (possibleValue != null) {
+ // here we do the adjusting according to spec in #15038
+ double adjustedValue = possibleValue.doubleValue() * dsc.getVariableGain() + dsc.getVariableBias();
+ DynamicSizeMap defaultSizeMap = dsc.getDefaultSizeMap();
+ double size = defaultSizeMap.getSize(adjustedValue, dsc.getDefaultMin(), dsc.getDefaultMax());
+ return size;
+ } else {
+ LOGGER.warn("No value for {}", attribute.getURI(graph));
+ }
+ } else {
+ LOGGER.warn("Wrong attribute name {} for {} !!", dsc.getAttributeName(), module.getURI(graph));
+ }
+ } else {
+ LOGGER.warn("Wrong modulename {} for {} !!", dsc.getModuleName(), possibleActiveVariable.getURI(graph));
+ }
+ } else {
+ LOGGER.debug("No active experiment for {}", variable.getURI(graph));
+ }
+ } else {
+ LOGGER.debug("No mapped component for {} to calculate dynamic size style", groupItem);
+ }
+ }
+ }
+ }
+ finally {
+ graph.setSynchronous(wasSynchronous);
+ }
+ return null;
+ }
+
+ @Override
+ public void applyThrottledStyleForNode(EvaluationContext observer, INode node, Double value) {
+ //System.out.println("apply: " + node + " : " + value);
+ SingleElementNode n = (SingleElementNode) node;
+ if (value == PENDING) {
+ ((G2DSceneGraph)node.getRootNode()).setPending(node);
+ } else {
+ ((G2DSceneGraph)node.getRootNode()).clearPending(node);
+ }
+ if (value == null)
+ value = ONE;
+ for (INode nn : n.getNodes()) {
+ ProfileVariables.claimNodeProperty(nn, "size", value, observer);
+ ProfileVariables.claimNodeProperty(nn, "stroke", value, observer);
+ }
+ }
+
+ @Override
+ protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
+ ((G2DSceneGraph)node.getRootNode()).clearPending(node);
+ SingleElementNode n = (SingleElementNode) node;
+ for (INode nn : n.getNodes()) {
+ ProfileVariables.claimNodeProperty(nn, "size", ONE, evaluationContext);
+ ProfileVariables.claimNodeProperty(nn, "stroke", ONE, evaluationContext);
+ }
+ }
+
+}
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.district.network.ontology.DistrictNetworkResource;
+import org.simantics.layer0.Layer0;
+
+/**
+ * @author Jani Simomaa
+ */
+public class DynamicVisualisationsRequest extends ResourceRead<Collection<NamedResource>> {
+
+ public DynamicVisualisationsRequest(Resource diagram) {
+ super(diagram);
+ }
+
+ @Override
+ public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ Collection<Resource> visualisationResources = graph.getObjects(resource, DN.Diagram_hasVisualisation);
+ List<NamedResource> results = new ArrayList<>();
+ if (visualisationResources != null && !visualisationResources.isEmpty()) {
+ for (Resource visualisationResource : visualisationResources) {
+ String name = graph.getRelatedValue(visualisationResource, Layer0.getInstance(graph).HasName);
+ results.add(new NamedResource(name, visualisationResource));
+ }
+ }
+ return results;
+ }
+
+}
import org.simantics.scenegraph.INode;
import org.simantics.scenegraph.g2d.nodes.SingleElementNode;
import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.common.ProfileVariables;
/**
* @author Tuukka Lehtonen
}
@Override
- public void applyStyleForNode(EvaluationContext observer, INode node, Boolean result) {
+ public void applyStyleForNode(EvaluationContext evaluationContext, INode node, Boolean result) {
SingleElementNode n = (SingleElementNode) node;
- n.setVisible(false);
+ for (INode nn : n.getNodes())
+ ProfileVariables.claimNodeProperty(nn, "hidden", true, evaluationContext);
}
-
+
@Override
protected void cleanupStyleForNode(EvaluationContext evaluationContext, INode node) {
SingleElementNode n = (SingleElementNode) node;
- n.setVisible(true);
+ for (INode nn : n.getNodes())
+ ProfileVariables.claimNodeProperty(nn, "hidden", false, evaluationContext);
}
@Override
--- /dev/null
+package org.simantics.district.network.profile;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+
+public class MidBranchEdgeSetRequest extends ResourceRead<Set<Resource>> {
+ public MidBranchEdgeSetRequest(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public Set<Resource> perform(ReadGraph graph) throws DatabaseException {
+ List<Resource> edges = Simantics.applySCL("Simantics/District/Algorithm", "midBranchEdges", graph, resource);
+ return new HashSet<>(edges);
+ }
+}
--- /dev/null
+package org.simantics.district.network.profile;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.district.network.visualisations.model.DynamicVisualisation;
+
+/**
+ * @author Jani Simomaa
+ */
+public class RuntimeDynamicVisualisationsRequest extends ResourceRead<DynamicVisualisation> {
+
+ public RuntimeDynamicVisualisationsRequest(Resource runtimeDiagram) {
+ super(runtimeDiagram);
+ }
+
+ @Override
+ public DynamicVisualisation perform(ReadGraph graph) throws DatabaseException {
+ DiagramResource DIA = DiagramResource.getInstance(graph);
+ Resource diagram = graph.getPossibleObject(resource, DIA.RuntimeDiagram_HasConfiguration);
+ if (diagram != null) {
+ return graph.syncRequest(new ActiveDynamicVisualisationsRequest(diagram), TransientCacheAsyncListener.instance());
+ }
+ return null;
+ }
+
+}
private static final Logger LOGGER = LoggerFactory.getLogger(ThrottledStyleBase.class);
private static final long DEFAULT_INTERVAL = 2000;
- private long lastCalculateTimestamp = 0;
+ //private long lastCalculateTimestamp = 0;
private AtomicLong interval = new AtomicLong(DEFAULT_INTERVAL);
private Listener<Optional<Result>> resultListener;
--- /dev/null
+package org.simantics.district.network.visualisations;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.simantics.NameLabelUtil;
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ObjectsWithSupertype;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.district.network.visualisations.model.DynamicColorContribution;
+import org.simantics.district.network.visualisations.model.DynamicColorMap;
+import org.simantics.district.network.visualisations.model.DynamicSizeContribution;
+import org.simantics.district.network.visualisations.model.DynamicSizeMap;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.top.ValueNotFound;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.tuple.Tuple0;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicVisualisationsContributions {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DynamicVisualisationsContributions.class);
+
+ private static final String COMMON_DYNAMIC_VISUALISATIONS_MODULE = "CommonDynamicVisualisations";
+ private static final String COLOR_MAP_CONTRIBUTION = "colorMapContribution";
+ private static final String SIZE_MAP_CONTRIBUTION = "sizeMapContribution";
+
+ private static final String DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE = "DynamicVisualisationsContribution";
+ private static final String COLOR_CONTRIBUTION = "colorContribution";
+ private static final String SIZE_CONTRIBUTION = "sizeContribution";
+
+ public static Map<String, DynamicColorMap> dynamicColorMaps(ReadGraph graph) throws DatabaseException {
+ List<Resource> sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+
+ Map<String, DynamicColorMap> results = new HashMap<>();
+ Layer0 L0 = Layer0.getInstance(graph);
+ for (Resource sharedOntology : sharedOntologies) {
+ Resource sclModule = Layer0Utils.getPossibleChild(graph, sharedOntology, L0.SCLModule, COMMON_DYNAMIC_VISUALISATIONS_MODULE);
+ if (sclModule != null) {
+ String moduleURI = graph.getURI(sclModule);
+ Object oldGraph = SCLContext.getCurrent().get("graph");
+ try {
+ // let's put the graph to SCLContext for resolving the color maps
+ SCLContext.getCurrent().put("graph", graph);
+ @SuppressWarnings("unchecked")
+ List<DynamicColorMap> result = (List<DynamicColorMap>) SCLOsgi.MODULE_REPOSITORY.getValue(moduleURI, COLOR_MAP_CONTRIBUTION);
+
+ for (DynamicColorMap colorMap : result) {
+ results.put(colorMap.getLabel(), colorMap);
+ }
+ } catch (ValueNotFound e) {
+ e.printStackTrace();
+ } finally {
+ SCLContext.getCurrent().put("graph", oldGraph);
+ }
+ }
+ }
+ return results;
+ }
+
+ public static Map<String, DynamicSizeMap> dynamicSizeMaps(ReadGraph graph) throws DatabaseException {
+ List<Resource> sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+
+ Map<String, DynamicSizeMap> results = new HashMap<>();
+ Layer0 L0 = Layer0.getInstance(graph);
+ for (Resource sharedOntology : sharedOntologies) {
+ Resource sclModule = Layer0Utils.getPossibleChild(graph, sharedOntology, L0.SCLModule, COMMON_DYNAMIC_VISUALISATIONS_MODULE);
+ if (sclModule != null) {
+ String moduleURI = graph.getURI(sclModule);
+ Object oldGraph = SCLContext.getCurrent().get("graph");
+ try {
+ // let's put the graph to SCLContext for resolving the color maps
+ SCLContext.getCurrent().put("graph", graph);
+ @SuppressWarnings("unchecked")
+ List<DynamicSizeMap> result = (List<DynamicSizeMap>) SCLOsgi.MODULE_REPOSITORY.getValue(moduleURI, SIZE_MAP_CONTRIBUTION);
+
+ for (DynamicSizeMap sizeMap : result) {
+ results.put(sizeMap.getLabel(), sizeMap);
+ }
+ } catch (ValueNotFound e) {
+ e.printStackTrace();
+ } finally {
+ SCLContext.getCurrent().put("graph", oldGraph);
+ }
+ }
+ }
+ return results;
+ }
+
+ public static Collection<DynamicColoringObject> dynamicColoringObjects(ReadGraph graph) throws DatabaseException {
+
+ List<Resource> sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+
+ List<DynamicColoringObject> results = new ArrayList<>();
+
+ for (Resource sharedOntology : sharedOntologies) {
+ Collection<Resource> findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component));
+ //Collection<Resource> findByType = QueryIndexUtils.searchByType(graph, sharedOntology, );
+ for (Resource find : findByType) {
+ NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find);
+ DynamicColoringObject dynamicColoringObject = dynamicColoringObject(graph, moduleType);
+ if (dynamicColoringObject != null)
+ results.add(dynamicColoringObject);
+ }
+ }
+ return results;
+ }
+
+ public static Collection<DynamicSizingObject> dynamicSizingObjects(ReadGraph graph) throws DatabaseException {
+
+ List<Resource> sharedOntologies = Simantics.applySCL("Simantics/SharedOntologies", "getSharedOntologies", graph, Tuple0.INSTANCE);
+
+ List<DynamicSizingObject> results = new ArrayList<>();
+
+ for (Resource sharedOntology : sharedOntologies) {
+ Collection<Resource> findByType = graph.syncRequest(new ObjectsWithSupertype(sharedOntology, Layer0.getInstance(graph).ConsistsOf, StructuralResource2.getInstance(graph).Component));
+ //Collection<Resource> findByType = QueryIndexUtils.searchByType(graph, sharedOntology, );
+ for (Resource find : findByType) {
+ NamedResource moduleType = new NamedResource(NameLabelUtil.modalName(graph, find), find);
+ DynamicSizingObject dynamicSizingObject = dynamicSizingObject(graph, moduleType);
+ if (dynamicSizingObject != null)
+ results.add(dynamicSizingObject);
+ }
+ }
+ return results;
+ }
+
+ private static DynamicColoringObject dynamicColoringObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE);
+ if (sclModule != null) {
+ String moduleURI = graph.getURI(sclModule);
+ return new DynamicColoringObject(moduleType, getDynamicColorContributionSupplier(moduleURI, COLOR_CONTRIBUTION));
+ }
+ return null;
+ }
+
+// private static DynamicColoringMap dynamicColoringMap(ReadGraph graph, NamedResource moduleType) throws DatabaseException {
+// Layer0 L0 = Layer0.getInstance(graph);
+// Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE);
+// if (sclModule != null) {
+// String moduleURI = graph.getURI(sclModule);
+// return new DynamicColoringMap(moduleType, getDynamicColoringMapSupplier(moduleURI, COLOR_CONTRIBUTION));
+// }
+// return null;
+// }
+
+ private static DynamicSizingObject dynamicSizingObject(ReadGraph graph, NamedResource moduleType) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ Resource sclModule = Layer0Utils.getPossibleChild(graph, moduleType.getResource(), L0.SCLModule, DYNAMIC_VISUALISATIONS_CONTRIBUTION_MODULE);
+ if (sclModule != null) {
+ String moduleURI = graph.getURI(sclModule);
+ return new DynamicSizingObject(moduleType, getDynamicSizeContributionSupplier(moduleURI, SIZE_CONTRIBUTION));
+ }
+ return null;
+ }
+
+ private static Supplier<Stream<DynamicColorMap>> getDynamicColorMapSupplier(String uri, String expressionText) {
+ return () -> {
+ try {
+ @SuppressWarnings("unchecked")
+ List<DynamicColorMap> result = (List<DynamicColorMap>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, expressionText);
+ return result.stream();//result.stream().map(DynamicColorContribution::fromTuple9);
+ } catch (ValueNotFound e) {
+ LOGGER.error("Could not find contributions", e);
+ //throw new RuntimeException(e);
+ return Stream.empty();
+ }
+ };
+ }
+
+ private static Supplier<Stream<DynamicColorContribution>> getDynamicColorContributionSupplier(String uri, String expressionText) {
+ return () -> {
+ try {
+ @SuppressWarnings("unchecked")
+ List<DynamicColorContribution> result = (List<DynamicColorContribution>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, expressionText);
+ return result.stream();//result.stream().map(DynamicColorContribution::fromTuple9);
+ } catch (ValueNotFound e) {
+ LOGGER.error("Could not find contributions", e);
+ //throw new RuntimeException(e);
+ return Stream.empty();
+ }
+ };
+ }
+
+ private static Supplier<Stream<DynamicSizeContribution>> getDynamicSizeContributionSupplier(String uri, String expressionText) {
+ return () -> {
+ try {
+ @SuppressWarnings("unchecked")
+ List<DynamicSizeContribution> result = (List<DynamicSizeContribution>) SCLOsgi.MODULE_REPOSITORY.getValue(uri, expressionText);
+ return result.stream();//result.stream().map(DynamicColorContribution::fromTuple9);
+ } catch (ValueNotFound e) {
+ LOGGER.error("Could not find contributions", e);
+ //throw new RuntimeException(e);
+ return Stream.empty();
+ }
+ };
+ }
+
+ public static class DynamicColoringObject {
+
+ private final NamedResource coloringObject;
+ private final Supplier<Stream<DynamicColorContribution>> colorContributionSupplier;
+ private Map<String, DynamicColorContribution> colorContributions;
+
+ public DynamicColoringObject(NamedResource coloringObject, Supplier<Stream<DynamicColorContribution>> colorContributionSupplier) {
+ this.coloringObject = coloringObject;
+ this.colorContributionSupplier = colorContributionSupplier;
+ }
+
+ public NamedResource getColoringObject() {
+ return coloringObject;
+ }
+
+ public Map<String, DynamicColorContribution> getColorContributions() {
+ if (colorContributions == null)
+ colorContributions = colorContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c));
+ return colorContributions;
+ }
+ }
+
+ public static class DynamicColoringMap {
+
+ private final NamedResource coloringObject;
+ private final Supplier<Stream<DynamicColorMap>> colorContributionSupplier;
+ private Map<String, DynamicColorMap> colorContributions;
+
+ public DynamicColoringMap(NamedResource coloringObject, Supplier<Stream<DynamicColorMap>> colorContributionSupplier) {
+ this.coloringObject = coloringObject;
+ this.colorContributionSupplier = colorContributionSupplier;
+ }
+
+ public NamedResource getColoringObject() {
+ return coloringObject;
+ }
+
+ public Map<String, DynamicColorMap> getColorContributions() {
+ if (colorContributions == null)
+ colorContributions = colorContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c));
+ return colorContributions;
+ }
+ }
+
+ public static class DynamicSizingObject {
+
+ private final NamedResource sizingObject;
+ private final Supplier<Stream<DynamicSizeContribution>> sizeContributionSupplier;
+ private Map<String, DynamicSizeContribution> sizeContributions;
+
+ public DynamicSizingObject(NamedResource coloringObject, Supplier<Stream<DynamicSizeContribution>> sizeContributionSupplier) {
+ this.sizingObject = coloringObject;
+ this.sizeContributionSupplier = sizeContributionSupplier;
+ }
+
+ public NamedResource getSizingObject() {
+ return sizingObject;
+ }
+
+ public Map<String, DynamicSizeContribution> getSizeContributions() {
+ if (sizeContributions == null)
+ sizeContributions = sizeContributionSupplier.get().collect(Collectors.toMap(c -> c.getLabel(), c -> c));
+ return sizeContributions;
+ }
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations;
+
+public class VisualisationColoringObject {
+
+ private String label;
+ private boolean used;
+ private String variable;
+ private double min;
+ private double max;
+ private String unit;
+ private String colorMap;
+ private boolean isDefault;
+
+ public VisualisationColoringObject(String label, boolean used, String variable, double min, double max, String unit, String colorMap, boolean isDefault) {
+ this.label = label;
+ this.used = used;
+ this.variable = variable;
+ this.min = min;
+ this.max = max;
+ this.unit = unit;
+ this.colorMap = colorMap;
+ this.isDefault = isDefault;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public boolean isUsed() {
+ return used;
+ }
+
+ public String getVariable() {
+ return variable;
+ }
+
+ public double getMin() {
+ return min;
+ }
+
+ public double getMax() {
+ return max;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public String getColorMap() {
+ return colorMap;
+ }
+
+ public boolean isDefault() {
+ return isDefault;
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+public class ColorBarOptions {
+
+ private boolean showColorBars;
+ private boolean showColorBarsTicks;
+ private ColorBarsLocation location;
+ private ColorBarsSize size;
+
+ public boolean isShowColorBars() {
+ return showColorBars;
+ }
+
+ public ColorBarOptions showColorBars(boolean show) {
+ this.showColorBars = show;
+ return this;
+ }
+
+ public boolean isShowColorBarsTicks() {
+ return showColorBarsTicks;
+ }
+
+ public ColorBarOptions showColorBarsTicks(boolean show) {
+ this.showColorBarsTicks = show;
+ return this;
+ }
+
+ public ColorBarsLocation getLocation() {
+ return location;
+ }
+
+ public ColorBarOptions withLocation(ColorBarsLocation location) {
+ this.location = location;
+ return this;
+ }
+
+ public ColorBarsSize getSize() {
+ return size;
+ }
+
+ public ColorBarOptions withSize(ColorBarsSize size) {
+ this.size = size;
+ return this;
+ }
+
+ public enum ColorBarsLocation {
+ NORTH, EAST, SOUTH, WEST
+ }
+
+ public enum ColorBarsSize {
+ SMALL(1), MEDIUM(2), LARGE(3);
+
+ int size;
+
+ ColorBarsSize(int size) {
+ this.size = size;
+ }
+
+ public int getSize() {
+ return size;
+ }
+ }
+
+ public static ColorBarOptions useDefault() {
+ return new ColorBarOptions().showColorBars(true).withLocation(ColorBarsLocation.EAST).withSize(ColorBarsSize.SMALL);
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+public class DynamicColorContribution {
+
+ private String label;
+ private String moduleName;
+ private String attributeName;
+ private String unit;
+ private double variableGain;
+ private double variableBias;
+ private DynamicColorMap defaultColorMap;
+ private double defaultMin;
+ private double defaultMax;
+
+ // for graph persistence only
+ private boolean used;
+ private boolean useDefault;
+
+ public DynamicColorContribution(String label, String moduleName, String attributeName, String unit,
+ double variableGain, double variableBias, DynamicColorMap defaultColorMap, double defaultMin, double defaultMax) {
+ this.label = label;
+ this.moduleName = moduleName;
+ this.attributeName = attributeName;
+ this.unit = unit;
+ this.variableGain = variableGain;
+ this.variableBias = variableBias;
+ this.defaultColorMap = defaultColorMap;
+ this.defaultMin = defaultMin;
+ this.defaultMax = defaultMax;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+
+ public String getAttributeName() {
+ return attributeName;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public double getVariableGain() {
+ return variableGain;
+ }
+
+ public double getVariableBias() {
+ return variableBias;
+ }
+
+ public DynamicColorMap getDefaultColorMap() {
+ return defaultColorMap;
+ }
+
+ public double getDefaultMin() {
+ return defaultMin;
+ }
+
+ public double getDefaultMax() {
+ return defaultMax;
+ }
+
+ public void setUsed(boolean used) {
+ this.used = used;
+ }
+
+ public boolean isUsed() {
+ return used;
+ }
+
+ public void setUseDefault(boolean useDefault) {
+ this.useDefault = useDefault;
+ }
+
+ public boolean isUseDefault() {
+ return useDefault;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+import java.awt.Color;
+import java.util.Arrays;
+import java.util.List;
+
+public class DynamicColorMap {
+
+ static List<RGBIntensity> blues = Arrays.asList(new RGBIntensity(0, 0, 0.1), new RGBIntensity(0, 0, 0.5), new RGBIntensity(0, 0, 0.9));
+
+ public static final DynamicColorMap DEFAULT = new DynamicColorMap("default", blues);
+
+ private String label;
+ private List<RGBIntensity> intensities;
+
+ public DynamicColorMap(String label, List<RGBIntensity> intensities) {
+ this.label = label;
+ this.intensities = intensities;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public List<RGBIntensity> getIntensities() {
+ return intensities;
+ }
+
+ public static class RGBIntensity {
+
+ private double red;
+ private double green;
+ private double blue;
+
+ public RGBIntensity(double red, double green, double blue) {
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ }
+
+ public double getRed() {
+ return red;
+ }
+
+ public double getGreen() {
+ return green;
+ }
+
+ public double getBlue() {
+ return blue;
+ }
+ }
+
+ public Color getColor(double value, double defaultMin, double defaultMax) {
+
+ double gap = defaultMax - defaultMin;
+ double singleGap = gap / getIntensities().size();
+
+ int i = 0;
+ while (i < getIntensities().size() - 1) {
+ if (value <= defaultMin + (i * singleGap)) {
+ break;
+ }
+ i++;
+ }
+
+ RGBIntensity intensity = getIntensities().get(i);
+ return new Color((float)intensity.getRed(), (float)intensity.getGreen(), (float)intensity.getBlue());
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+public class DynamicSizeContribution {
+
+ private String label;
+ private String moduleName;
+ private String attributeName;
+ private String unit;
+ private double variableGain;
+ private double variableBias;
+ private DynamicSizeMap defaultSizeMap;
+ private double defaultMin;
+ private double defaultMax;
+
+ // for graph persistence only
+ private boolean used;
+ private boolean useDefault;
+
+ public DynamicSizeContribution(String label, String moduleName, String attributeName, String unit,
+ double variableGain, double variableBias, DynamicSizeMap defaultSizeMap, double defaultMin, double defaultMax) {
+ this.label = label;
+ this.moduleName = moduleName;
+ this.attributeName = attributeName;
+ this.unit = unit;
+ this.variableGain = variableGain;
+ this.variableBias = variableBias;
+ this.defaultSizeMap = defaultSizeMap;
+ this.defaultMin = defaultMin;
+ this.defaultMax = defaultMax;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getModuleName() {
+ return moduleName;
+ }
+
+ public String getAttributeName() {
+ return attributeName;
+ }
+
+ public String getUnit() {
+ return unit;
+ }
+
+ public double getVariableGain() {
+ return variableGain;
+ }
+
+ public double getVariableBias() {
+ return variableBias;
+ }
+
+ public DynamicSizeMap getDefaultSizeMap() {
+ return defaultSizeMap;
+ }
+
+ public double getDefaultMin() {
+ return defaultMin;
+ }
+
+ public double getDefaultMax() {
+ return defaultMax;
+ }
+
+ public boolean isUsed() {
+ return used;
+ }
+
+ public void setUsed(boolean used) {
+ this.used = used;
+ }
+
+ public boolean isUseDefault() {
+ return useDefault;
+ }
+
+ public void setUseDefault(boolean useDefault) {
+ this.useDefault = useDefault;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+import java.util.List;
+
+public class DynamicSizeMap {
+
+ private String label;
+ private List<Double> sizes;
+
+ public DynamicSizeMap(String label, List<Double> sizes) {
+ this.label = label;
+ this.sizes = sizes;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public List<Double> getSizes() {
+ return sizes;
+ }
+
+ public double getSize(double value, double defaultMin, double defaultMax) {
+
+ double gap = defaultMax - defaultMin;
+ double singleGap = gap / getSizes().size();
+
+ int i = 0;
+ while (i < getSizes().size() - 1) {
+ if (value <= defaultMin + (i * singleGap)) {
+ break;
+ }
+ i++;
+ }
+
+ return getSizes().get(i);
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+import java.util.Map;
+
+import org.simantics.db.Resource;
+
+public class DynamicVisualisation {
+
+ private String name;
+ private Resource visualisationResource;
+
+ private Map<String, DynamicColorContribution> colorContributions;
+ private ColorBarOptions colorBarOptions;
+ private Map<String, DynamicSizeContribution> sizeContributions;
+ private SizeBarOptions sizeBarOptions;
+
+ public DynamicVisualisation(String name, Resource visualisationResource, Map<String, DynamicColorContribution> colorContributions, ColorBarOptions colorBarOptions, Map<String, DynamicSizeContribution> sizeContributions, SizeBarOptions sizeBarOptions) {
+ this.name = name;
+ this.visualisationResource = visualisationResource;
+ this.colorContributions = colorContributions;
+ this.colorBarOptions = colorBarOptions;
+ this.sizeContributions = sizeContributions;
+ this.sizeBarOptions = sizeBarOptions;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Resource getVisualisationResource() {
+ return visualisationResource;
+ }
+
+ public Map<String, DynamicColorContribution> getColorContributions() {
+ return colorContributions;
+ }
+
+ public ColorBarOptions getColorBarOptions() {
+ return colorBarOptions;
+ }
+
+ public Map<String, DynamicSizeContribution> getSizeContributions() {
+ return sizeContributions;
+ }
+
+ public SizeBarOptions getSizeBarOptions() {
+ return sizeBarOptions;
+ }
+}
--- /dev/null
+package org.simantics.district.network.visualisations.model;
+
+public class SizeBarOptions {
+
+ private boolean showColorBars;
+ private boolean showColorBarsTicks;
+ private SizeBarsLocation location;
+ private SizeBarsSize size;
+
+ public boolean isShowSizeBars() {
+ return showColorBars;
+ }
+
+ public SizeBarOptions showSizeBars(boolean show) {
+ this.showColorBars = show;
+ return this;
+ }
+
+ public boolean isShowSizeBarsTicks() {
+ return showColorBarsTicks;
+ }
+
+ public SizeBarOptions showSizeBarsTicks(boolean show) {
+ this.showColorBarsTicks = show;
+ return this;
+ }
+
+ public SizeBarsLocation getLocation() {
+ return location;
+ }
+
+ public SizeBarOptions withLocation(SizeBarsLocation location) {
+ this.location = location;
+ return this;
+ }
+
+ public SizeBarsSize getSize() {
+ return size;
+ }
+
+ public SizeBarOptions withSize(SizeBarsSize size) {
+ this.size = size;
+ return this;
+ }
+ public enum SizeBarsLocation {
+ NORTH, EAST, SOUTH, WEST
+ }
+
+ public enum SizeBarsSize {
+ SMALL(1), MEDIUM(2), LARGE(3);
+
+ int size;
+
+ SizeBarsSize(int size) {
+ this.size = size;
+ }
+
+ public double getSize() {
+ return size;
+ }
+ }
+
+ public static SizeBarOptions useDefault() {
+ return new SizeBarOptions().showSizeBars(true).withLocation(SizeBarsLocation.EAST).withSize(SizeBarsSize.SMALL);
+ }
+}
public Object[] getElements(Object inputElement) {
if (inputElement == null && (!(inputElement instanceof Collection)))
return new Object[0];
- Set<DiagramRegion> set = (Set) inputElement;
+ @SuppressWarnings("unchecked")
+ Set<DiagramRegion> set = (Set<DiagramRegion>) inputElement;
return set.toArray();
}
public class RemoveRegionHandler {
- private static final Logger LOGGER = LoggerFactory.getLogger(RemoveRegionHandler.class);
+ @SuppressWarnings("unused")
+ private static final Logger LOGGER = LoggerFactory.getLogger(RemoveRegionHandler.class);
public static final String COMMAND_ID = "org.simantics.district.region.ui.command.removeRegion";
public static final String LABEL = "Remove Region";
Bundle-Vendor: Semantum Oy
Require-Bundle: org.simantics.layer0,
org.simantics.district.network.ontology;bundle-version="1.0.0",
- org.simantics.diagram.ontology;bundle-version="2.2.0"
+ org.simantics.diagram.ontology;bundle-version="2.2.0",
+ org.simantics.action.ontology;bundle-version="1.1.0",
+ org.simantics.silk.ontology;bundle-version="1.1.0",
+ org.simantics.viewpoint.ontology;bundle-version="1.2.0"
Automatic-Module-Name: fi.vtt.apros.district.route.ontology
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: org.simantics.district.route.ontology
--- /dev/null
+L0 = <http://www.simantics.org/Layer0-1.1>
+DN = <http://www.simantics.org/DistrictNetwork-1.0>
+DNR = <http://www.simantics.org/DistrictNetworkRoutes-1.0>
+VP = <http://www.simantics.org/Viewpoint-1.2>
+ACT = <http://www.simantics.org/Action-1.1>
+SILK = <http://www.simantics.org/Silk-1.1>
+
+RAC = DNR.RouteActionContext : VP.BrowseContext
+ @VP.actionContribution "Select Route" DNR.Route SILK.wand VP.EditActionCategory DNR.Actions.SelectRoute
+ @VP.actionContribution "Validate Route" DNR.Route SILK.accept VP.EditActionCategory DNR.Actions.ValidateRoute
+
+DNR.Actions : L0.Library
+
+DNR.Actions.SelectRoute : ACT.Action
+DNR.Actions.ValidateRoute : ACT.Action
\ No newline at end of file
public class RouteResource {
+ public final Resource Actions;
+ public final Resource Actions_SelectRoute;
+ public final Resource Actions_ValidateRoute;
public final Resource Route;
+ public final Resource RouteActionContext;
public final Resource RouteFolder;
public static class URIs {
+ public static final String Actions = "http://www.simantics.org/DistrictNetworkRoutes-1.0/Actions";
+ public static final String Actions_SelectRoute = "http://www.simantics.org/DistrictNetworkRoutes-1.0/Actions/SelectRoute";
+ public static final String Actions_ValidateRoute = "http://www.simantics.org/DistrictNetworkRoutes-1.0/Actions/ValidateRoute";
public static final String Route = "http://www.simantics.org/DistrictNetworkRoutes-1.0/Route";
+ public static final String RouteActionContext = "http://www.simantics.org/DistrictNetworkRoutes-1.0/RouteActionContext";
public static final String RouteFolder = "http://www.simantics.org/DistrictNetworkRoutes-1.0/RouteFolder";
}
}
public RouteResource(ReadGraph graph) {
+ Actions = getResourceOrNull(graph, URIs.Actions);
+ Actions_SelectRoute = getResourceOrNull(graph, URIs.Actions_SelectRoute);
+ Actions_ValidateRoute = getResourceOrNull(graph, URIs.Actions_ValidateRoute);
Route = getResourceOrNull(graph, URIs.Route);
+ RouteActionContext = getResourceOrNull(graph, URIs.RouteActionContext);
RouteFolder = getResourceOrNull(graph, URIs.RouteFolder);
}
org.simantics.ui,
org.simantics.district.route,
org.simantics.district.network.ui;bundle-version="1.0.0",
- org.slf4j.api
+ org.slf4j.api,
+ org.simantics.modeling.ui;bundle-version="1.1.1"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Automatic-Module-Name: fi.vtt.apros.district.route.ui
Import-Package: javax.annotation;version="1.0.0";resolution:=optional,
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<adapters>
+ <target interface="org.simantics.db.layer0.adapter.ActionFactory">
+ <resource uri="http://www.simantics.org/DistrictNetworkRoutes-1.0/Actions/SelectRoute"
+ class="org.simantics.district.route.ui.actions.SelectRouteAction" />
+ </target>
+ <target interface="org.simantics.db.layer0.adapter.ActionFactory">
+ <resource uri="http://www.simantics.org/DistrictNetworkRoutes-1.0/Actions/ValidateRoute"
+ class="org.simantics.district.route.ui.actions.ValidateRouteAction" />
+ </target>
+</adapters>
bin.includes = META-INF/,\
.,\
plugin.xml,\
+ adapters.xml,\
fragment.e4xmi,\
OSGI-INF/
<elements xsi:type="commands:Command" xmi:id="_k63rkP6zEeiBo8tg-6EPYA" elementId="org.simantics.district.route.ui.command.selectRouteOnDiagram" commandName="Select Route on Diagram"/>
<elements xsi:type="commands:Command" xmi:id="_bA61IAI7EemGocelWS26pQ" elementId="org.simantics.district.route.ui.command.discardRoute" commandName="Discard Route"/>
<elements xsi:type="commands:Command" xmi:id="_bfN6sAI7EemGocelWS26pQ" elementId="org.simantics.district.route.ui.command.renameRoute" commandName="Rename Route"/>
+ <elements xsi:type="commands:Command" xmi:id="_Of1BQGp0EemcK4j7CyatJA" elementId="org.simantics.district.route.ui.command.activatecreateroute" commandName="Activate Create Route"/>
+ <elements xsi:type="commands:Command" xmi:id="_QSvwYGp0EemcK4j7CyatJA" elementId="org.simantics.district.route.ui.command.deactivatecreateroute" commandName="Deactivate Create Route"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_1Ds_gMqVEeeUz6Cs9kKeKg" featurename="handlers" parentElementId="xpath:/">
<elements xsi:type="commands:Handler" xmi:id="_1G5RYH4WEei74IuRct85qQ" elementId="org.simantics.district.route.ui.handlers.openRouteView" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.OpenRouteView" command="_x1nG0H4WEei74IuRct85qQ"/>
<elements xsi:type="commands:Handler" xmi:id="_O9tbQP60EeiBo8tg-6EPYA" elementId="org.simantics.district.route.ui.handlers.selectRouteOnDiagram" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.handlers.SelectRouteOnDiagram" command="_k63rkP6zEeiBo8tg-6EPYA"/>
<elements xsi:type="commands:Handler" xmi:id="_mRg_oAI7EemGocelWS26pQ" elementId="org.simantics.district.route.ui.handler.discardRoute" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.handlers.DiscardRoute" command="_bA61IAI7EemGocelWS26pQ"/>
<elements xsi:type="commands:Handler" xmi:id="_mh_EkAI7EemGocelWS26pQ" elementId="org.simantics.district.route.ui.handler.renameRoute" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.handlers.RenameRoute" command="_bfN6sAI7EemGocelWS26pQ"/>
+ <elements xsi:type="commands:Handler" xmi:id="_YkoHAGp0EemcK4j7CyatJA" elementId="org.simantics.district.route.ui.handler.0" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.handlers.ActivateCreateRoute" command="_Of1BQGp0EemcK4j7CyatJA"/>
+ <elements xsi:type="commands:Handler" xmi:id="_aQl5kGp0EemcK4j7CyatJA" elementId="org.simantics.district.route.ui.handler.1" contributionURI="bundleclass://org.simantics.district.route.ui/org.simantics.district.route.ui.handlers.DeactivateCreateRoute" command="_QSvwYGp0EemcK4j7CyatJA"/>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_Fso08MrIEeeUz6Cs9kKeKg" featurename="toolBarContributions" parentElementId="xpath:/"/>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_WNB8EH4oEei74IuRct85qQ" featurename="trimContributions" parentElementId="xpath:/">
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuContribution;
import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MToolBar;
import org.eclipse.e4.ui.services.EMenuService;
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
import org.eclipse.swt.widgets.Composite;
}
}
part.getMenus().add(popupMenu);
+
+ /**
+ * See
+ * http://www.vogella.com/tutorials/EclipsePlugin/article.html#adding-eclipse-4-x-parts-to-eclipse-3-x-applications-via-the-code-org-eclipse-ui-views-code-extension-point
+ *
+ * Cannot contribute toolbar items via fragment at this point
+ */
+ MToolBar toolBar = MMenuFactory.INSTANCE.createToolBar();
+ toolBar.setToBeRendered(true);
+ toolBar.getChildren().add(createActivateRouteToolItem(app));
+ toolBar.getChildren().add(createDeactivateRouteToolItem(app));
+ part.setToolbar(toolBar);
+ }
+
+
+ private static MHandledToolItem createActivateRouteToolItem(MApplication app) {
+ MHandledToolItem createHandledToolItem = MMenuFactory.INSTANCE.createHandledToolItem();
+ createHandledToolItem.setCommand(app.getCommand("org.simantics.district.route.ui.command.activatecreateroute")); // Command is contributed via fragment //$NON-NLS-1$
+ createHandledToolItem.setLabel("Activate create route");
+ createHandledToolItem.setIconURI("platform:/plugin/com.famfamfam.silk/icons/table_add.png"); //$NON-NLS-1$
+ createHandledToolItem.setEnabled(true);
+ return createHandledToolItem;
+ }
+
+ private static MHandledToolItem createDeactivateRouteToolItem(MApplication app) {
+ MHandledToolItem createHandledToolItem = MMenuFactory.INSTANCE.createHandledToolItem();
+ createHandledToolItem.setCommand(app.getCommand("org.simantics.district.route.ui.command.deactivatecreateroute")); // Command is contributed via fragment //$NON-NLS-1$
+ createHandledToolItem.setLabel("Deactivate create route");
+ createHandledToolItem.setIconURI("platform:/plugin/com.famfamfam.silk/icons/table_edit.png"); //$NON-NLS-1$
+ createHandledToolItem.setEnabled(true);
+ return createHandledToolItem;
}
@PostConstruct
--- /dev/null
+package org.simantics.district.route.ui.actions;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.eclipse.swt.widgets.Display;
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.district.network.ui.DistrictNetworkUIUtil;
+import org.simantics.district.route.Route;
+import org.simantics.district.route.RouteJob;
+import org.simantics.district.route.RouterConfiguration;
+import org.simantics.district.route.internal.RoutePersistence;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SelectRouteAction implements ActionFactory {
+
+ protected static final Logger LOGGER = LoggerFactory.getLogger(SelectRouteAction.class);
+
+ @Override
+ public Runnable create(Object target) {
+ if (!(target instanceof Resource))
+ return null;
+
+ return new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Route route = Simantics.getSession().syncRequest(new RoutePersistence.RouteRequest((Resource)target));
+ if (route == null) {
+ LOGGER.error("Reading a route object failed"); //$NON-NLS-1$
+ return;
+ }
+
+ CompletableFuture<List<Resource>> result = new CompletableFuture<>();
+ result
+ .exceptionally(e -> Collections.emptyList())
+ .thenAccept(dnElements -> {
+ if (!dnElements.isEmpty()) {
+ try {
+ Display display = Display.getDefault();
+ if (display != null)
+ DistrictNetworkUIUtil.openDNDiagramWithSelection(display, dnElements);
+ else
+ LOGGER.error("No display found"); //$NON-NLS-1$
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to open district network diagram with selection " + dnElements, e); //$NON-NLS-1$
+
+ }
+ }
+ });
+
+ RouterConfiguration config = new RouterConfiguration();
+ new RouteJob(config, route, result).schedule();
+ }
+ catch (DatabaseException e) {
+ LOGGER.error("Error in selecting route " + target, e); //$NON-NLS-1$
+ }
+ }
+ };
+ }
+
+}
--- /dev/null
+package org.simantics.district.route.ui.actions;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.ActionFactory;
+import org.simantics.district.route.Route;
+import org.simantics.district.route.RouteJob;
+import org.simantics.district.route.RouterConfiguration;
+import org.simantics.district.route.internal.RoutePersistence;
+import org.simantics.utils.ui.dialogs.ShowMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ValidateRouteAction implements ActionFactory {
+
+ protected static final Logger LOGGER = LoggerFactory.getLogger(ValidateRouteAction.class);
+
+ @Override
+ public Runnable create(Object target) {
+ if (!(target instanceof Resource))
+ return null;
+
+ return new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Route route = Simantics.getSession().syncRequest(new RoutePersistence.RouteRequest((Resource)target));
+ if (route == null) {
+ ShowMessage.showInformation("Route Validation", "Reading the route object failed");
+ LOGGER.error("Reading a route object failed"); //$NON-NLS-1$
+ return;
+ }
+
+ CompletableFuture<List<Resource>> result = new CompletableFuture<>();
+ result.exceptionally(e -> null).thenAccept(dnElements -> {
+ if (dnElements != null) {
+ if (!dnElements.isEmpty())
+ ShowMessage.showInformation("Route Validation", "The route is valid");
+ else
+ ShowMessage.showInformation("Route Validation", "The route produced an empty list of vertices");
+ }
+ });
+
+ RouterConfiguration config = new RouterConfiguration();
+ new RouteJob(config, route, result).schedule();
+ }
+ catch (DatabaseException e) {
+ LOGGER.error("Error in selecting route " + target, e); //$NON-NLS-1$
+ }
+ }
+ };
+ }
+}
--- /dev/null
+package org.simantics.district.route.ui.handlers;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.district.network.ui.participants.RoutingMode;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * @author Jani Simomaa
+ */
+public class ActivateCreateRoute {
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor != null && activeEditor instanceof DistrictDiagramEditor) {
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditor;
+ DiagramViewer viewer = editor.getAdapter(DiagramViewer.class);
+ ICanvasContext context = viewer.getAdapter(ICanvasContext.class);
+ RoutingMode routingMode = context.getAtMostOneItemOfClass(RoutingMode.class);
+ return routingMode == null;
+ }
+ return false;
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell,
+ @Named(IServiceConstants.ACTIVE_PART) MPart part,
+ @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor != null && activeEditor instanceof DistrictDiagramEditor) {
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditor;
+ DiagramViewer viewer = editor.getAdapter(DiagramViewer.class);
+ ICanvasContext context = viewer.getAdapter(ICanvasContext.class);
+ RoutingMode routingMode = context.getAtMostOneItemOfClass(RoutingMode.class);
+ if (routingMode == null || routingMode.isRemoved()) {
+ routingMode = new RoutingMode(0);
+ context.add(routingMode);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.district.route.ui.handlers;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.CanExecute;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.simantics.district.network.ui.DistrictDiagramEditor;
+import org.simantics.district.network.ui.participants.RoutingMode;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.modeling.ui.diagramEditor.DiagramViewer;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * @author Jani Simomaa
+ */
+public class DeactivateCreateRoute {
+
+ @CanExecute
+ public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor != null && activeEditor instanceof DistrictDiagramEditor) {
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditor;
+ DiagramViewer viewer = editor.getAdapter(DiagramViewer.class);
+ ICanvasContext context = viewer.getAdapter(ICanvasContext.class);
+ RoutingMode routingMode = context.getAtMostOneItemOfClass(RoutingMode.class);
+ return routingMode != null;
+ }
+ return false;
+ }
+
+ @Execute
+ public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell activeShell,
+ @Named(IServiceConstants.ACTIVE_PART) MPart part,
+ @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
+
+ IEditorPart activeEditor = WorkbenchUtils.getActiveEditor();
+ if (activeEditor != null && activeEditor instanceof DistrictDiagramEditor) {
+ DistrictDiagramEditor editor = (DistrictDiagramEditor) activeEditor;
+ DiagramViewer viewer = editor.getAdapter(DiagramViewer.class);
+ ICanvasContext context = viewer.getAdapter(ICanvasContext.class);
+
+// context.getSceneGraph
+//
+// RoutingMode routingMode = context.getAtMostOneItemOfClass(RoutingMode.class);
+// if (routingMode == null || routingMode.isRemoved()) {
+// routingMode = new RoutingMode(0);
+// context.add(routingMode);
+// }
+ }
+ }
+}
\ No newline at end of file
List<Router> routers();
+ Route readRoute(Object backendRouteObject);
+
}
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.QueryIndexUtils;
import org.simantics.db.layer0.request.PossibleActiveModel;
+import org.simantics.db.layer0.request.PossibleModel;
import org.simantics.db.layer0.util.RemoverUtil;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.route.Waypoint;
List<RouteImpl> routes = new ArrayList<>();
for (Resource route : graph.syncRequest(new ObjectsWithType(rf, L0.ConsistsOf, RR.Route))) {
- RouteImpl ri = new RouteImpl(graph.getRelatedValue(route, L0.HasLabel, Bindings.STRING))
- .backend(route)
- .modelEntity(model)
- .waypoints(toWaypoints(graph, ListUtils.toList(graph, route)));
- routes.add(ri);
+ routes.add(getRoute(graph, model, route));
}
return routes;
}
+ public static RouteImpl getRoute(ReadGraph graph, Resource model, Resource route) throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ RouteImpl ri = new RouteImpl(graph.getRelatedValue(route, L0.HasLabel, Bindings.STRING))
+ .backend(route)
+ .modelEntity(model)
+ .waypoints(toWaypoints(graph, ListUtils.toList(graph, route)));
+ return ri;
+ }
+
+ public static class RouteRequest extends ResourceRead<RouteImpl> {
+ public RouteRequest(Resource resource) {
+ super(resource);
+ }
+
+ @Override
+ public RouteImpl perform(ReadGraph graph) throws DatabaseException {
+ Resource model = graph.syncRequest(new PossibleModel(resource));
+ return model != null ? getRoute(graph, model, resource) : null;
+ }
+ }
+
public static class ModelRoutesRequest extends ResourceRead<List<RouteImpl>> {
public ModelRoutesRequest(Resource model) {
super(model);
return findRoutes(graph, resource);
}
}
-
+
public static class ActiveModelRoutesRequest extends UniqueRead<List<RouteImpl>> {
@Override
public List<RouteImpl> perform(ReadGraph graph) throws DatabaseException {
import org.simantics.db.Session;
import org.simantics.db.common.procedure.adapter.DisposableListener;
import org.simantics.db.common.procedure.adapter.DisposableSyncListener;
+import org.simantics.db.exception.DatabaseException;
import org.simantics.db.layer0.request.PossibleActiveModel;
import org.simantics.db.management.ISessionContext;
import org.simantics.db.management.ISessionContextChangedListener;
});
}
+ @Override
+ public Route readRoute(Object backendRouteObject) {
+ if (!(backendRouteObject instanceof Resource))
+ return null;
+
+ try {
+ return Simantics.getSession().syncRequest(new RoutePersistence.RouteRequest((Resource)backendRouteObject));
+ } catch (DatabaseException e) {
+ LOGGER.error("Failed to read district route object for " + backendRouteObject, e);
+ return null;
+ }
+ }
+
}
public class DeleteElementSelector {
+ @SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(DeleteElementSelector.class);
@Inject
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.simantics.maps.elevation.server.ui"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.maps.elevation.server.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics Maps Elevation Server UI
+Bundle-SymbolicName: org.simantics.maps.elevation.server.ui;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.maps.elevation.server.ui.Activator
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.slf4j.api;bundle-version="1.7.25",
+ org.simantics.maps.elevation.server;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Automatic-Module-Name: org.simantics.maps.elevation.server.ui
+Bundle-ActivationPolicy: lazy
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.simantics.district.network.ui.preferences"
+ class="org.simantics.maps.elevation.server.ui.MapsElevationServerPreferencePage"
+ id="org.simantics.maps.elevation.server.ui.preferences"
+ name="Elevation server">
+ </page>
+ </extension>
+</plugin>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.simantics.district</groupId>
+ <artifactId>org.simantics.district.root</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.simantics.maps.elevation.server.ui</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+
+</project>
--- /dev/null
+package org.simantics.maps.elevation.server.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.simantics.maps.elevation.server.ui"; //$NON-NLS-1$
+
+ // The shared instance
+ private static Activator plugin;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+}
--- /dev/null
+package org.simantics.maps.elevation.server.ui;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.preference.StringFieldEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.preferences.ScopedPreferenceStore;
+import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MapsElevationServerPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(MapsElevationServerPreferencePage.class);
+
+ public MapsElevationServerPreferencePage() {
+ super(GRID);
+ setDescription("Maps elevation server preferences");
+ }
+
+ @Override
+ protected IPreferenceStore doGetPreferenceStore() {
+ return new ScopedPreferenceStore(InstanceScope.INSTANCE, MapsElevationServerPreferences.P_NODE);
+ }
+
+ private void createGeneralGroup() {
+ Group serverGroup = new Group(getFieldEditorParent(), SWT.NONE);
+ serverGroup.setText("General");
+ GridDataFactory.fillDefaults().grab(true, false).span(2, 1).applyTo(serverGroup);
+
+ BooleanFieldEditor automatically = new BooleanFieldEditor(MapsElevationServerPreferences.P_USE_ELEVATION_SERVER, "Use elevation server", serverGroup);
+ addField(automatically);
+
+ StringFieldEditor tifFolderPath = new StringFieldEditor(MapsElevationServerPreferences.P_TIFF_FOLDER_PATH, "Tiff folder path", serverGroup);
+ addField(tifFolderPath);
+
+ IntegerFieldEditor pipeDepth = new IntegerFieldEditor(MapsElevationServerPreferences.P_PIPE_DEPTH_UNDER_GROUND, "Pipe depth under ground", serverGroup);
+ pipeDepth.setValidRange(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ addField(pipeDepth);
+
+ GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(serverGroup);
+ }
+
+ @Override
+ protected void createFieldEditors() {
+ createGeneralGroup();
+
+ }
+
+ @Override
+ protected void performApply() {
+ super.performApply();
+ }
+
+ @Override
+ public boolean performOk() {
+ boolean ok = super.performOk();
+ if (ok) {
+ try {
+ SingletonTiffTileInterface.reloadElevationServer();
+ } catch (Exception e) {
+ LOGGER.error("Could not reload elevation server", e);
+ setErrorMessage(e.getMessage());
+ return false;
+ }
+ }
+ return ok;
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+
+ }
+
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.maps.elevation.server</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics Maps Elevation Server
+Bundle-SymbolicName: org.simantics.maps.elevation.server;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Automatic-Module-Name: org.simantics.maps.elevation.server
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.simantics.district.geotools;bundle-version="1.0.0",
+ org.slf4j.api;bundle-version="1.7.25",
+ com.github.benmanes.caffeine;bundle-version="2.6.2",
+ org.eclipse.osgi,
+ org.eclipse.core.runtime;bundle-version="3.13.0",
+ org.eclipse.equinox.preferences
+Export-Package: org.simantics.maps.elevation.server,
+ org.simantics.maps.elevation.server.prefs
+Bundle-ActivationPolicy: lazy
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ scl/
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.simantics.district</groupId>
+ <artifactId>org.simantics.district.root</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.simantics.maps.elevation.server</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+
+</project>
--- /dev/null
+
+importJava "org.simantics.maps.elevation.server.SingletonTiffTileInterface" where
+ @JavaName lookupd
+ lookupElevation :: Double -> Double -> <Proc> Double
\ No newline at end of file
--- /dev/null
+package org.simantics.maps.elevation.server;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.imageio.spi.IIORegistry;
+import javax.imageio.spi.ImageInputStreamSpi;
+import javax.imageio.spi.ImageOutputStreamSpi;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import it.geosolutions.imageio.stream.input.spi.FileImageInputStreamExtImplSpi;
+import it.geosolutions.imageio.stream.input.spi.StringImageInputStreamSpi;
+import it.geosolutions.imageio.stream.input.spi.URLImageInputStreamSpi;
+import it.geosolutions.imageio.stream.output.spi.FileImageOutputStreamExtImplSpi;
+import it.geosolutions.imageio.stream.output.spi.StringImageOutputStreamSpi;
+import it.geosolutions.imageio.stream.output.spi.URLImageOutputStreamSpi;
+
+public class Activator implements BundleActivator {
+
+ private static AtomicBoolean registered = new AtomicBoolean(false);
+
+ public static final String PLUGIN_ID = "org.simantics.maps.elevation.server";
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ // register SPI's
+ registerSpis();
+ }
+
+ public static void registerSpis() {
+ if (!registered.getAndSet(true)) {
+ IIORegistry.getDefaultInstance().registerServiceProvider(new FileImageInputStreamExtImplSpi(), ImageInputStreamSpi.class);
+ IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageInputStreamSpi(), ImageInputStreamSpi.class);
+ IIORegistry.getDefaultInstance().registerServiceProvider(new StringImageInputStreamSpi(), ImageInputStreamSpi.class);
+ IIORegistry.getDefaultInstance().registerServiceProvider(new FileImageOutputStreamExtImplSpi(), ImageOutputStreamSpi.class);
+ IIORegistry.getDefaultInstance().registerServiceProvider(new URLImageOutputStreamSpi(), ImageOutputStreamSpi.class);
+ IIORegistry.getDefaultInstance().registerServiceProvider(new StringImageOutputStreamSpi(), ImageOutputStreamSpi.class);
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+
+ }
+
+}
--- /dev/null
+package org.simantics.maps.elevation.server;
+
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SingletonTiffTileInterface {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SingletonTiffTileInterface.class);
+
+ private static SingletonTiffTileInterface instance;
+ private TiffTileInterface tileInterface;
+
+ static {
+ // register spis
+ Activator.registerSpis();
+ }
+
+ private SingletonTiffTileInterface() {
+ Path tilesFolder = Paths.get(MapsElevationServerPreferences.tifFolderPath());
+ try {
+ Files.createDirectories(tilesFolder);
+ } catch (IOException e) {
+ LOGGER.error("Could not create directories {}", tilesFolder.toAbsolutePath(), e);
+ }
+ LOGGER.info("Elevation server looking for tif files at {}", tilesFolder.toAbsolutePath());
+ tileInterface = new TiffTileInterface(tilesFolder);
+ }
+
+ private static SingletonTiffTileInterface getInstance() {
+ if (instance == null ) {
+ synchronized (SingletonTiffTileInterface.class) {
+ if (instance == null) {
+ instance = new SingletonTiffTileInterface();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public static synchronized void reloadElevationServer() {
+ if (instance != null) {
+ try {
+ instance.tileInterface.close();
+ } catch (IOException e) {
+ LOGGER.error("Could not close current elevation server interface", e);
+ } finally {
+ instance = null;
+ }
+ }
+ // let's re-initialize
+ getInstance();
+ }
+
+ public static double lookupd(double x, double y) {
+ return lookup(x, y).doubleValue();
+ }
+
+ public static Number lookup(double x, double y) {
+ return getInstance().tileInterface.lookup(x, y);
+ }
+
+ public static Collection<Rectangle2D> getBoundingBoxes() {
+ return getInstance().tileInterface.getBoundingBoxes();
+ }
+}
--- /dev/null
+package org.simantics.maps.elevation.server;
+
+import java.awt.image.DataBuffer;
+import java.io.Closeable;
+import java.nio.file.Path;
+
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.gce.geotiff.GeoTiffReader;
+import org.geotools.geometry.Envelope2D;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.simantics.maps.elevation.server.prefs.MapsElevationServerPreferences;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TiffInterface implements Closeable {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TiffInterface.class);
+
+ private final Path tifPath;
+ private GridCoverage2D coverage;
+
+ private boolean init = false;
+
+ public TiffInterface(Path tifPath) {
+ this.tifPath = tifPath;
+ loadMetadata();
+ }
+
+ private void loadMetadata() {
+ GeoTiffReader reader = null;
+ try {
+ reader = new GeoTiffReader(this.tifPath.toFile());
+ this.coverage = reader.read(null);
+ this.init = true;
+ } catch (Exception e) {
+ LOGGER.error("Could not load {}", tifPath, e);
+ } finally {
+ if (reader != null) {
+ reader.dispose();
+ }
+ }
+ }
+
+ public boolean contains(DirectPosition pos) {
+ ensureInit();
+ Envelope2D e = coverage.getEnvelope2D();
+ try {
+ MathTransform transform = CRS.findMathTransform(pos.getCoordinateReferenceSystem(), getCRS(), false);
+ DirectPosition target = transform.transform(pos, null);
+ boolean contains = e.contains(target);
+ return contains;
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ public Number lookup(DirectPosition pos) {
+ ensureInit();
+ Object r = coverage.evaluate(pos);
+ final int dataType = coverage.getRenderedImage().getSampleModel().getDataType();
+ int pipeDepthUnderGround = MapsElevationServerPreferences.pipeDepthUnderGround();
+ switch (dataType) {
+ case DataBuffer.TYPE_BYTE: {
+ // TODO: if the result is byte how does one subtract the pipeDepth form the value?
+ // Might not be even relevant with this use case
+ return new Byte(((byte[]) r)[0]);
+ }
+ case DataBuffer.TYPE_SHORT: // Fall through
+ case DataBuffer.TYPE_USHORT: // Fall through
+ case DataBuffer.TYPE_INT: {
+ int val = ((int[]) r)[0] - pipeDepthUnderGround;
+ return new Integer(val);
+ }
+ case DataBuffer.TYPE_FLOAT: {
+ float val = ((float[]) r)[0] - pipeDepthUnderGround;
+ return new Float(val);
+ }
+ case DataBuffer.TYPE_DOUBLE: {
+ double val = ((double[]) r)[0] - pipeDepthUnderGround;
+ return new Double(val);
+ }
+ default: return null;
+ }
+ }
+
+ private void ensureInit() {
+ if (!init) {
+ throw new IllegalStateException("Interface is not initialized for " + this.tifPath);
+ }
+ }
+
+ public void close() {
+ coverage.dispose(true);
+ }
+
+ public Envelope2D getCornerCoords() {
+ return coverage.getEnvelope2D();
+ }
+
+ public CoordinateReferenceSystem getCRS() {
+ return coverage.getCoordinateReferenceSystem();
+ }
+}
--- /dev/null
+package org.simantics.maps.elevation.server;
+
+import java.awt.geom.Rectangle2D;
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.geotools.geometry.DirectPosition2D;
+import org.geotools.geometry.Envelope2D;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.index.strtree.STRtree;
+
+public class TiffTileInterface implements Closeable {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TiffTileInterface.class);
+
+ private Path tilesFolder;
+ private Map<Path, Envelope> envelopes = new ConcurrentHashMap<>();
+ private LoadingCache<Path, TiffInterface> interfaceCache;
+ private int openInterfacesSize;
+ private STRtree index;
+
+ public TiffTileInterface(Path tilesFolder) {
+ this(tilesFolder, 5);
+ }
+
+ public TiffTileInterface(Path tilesFolder, int openInterfacesSize) {
+ if (!Files.isDirectory(tilesFolder)) {
+ throw new IllegalArgumentException("tilesFolder has to be a folder: " + tilesFolder.toAbsolutePath());
+ }
+ this.tilesFolder = tilesFolder;
+ this.index = new STRtree();
+ this.openInterfacesSize = openInterfacesSize;
+
+ this.interfaceCache = Caffeine.newBuilder()
+ .maximumSize(this.openInterfacesSize)
+ .removalListener((key, gdalInterface, cause) -> ((TiffInterface) gdalInterface).close())
+ .build(key -> new TiffInterface(key));
+
+ try {
+ initializeIndex();
+ } catch (IOException e) {
+ LOGGER.error("Could not initialize index for folder {}", tilesFolder, e);
+ }
+ }
+
+ private TiffInterface openTifInterface(Path tifFile) {
+ return interfaceCache.get(tifFile);
+ }
+
+ private Stream<Path> allTiffFiles() throws IOException {
+ return Files.walk(tilesFolder).filter(Files::isRegularFile).filter(tif -> tif.getFileName().toString().endsWith(".tif"));
+ }
+
+ public void initializeIndex() throws IOException {
+ LOGGER.info("Initializing index..");
+ AtomicInteger counter = new AtomicInteger();
+ allTiffFiles().parallel().forEach(tifFile -> {
+ TiffInterface tifInterface = openTifInterface(tifFile);
+ Envelope2D coords = tifInterface.getCornerCoords();
+ try {
+ ReferencedEnvelope refEnv = new ReferencedEnvelope(coords);
+ ReferencedEnvelope targetEnv = refEnv.transform(c4326, false, 30);
+
+ synchronized(index) {
+ index.insert(targetEnv, tifFile);
+ }
+ envelopes.put(tifFile, targetEnv);
+ } catch (Exception e) {
+ LOGGER.error("Could not initialize index for file {}", tifFile, e);
+ } finally {
+ tifInterface.close();
+ int current = counter.getAndIncrement();
+ if (current % 100 == 0) {
+ LOGGER.info(" {}", current);
+ }
+ }
+ });
+ }
+
+ public Collection<Rectangle2D> getBoundingBoxes() {
+ Collection<Rectangle2D> rects = envelopes.values().stream().map(env -> {
+ double x = env.getMinX();
+ double y = env.getMinY();
+ return new Rectangle2D.Double(x, y, env.getMaxX() - x, env.getMaxY() - y);
+ }).collect(Collectors.toList());
+ return rects;
+ }
+
+ private static CoordinateReferenceSystem c4326;
+
+ static {
+ try {
+ c4326 = CRS.decode("EPSG:4326");
+ } catch (Exception e) {
+ LOGGER.error("Could not initialize epsg:4326", e);
+ }
+ }
+
+ public Number lookup(double x, double y) {
+ LOGGER.info("Looking up x={} y={}", x, y);
+ DirectPosition p = new DirectPosition2D(c4326, x, y);
+ List<Path> tifFiles = (List<Path>) index.query(new Envelope(new Coordinate(x, y)));
+ for (Path tifFile : tifFiles) {
+ TiffInterface tifInterface = openTifInterface(tifFile);
+ if (tifInterface.contains(p)) {
+ try {
+ return tifInterface.lookup(p);
+ } finally {
+ tifInterface.close();
+ }
+ } else {
+ System.out.println("not found");
+ }
+ }
+ return new Double(0); // use 0 by default for now
+ }
+
+ @Override
+ public void close() throws IOException {
+ interfaceCache.invalidateAll();
+ interfaceCache.cleanUp();
+
+ envelopes.clear();
+ envelopes = null;
+ index = null;
+ interfaceCache = null;
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.simantics.maps.elevation.server.prefs;
+
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.Preferences;
+import org.simantics.maps.elevation.server.Activator;
+
+public class MapsElevationServerPreferences {
+
+ public static final String P_NODE = Activator.PLUGIN_ID;
+
+ public static final String P_USE_ELEVATION_SERVER = "org.simantics.maps.elevation.server.useElevationServer";
+ public static final String P_TIFF_FOLDER_PATH = "org.simantics.maps.elevation.server.tifsFolderPath";
+ public static final String P_PIPE_DEPTH_UNDER_GROUND = "org.simantics.maps.elevation.server.pipeDepthUnderGround";
+
+ public static Preferences getPreferences() {
+ return InstanceScope.INSTANCE.getNode(MapsElevationServerPreferences.P_NODE);
+ }
+
+ public static boolean useElevationServer() {
+ return getPreferences().getBoolean(P_USE_ELEVATION_SERVER, false);
+ }
+
+ public static String tifFolderPath() {
+ return getPreferences().get(P_TIFF_FOLDER_PATH, "tifsFolder");
+ }
+
+ public static int pipeDepthUnderGround() {
+ return getPreferences().getInt(P_PIPE_DEPTH_UNDER_GROUND, -1);
+ }
+}
version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.simantics.maps.elevation.server"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="com.github.benmanes.caffeine"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
</feature>
String labelText = "";
String buttonText = "";
int labelColor = -1;
- boolean running = false;
try {
if (server.isRunning()) {
- running = true;
buttonText = "Stop";
labelText = "running";
labelColor = SWT.COLOR_DARK_GREEN;
package org.simantics.district.maps.server;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.HashMap;
public class TileserverMapnik {
private static final Logger LOGGER = LoggerFactory.getLogger(TileserverMapnik.class);
- private static final String[] ADDITIONAL_DEPENDENCIES = new String[] { "tilelive-vector@3.9.4", "tilelive-tmstyle@0.6.0" };
private SystemProcess process;
private Path serverRoot;
// }
- private Path tileserverMapnikRoot() {
+ @SuppressWarnings("unused")
+ private Path tileserverMapnikRoot() {
return serverRoot.resolve("tileserver-mapnik").toAbsolutePath();
}
return serverRoot.resolve("dist/share/icu").toAbsolutePath();
}
- private Path getTessera() {
+ @SuppressWarnings("unused")
+ private Path getTessera() {
return serverRoot.resolve("tileserver-mapnik/bin/tessera.js").toAbsolutePath();
}
return getDataDirectory().resolve(MapsServerPreferences.currentMBTiles());
}
+ @SuppressWarnings("unchecked")
public void checkTm2Styles() {
Path tm2 = getStyleDirectory();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(tm2)) {
<layout>p2</layout>
<url>${simantics-download-site}/${branch-spec}/sdk</url>
</repository>
+ <repository>
+ <id>external-components</id>
+ <layout>p2</layout>
+ <url>${simantics-download-site}/${branch-spec}/external-components/maven</url>
+ </repository>
</repositories>
<pluginRepositories>
<module>org.simantics.district.route.feature</module>
<module>org.simantics.district.ui.feature</module>
<module>org.simantics.maps.server.feature</module>
-
+
+ <module>org.simantics.maps.elevation.server</module>
+ <module>org.simantics.maps.elevation.server.ui</module>
+
<module>org.simantics.district.repository</module>
</modules>
</project>