Beispiel #1
0
 def testPolyline(self):
     p = czml.Polyline()
     p.color = {'rgba': [0, 255, 127, 55]}
     self.assertEqual(p.data(), {'color':
             {'rgba': [0, 255, 127, 55]},
             'show': False})
     p.outlineColor = {'rgbaf': [0.0, 0.255, 0.127, 0.55]}
     self.assertEqual(p.data(), {'color':
                 {'rgba': [0, 255, 127, 55]},
                 'outlineColor': {'rgbaf': [0.0, 0.255, 0.127, 0.55]},
                 'show': False})
     p.width = 10
     p.outlineWidth = 2
     p.show = True
     self.assertEqual(p.data(), {'color':
                     {'rgba': [0, 255, 127, 55]},
                 'width': 10,
                 'outlineColor':
                     {'rgbaf': [0.0, 0.255, 0.127, 0.55]},
                 'outlineWidth': 2,
                 'show': True})
     p2 = czml.Polyline()
     p2.loads(p.dumps())
     self.assertEqual(p.data(), p2.data())
Beispiel #2
0
    packet = czml.CZMLPacket(
        id=rail['segment'].lower().replace(' ', ""),
        status="t")  #id=str(random.randint(0, 99999)), name=rail['segment'])
    packet._name = rail['segment']
    packet._description = DummyObject(rail['segment'])

    props = list(packet._properties)
    props.append("status")
    packet._properties = props
    #print(packet._properties)
    packet.status = DummyObject(rail['new_track'])
    #packet._description = "t"#str(rail['new_track'])

    positions = czml.Positions(cartographicDegrees=positions)

    pl = czml.Polyline(positions=positions)
    if rail['new_track'].lower() == "new":
        color = {'rgba': [255, 0, 0, 255]}
    else:
        color = {'rgba': [0, 0, 255, 255]}
    pl.material = czml.Material(solidColor=czml.SolidColor(color=color))
    pl.width = 5
    pl.clampToGround = True
    # https://icons-for-free.com/iconfiles/png/512/express+harry+hogwarts+potter+train+icon-1320183591487406864.png

    packet.polyline = pl
    doc.packets.append(packet)

    # time packet

filename = "../wwwroot/test/rails.czml"
Beispiel #3
0
    def testCZMLPacket(self):
        p = czml.CZMLPacket(id='abc')
        self.assertEqual(p.dumps(), '{"id": "abc"}')
        bb = czml.Billboard()
        bb.image = 'http://localhost/img.png'
        bb.scale = 0.7
        bb.show = True
        p.billboard = bb
        self.assertEqual(p.data(),
            {'billboard': {'image': 'http://localhost/img.png',
            'scale': 0.7, 'show': True}, 'id': 'abc'})
        p2 = czml.CZMLPacket(id='abc')
        p2.loads(p.dumps())
        self.assertEqual(p.data(), p2.data())
        pos = czml.Position()
        coords = [7.0, 0.0, 1.0, 2.0, 6.0, 3.0, 4.0, 5.0]
        pos.cartesian = coords
        p.position = pos
        l = czml.Label()
        l.text = 'test label'
        l.show = False
        p.label = l
        self.assertEqual(p.data(),
            {'billboard': {'image': 'http://localhost/img.png',
            'scale': 0.7, 'show': True}, 'id': 'abc',
            'label': {'show': False, 'text': 'test label'},
            'position': {'cartesian': [7.0, 0.0, 1.0, 2.0, 6.0, 3.0, 4.0, 5.0]},
            })
        p2.loads(p.dumps())
        self.assertEqual(p.data(), p2.data())
        p3 = czml.CZMLPacket(id='cde')
        p3.point = {'color':
                    {'rgba': [0, 255, 127, 55]},
                    'show': True}
        self.assertEqual(p3.data(), {'id': 'cde',
                                    'point': {'color':
                                        {'rgba': [0, 255, 127, 55]},
                                        'show': True}})
        p32 = czml.CZMLPacket(id='abc')
        p32.loads(p3.dumps())
        self.assertEqual(p3.data(), p32.data())
        p4 = czml.CZMLPacket(id='defg')

        pl = czml.Polyline()
        pl.color = {'rgba': [0, 255, 127, 55]}
        pl.width = 10
        pl.outlineWidth = 2
        pl.show = True
        v = czml.VertexPositions()
        v.cartographicDegrees = [0.0, 0.0, .0, 1.0, 1.0, 1.0]
        p4.vertexPositions = v
        p4.polyline = pl
        self.assertEqual(p4.data(),
             {'polyline':
                {'color': {'rgba': [0, 255, 127, 55]},
                'width': 10,
                'outlineWidth': 2,
                'show': True},
            'id': 'defg',
            'vertexPositions':
                {'cartographicDegrees':
                    [0.0, 0.0, 0.0, 1.0, 1.0, 1.0]}
            })
        p42 = czml.CZMLPacket(id='abc')
        p42.loads(p4.dumps())
        self.assertEqual(p4.data(), p42.data())
        p5 = czml.CZMLPacket(id='efgh')
        p5.vertexPositions = v
        poly = czml.Polygon(color={'rgba': [0, 255, 127, 55]})
        p5.polygon = poly
        self.assertEqual(p5.data(),
            {'polygon':
                {'material':
                    {'solidColor':
                        {'color':
                            {'rgba': [0, 255, 127, 55]}}}},
                    'id': 'efgh',
                    'vertexPositions':
                        {'cartographicDegrees':
                            [0.0, 0.0, 0.0, 1.0, 1.0, 1.0]}})
        p52 = czml.CZMLPacket(id='abc')
        p52.loads(p5.dumps())
        self.assertEqual(p5.data(), p52.data())
        return p
