示例#1
0
    def testDocument(self):

        # Create a new document packet
        doc_packet1 = czml.CZMLPacket(id='document', version='1.0')
        self.assertEqual(doc_packet1.data(), {
            'id': 'document',
            'version': '1.0'
        })

        # Modify an existing document packet
        doc_packet1.version = '1.1'
        self.assertEqual(doc_packet1.data(), {
            'id': 'document',
            'version': '1.1'
        })

        # Create a new document packet from an existing document packet
        doc_packet2 = czml.CZMLPacket()
        doc_packet2.loads(doc_packet1.dumps())
        self.assertEqual(doc_packet1.data(), doc_packet2.data())

        # Test that version can only be added to the document packet (id='document')
        with self.assertRaises(Exception):
            doc_packet1 = czml.CZMLPacket(id='foo', version='1.0')
        doc_packet1 = czml.CZMLPacket(id='foo')
        self.assertRaises(Exception, setattr, doc_packet1, 'version', '1.0')

        # Test the writing of CZML using the write() method and the reading of that CZML using the loads() method
        doc = czml.CZML()
        doc.packets.append(doc_packet2)
        label_packet = czml.CZMLPacket(id='label')
        label = czml.Label()
        label.text = 'test label'
        label.show = True
        label_packet.label = label
        doc.packets.append(label_packet)
        test_filename = 'test.czml'
        doc.write(test_filename)
        with open(test_filename, 'r') as test_file:
            doc2 = czml.CZML()
            doc2.loads(test_file.read())
            self.assertEqual(doc.dumps(), doc2.dumps())
        os.remove(test_filename)
示例#2
0
    def __init__(self, verbose=False):
        """Construct a CZMLWriter.

        Args:
            verbose (bool): Extra messaging from methods.

        """
        self.doc = czml.CZML()
        self.doc.packets.append(czml.CZMLPacket(id="document", version="1.0"))
        self.timestep_count = 0
        self.sim_end_date = None
        self.sim_start_date = None
        self._verbose = verbose
示例#3
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())
def geojsonToCzmlTotal(file, total=True):
  doc = czml.CZML()
  clock={
    'interval': '2019-12-31T00:00:00Z/2020-08-16T23:59:59Z',
    'currentTime': '2019-12-31T00:00:00Z',
    'multiplier': 320000,
    'range': 'LOOP_STOP',
    'step': 'SYSTEM_CLOCK_MULTIPLIER'
  }
  packet1 = czml.CZMLPacket(
    id='document', 
    version='1.0',
    clock=clock
  )
  doc.packets.append(packet1)

  with open(file) as f:
    ids = {}
    data = json.load(f)
    for feature in data['features']:
      total_values = 0
      if total:
        total_values = feature['properties']['total_cases'] if feature['properties']['total_cases'] != None else 0
      else:
        total_values = feature['properties']['total_deaths'] if feature['properties']['total_deaths'] != None else 0
        description = 'Total deaths on ' + feature['properties']['date'] + ' is ' + str(total_values)

      description= '\
        <h2>General Details:</h2> \
        <p>\
          Date: {date} <br /> \
          Total cases: {total_cases} <br /> \
          Total cases/million: {total_cases_pm} <br /> \
          Total deaths: {total_deaths} <br /> \
          Total deaths/million: {total_deaths_pm} <br /> \
          New cases: {new_cases} <br /> \
          New deaths: {new_deaths} <br /> \
        </p>\
        <h2>Demographic Details:</h2> \
        <p> \
          Population: {population} <br /> \
          Median age: {median_age} <br /> \
          Hospital beds/thoudsand: {hospital_beds_per_thousand} \
        </p> \
      '.format(
        date=feature['properties']['date'],
        total_cases=feature['properties']['total_cases'],
        total_cases_pm=feature['properties']['total_cases_per_million'],
        total_deaths=feature['properties']['total_deaths'],
        total_deaths_pm=feature['properties']['total_deaths_per_million'],
        new_cases=feature['properties']['new_cases'],
        new_deaths=feature['properties']['new_deaths'],
        population=feature['properties']['population'],
        median_age=feature['properties']['median_age'],
        hospital_beds_per_thousand=feature['properties']['hospital_beds_per_thousand'],
      )

      id = 0
      if feature['properties']['Address'] in ids:
        ids[feature['properties']['Address']] += 1
        id = ids[feature['properties']['Address']]
      else:
        ids[feature['properties']['Address']] = 0

      packet = czml.CZMLPacket(
        id=feature['properties']['Address']+str(id), 
        name=feature['properties']['Address'],
        description=description,
        availability=feature['properties']['date'] + 'T00:00:00.000Z'+ '/' + feature['properties']['date'] + 'T23:59:59.999Z'
      )
      # pixel_size=0
      # if total_values > 5:
      #   pixel_size = math.log(total_values)

      point = czml.Point(
        show=True,
        pixelSize=clamp(total_values, 0, 100)
      )
      # Coloring based on number of cases
      color = [255, 0, 0, 65]
      if total_values < 50:
        color = [52, 235, 61, 65]
      elif total_values >= 50 and total_values < 200:
        color = [235, 222, 52, 65]
      elif total_values >= 200 and total_values < 2000:
        color = [235, 155, 52, 65]
      else:
        color = [235, 76, 52, 65]

      point.color = {'rgba': color}
      packet.point = point
      packet.position = {
        'cartographicDegrees': [
          feature['geometry']['coordinates'][0], 
          feature['geometry']['coordinates'][1], 
          0.0
        ]
      }
      doc.packets.append(packet)
  
  # Write the czml document to a file
  if total:
    filename = "./data_total.czml"
    doc.write(filename)
  else:
    filename = "./data_deaths.czml"
    doc.write(filename)