Beispiel #4
0
    def testPolyline(self):

        # Create a new polyline
        sc = czml.SolidColor(color={'rgba': [0, 255, 127, 55]})
        m1 = czml.Material(solidColor=sc)
        c1 = geometry.LineString([(-162, 41, 0), (-151, 43, 0), (-140, 45, 0)])
        v1 = czml.Positions(cartographicDegrees=c1)
        p1 = czml.Polyline(show=True,
                           width=5,
                           followSurface=False,
                           material=m1,
                           positions=v1)
        self.assertEqual(
            p1.data(), {
                'show': True,
                'width': 5,
                'followSurface': False,
                'material': {
                    'solidColor': {
                        'color': {
                            'rgba': [0, 255, 127, 55]
                        }
                    },
                },
                'positions': {
                    'cartographicDegrees':
                    [-162, 41, 0, -151, 43, 0, -140, 45, 0]
                },
            })

        # Create a new polyline
        pg = czml.PolylineGlow(color={'rgba': [0, 255, 127, 55]},
                               glowPower=0.25)
        m2 = czml.Material(polylineGlow=pg)
        c2 = geometry.LineString([(1.6, 5.3, 10), (2.4, 4.2, 20),
                                  (3.8, 3.1, 30)])
        v2 = czml.Positions(cartographicRadians=c2)
        p2 = czml.Polyline(show=False,
                           width=7,
                           followSurface=True,
                           material=m2,
                           positions=v2)
        self.assertEqual(
            p2.data(), {
                'show': False,
                'width': 7,
                'followSurface': True,
                'material': {
                    'polylineGlow': {
                        'color': {
                            'rgba': [0, 255, 127, 55]
                        },
                        'glowPower': 0.25
                    },
                },
                'positions': {
                    'cartographicRadians':
                    [1.6, 5.3, 10, 2.4, 4.2, 20, 3.8, 3.1, 30]
                },
            })

        # Create a polyline from an existing polyline
        p3 = czml.Polyline()
        p3.loads(p2.dumps())
        self.assertEqual(p3.data(), p2.data())

        # Modify an existing polyline
        po = czml.PolylineOutline(color={'rgba': [0, 255, 127, 55]},
                                  outlineColor={'rgba': [0, 55, 127, 255]},
                                  outlineWidth=4)
        m3 = czml.Material(polylineOutline=po)
        c3 = geometry.LineString([(1000, 7500, 90), (2000, 6500, 50),
                                  (3000, 5500, 20)])
        v3 = czml.Positions(cartesian=c3)
        p3.material = m3
        p3.positions = v3
        self.assertEqual(
            p3.data(), {
                'show': False,
                'width': 7,
                'followSurface': True,
                'material': {
                    'polylineOutline': {
                        'color': {
                            'rgba': [0, 255, 127, 55]
                        },
                        'outlineColor': {
                            'rgba': [0, 55, 127, 255]
                        },
                        'outlineWidth': 4
                    },
                },
                'positions': {
                    'cartesian':
                    [1000, 7500, 90, 2000, 6500, 50, 3000, 5500, 20]
                },
            })

        # Add a polyline to a CZML packet
        packet = czml.CZMLPacket(id='abc')
        packet.polyline = p3
        self.assertEqual(
            packet.data(), {
                'id': 'abc',
                'polyline': {
                    'show': False,
                    'width': 7,
                    'followSurface': True,
                    'material': {
                        'polylineOutline': {
                            'color': {
                                'rgba': [0, 255, 127, 55]
                            },
                            'outlineColor': {
                                'rgba': [0, 55, 127, 255]
                            },
                            'outlineWidth': 4
                        },
                    },
                    'positions': {
                        'cartesian':
                        [1000, 7500, 90, 2000, 6500, 50, 3000, 5500, 20]
                    },
                },
            })
Beispiel #5
0
    def add_weighted_network(self, demographics, network, gradient_spec,
                             opacity_func):
        """Adds a weighted network visualization layer to a CZML output.

        This method emits a CZML animation that provides a visual representation
        of a weighted network between nodes.

        Returns:
            Number of network segments added

        Args:
            demographics (Demographics): Demographics object for nodes.

            network (array): array of objects::

                {
                    from: <from-node-id>,
                    to: <to-node-id>,
                    weight: <float-weight>
                }

            gradient_spec (str): gradient spec for a gradient with which to
            color the network lines.

            opacity_func (function): function(weight, norm_weight) that returns
            the desired opacity in range [0,1].

        """
        # First pass - collect min/max rate
        min_weight = network[0]["weight"]
        max_weight = network[0]["weight"]
        for segment in network:
            weight = segment["weight"]
            min_weight = weight if weight < min_weight else min_weight
            max_weight = weight if weight > max_weight else max_weight
        weight_range = max_weight - min_weight

        # Second pass - precalculate norm_weight and opacity
        for segment in network:
            weight = segment["weight"]
            norm_weight = (weight - min_weight) / weight_range
            segment["norm_weight"] = norm_weight
            segment["opacity"] = opacity_func(weight, norm_weight)

        # Sort network by opacity, lowest opacity first
        # network.sort(key=lambda seg: seg["opacity"])
        def sort_func(a, b):
            diff = a["opacity"] - b["opacity"]
            if diff < 0: return -1
            elif diff == 0: return 0
            else: return 1

        if sys.version_info.major == 3:
            # python 3: use a key function
            network = sorted(network, key=functools.cmp_to_key(sort_func))
        else:
            # python 2: use a cmp function
            network = sorted(network, cmp=sort_func)

        gradient = Gradient(gradient_spec)
        count = 0
        for segment in network:
            from_node = demographics[segment["from"]]
            to_node = demographics[segment["to"]]
            color = gradient.sample(segment["norm_weight"]).to_rgba_array()
            color[3] = int(segment["opacity"] * 255)
            # id = repr(segment["from"]) + "-" + repr(segment["to"])
            id = count
            packet = czml.CZMLPacket(id=id)
            positions = {
                "cartographicDegrees": [
                    from_node["NodeAttributes"]["Longitude"],
                    from_node["NodeAttributes"]["Latitude"], 0,
                    to_node["NodeAttributes"]["Longitude"],
                    to_node["NodeAttributes"]["Latitude"], 0
                ]
            }
            line = czml.Polyline(
                show=True,
                positions=positions,
                width=1,
                material={"solidColor": {
                    "color": {
                        "rgba": color
                    }
                }})
            packet.polyline = line
            self.doc.packets.append(packet)
            count += 1
        if self._verbose:
            print("CZMLWriter.add_network: %d network segments added." % count)
        return count
Beispiel #6
0
    def add_simplified_vector_migrations(self, vector_migrations, demographics,
                                         migration_duration_timesteps,
                                         arrow_color, arrow_thickness_pixels):
        """Adds vector cohort migration animations to a CZML output.

        This function, given vector migrations in a particular format and a
        demographics file, adds "comet" animations for migration events.

        This function expects the following fields in vector_migrations:

            * Time (int): the timestep of the beginning of the migration event
            * FromNodeID (int): the node ID from which the migration emanates
            * ToNodeID (int): the node ID to which the migration completes

        Returns:
            Number of vector cohort migrations in animation layer

        Args:
            vector_migrations (CSVReport): The ReportVectorMigrations.csv
            report.

            demographics (Demographics): The Demographics object describing the
            nodes.

            migration_duration_timesteps (int): The duration of the migration
            animations in timesteps.

            arrow_color (string): A CSS #rrggbb color for the migration arrow.

            arrow_thickness_pixels (float): Thickness in pixels of comet tail.

        """
        czml.Material._properties = \
            ('grid', 'image', 'stripe', 'solidColor', 'polylineGlow',
             'polylineOutline', 'polylineArrow')

        # This is a little ugly - I run-time extend Material with a
        # PolylineArrow property, since the one in module czml lacks that.
        class PolylineArrow(czml._CZMLBaseObject):
            """Colors the line with a color and an arrow."""
            _color = None
            _properties = ('color', )

        czml.Material._polylineArrow = None
        czml.Material.polylineArrow = czml.class_property(
            PolylineArrow,
            'polylineArrow',
            doc="""Colors the line with a color and an arrow.""")

        count = 0
        for row in vector_migrations:
            timestep = int(row["Time"])
            from_node_id = row["FromNodeID"]
            to_node_id = row["ToNodeID"]
            if not (from_node_id in demographics
                    and to_node_id in demographics):
                continue
            from_node = demographics[from_node_id]
            to_node = demographics[to_node_id]
            dur_seconds = migration_duration_timesteps * 60 * 60 * 24
            availability = self._timestep_to_iso(timestep) + "/" +\
                self._timestep_to_iso(timestep + migration_duration_timesteps)
            id_txt = "%s-%s@%d_%d" % (from_node_id, to_node_id, timestep,
                                      count)
            ac = Color.from_html_hash(arrow_color)
            packet = czml.CZMLPacket(id=id_txt, availability=availability)
            polyline = czml.Polyline(
                followSurface=False,
                positions={
                    "cartographicDegrees": [
                        from_node["NodeAttributes"]["Longitude"],
                        from_node["NodeAttributes"]["Latitude"],
                        0,  # altitude
                        to_node["NodeAttributes"]["Longitude"],
                        to_node["NodeAttributes"]["Latitude"],
                        0  # altitude
                    ]
                },
                material={
                    "polylineArrow": {
                        "color": {
                            "epoch":
                            self._timestep_to_iso(timestep),
                            "rgba": [
                                0, ac.r, ac.g, ac.b, 255,
                                dur_seconds + 60 * 60 * 12, ac.r, ac.g, ac.b, 0
                            ]
                        }
                    }
                },
                width=arrow_thickness_pixels)
            packet.polyline = polyline
            self.doc.packets.append(packet)
            count += 1
        if self._verbose:
            print("CZMLWriter.add_vector_migrations: %d migrations added." %\
                count)
        return count
Beispiel #7
0
    def czml(self):

        doc = czml.CZML();
        iso = self.date.isoformat()

        # Generate time-specific lists for various objects
        central_polyline_degrees = []
        north_polyline_degrees = []
        south_polyline_degrees = []
        ellipse_position = []
        ellipse_semiMajorAxis = []
        ellipse_semiMinorAxis = []
        ellipse_rotation = []

        for t in range(len(self.time)):

            time = iso + "T" + self.time[t] + ":00Z"

            # Define polyline waypoints only where data exist
            if self.position['north'][t] != None:
                north_polyline_degrees += [self.position['north'][t][0], self.position['north'][t][1], 0.0]
            if self.position['central'][t] != None:
                central_polyline_degrees += [self.position['central'][t][0], self.position['central'][t][1], 0.0]
            if self.position['south'][t] != None:
                south_polyline_degrees += [self.position['south'][t][0], self.position['south'][t][1], 0.0]

            # Define ellipse positions and attributes for every time in the interval, using limits where necessary
            use_limit = min(int(math.floor(t/(len(self.time)/2))),1)
            if self.position['north'][t] == None:
                north = self.limits['north'][use_limit]
            else:
                north = self.position['north'][t]
            if self.position['central'][t] == None:
                central = self.limits['central'][use_limit]
            else:
                central = self.position['central'][t]
            if self.position['south'][t] == None:
                south = self.limits['south'][use_limit]
            else:
                south = self.position['south'][t]

            # Approximate ellipse semiMajorAxis from vincenty distance between limit polylines
            north2 = (north[1], north[0])
            south2 = (south[1], south[0])
            semi_major_axis = vincenty(north2, south2).meters / 2

            # Approximate elipse semiMinorAxis from sun altitude (probably way wrong!)
            ellipse_axis_ratio = self.sun_altitude[t] / 90
            semi_minor_axis = semi_major_axis * ellipse_axis_ratio

            # Approximate ellipse rotation using basic spheroid (TODO: replace with WGS-84)
            # Calculate bearing in both directions and average them
            nlat = north[1]/180 * math.pi;
            nlon = north[0]/180 * math.pi;
            clat = central[1]/180 * math.pi;
            clon = central[0]/180 * math.pi;
            slat = south[1]/180 * math.pi;
            slon = south[0]/180 * math.pi;

            y = math.sin(slon-nlon) * math.cos(slat);
            x = math.cos(nlat) * math.sin(slat) - math.sin(nlat) * math.cos(slat) * math.cos(slon-nlon);
            initial_bearing = math.atan2(y, x)
            if (initial_bearing < 0):
                initial_bearing += math.pi * 2

            y = math.sin(nlon-slon) * math.cos(nlat);
            x = math.cos(slat) * math.sin(nlat) - math.sin(slat) * math.cos(nlat) * math.cos(nlon-slon);
            final_bearing = math.atan2(y, x) - math.pi
            if (final_bearing < 0):
                final_bearing += math.pi * 2

            rotation = -1 * ((initial_bearing + final_bearing) / 2 - (math.pi / 2))

            ellipse_position += [time, central[0], central[1], 0.0]
            ellipse_semiMajorAxis += [time, round(semi_major_axis, 3)]
            ellipse_semiMinorAxis += [time, round(semi_minor_axis, 3)]
            ellipse_rotation += [time, round(rotation, 3)]        

        # Generate document packet with clock
        start_time = iso + "T" + self.time[0] + ":00Z"
        end_time = iso + "T" + self.time[-1] + ":00Z"
        packet = czml.CZMLPacket(id='document',version='1.0')
        c = czml.Clock()
        c.multiplier = 300
        c.range = "LOOP_STOP"
        c.step = "SYSTEM_CLOCK_MULTIPLIER"
        c.currentTime = start_time
        c.interval = start_time + "/" + end_time
        packet.clock = c
        doc.packets.append(packet)

        # Generate a polyline packet for the north and south polylines, connected and filled
        limit_polyline_degrees = list(north_polyline_degrees)
        point = len(south_polyline_degrees)/3
        while (point > 0):
            offset = (point-1) * 3
            limit_polyline_degrees += [ south_polyline_degrees[offset],
                                        south_polyline_degrees[offset+1],
                                        south_polyline_degrees[offset+2] ]
            point -= 1
        packet_id = iso + '_bounds_polygon'
        packet = czml.CZMLPacket(id=packet_id)
        boc = czml.Color(rgba=(232, 72, 68, 255))
        bsc = czml.SolidColor(color=czml.Color(rgba=(0, 0, 0, 66)))
        bmat = czml.Material(solidColor=bsc)
        bdeg = limit_polyline_degrees
        bpos = czml.Positions(cartographicDegrees=bdeg)
        bpg = czml.Polygon(show=True, height=0, outline=True, outlineColor=boc, outlineWidth=2, material=bmat, positions=bpos)
        packet.polygon = bpg
        doc.packets.append(packet)

        # Generate central polyline packet
        packet_id = iso + '_central_polyline'
        packet = czml.CZMLPacket(id=packet_id)
        csc = czml.SolidColor(color=czml.Color(rgba=(241, 226, 57, 255)))
        cmat = czml.Material(solidColor=csc)
        cpos = czml.Positions(cartographicDegrees=central_polyline_degrees)
        cpl = czml.Polyline(show=True, width=4, followSurface=True, material=cmat, positions=cpos)
        packet.polyline = cpl
        doc.packets.append(packet)

        # Generate ellipse shadow packet
        packet_id = iso + '_shadow_ellipse'
        packet = czml.CZMLPacket(id=packet_id)
        esc = czml.SolidColor(color=czml.Color(rgba=(0, 0, 0, 160)))
        emat = czml.Material(solidColor=esc)
        xmaj = czml.Number(ellipse_semiMajorAxis)
        xmin = czml.Number(ellipse_semiMinorAxis)
        rot = czml.Number(ellipse_rotation)
        ell = czml.Ellipse(show=True, fill=True, granularity=0.002, material=emat, semiMajorAxis=xmaj, semiMinorAxis=xmin, rotation=rot)
        packet.ellipse = ell
        packet.position = czml.Position(cartographicDegrees=ellipse_position)
        doc.packets.append(packet)

        return list(doc.data())